PageRenderTime 65ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/Atomic Projects/vendor/phpoffice/phpword/src/PhpWord/Element/Image.php

https://gitlab.com/imamul68e/137619_PHP31
PHP | 544 lines | 251 code | 52 blank | 241 comment | 34 complexity | 1fd7eb2a019749034c0efff3897baa5d MD5 | raw file
  1. <?php
  2. /**
  3. * This file is part of PHPWord - A pure PHP library for reading and writing
  4. * word processing documents.
  5. *
  6. * PHPWord is free software distributed under the terms of the GNU Lesser
  7. * General Public License version 3 as published by the Free Software Foundation.
  8. *
  9. * For the full copyright and license information, please read the LICENSE
  10. * file that was distributed with this source code. For the full list of
  11. * contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
  12. *
  13. * @link https://github.com/PHPOffice/PHPWord
  14. * @copyright 2010-2016 PHPWord contributors
  15. * @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
  16. */
  17. namespace PhpOffice\PhpWord\Element;
  18. use PhpOffice\PhpWord\Exception\CreateTemporaryFileException;
  19. use PhpOffice\PhpWord\Exception\InvalidImageException;
  20. use PhpOffice\PhpWord\Exception\UnsupportedImageTypeException;
  21. use PhpOffice\PhpWord\Settings;
  22. use PhpOffice\PhpWord\Shared\ZipArchive;
  23. use PhpOffice\PhpWord\Style\Image as ImageStyle;
  24. /**
  25. * Image element
  26. */
  27. class Image extends AbstractElement
  28. {
  29. /**
  30. * Image source type constants
  31. */
  32. const SOURCE_LOCAL = 'local'; // Local images
  33. const SOURCE_GD = 'gd'; // Generated using GD
  34. const SOURCE_ARCHIVE = 'archive'; // Image in archives zip://$archive#$image
  35. /**
  36. * Image source
  37. *
  38. * @var string
  39. */
  40. private $source;
  41. /**
  42. * Source type: local|gd|archive
  43. *
  44. * @var string
  45. */
  46. private $sourceType;
  47. /**
  48. * Image style
  49. *
  50. * @var ImageStyle
  51. */
  52. private $style;
  53. /**
  54. * Is watermark
  55. *
  56. * @var boolean
  57. */
  58. private $watermark;
  59. /**
  60. * Image type
  61. *
  62. * @var string
  63. */
  64. private $imageType;
  65. /**
  66. * Image create function
  67. *
  68. * @var string
  69. */
  70. private $imageCreateFunc;
  71. /**
  72. * Image function
  73. *
  74. * @var string
  75. */
  76. private $imageFunc;
  77. /**
  78. * Image extension
  79. *
  80. * @var string
  81. */
  82. private $imageExtension;
  83. /**
  84. * Is memory image
  85. *
  86. * @var boolean
  87. */
  88. private $memoryImage;
  89. /**
  90. * Image target file name
  91. *
  92. * @var string
  93. */
  94. private $target;
  95. /**
  96. * Image media index
  97. *
  98. * @var integer
  99. */
  100. private $mediaIndex;
  101. /**
  102. * Has media relation flag; true for Link, Image, and Object
  103. *
  104. * @var bool
  105. */
  106. protected $mediaRelation = true;
  107. /**
  108. * Create new image element
  109. *
  110. * @param string $source
  111. * @param mixed $style
  112. * @param boolean $watermark
  113. *
  114. * @throws \PhpOffice\PhpWord\Exception\InvalidImageException
  115. * @throws \PhpOffice\PhpWord\Exception\UnsupportedImageTypeException
  116. */
  117. public function __construct($source, $style = null, $watermark = false)
  118. {
  119. $this->source = $source;
  120. $this->setIsWatermark($watermark);
  121. $this->style = $this->setNewStyle(new ImageStyle(), $style, true);
  122. $this->checkImage($source);
  123. }
  124. /**
  125. * Get Image style
  126. *
  127. * @return ImageStyle
  128. */
  129. public function getStyle()
  130. {
  131. return $this->style;
  132. }
  133. /**
  134. * Get image source
  135. *
  136. * @return string
  137. */
  138. public function getSource()
  139. {
  140. return $this->source;
  141. }
  142. /**
  143. * Get image source type
  144. *
  145. * @return string
  146. */
  147. public function getSourceType()
  148. {
  149. return $this->sourceType;
  150. }
  151. /**
  152. * Get image media ID
  153. *
  154. * @return string
  155. */
  156. public function getMediaId()
  157. {
  158. return md5($this->source);
  159. }
  160. /**
  161. * Get is watermark
  162. *
  163. * @return boolean
  164. */
  165. public function isWatermark()
  166. {
  167. return $this->watermark;
  168. }
  169. /**
  170. * Set is watermark
  171. *
  172. * @param boolean $value
  173. */
  174. public function setIsWatermark($value)
  175. {
  176. $this->watermark = $value;
  177. }
  178. /**
  179. * Get image type
  180. *
  181. * @return string
  182. */
  183. public function getImageType()
  184. {
  185. return $this->imageType;
  186. }
  187. /**
  188. * Get image create function
  189. *
  190. * @return string
  191. */
  192. public function getImageCreateFunction()
  193. {
  194. return $this->imageCreateFunc;
  195. }
  196. /**
  197. * Get image function
  198. *
  199. * @return string
  200. */
  201. public function getImageFunction()
  202. {
  203. return $this->imageFunc;
  204. }
  205. /**
  206. * Get image extension
  207. *
  208. * @return string
  209. */
  210. public function getImageExtension()
  211. {
  212. return $this->imageExtension;
  213. }
  214. /**
  215. * Get is memory image
  216. *
  217. * @return boolean
  218. */
  219. public function isMemImage()
  220. {
  221. return $this->memoryImage;
  222. }
  223. /**
  224. * Get target file name
  225. *
  226. * @return string
  227. */
  228. public function getTarget()
  229. {
  230. return $this->target;
  231. }
  232. /**
  233. * Set target file name.
  234. *
  235. * @param string $value
  236. * @return void
  237. */
  238. public function setTarget($value)
  239. {
  240. $this->target = $value;
  241. }
  242. /**
  243. * Get media index
  244. *
  245. * @return integer
  246. */
  247. public function getMediaIndex()
  248. {
  249. return $this->mediaIndex;
  250. }
  251. /**
  252. * Set media index.
  253. *
  254. * @param integer $value
  255. * @return void
  256. */
  257. public function setMediaIndex($value)
  258. {
  259. $this->mediaIndex = $value;
  260. }
  261. /**
  262. * Get image string data
  263. *
  264. * @param bool $base64
  265. * @return string|null
  266. * @since 0.11.0
  267. */
  268. public function getImageStringData($base64 = false)
  269. {
  270. $source = $this->source;
  271. $actualSource = null;
  272. $imageBinary = null;
  273. $imageData = null;
  274. $isTemp = false;
  275. // Get actual source from archive image or other source
  276. // Return null if not found
  277. if ($this->sourceType == self::SOURCE_ARCHIVE) {
  278. $source = substr($source, 6);
  279. list($zipFilename, $imageFilename) = explode('#', $source);
  280. $zip = new ZipArchive();
  281. if ($zip->open($zipFilename) !== false) {
  282. if ($zip->locateName($imageFilename)) {
  283. $isTemp = true;
  284. $zip->extractTo(Settings::getTempDir(), $imageFilename);
  285. $actualSource = Settings::getTempDir() . DIRECTORY_SEPARATOR . $imageFilename;
  286. }
  287. }
  288. $zip->close();
  289. } else {
  290. $actualSource = $source;
  291. }
  292. // Can't find any case where $actualSource = null hasn't captured by
  293. // preceding exceptions. Please uncomment when you find the case and
  294. // put the case into Element\ImageTest.
  295. // if ($actualSource === null) {
  296. // return null;
  297. // }
  298. // Read image binary data and convert to hex/base64 string
  299. if ($this->sourceType == self::SOURCE_GD) {
  300. $imageResource = call_user_func($this->imageCreateFunc, $actualSource);
  301. ob_start();
  302. call_user_func($this->imageFunc, $imageResource);
  303. $imageBinary = ob_get_contents();
  304. ob_end_clean();
  305. } else {
  306. $fileHandle = fopen($actualSource, 'rb', false);
  307. if ($fileHandle !== false) {
  308. $imageBinary = fread($fileHandle, filesize($actualSource));
  309. fclose($fileHandle);
  310. }
  311. }
  312. if ($imageBinary !== null) {
  313. if ($base64) {
  314. $imageData = chunk_split(base64_encode($imageBinary));
  315. } else {
  316. $imageData = chunk_split(bin2hex($imageBinary));
  317. }
  318. }
  319. // Delete temporary file if necessary
  320. if ($isTemp === true) {
  321. @unlink($actualSource);
  322. }
  323. return $imageData;
  324. }
  325. /**
  326. * Check memory image, supported type, image functions, and proportional width/height.
  327. *
  328. * @param string $source
  329. *
  330. * @return void
  331. *
  332. * @throws \PhpOffice\PhpWord\Exception\InvalidImageException
  333. * @throws \PhpOffice\PhpWord\Exception\UnsupportedImageTypeException
  334. */
  335. private function checkImage($source)
  336. {
  337. $this->setSourceType($source);
  338. // Check image data
  339. if ($this->sourceType == self::SOURCE_ARCHIVE) {
  340. $imageData = $this->getArchiveImageSize($source);
  341. } else {
  342. $imageData = @getimagesize($source);
  343. }
  344. if (!is_array($imageData)) {
  345. throw new InvalidImageException();
  346. }
  347. list($actualWidth, $actualHeight, $imageType) = $imageData;
  348. // Check image type support
  349. $supportedTypes = array(IMAGETYPE_JPEG, IMAGETYPE_GIF, IMAGETYPE_PNG);
  350. if ($this->sourceType != self::SOURCE_GD) {
  351. $supportedTypes = array_merge($supportedTypes, array(IMAGETYPE_BMP, IMAGETYPE_TIFF_II, IMAGETYPE_TIFF_MM));
  352. }
  353. if (!in_array($imageType, $supportedTypes)) {
  354. throw new UnsupportedImageTypeException();
  355. }
  356. // Define image functions
  357. $this->imageType = image_type_to_mime_type($imageType);
  358. $this->setFunctions();
  359. $this->setProportionalSize($actualWidth, $actualHeight);
  360. }
  361. /**
  362. * Set source type.
  363. *
  364. * @param string $source
  365. * @return void
  366. */
  367. private function setSourceType($source)
  368. {
  369. if (stripos(strrev($source), strrev('.php')) === 0) {
  370. $this->memoryImage = true;
  371. $this->sourceType = self::SOURCE_GD;
  372. } elseif (strpos($source, 'zip://') !== false) {
  373. $this->memoryImage = false;
  374. $this->sourceType = self::SOURCE_ARCHIVE;
  375. } else {
  376. $this->memoryImage = (filter_var($source, FILTER_VALIDATE_URL) !== false);
  377. $this->sourceType = $this->memoryImage ? self::SOURCE_GD : self::SOURCE_LOCAL;
  378. }
  379. }
  380. /**
  381. * Get image size from archive
  382. *
  383. * @since 0.12.0 Throws CreateTemporaryFileException.
  384. *
  385. * @param string $source
  386. *
  387. * @return array|null
  388. *
  389. * @throws \PhpOffice\PhpWord\Exception\CreateTemporaryFileException
  390. */
  391. private function getArchiveImageSize($source)
  392. {
  393. $imageData = null;
  394. $source = substr($source, 6);
  395. list($zipFilename, $imageFilename) = explode('#', $source);
  396. $tempFilename = tempnam(Settings::getTempDir(), 'PHPWordImage');
  397. if (false === $tempFilename) {
  398. throw new CreateTemporaryFileException();
  399. }
  400. $zip = new ZipArchive();
  401. if ($zip->open($zipFilename) !== false) {
  402. if ($zip->locateName($imageFilename)) {
  403. $imageContent = $zip->getFromName($imageFilename);
  404. if ($imageContent !== false) {
  405. file_put_contents($tempFilename, $imageContent);
  406. $imageData = getimagesize($tempFilename);
  407. unlink($tempFilename);
  408. }
  409. }
  410. $zip->close();
  411. }
  412. return $imageData;
  413. }
  414. /**
  415. * Set image functions and extensions.
  416. *
  417. * @return void
  418. */
  419. private function setFunctions()
  420. {
  421. switch ($this->imageType) {
  422. case 'image/png':
  423. $this->imageCreateFunc = 'imagecreatefrompng';
  424. $this->imageFunc = 'imagepng';
  425. $this->imageExtension = 'png';
  426. break;
  427. case 'image/gif':
  428. $this->imageCreateFunc = 'imagecreatefromgif';
  429. $this->imageFunc = 'imagegif';
  430. $this->imageExtension = 'gif';
  431. break;
  432. case 'image/jpeg':
  433. case 'image/jpg':
  434. $this->imageCreateFunc = 'imagecreatefromjpeg';
  435. $this->imageFunc = 'imagejpeg';
  436. $this->imageExtension = 'jpg';
  437. break;
  438. case 'image/bmp':
  439. case 'image/x-ms-bmp':
  440. $this->imageType = 'image/bmp';
  441. $this->imageExtension = 'bmp';
  442. break;
  443. case 'image/tiff':
  444. $this->imageExtension = 'tif';
  445. break;
  446. }
  447. }
  448. /**
  449. * Set proportional width/height if one dimension not available.
  450. *
  451. * @param integer $actualWidth
  452. * @param integer $actualHeight
  453. * @return void
  454. */
  455. private function setProportionalSize($actualWidth, $actualHeight)
  456. {
  457. $styleWidth = $this->style->getWidth();
  458. $styleHeight = $this->style->getHeight();
  459. if (!($styleWidth && $styleHeight)) {
  460. if ($styleWidth == null && $styleHeight == null) {
  461. $this->style->setWidth($actualWidth);
  462. $this->style->setHeight($actualHeight);
  463. } elseif ($styleWidth) {
  464. $this->style->setHeight($actualHeight * ($styleWidth / $actualWidth));
  465. } else {
  466. $this->style->setWidth($actualWidth * ($styleHeight / $actualHeight));
  467. }
  468. }
  469. }
  470. /**
  471. * Get is watermark
  472. *
  473. * @deprecated 0.10.0
  474. *
  475. * @codeCoverageIgnore
  476. */
  477. public function getIsWatermark()
  478. {
  479. return $this->isWatermark();
  480. }
  481. /**
  482. * Get is memory image
  483. *
  484. * @deprecated 0.10.0
  485. *
  486. * @codeCoverageIgnore
  487. */
  488. public function getIsMemImage()
  489. {
  490. return $this->isMemImage();
  491. }
  492. }