Advertisement
Guest User

Untitled

a guest
Jun 20th, 2018
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.89 KB | None | 0 0
  1. <?php
  2.  
  3. class ogImage
  4. {
  5. /**
  6. * @var modX $modx
  7. * @var array $params
  8. * @var array $config
  9. * @var string $error
  10. */
  11. public $modx, $params;
  12. private $config, $error = '';
  13.  
  14.  
  15. /**
  16. * @param modX $modx
  17. * @param array $params
  18. */
  19. function __construct(modX &$modx, array $params = array())
  20. {
  21. $this->modx =& $modx;
  22.  
  23. $corePath = $this->modx->getOption('ogimage_core_path', null,
  24. $this->modx->getOption('core_path') . 'components/ogimage/'
  25. );
  26. $assetsUrl = $this->modx->getOption('ogimage_assets_url', null,
  27. $this->modx->getOption('assets_url') . 'components/ogimage/'
  28. );
  29.  
  30. $this->config = array(
  31. 'assetsUrl' => $assetsUrl,
  32. 'cssUrl' => $assetsUrl . 'css/',
  33. 'jsUrl' => $assetsUrl . 'js/',
  34. 'imagesUrl' => $assetsUrl . 'images/',
  35. 'connectorUrl' => $assetsUrl . 'connector.php',
  36.  
  37. 'corePath' => $corePath,
  38. 'modelPath' => $corePath . 'model/',
  39. 'chunksPath' => $corePath . 'elements/chunks/',
  40. 'templatesPath' => $corePath . 'elements/templates/',
  41. 'chunkSuffix' => '.chunk.tpl',
  42. 'snippetsPath' => $corePath . 'elements/snippets/',
  43. 'processorsPath' => $corePath . 'processors/',
  44. );
  45.  
  46. if (!$this->modx->resource) {
  47. $this->error('ogimage_resource_nf', true);
  48. return false;
  49. }
  50.  
  51. $this->setParams($params);
  52.  
  53. $this->modx->addPackage('ogimage', $this->config['modelPath']);
  54. $this->modx->lexicon->load('ogimage:default');
  55.  
  56. return;
  57. }
  58.  
  59. /**
  60. * @param string $message
  61. * @param bool $fromLexicon
  62. */
  63. public function error($message, $fromLexicon = false)
  64. {
  65. if ($fromLexicon)
  66. $message = $this->modx->lexicon($message);
  67. $this->error = $message;
  68. }
  69.  
  70. /**
  71. * @param array $params
  72. */
  73. public function setParams(array $params = array())
  74. {
  75. // valid params
  76. $valid = array(
  77. "textPosition" => array("top", "middle", "bottom"),
  78. "textAlign" => array("left", "right", "center")
  79. );
  80.  
  81. if (isset($params["fontSize"]) && !is_numeric($params["fontSize"]))
  82. unset($params["fontSize"]);
  83.  
  84. if (isset($params["lineHeight"]) && !is_numeric($params["lineHeight"]))
  85. unset($params["lineHeight"]);
  86.  
  87. if (isset($params["brightness"]) && !is_numeric($params["brightness"]))
  88. unset($params["brightness"]);
  89.  
  90. if (isset($params["padding"]) && !is_numeric($params["padding"]))
  91. unset($params["padding"]);
  92.  
  93. if (isset($params["quality"]) && !is_numeric($params["quality"]))
  94. unset($params["quality"]);
  95.  
  96. foreach ($valid as $key => $values) {
  97. if (isset($params[$key])) {
  98. if (!in_array($params[$key], $values)) {
  99. unset($params[$key]);
  100. }
  101. }
  102. }
  103.  
  104. if (isset($params["fontColor"])) {
  105. if (!preg_match("/#([a-f0-9]{3}){1,2}\b/i", $params["fontColor"]))
  106. unset($params["fontColor"]);
  107. }
  108.  
  109.  
  110. // default params
  111. $this->params = array_merge(array(
  112. 'caption' => $this->modx->getOption('site_name'),
  113. //'descriptionSrc' => 'description',
  114. 'imageSrc' => $this->config['assetsUrl'] . "ogimage_background.jpg",
  115. 'previewsUrl' => trim($this->modx->getOption('ogimage_previews_url', null)),
  116.  
  117. 'font' => trim($this->modx->getOption('ogimage_image_font_file', null)),
  118. 'textPosition' => 'top',
  119. 'textAlign' => 'left',
  120. 'fontSize' => 30,
  121. 'lineHeight' => 1.45,
  122. 'fontColor' => '#FFFFFF',
  123. 'padding' => 20,
  124. 'width' => '',
  125. 'height' => '',
  126. 'brightness' => 0,
  127. 'quality' => 90,
  128.  
  129. 'override' => false,
  130. ), $params);
  131.  
  132. $previewsPath = MODX_BASE_PATH . trim($this->params["previewsUrl"], '/\\') . "/";
  133. if (!is_dir($previewsPath)) {
  134. $this->params['previewsUrl'] = $this->config['assetsUrl'] . "previews/";
  135. }
  136. $this->params['previewsPath'] = MODX_BASE_PATH . ltrim($this->params['previewsUrl'], '/\\');
  137.  
  138. $this->params['font'] = MODX_BASE_PATH . ltrim($this->params['font'], '/\\');
  139. if (!file_exists($this->params['font']))
  140. $this->params["font"] = MODX_ASSETS_PATH . "components/ogimage/fonts/OpenSans-Regular.ttf";
  141.  
  142. // color to array
  143. $this->params['fontColor'] = sscanf($this->params['fontColor'], '#%02x%02x%02x');
  144. // convert font size
  145. $this->params['fontSize'] = $this->convertFontSize($this->params['fontSize']);
  146. $this->params['lineHeight'] = $this->params['lineHeight'] * $this->params['fontSize'];
  147. }
  148.  
  149. /**
  150. * @param $size
  151. * @return float
  152. */
  153. protected function convertFontSize($size)
  154. {
  155. return 0.75 * $size;
  156. }
  157.  
  158. /**
  159. * @return mixed
  160. */
  161. public function run()
  162. {
  163. $image = MODX_BASE_PATH . ltrim($this->params['imageSrc'], '/\\');
  164. if(!is_file($image))
  165. $this->error('ogimage_err_ne_image', true);
  166.  
  167. $title = $this->params['caption'];
  168.  
  169. $preview = $this->generatePreview($image, $title);
  170.  
  171. if (!empty($this->error)) {
  172. $this->modx->log(modX::LOG_LEVEL_ERROR, $this->error);
  173. }
  174.  
  175. $results = array(
  176. 'image' => $preview,
  177. 'title' => $title,
  178. 'error' => !empty($this->error)
  179. );
  180.  
  181. return $results;
  182. }
  183.  
  184. /**
  185. * @param string $image
  186. * @param string $text
  187. * @return mixed
  188. */
  189. public function generatePreview($image, $text)
  190. {
  191. if (!function_exists('gd_info')) {
  192. $this->error('ogimage_err_gd', true);
  193. return false;
  194. }
  195. if (!file_exists($image) || !is_file($image)) {
  196. $this->error('ogimage_err_ne_image', true);
  197. $this->error($image);
  198. return false;
  199. }
  200.  
  201. $resID = $this->modx->resource->get('id');
  202. $resultImage = $this->params['previewsPath'] . "{$resID}.jpg";
  203.  
  204. if (!$this->params['override']) {
  205. if (file_exists($resultImage)) {
  206. return $this->params['previewsUrl'] . "{$resID}.jpg";
  207. }
  208. }
  209.  
  210. $imgDimensions = getimagesize($image);
  211. $customDimensions = false;
  212. if (empty($this->params['width']))
  213. $width = $imgDimensions[0];
  214. else {
  215. $width = $this->params['width'];
  216. $customDimensions = true;
  217. }
  218.  
  219. if (empty($this->params['height']))
  220. $height = $imgDimensions[1];
  221. else {
  222. $height = $this->params['height'];
  223. $customDimensions = true;
  224. }
  225.  
  226. if($customDimensions) {
  227. $aspectRatio = $imgDimensions[0] / $imgDimensions[1];
  228. if ($width / $height > $aspectRatio) {
  229. $width = $height * $aspectRatio;
  230. } else {
  231. $height = $width / $aspectRatio;
  232. }
  233. }
  234.  
  235.  
  236. $tmpImg = imagecreatetruecolor($width, $height);
  237. imagecopyresampled($tmpImg,
  238. $this->imageCreateFromAny($image),
  239. 0, 0,
  240. 0, 0,
  241. $width, $height,
  242. $imgDimensions[0], $imgDimensions[1]
  243. );
  244.  
  245. imagefilter($tmpImg, IMG_FILTER_BRIGHTNESS, $this->params['brightness']);
  246.  
  247. $textColor = imagecolorallocate($tmpImg, $this->params["fontColor"][0], $this->params["fontColor"][1], $this->params["fontColor"][2]);
  248.  
  249. $lines = $this->prepareLines($text, $width);
  250. $lineHeight = $this->params['lineHeight'];
  251. $fontSize = $this->params['fontSize'];
  252. $textHeight = count($lines) * $lineHeight;
  253. $padding = $this->params['padding'];
  254. $i = 0;
  255. foreach ($lines as $line) {
  256. $yShift = round($i * $lineHeight);
  257. $textBox = $this->calculateTextBox($fontSize, $this->params['font'], $line);
  258. switch ($this->params['textAlign']) {
  259. case 'center':
  260. $x = ($width - $textBox['width']) / 2;
  261. break;
  262. case 'right':
  263. $x = ($width - $textBox['width']) - $padding;
  264. break;
  265. case 'left':
  266. default:
  267. $x = $padding;
  268. }
  269.  
  270. switch ($this->params['textPosition']) {
  271. case 'middle':
  272. $y = round(($height / 2) - ($textHeight / 2)) + $padding;
  273. break;
  274. case 'bottom':
  275. $y = $height - $padding - $textHeight + $fontSize;
  276. break;
  277. case 'top':
  278. default:
  279. $y = $fontSize + $padding;
  280. }
  281. $y += $yShift;
  282.  
  283. imagettftext($tmpImg, $fontSize, 0, $x, $y, $textColor, $this->params["font"], $line);
  284. $i++;
  285. }
  286.  
  287. $result = imagejpeg($tmpImg, $resultImage, $this->params['quality']);
  288. imagedestroy($tmpImg);
  289.  
  290. if ($result)
  291. return $this->params['previewsUrl'] . "{$resID}.jpg";
  292. else
  293. return false;
  294. }
  295.  
  296. /**
  297. * @param $filepath
  298. * @return bool|resource
  299. */
  300. protected function imageCreateFromAny($filepath)
  301. {
  302. $type = exif_imagetype($filepath);
  303. $allowedTypes = array(
  304. 1, // [] gif
  305. 2, // [] jpg
  306. 3, // [] png
  307. );
  308. if (!in_array($type, $allowedTypes)) {
  309. return false;
  310. }
  311. switch ($type) {
  312. case 1 :
  313. $im = imageCreateFromGif($filepath);
  314. break;
  315. case 2 :
  316. $im = imageCreateFromJpeg($filepath);
  317. break;
  318. case 3 :
  319. $im = imageCreateFromPng($filepath);
  320. break;
  321. default:
  322. $im = false;
  323. break;
  324. }
  325. return $im;
  326. }
  327.  
  328. /**
  329. * @param $text
  330. * @param $imageWidth
  331. * @return array
  332. */
  333. protected function prepareLines($text, $imageWidth)
  334. {
  335. $imageWidth = $imageWidth - $this->params['padding'] * 2;
  336. $lines = array();
  337. $explicitLines = preg_split('/\n|\r\n?/', $text);
  338. foreach ($explicitLines as $line) {
  339. $words = explode(" ", $line);
  340. $line = $words[0];
  341. for ($i = 1; $i < count($words); $i++) {
  342. $textBox = $this->calculateTextBox($this->params['fontSize'], $this->params['font'], $line . " " . $words[$i]);
  343. if ($textBox['width'] >= $imageWidth) {
  344. $lines[] = $line;
  345. $line = $words[$i];
  346. } else {
  347. $line .= " " . $words[$i];
  348. }
  349. }
  350. $lines[] = $line;
  351. }
  352.  
  353. return $lines;
  354. }
  355.  
  356. /**
  357. * @param $fontSize
  358. * @param $font
  359. * @param $text
  360. * @return array
  361. */
  362. protected function calculateTextBox($fontSize, $font, $text)
  363. {
  364. $rect = imagettfbbox($fontSize, 0, $font, $text);
  365. $minX = min(array($rect[0], $rect[2], $rect[4], $rect[6]));
  366. $maxX = max(array($rect[0], $rect[2], $rect[4], $rect[6]));
  367. $minY = min(array($rect[1], $rect[3], $rect[5], $rect[7]));
  368. $maxY = max(array($rect[1], $rect[3], $rect[5], $rect[7]));
  369.  
  370. return array(
  371. "left" => abs($minX) - 1,
  372. "top" => abs($minY) - 1,
  373. "width" => $maxX - $minX,
  374. "height" => $maxY - $minY,
  375. "box" => $rect
  376. );
  377. }
  378.  
  379. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement