diff --git a/bl-kernel/helpers/simple-image.class.php b/bl-kernel/helpers/simple-image.class.php index bfc89455..51e56733 100644 --- a/bl-kernel/helpers/simple-image.class.php +++ b/bl-kernel/helpers/simple-image.class.php @@ -1,6 +1,6 @@ flags = [ + "sslVerify" => true // Skip SSL peer validation + ]; + + // Override default flag values. + foreach($flags as $flag => $value) { + $this->setFlag($flag, $value); + } + // Load an image through the constructor if(preg_match('/^data:(.*?);/', $image)) { $this->fromDataUri($image); @@ -77,6 +89,37 @@ class SimpleImage { } } + ////////////////////////////////////////////////////////////////////////////////////////////////// + // Helper functions + ////////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * Set flag value. + * + * @param string $flag Name of the flag to set. + * @param boolean $value State of the flag. + * @throws \Exception Thrown if flag does not exist (no default value). + */ + public function setFlag($flag, $value) { + // Throw if flag does not exist + if(!in_array($flag, array_keys($this->flags))) { + throw new \Exception('Invalid flag.', self::ERR_INVALID_FLAG); + } + + // Set flag value by name + $this->flags[$flag] = $value; + } + + /** + * Get flag value. + * + * @param string $flag Name of the flag to get. + * @return boolean|null + */ + public function getFlag($flag) { + return in_array($flag, array_keys($this->flags)) ? $this->flags[$flag] : null; + } + ////////////////////////////////////////////////////////////////////////////////////////////////// // Loaders ////////////////////////////////////////////////////////////////////////////////////////////////// @@ -118,70 +161,66 @@ class SimpleImage { * Loads an image from a file. * * @param string $file The image file to load. + * @param boolean $sslVerify Set to false to skip SSL validation. * @throws \Exception Thrown if file or image data is invalid. * @return \claviska\SimpleImage */ public function fromFile($file) { - // Check if the file exists and is readable. We're using fopen() instead of file_exists() - // because not all URL wrappers support the latter. - $handle = @fopen($file, 'r'); - if($handle === false) { + // Set fopen options. + $sslVerify = $this->getFlag("sslVerify"); // Don't perform peer validation when true + $opts = [ + "ssl" => [ + "verify_peer" => $sslVerify, + "verify_peer_name" => $sslVerify + ] + ]; + + // Check if the file exists and is readable. + $file = @file_get_contents($file, false, stream_context_create($opts)); + if($file === false) { throw new \Exception("File not found: $file", self::ERR_FILE_NOT_FOUND); } - fclose($handle); + + // Create image object from string + $this->image = imagecreatefromstring($file); // Get image info - $info = @getimagesize($file); + $info = @getimagesizefromstring($file); if($info === false) { throw new \Exception("Invalid image file: $file", self::ERR_INVALID_IMAGE); } $this->mimeType = $info['mime']; - // Create image object from file - switch($this->mimeType) { - case 'image/gif': - // Load the gif - $gif = imagecreatefromgif($file); - if($gif) { - // Copy the gif over to a true color image to preserve its transparency. This is a - // workaround to prevent imagepalettetruecolor() from borking transparency. - $width = imagesx($gif); - $height = imagesy($gif); - $this->image = imagecreatetruecolor($width, $height); - $transparentColor = imagecolorallocatealpha($this->image, 0, 0, 0, 127); - imagecolortransparent($this->image, $transparentColor); - imagefill($this->image, 0, 0, $transparentColor); - imagecopy($this->image, $gif, 0, 0, 0, 0, $width, $height); - imagedestroy($gif); - } - break; - case 'image/jpeg': - $this->image = imagecreatefromjpeg($file); - break; - case 'image/png': - $this->image = imagecreatefrompng($file); - break; - case 'image/webp': - $this->image = imagecreatefromwebp($file); - break; - case 'image/bmp': - case 'image/x-ms-bmp': - case 'image/x-windows-bmp': - $this->image = imagecreatefrombmp($file); - break; - } if(!$this->image) { throw new \Exception("Unsupported format: " . $this->mimeType, self::ERR_UNSUPPORTED_FORMAT); } + switch($this->mimeType) { + case 'image/gif': + // Copy the gif over to a true color image to preserve its transparency. This is a + // workaround to prevent imagepalettetotruecolor() from borking transparency. + $width = imagesx($this->image); + $height = imagesx($this->image); + + $gif = imagecreatetruecolor((int) $width, (int) $height); + $alpha = imagecolorallocatealpha($gif, 0, 0, 0, 127); + imagecolortransparent($gif, $alpha); + imagefill($gif, 0, 0, $alpha); + + imagecopy($this->image, $gif, 0, 0, 0, 0, $width, $height); + imagedestroy($gif); + break; + case 'image/jpeg': + // Load exif data from JPEG images + if(function_exists('exif_read_data')) { + $this->exif = @exif_read_data("data://image/jpeg;base64," . base64_encode($file)); + } + break; + } + // Convert pallete images to true color images imagepalettetotruecolor($this->image); - // Load exif data from JPEG images - if($this->mimeType === 'image/jpeg' && function_exists('exif_read_data')) { - $this->exif = @exif_read_data($file); - } - return $this; } @@ -194,7 +233,7 @@ class SimpleImage { * @return \claviska\SimpleImage */ public function fromNew($width, $height, $color = 'transparent') { - $this->image = imagecreatetruecolor($width, $height); + $this->image = imagecreatetruecolor((int) $width, (int) $height); // Use PNG for dynamically created images because it's lossless and supports transparency $this->mimeType = 'image/png'; @@ -490,7 +529,7 @@ class SimpleImage { imagefilter($srcIm, IMG_FILTER_COLORIZE, 0, 0, 0, 127 * ((100 - $pct) / 100)); } - imagecopy($dstIm, $srcIm, $dstX, $dstY, $srcX, $srcY, $srcW, $srcH); + imagecopy($dstIm, $srcIm, (int) $dstX, (int) $dstY, (int) $srcX, (int) $srcY, (int) $srcW, (int) $srcH); return true; } @@ -593,7 +632,7 @@ class SimpleImage { // Avoid using native imagecrop() because of a bug with PNG transparency $dstW = abs($x2 - $x1); $dstH = abs($y2 - $y1); - $newImage = imagecreatetruecolor($dstW, $dstH); + $newImage = imagecreatetruecolor((int) $dstW, (int) $dstH); $transparentColor = imagecolorallocatealpha($newImage, 0, 0, 0, 127); imagecolortransparent($newImage, $transparentColor); imagefill($newImage, 0, 0, $transparentColor); @@ -603,10 +642,10 @@ class SimpleImage { $newImage, $this->image, 0, 0, min($x1, $x2), min($y1, $y2), - $dstW, - $dstH, - $dstW, - $dstH + (int) $dstW, + (int) $dstH, + (int) $dstW, + (int) $dstH ); // Swap out the new image @@ -802,7 +841,7 @@ class SimpleImage { // We can't use imagescale because it doesn't seem to preserve transparency properly. The // workaround is to create a new truecolor image, allocate a transparent color, and copy the // image over to it using imagecopyresampled. - $newImage = imagecreatetruecolor($width, $height); + $newImage = imagecreatetruecolor((int) $width, (int) $height); $transparentColor = imagecolorallocatealpha($newImage, 0, 0, 0, 127); imagecolortransparent($newImage, $transparentColor); imagefill($newImage, 0, 0, $transparentColor); @@ -810,8 +849,8 @@ class SimpleImage { $newImage, $this->image, 0, 0, 0, 0, - $width, - $height, + (int) $width, + (int) $height, $this->getWidth(), $this->getHeight() ); @@ -1885,7 +1924,7 @@ class SimpleImage { $color['red'], $color['green'], $color['blue'], - 127 - ($color['alpha'] * 127) + (int) (127 - ($color['alpha'] * 127)) ); if($index > -1) { // Yes, return this color index diff --git a/bl-plugins/twitter-cards/languages/cs_CZ.json b/bl-plugins/twitter-cards/languages/cs_CZ.json new file mode 100644 index 00000000..3b3edfcc --- /dev/null +++ b/bl-plugins/twitter-cards/languages/cs_CZ.json @@ -0,0 +1,13 @@ +{ + "plugin-data": + { + "name": "Twitter Cards", + "description": "With Twitter Cards, you can attach rich photos, videos and media experiences to Tweets, helping to drive traffic to your website." + }, + "default-image": "Výchozí obrázek", + "twitter-site-profile": "Profil stránky na Twitteru", + "twitter-author-profile": "Profil autora příspěvku na Twitteru", + "minimum-image-dimensions": "Minimální rozměry obrázku jsou 300x157px a maximum 4096x4096px.", + "image-must-be-less": "Obrázek musí být menší než 5MB.", + "formats-are-supported": "Jsou podporovány formáty pouze JPG, PNG, WEBP a GIF." +} diff --git a/bl-plugins/twitter-cards/languages/en.json b/bl-plugins/twitter-cards/languages/en.json index 5f98378d..f314a695 100644 --- a/bl-plugins/twitter-cards/languages/en.json +++ b/bl-plugins/twitter-cards/languages/en.json @@ -4,5 +4,10 @@ "name": "Twitter Cards", "description": "With Twitter Cards, you can attach rich photos, videos and media experiences to Tweets, helping to drive traffic to your website." }, - "default-image": "Default image" -} \ No newline at end of file + "default-image": "Default image", + "twitter-site-profile": "Twitter site profile", + "twitter-author-profile": "Twitter author profile", + "minimum-image-dimensions": "The minimum image dimensions are 300x157px and the maximum 4096x4096px.", + "image-must-be-less": "Image must be less than 5MB in size.", + "formats-are-supported": "JPG, PNG, WEBP and GIF formats are supported." +} diff --git a/bl-plugins/twitter-cards/metadata.json b/bl-plugins/twitter-cards/metadata.json index d62ed64e..5540bdca 100644 --- a/bl-plugins/twitter-cards/metadata.json +++ b/bl-plugins/twitter-cards/metadata.json @@ -3,8 +3,8 @@ "email": "", "website": "https://plugins.bludit.com", "version": "4.0.0", - "releaseDate": "2021-05-23", + "releaseDate": "2022-10-01", "license": "MIT", "compatible": "4.0.0", "notes": "" -} \ No newline at end of file +} diff --git a/bl-plugins/twitter-cards/plugin.php b/bl-plugins/twitter-cards/plugin.php index 26acdc80..754e3df1 100644 --- a/bl-plugins/twitter-cards/plugin.php +++ b/bl-plugins/twitter-cards/plugin.php @@ -6,7 +6,9 @@ class pluginTwitterCards extends Plugin { { // Fields and default values for the database of this plugin $this->dbFields = array( - 'defaultImage'=>'' + 'defaultImage' => '', + 'twitterSite' => '', + 'twitterCreator' => '' ); } @@ -14,9 +16,24 @@ class pluginTwitterCards extends Plugin { { global $L; - $html = '
' . $L->get('minimum-image-dimensions') . ' ' . $L->get('image-must-be-less') . ' ' . $L->get('formats-are-supported') . '
'; + $html .= '' . $error . ' | +' . $L->get( $error ) . ' |
---|