PageRenderTime 33ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/app/code/core/Mage/Catalog/Model/Product/Image.php

https://github.com/jpratt/cal
PHP | 520 lines | 330 code | 59 blank | 131 comment | 40 complexity | a481e5043ef4696739f8c25104b65ccf MD5 | raw file
  1. <?php
  2. /**
  3. * Magento
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@magentocommerce.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade Magento to newer
  18. * versions in the future. If you wish to customize Magento for your
  19. * needs please refer to http://www.magentocommerce.com for more information.
  20. *
  21. * @category Mage
  22. * @package Mage_Catalog
  23. * @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
  24. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  25. */
  26. /**
  27. * Catalog product link model
  28. *
  29. * @category Mage
  30. * @package Mage_Catalog
  31. * @author Magento Core Team <core@magentocommerce.com>
  32. */
  33. class Mage_Catalog_Model_Product_Image extends Mage_Core_Model_Abstract
  34. {
  35. protected $_width;
  36. protected $_height;
  37. protected $_keepAspectRatio = true;
  38. protected $_keepFrame = true;
  39. protected $_keepTransparency = true;
  40. protected $_constrainOnly = false;
  41. protected $_backgroundColor = array(255, 255, 255);
  42. protected $_baseFile;
  43. protected $_newFile;
  44. protected $_processor;
  45. protected $_destinationSubdir;
  46. protected $_angle;
  47. protected $_watermarkPosition;
  48. protected $_watermarkWidth;
  49. protected $_watermarkHeigth;
  50. /**
  51. * @return Mage_Catalog_Model_Product_Image
  52. */
  53. public function setWidth($width)
  54. {
  55. $this->_width = $width;
  56. return $this;
  57. }
  58. public function getWidth()
  59. {
  60. return $this->_width;
  61. }
  62. /**
  63. * @return Mage_Catalog_Model_Product_Image
  64. */
  65. public function setHeight($height)
  66. {
  67. $this->_height = $height;
  68. return $this;
  69. }
  70. public function getHeight()
  71. {
  72. return $this->_height;
  73. }
  74. /**
  75. * @return Mage_Catalog_Model_Product_Image
  76. */
  77. public function setKeepAspectRatio($keep)
  78. {
  79. $this->_keepAspectRatio = (bool)$keep;
  80. return $this;
  81. }
  82. /**
  83. * @return Mage_Catalog_Model_Product_Image
  84. */
  85. public function setKeepFrame($keep)
  86. {
  87. $this->_keepFrame = (bool)$keep;
  88. return $this;
  89. }
  90. /**
  91. * @return Mage_Catalog_Model_Product_Image
  92. */
  93. public function setKeepTransparency($keep)
  94. {
  95. $this->_keepTransparency = (bool)$keep;
  96. return $this;
  97. }
  98. /**
  99. * @return Mage_Catalog_Model_Product_Image
  100. */
  101. public function setConstrainOnly($flag)
  102. {
  103. $this->_constrainOnly = (bool)$flag;
  104. return $this;
  105. }
  106. /**
  107. * @return Mage_Catalog_Model_Product_Image
  108. */
  109. public function setBackgroundColor(array $rgbArray)
  110. {
  111. $this->_backgroundColor = $rgbArray;
  112. return $this;
  113. }
  114. /**
  115. * @return Mage_Catalog_Model_Product_Image
  116. */
  117. public function setSize($size)
  118. {
  119. // determine width and height from string
  120. list($width, $height) = explode('x', strtolower($size), 2);
  121. foreach (array('width', 'height') as $wh) {
  122. $$wh = (int)$$wh;
  123. if (empty($$wh))
  124. $$wh = null;
  125. }
  126. // set sizes
  127. $this->setWidth($width)->setHeight($height);
  128. return $this;
  129. }
  130. protected function _checkMemory($file = null)
  131. {
  132. // print '$this->_getMemoryLimit() = '.$this->_getMemoryLimit();
  133. // print '$this->_getMemoryUsage() = '.$this->_getMemoryUsage();
  134. // print '$this->_getNeedMemoryForBaseFile() = '.$this->_getNeedMemoryForBaseFile();
  135. return $this->_getMemoryLimit() > ($this->_getMemoryUsage() + $this->_getNeedMemoryForFile($file));
  136. }
  137. protected function _getMemoryLimit()
  138. {
  139. $memoryLimit = ini_get('memory_limit');
  140. if (!isSet($memoryLimit[0])){
  141. $memoryLimit = "128M";
  142. }
  143. if (substr($memoryLimit, -1) == 'M') {
  144. return (int)$memoryLimit * 1024 * 1024;
  145. }
  146. return $memoryLimit;
  147. }
  148. protected function _getMemoryUsage()
  149. {
  150. if (function_exists('memory_get_usage')) {
  151. return memory_get_usage();
  152. }
  153. return 0;
  154. }
  155. protected function _getNeedMemoryForFile($file = null)
  156. {
  157. $file = is_null($file) ? $this->getBaseFile() : $file;
  158. if (!$file) {
  159. return 0;
  160. }
  161. if (!file_exists($file) || !is_file($file)) {
  162. return 0;
  163. }
  164. $imageInfo = getimagesize($file);
  165. if (!isset($imageInfo[0]) || !isset($imageInfo[1])) {
  166. return 0;
  167. }
  168. if (!isset($imageInfo['channels'])) {
  169. // if there is no info about this parameter lets set it for maximum
  170. $imageInfo['channels'] = 4;
  171. }
  172. if (!isset($imageInfo['bits'])) {
  173. // if there is no info about this parameter lets set it for maximum
  174. $imageInfo['bits'] = 8;
  175. }
  176. return round(($imageInfo[0] * $imageInfo[1] * $imageInfo['bits'] * $imageInfo['channels'] / 8 + Pow(2, 16)) * 1.65);
  177. }
  178. /**
  179. * Convert array of 3 items (decimal r, g, b) to string of their hex values
  180. *
  181. * @param array $rgbArray
  182. * @return string
  183. */
  184. private function _rgbToString($rgbArray)
  185. {
  186. $result = array();
  187. foreach ($rgbArray as $value) {
  188. if (null === $value) {
  189. $result[] = 'null';
  190. }
  191. else {
  192. $result[] = sprintf('%02s', dechex($value));
  193. }
  194. }
  195. return implode($result);
  196. }
  197. /**
  198. * Set filenames for base file and new file
  199. *
  200. * @param string $file
  201. * @return Mage_Catalog_Model_Product_Image
  202. */
  203. public function setBaseFile($file)
  204. {
  205. if (($file) && (0 !== strpos($file, '/', 0))) {
  206. $file = '/' . $file;
  207. }
  208. $baseDir = Mage::getSingleton('catalog/product_media_config')->getBaseMediaPath();
  209. if ('/no_selection' == $file) {
  210. $file = null;
  211. }
  212. if ($file) {
  213. if ((!file_exists($baseDir . $file)) || !$this->_checkMemory($baseDir . $file)) {
  214. $file = null;
  215. }
  216. }
  217. if (!$file) {
  218. // check if placeholder defined in config
  219. $isConfigPlaceholder = Mage::getStoreConfig("catalog/placeholder/{$this->getDestinationSubdir()}_placeholder");
  220. $configPlaceholder = '/placeholder/' . $isConfigPlaceholder;
  221. if ($isConfigPlaceholder && file_exists($baseDir . $configPlaceholder)) {
  222. $file = $configPlaceholder;
  223. }
  224. else {
  225. // replace file with skin or default skin placeholder
  226. $skinBaseDir = Mage::getDesign()->getSkinBaseDir();
  227. $skinPlaceholder = "/images/catalog/product/placeholder/{$this->getDestinationSubdir()}.jpg";
  228. $file = $skinPlaceholder;
  229. if (file_exists($skinBaseDir . $file)) {
  230. $baseDir = $skinBaseDir;
  231. }
  232. else {
  233. $baseDir = Mage::getDesign()->getSkinBaseDir(array('_theme' => 'default'));
  234. }
  235. }
  236. }
  237. $baseFile = $baseDir . $file;
  238. if ((!$file) || (!file_exists($baseFile))) {
  239. throw new Exception(Mage::helper('catalog')->__('Image file not found'));
  240. }
  241. $this->_baseFile = $baseFile;
  242. // build new filename (most important params)
  243. $path = array(
  244. Mage::getSingleton('catalog/product_media_config')->getBaseMediaPath(),
  245. 'cache',
  246. Mage::app()->getStore()->getId(),
  247. $path[] = $this->getDestinationSubdir()
  248. );
  249. if((!empty($this->_width)) || (!empty($this->_height)))
  250. $path[] = "{$this->_width}x{$this->_height}";
  251. // add misc params as a hash
  252. $path[] = md5(
  253. implode('_', array(
  254. ($this->_keepAspectRatio ? '' : 'non') . 'proportional',
  255. ($this->_keepFrame ? '' : 'no') . 'frame',
  256. ($this->_keepTransparency ? '' : 'no') . 'transparency',
  257. ($this->_constrainOnly ? 'do' : 'not') . 'constrainonly',
  258. $this->_rgbToString($this->_backgroundColor),
  259. 'angle' . $this->_angle
  260. ))
  261. );
  262. // append prepared filename
  263. $this->_newFile = implode('/', $path) . $file; // the $file contains heading slash
  264. return $this;
  265. }
  266. public function getBaseFile()
  267. {
  268. return $this->_baseFile;
  269. }
  270. public function getNewFile()
  271. {
  272. return $this->_newFile;
  273. }
  274. /**
  275. * @return Mage_Catalog_Model_Product_Image
  276. */
  277. public function setImageProcessor($processor)
  278. {
  279. $this->_processor = $processor;
  280. return $this;
  281. }
  282. /**
  283. * @return Varien_Image
  284. */
  285. public function getImageProcessor()
  286. {
  287. if( !$this->_processor ) {
  288. // var_dump($this->_checkMemory());
  289. // if (!$this->_checkMemory()) {
  290. // $this->_baseFile = null;
  291. // }
  292. $this->_processor = new Varien_Image($this->getBaseFile());
  293. }
  294. $this->_processor->keepAspectRatio($this->_keepAspectRatio);
  295. $this->_processor->keepFrame($this->_keepFrame);
  296. $this->_processor->keepTransparency($this->_keepTransparency);
  297. $this->_processor->constrainOnly($this->_constrainOnly);
  298. $this->_processor->backgroundColor($this->_backgroundColor);
  299. return $this->_processor;
  300. }
  301. /**
  302. * @see Varien_Image_Adapter_Abstract
  303. * @return Mage_Catalog_Model_Product_Image
  304. */
  305. public function resize()
  306. {
  307. if (is_null($this->getWidth()) && is_null($this->getHeight())) {
  308. return $this;
  309. }
  310. $this->getImageProcessor()->resize($this->_width, $this->_height);
  311. return $this;
  312. }
  313. /**
  314. * @return Mage_Catalog_Model_Product_Image
  315. */
  316. public function rotate($angle)
  317. {
  318. $angle = intval($angle);
  319. $this->getImageProcessor()->rotate($angle);
  320. return $this;
  321. }
  322. /**
  323. * Set angle for rotating
  324. *
  325. * This func actually affects only the cache filename.
  326. *
  327. * @param int $angle
  328. * @return Mage_Catalog_Model_Product_Image
  329. */
  330. public function setAngle($angle)
  331. {
  332. $this->_angle = $angle;
  333. return $this;
  334. }
  335. /**
  336. * @return Mage_Catalog_Model_Product_Image
  337. */
  338. public function setWatermark($file, $position=null, $size=null, $width=null, $heigth=null)
  339. {
  340. $filename = false;
  341. if( !$file ) {
  342. return $this;
  343. }
  344. $baseDir = Mage::getSingleton('catalog/product_media_config')->getBaseMediaPath();
  345. if( file_exists($baseDir . '/watermark/stores/' . Mage::app()->getStore()->getId() . $file) ) {
  346. $filename = $baseDir . '/watermark/stores/' . Mage::app()->getStore()->getId() . $file;
  347. } elseif ( file_exists($baseDir . '/watermark/websites/' . Mage::app()->getWebsite()->getId() . $file) ) {
  348. $filename = $baseDir . '/watermark/websites/' . Mage::app()->getWebsite()->getId() . $file;
  349. } elseif ( file_exists($baseDir . '/watermark/default/' . $file) ) {
  350. $filename = $baseDir . '/watermark/default/' . $file;
  351. } elseif ( file_exists($baseDir . '/watermark/' . $file) ) {
  352. $filename = $baseDir . '/watermark/' . $file;
  353. } else {
  354. $baseDir = Mage::getDesign()->getSkinBaseDir();
  355. if( file_exists($baseDir . $file) ) {
  356. $filename = $baseDir . $file;
  357. }
  358. }
  359. if( $filename ) {
  360. $this->getImageProcessor()
  361. ->setWatermarkPosition( ($position) ? $position : $this->getWatermarkPosition() )
  362. ->setWatermarkWidth( ($width) ? $width : $this->getWatermarkWidth() )
  363. ->setWatermarkHeigth( ($heigth) ? $heigth : $this->getWatermarkHeigth() )
  364. ->watermark($filename);
  365. }
  366. return $this;
  367. }
  368. /**
  369. * @return Mage_Catalog_Model_Product_Image
  370. */
  371. public function saveFile()
  372. {
  373. $this->getImageProcessor()->save($this->getNewFile());
  374. return $this;
  375. }
  376. /**
  377. * @return string
  378. */
  379. public function getUrl()
  380. {
  381. $baseDir = Mage::getBaseDir('media');
  382. $path = str_replace($baseDir . DS, "", $this->_newFile);
  383. return Mage::getBaseUrl('media') . str_replace(DS, '/', $path);
  384. }
  385. public function push()
  386. {
  387. $this->getImageProcessor()->display();
  388. }
  389. /**
  390. * @return Mage_Catalog_Model_Product_Image
  391. */
  392. public function setDestinationSubdir($dir)
  393. {
  394. $this->_destinationSubdir = $dir;
  395. return $this;
  396. }
  397. /**
  398. * @return string
  399. */
  400. public function getDestinationSubdir()
  401. {
  402. return $this->_destinationSubdir;
  403. }
  404. public function isCached()
  405. {
  406. return file_exists($this->_newFile);
  407. }
  408. /**
  409. * @return Mage_Catalog_Model_Product_Image
  410. */
  411. public function setWatermarkPosition($position)
  412. {
  413. $this->_watermarkPosition = $position;
  414. return $this;
  415. }
  416. public function getWatermarkPosition()
  417. {
  418. return $this->_watermarkPosition;
  419. }
  420. /**
  421. * @return Mage_Catalog_Model_Product_Image
  422. */
  423. public function setWatermarkSize($size)
  424. {
  425. if( is_array($size) ) {
  426. $this->setWatermarkWidth($size['width'])
  427. ->setWatermarkHeigth($size['heigth']);
  428. }
  429. return $this;
  430. }
  431. /**
  432. * @return Mage_Catalog_Model_Product_Image
  433. */
  434. public function setWatermarkWidth($width)
  435. {
  436. $this->_watermarkWidth = $width;
  437. return $this;
  438. }
  439. public function getWatermarkWidth()
  440. {
  441. return $this->_watermarkWidth;
  442. }
  443. /**
  444. * @return Mage_Catalog_Model_Product_Image
  445. */
  446. public function setWatermarkHeigth($heigth)
  447. {
  448. $this->_watermarkHeigth = $heigth;
  449. return $this;
  450. }
  451. public function getWatermarkHeigth()
  452. {
  453. return $this->_watermarkHeigth;
  454. }
  455. public function clearCache()
  456. {
  457. $directory = Mage::getBaseDir('media') . DS.'catalog'.DS.'product'.DS.'cache'.DS;
  458. $io = new Varien_Io_File();
  459. $io->rmdir($directory, true);
  460. }
  461. }