| @@ -6,10 +6,13 @@ | ||
| 6 | 6 | |
| 7 | 7 | class ImageHelper extends AcymObject |
| 8 | 8 | { |
| 9 | 9 | public string $error = ''; |
| 10 | + // New Height the picture should be | |
| 10 | 11 | public int $maxHeight; |
| 12 | + // New Width the picture should be | |
| 11 | 13 | public int $maxWidth; |
| 14 | + // Folder where pictures should be stored | |
| 12 | 15 | public string $destination; |
| 13 | 16 | |
| 14 | 17 | public function removePictures(string $text): string |
| 15 | 18 | { |
| @@ -14,8 +17,9 @@ | ||
| 14 | 17 | public function removePictures(string $text): string |
| 15 | 18 | { |
| 16 | 19 | $return = preg_replace('#< *img((?!content_main_image)[^>])*>#Ui', '', $text); |
| 17 | 20 | |
| 21 | + // Clean JCE caption | |
| 18 | 22 | return preg_replace('#< *div[^>]*class="jce_caption"[^>]*>[^<]*(< *div[^>]*>[^<]*<\/div>)*[^<]*<\/div>#Ui', '', $return); |
| 19 | 23 | } |
| 20 | 24 | |
| 21 | 25 | public function available(): bool |
| @@ -38,8 +42,9 @@ | ||
| 38 | 42 | |
| 39 | 43 | return true; |
| 40 | 44 | } |
| 41 | 45 | |
| 46 | + //This function will check all images from the input and return an output with the pictures transformed with the right size | |
| 42 | 47 | public function resizePictures(string $input): string |
| 43 | 48 | { |
| 44 | 49 | $this->destination = ACYM_MEDIA.'resized'.DS; |
| 45 | 50 | acym_createDir($this->destination); |
| @@ -44,8 +49,9 @@ | ||
| 44 | 49 | $this->destination = ACYM_MEDIA.'resized'.DS; |
| 45 | 50 | acym_createDir($this->destination); |
| 46 | 51 | $content = acym_absoluteURL($input); |
| 47 | 52 | |
| 53 | + //regex take all images: | |
| 48 | 54 | preg_match_all('#<img([^>]*)>#Ui', $content, $results); |
| 49 | 55 | if (empty($results[1])) { |
| 50 | 56 | return $input; |
| 51 | 57 | } |
| @@ -52,19 +58,24 @@ | ||
| 52 | 58 | |
| 53 | 59 | $replace = []; |
| 54 | 60 | |
| 55 | 61 | foreach ($results[1] as $onepicture) { |
| 62 | + //Check if there the "donotresize" element inside, we don't resize it. | |
| 63 | + //It can be either in the class or in the filename itself | |
| 56 | 64 | if (strpos($onepicture, 'donotresize') !== false) { |
| 57 | 65 | continue; |
| 58 | 66 | } |
| 59 | 67 | |
| 68 | + //Take the path | |
| 60 | 69 | if (!preg_match('#src="([^"]*)"#Ui', $onepicture, $path)) { |
| 61 | 70 | continue; |
| 62 | 71 | } |
| 63 | 72 | $imageUrl = $path[1]; |
| 64 | 73 | |
| 74 | + //images paths on joomla 4 have some content like : #joomlaImage... , we delete it to get and resize the image without errors | |
| 65 | 75 | $imageUrl = preg_replace('/#joomlaImage.*/', '', $imageUrl); |
| 66 | 76 | |
| 77 | + //We are nice guys... sometimes users use www. or not... so we convert both, same thing for httpS or http | |
| 67 | 78 | $imageUrl = acym_internalUrlToPath($imageUrl); |
| 68 | 79 | |
| 69 | 80 | $newPicture = $this->generateThumbnail($imageUrl); |
| 70 | 81 | |
| @@ -69,8 +80,9 @@ | ||
| 69 | 80 | $newPicture = $this->generateThumbnail($imageUrl); |
| 70 | 81 | |
| 71 | 82 | $newDimension = 'max-width:'.$this->maxWidth.'px;max-height:'.$this->maxHeight.'px;'; |
| 72 | 83 | |
| 84 | + //Maybe we don't need to resize anything... | |
| 73 | 85 | if (empty($newPicture)) { |
| 74 | 86 | if (strpos($onepicture, 'style="') !== false) { |
| 75 | 87 | $replace[$onepicture] = preg_replace('#style="([^"]*)"#Uis', 'style="'.$newDimension.'$1"', $onepicture); |
| 76 | 88 | } else { |
| @@ -78,12 +90,15 @@ | ||
| 78 | 90 | } |
| 79 | 91 | continue; |
| 80 | 92 | } |
| 81 | 93 | |
| 94 | + //Because the ACYM_ROOT may be empty, we only make sure to replace the first instance found. | |
| 82 | 95 | $newPicture['file'] = preg_replace('#^'.preg_quote(ACYM_ROOT, '#').'#i', ACYM_LIVE, $newPicture['file']); |
| 83 | 96 | $newPicture['file'] = str_replace(DS, '/', $newPicture['file']); |
| 97 | + //replace the image url now with the new one... | |
| 84 | 98 | $replaceImage = []; |
| 85 | 99 | $replaceImage[$path[1]] = $newPicture['file']; |
| 100 | + //replace information if we had some (height,width...) | |
| 86 | 101 | if (preg_match_all('#(width|height)(:|=) *"?([0-9]+)#i', $onepicture, $resultsSize)) { |
| 87 | 102 | foreach ($resultsSize[0] as $i => $oneArg) { |
| 88 | 103 | $newVal = (strtolower($resultsSize[1][$i]) == 'width') ? $newPicture['width'] : $newPicture['height']; |
| 89 | 104 | if ($newVal > $resultsSize[3][$i]) { |
| @@ -94,8 +109,9 @@ | ||
| 94 | 109 | } |
| 95 | 110 | |
| 96 | 111 | $replace[$onepicture] = str_replace(array_keys($replaceImage), $replaceImage, $onepicture); |
| 97 | 112 | |
| 113 | + // Make sure that we resized the image | |
| 98 | 114 | if (strpos($replace[$onepicture], 'width') === false) { |
| 99 | 115 | if (strpos($onepicture, 'style="') !== false) { |
| 100 | 116 | $replace[$onepicture] = preg_replace('#style="([^"]*)"#Uis', 'style="'.$newDimension.'$1"', $replace[$onepicture]); |
| 101 | 117 | } else { |
| @@ -135,8 +151,9 @@ | ||
| 135 | 151 | $filename = basename($picturePath); |
| 136 | 152 | } |
| 137 | 153 | |
| 138 | 154 | if (substr($picturePath, 0, 10) == 'data:image') { |
| 155 | + //It's a picture in base64 encoding... we will apply an extension name and name based on the content... | |
| 139 | 156 | preg_match('#data:image/([^;]{1,5});#', $picturePath, $resultextension); |
| 140 | 157 | if (empty($resultextension[1])) { |
| 141 | 158 | return []; |
| 142 | 159 | } |
| @@ -144,8 +161,10 @@ | ||
| 144 | 161 | $name = md5($picturePath); |
| 145 | 162 | } else { |
| 146 | 163 | $extension = strtolower(substr($filename, strrpos($filename, '.') + 1)); |
| 147 | 164 | $name = strtolower(substr($filename, 0, strrpos($filename, '.'))); |
| 165 | + //We add the creation date of the file so if the file is modified, we will generate a new thumbnail | |
| 166 | + //No need to use the full date, the last 4 characters will be enough! | |
| 148 | 167 | $name .= substr(@filemtime($picturePath), -4); |
| 149 | 168 | } |
| 150 | 169 | |
| 151 | 170 | $newImage = md5($picturePath).'-'.$name.'thumb'.$this->maxWidth.'x'.$this->maxHeight.'.'.$extension; |
| @@ -154,8 +173,9 @@ | ||
| 154 | 173 | } else { |
| 155 | 174 | $newFile = $this->destination.$newImage; |
| 156 | 175 | } |
| 157 | 176 | |
| 177 | + //The new file already exists, we don't have to create a new one | |
| 158 | 178 | if (file_exists($newFile)) { |
| 159 | 179 | return [ |
| 160 | 180 | 'file' => $newFile, |
| 161 | 181 | 'width' => $newWidth, |
| @@ -162,8 +182,9 @@ | ||
| 162 | 182 | 'height' => $newHeight, |
| 163 | 183 | ]; |
| 164 | 184 | } |
| 165 | 185 | |
| 186 | + // Checks the real file type as it can be renamed, but not available on all servers | |
| 166 | 187 | if (function_exists('exif_imagetype')) { |
| 167 | 188 | $imageRealType = exif_imagetype($picturePath); |
| 168 | 189 | } else { |
| 169 | 190 | if ($extension === 'gif') { |
| @@ -235,8 +256,9 @@ | ||
| 235 | 256 | $status = $status && acym_writeFile($newFile, $imageContent); |
| 236 | 257 | imagedestroy($thumb); |
| 237 | 258 | imagedestroy($img); |
| 238 | 259 | |
| 260 | + //We could not create the picture... so let's resize it anyway | |
| 239 | 261 | if (!$status) { |
| 240 | 262 | $newFile = $picturePath; |
| 241 | 263 | } |
| 242 | 264 | |