Skip to content

Commit

Permalink
Year in Review
Browse files Browse the repository at this point in the history
Dynamically generate images for use in Year in Review
  • Loading branch information
mdnoble73 committed Nov 27, 2024
1 parent 3eb881b commit 7d838b8
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 90 deletions.
21 changes: 5 additions & 16 deletions code/web/interface/themes/responsive/YearInReview/slide.tpl
Original file line number Diff line number Diff line change
@@ -1,20 +1,9 @@
{strip}
<div style="display: block">
<div style="object-fit: contain">
<img class="img-responsive" src="/year_in_review/images/{$slideInfo->background_lg}" alt="Year in review background"/>
</div>
{foreach from=$slideInfo->overlay_text item=textInfo}
<div style="display: block;
position: absolute;
top:{$textInfo->top};
left:{$textInfo->left};
width:{$textInfo->width};
height:{$textInfo->height};
color:{$textInfo->color};
font-size:{$textInfo->font_size};
text-align:{$textInfo->align}">
{$textInfo->text}
</div>
{/foreach}
{if empty($slideInfo->overlay_text)}
<img class="img-responsive" src="/year_in_review/images/{$slideInfo->background}" alt="Year in review background"/>
{else}
<img class="img-responsive" src="/MyAccount/AJAX?method=getYearInReviewSlideImage&slide={$slideNumber}" alt="Year in review background"/>
{/if}
</div>
{/strip}
3 changes: 2 additions & 1 deletion code/web/release_notes/24.12.00.MD
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
### Indexing Updates
- Add a new format for Tonies based on a publisher (260b, 264b, 710a) containing Boxine and a title (245a) containing Tonie. (*MDN*)
- Add a new format for Yoto based on a publisher (260b, 264b, 710a) containing Yoto and a title (245a) containing Yoto. (*MDN*)
- When filtering formats, if Zines is active, discard other formats. (*MDN*)
- When filtering formats, if Zines is active, discard other formats. (DIS-56) (*MDN*)
- When checking for the Zines format, ignore trailing punctuation. (DIS-56) (*MDN*)

### Local ILL (DIS-34)
- Add new settings to configure the Local ILL system in use. (*MDN*)
Expand Down
30 changes: 30 additions & 0 deletions code/web/services/MyAccount/AJAX.php
Original file line number Diff line number Diff line change
Expand Up @@ -8743,4 +8743,34 @@ function getYearInReviewSlide() : array {

return $result;
}

function getYearInReviewSlideImage() {
$gotImage = false;
//This returns an image to the browser
if (UserAccount::isLoggedIn()) {
$patron = UserAccount::getActiveUserObj();

//TODO: Take this out, the data should already be generated at this point
require_once ROOT_DIR . '/sys/YearInReview/YearInReviewGenerator.php';
generateYearInReview($patron);

if ($patron->hasYearInReview()) {
$slideNumber = $_REQUEST['slide'] ?? 1;
if (is_numeric($slideNumber)) {
$yearInReviewSettings = $patron->getYearInReviewSetting();
$gotImage = $yearInReviewSettings->getSlideImage($patron, (int)$slideNumber);
}
}
}
if (!$gotImage) {
global $interface;
$interface->assign('module', 'Error');
$interface->assign('action', 'Handle404');
$module = 'Error';
$action = 'Handle404';
require_once ROOT_DIR . "/services/Error/Handle404.php";
}
//Since this returns an image, don't return
die();
}
}
1 change: 0 additions & 1 deletion code/web/sys/DBMaintenance/version_updates/24.12.00.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ function getUpdates24_12_00(): array {
libraryId INT NOT NULL,
UNIQUE (yearInReviewId, libraryId)
) ENGINE INNODB CHARACTER SET utf8 COLLATE utf8_general_ci',
'DROP TABLE user_year_in_review',
'CREATE TABLE user_year_in_review (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
userId INT NOT NULL,
Expand Down
108 changes: 106 additions & 2 deletions code/web/sys/YearInReview/YearInReviewSetting.php
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ public function getSlide(User $patron, int|string $slideNumber) : array {
}

$result['slideConfiguration'] = $slideInfo;
$result['modalBody'] = $this->formatSlide($slideInfo, $patron);
$result['modalBody'] = $this->formatSlide($slideInfo, $patron, $slideNumber, $this->year);

$modalButtons = '';
if ($slideNumber > 1) {
Expand Down Expand Up @@ -251,9 +251,113 @@ public function getSlide(User $patron, int|string $slideNumber) : array {
return $result;
}

private function formatSlide(stdClass $slideInfo, User $patron) : string {
private function formatSlide(stdClass $slideInfo, User $patron, int $slideNumber, string|int $year) : string {
global $interface;
$interface->assign('slideNumber', $slideNumber);
$interface->assign('slideInfo', $slideInfo);
return $interface->fetch('YearInReview/slide.tpl');
}

public function getSlideImage(User $patron, int|string $slideNumber) : bool {
//Load slide configuration for the year
$gotImage = true;
$configurationFile = ROOT_DIR . "/year_in_review/$this->year.json";
if (file_exists($configurationFile)) {
$slideConfiguration = json_decode(file_get_contents($configurationFile));
$userYearInResults = $patron->getYearInReviewResults();
if ($userYearInResults !== false) {
if ($slideNumber > 0 && $slideNumber <= $userYearInResults->numSlidesToShow) {
$slideIndex = $userYearInResults->slidesToShow[$slideNumber - 1];
$slideInfo = $slideConfiguration->slides[$slideIndex - 1];

foreach ($slideInfo->overlay_text as $overlayText) {
foreach ($userYearInResults->userData as $field => $value) {
$overlayText->text = str_replace("{" . $field . "}", $value, $overlayText->text);
}
}

$gotImage = $this->createSlideImage($slideInfo);
}
}
}

return $gotImage;
}

private function createSlideImage(stdClass $slideInfo) : ?string {
$gotImage = false;
if (count($slideInfo->overlay_text) == 0) {
//This slide is not dynamic, we just return the static contents
}else{
require_once ROOT_DIR . '/sys/Covers/CoverImageUtils.php';
global $configArray;
//Get the background image for the slide
$backgroundImageFile = ROOT_DIR . '/year_in_review/images/' . $slideInfo->background;
$backgroundImageFile = realpath($backgroundImageFile);
$backgroundImage = imagecreatefrompng($backgroundImageFile);
$backgroundImageInfo = getimagesize($backgroundImageFile);
$backgroundWidth = $backgroundImageInfo[0];
$backgroundHeight = $backgroundImageInfo[1];
//Create a canvas for the slide
$slideCanvas = imagecreatetruecolor($backgroundWidth, $backgroundHeight);
//Display the background to the slide
imagecopy($slideCanvas, $backgroundImage, 0, 0, 0, 0, $backgroundWidth, $backgroundHeight);

$font = ROOT_DIR . '/fonts/JosefinSans-Bold.ttf';
$white = imagecolorallocate($slideCanvas, 255, 255, 255);
$black = imagecolorallocate($slideCanvas, 0, 0, 0);

//Add overlay text to the image
foreach ($slideInfo->overlay_text as $overlayText) {
$overlayWidth = $overlayText->width;
if (str_ends_with($overlayWidth,'%')) {
$percent = str_replace('%', '', $overlayWidth) / 100;
$textWidth = $backgroundWidth * $percent;
}else{
$textWidth = $overlayWidth;
}
$fontSize = $overlayText->font_size;
if (str_ends_with($fontSize,'em')) {
$fontSize = str_replace('em', '', $fontSize) * 16;
}
$left = $overlayText->left;
if (str_ends_with($left,'%')) {
$percent = str_replace('%', '', $left) / 100;
$left = $backgroundWidth * $percent;
}elseif (str_ends_with($left,'px')) {
$left = str_replace('px', '', $left);
}
$top = $overlayText->top;
if (str_ends_with($top,'%')) {
$percent = str_replace('%', '', $top) / 100;
$top = $backgroundWidth * $percent;
}elseif (str_ends_with($top,'px')) {
$top = str_replace('px', '', $top);
}

if ($overlayText == 'white') {
$color = $white;
}else{
$color = $black;
}

[
$totalHeight,
$lines,
] = wrapTextForDisplay($font, $overlayText->text, $fontSize, $fontSize * .1, $textWidth);
if ($overlayText->align == 'center') {
addCenteredWrappedTextToImage($slideCanvas, $font, $lines, $fontSize, $fontSize * .1, $left, $top, $textWidth, $color);
}else{
addWrappedTextToImage($slideCanvas, $font, $lines, $fontSize, $fontSize * .1, $left, $top, $color);
}
}

//Output the image to the browser
imagepng($slideCanvas);
imagedestroy($slideCanvas);
$gotImage = true;
}

return $gotImage;
}
}
Loading

0 comments on commit 7d838b8

Please sign in to comment.