1
0

BxDolTranscoderImage.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664
  1. <?php defined('BX_DOL') or die('hack attempt');
  2. /**
  3. * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
  4. * CC-BY License - http://creativecommons.org/licenses/by/3.0/
  5. *
  6. * @defgroup DolphinCore Dolphin Core
  7. * @{
  8. */
  9. bx_import('BxDolStorage');
  10. bx_import('BxDolTranscoderImageQuery');
  11. /**
  12. * @page objects
  13. * @section transcoder)images Images Transcoder
  14. * @ref BxDolTranscoderImage
  15. */
  16. /**
  17. * This class transcodes images on the fly.
  18. * Transcoded image is saved in the specified storage engine and next time ready image is served.
  19. *
  20. *
  21. * To add image transcoder object add record to 'sys_objects_transcoder_images' table:
  22. * - object - name of the transcoder object, in the format: vendor prefix, underscore, module prefix, underscore, image size name; for example: bx_images_thumb.
  23. * - storage_object - name of the storage object to store transcoded data, the specified storage object need to be created too, @see BxDolStorage.
  24. * - source_type - type of the source, where is source image is taken from, available options 'Storage' and 'Folder' for now.
  25. * - source_params - source_type params, each source_type can have own set of params, please read futher for more info about particular source_types, serialized array of params is stored here.
  26. * - private - how to store transcoded data:
  27. * - no - store transcoded data publicly.
  28. * - yes - store transcoded data privately.
  29. * - auto - detect automatically, not supported for 'Folder' source type.
  30. * - atime_tracking - track last access time to the transcoded data, allowed values 0 - disables or 1 - enabled.
  31. * - atime_pruning - prune transcoded images by last access time, if last access time of the image is older than atime_pruning seconds - it is deleted, it works when atime_tracking is enabled
  32. * - ts - unix timestamp of the last change of transcoder parameters, if transcoded image is older than this value - image is deleted and transcoded again.
  33. *
  34. *
  35. * Then you need to add image filters to 'sys_transcoder_images_filters' table:
  36. * - transcoder_object - name of the transcoded object to apply filter to.
  37. * - filter - filter name, please read futher for available filters.
  38. * - filter_params - serialized array of filter params, please read futher for particular filters params.
  39. * - order - if there are several filters for one object, they will be applied in this order.
  40. *
  41. *
  42. * 'Folder' source types:
  43. * This source type is some folder with original images for the transcoding, the identifier of the image (handler) is file name.
  44. * The params are the following:
  45. * - path - path to the folder with original images
  46. * This source type has some limitation:
  47. * - automatic detection of private files is not supported
  48. * - transcoded file is not automaticlaly deleted/renewed if original file is changed
  49. *
  50. *
  51. * 'Storage' source type:
  52. * The source of original files is Storage engine, the identifier of the image (handler) is file id.
  53. * The params are the following:
  54. * - object - name of the Storage object
  55. *
  56. *
  57. * Available filters:
  58. * - Resize - this filter resizes original image, the parameters are the following:
  59. * - w - width of resulted image.
  60. * - h - height of resulted image.
  61. * - square_resize - make resulted image square, even of original image is not square, 'w' and 'h' parameters must be the same.
  62. * - force_type - always change type of the image to the specified type: jpg, png, gif.
  63. * - Grayscale - make image grayscale, there is no parameters for this filter
  64. *
  65. *
  66. * Automatic deletetion of associated data is supported - in the case if original or transcoded file is deleted,
  67. * but you need to register alert handlers, just call registerHandlers () function to register handler (for example, during module installation)
  68. * and call unregisterHandlers () function to unregister handlers (for example, during module uninstallation)
  69. *
  70. *
  71. * Example of usage:
  72. * @code
  73. * bx_import('BxDolTranscoderImage');
  74. * $oTranscoder = BxDolTranscoderImage::getObjectInstance('bx_images_thumb'); // change images transcode object name to your own
  75. * $oTranscoder->registerHandlers(); // make sure to call it only once! before the first usage, no need to call it every time
  76. * $sTranscodedImageUrl = $oTranscoder->getImageUrl('my_dog.jpg'); // the name of file, in the case of 'Folder' storage type this is file name
  77. * echo 'My dog : <img src="' . $sUrl . '" />'; // transcoded(resized and/or grayscaled) image will be shown, according to the specified filters
  78. * @endcode
  79. *
  80. */
  81. class BxDolTranscoderImage extends BxDol implements iBxDolFactoryObject
  82. {
  83. protected $_aObject; ///< object properties
  84. protected $_oStorage; ///< storage object, transcoded images are stored here
  85. protected $_oDb; ///< database queries object
  86. protected $_sRetinaSuffix = '@2x'; ///< handler suffix for retina image file
  87. /**
  88. * constructor
  89. */
  90. protected function __construct($aObject, $oStorage)
  91. {
  92. parent::__construct();
  93. $this->_aObject = $aObject;
  94. $this->_oStorage = $oStorage;
  95. $this->_oDb = new BxDolTranscoderImageQuery($aObject);
  96. }
  97. /**
  98. * Get image transcode object instance.
  99. * @param $sObject - name of trancode object.
  100. * @return false on error or instance of BxDolTranscoderImage class.
  101. */
  102. public static function getObjectInstance($sObject)
  103. {
  104. if (isset($GLOBALS['bxDolClasses']['BxDolTranscoderImage!'.$sObject]))
  105. return $GLOBALS['bxDolClasses']['BxDolTranscoderImage!'.$sObject];
  106. // get transcode object
  107. $aObject = BxDolTranscoderImageQuery::getTranscoderObject($sObject);
  108. if (!$aObject || !is_array($aObject))
  109. return false;
  110. if ($aObject['source_params'])
  111. $aObject['source_params'] = unserialize($aObject['source_params']);
  112. $aObject['filters'] = false; // filters are initialized on demand
  113. // create storage object to store transcoded data
  114. $oStorage = BxDolStorage::getObjectInstance($aObject['storage_object']);
  115. if (!$oStorage)
  116. return false;
  117. // create instance
  118. $o = new BxDolTranscoderImage($aObject, $oStorage);
  119. return ($GLOBALS['bxDolClasses']['BxDolTranscoderImage!'.$sObject] = $o);
  120. }
  121. /**
  122. * Delete outdated transcoed data from all transcoeeed objects, by last access time.
  123. * It called on cron, usually every day.
  124. * @return total number of pruned/deleted files
  125. */
  126. static public function pruning ()
  127. {
  128. $iCount = 0;
  129. $aObjects = BxDolTranscoderImageQuery::getTranscoderObjects ();
  130. foreach ($aObjects as $aObject) {
  131. if (!$aObject['atime_tracking'] || !$aObject['atime_pruning'])
  132. continue;
  133. $oTranscoder = BxDolTranscoderImage::getObjectInstance($aObject['object']);
  134. if (!$oTranscoder)
  135. continue;
  136. $iCount += $oTranscoder->prune();
  137. }
  138. return $iCount;
  139. }
  140. /**
  141. * Register handlers array
  142. * It can be called upon module enable event.
  143. * @param $mixed array of transcoders objects, or just one object
  144. */
  145. static public function registerHandlersArray ($mixed)
  146. {
  147. self::_callFuncForObjectsArray ($mixed, 'registerHandlers');
  148. }
  149. /**
  150. * Unregister handlers array
  151. * It can be called upon module disbale event.
  152. * @param $mixed array of transcoders objects, or just one object
  153. */
  154. static public function unregisterHandlersArray ($mixed)
  155. {
  156. self::_callFuncForObjectsArray ($mixed, 'unregisterHandlers');
  157. }
  158. /**
  159. * Cleanup (queue for deletion all resized files)
  160. * It can be called upon module disbale event.
  161. * @param $mixed array of transcoders objects, or just one object
  162. */
  163. static public function cleanupObjectsArray ($mixed)
  164. {
  165. self::_callFuncForObjectsArray ($mixed, 'cleanup');
  166. }
  167. /**
  168. * Called automatically, upon local(transcoded) file deletetion.
  169. */
  170. static public function onAlertResponseFileDeleteLocal ($oAlert, $sObject)
  171. {
  172. $oTranscoder = BxDolTranscoderImage::getObjectInstance($sObject);
  173. if (!$oTranscoder)
  174. return;
  175. if ($oAlert->sAction != 'file_deleted')
  176. return;
  177. $oTranscoder->onDeleteFileLocal($oAlert->iObject);
  178. }
  179. /**
  180. * Called automatically, upon original file deletetion.
  181. */
  182. static public function onAlertResponseFileDeleteOrig ($oAlert, $sObject)
  183. {
  184. $oTranscoder = BxDolTranscoderImage::getObjectInstance($sObject);
  185. if (!$oTranscoder)
  186. return;
  187. if ($oAlert->sAction != 'file_deleted')
  188. return;
  189. $oTranscoder->onDeleteFileOrig($oAlert->iObject);
  190. }
  191. /**
  192. * Called automatically, upon local(transcoded) file deletetion.
  193. */
  194. public function onDeleteFileLocal($iFileId)
  195. {
  196. return $this->_oDb->deleteFileTraces($iFileId);
  197. }
  198. /**
  199. * Called automatically, upon original file deletetion.
  200. */
  201. public function onDeleteFileOrig($mixedHandler)
  202. {
  203. // delete main file
  204. $iFileId = $this->_oDb->getFileIdByHandler($mixedHandler);
  205. if (!$iFileId)
  206. return false;
  207. if (!$this->_oStorage->deleteFile($iFileId))
  208. return false;
  209. // delete retina file
  210. $iFileId = $this->_oDb->getFileIdByHandler($mixedHandler . $this->_sRetinaSuffix);
  211. if ($iFileId)
  212. $this->_oStorage->deleteFile($iFileId);
  213. return true;
  214. }
  215. /**
  216. * Register necessary alert handlers for automatic deletetion of transcoded data if source file is deleted.
  217. * Make sure that you call it once, before first usage, for example upon module installation.
  218. */
  219. public function registerHandlers ()
  220. {
  221. if (!$this->_oDb->registerHandlers ())
  222. return false;
  223. return $this->clearCacheDB();
  224. }
  225. /**
  226. * Unregister alert handlers for automatic deletetion of transcoded data if source file is deleted.
  227. * Make sure that you call it once, for example upon module uninstallation.
  228. */
  229. public function unregisterHandlers ()
  230. {
  231. if (!$this->_oDb->unregisterHandlers ())
  232. return false;
  233. return $this->clearCacheDB();
  234. }
  235. /**
  236. * Delete (queue for deletion) all resized files for the current object
  237. */
  238. public function cleanup ()
  239. {
  240. return $this->_oStorage->queueFilesForDeletionFromObject();
  241. }
  242. /**
  243. * Get storage object where transcoded data is stored
  244. */
  245. public function getStorage()
  246. {
  247. return $this->_oStorage;
  248. }
  249. /**
  250. * Get transcoded image url.
  251. * If transcoded image is ready then direct url to this image is returned.
  252. * If there is no transcoded data available, then special url is returned, upon opening this url image is transcoded automatically and redirects to the ready transcoed image.
  253. * @params $mixedHandler - image handler
  254. * @return image url, or false on error.
  255. */
  256. public function getImageUrl($mixedHandler)
  257. {
  258. if ($this->isImageReady($mixedHandler)) {
  259. $mixedHandler = $this->processHandlerForRetinaDevice($mixedHandler);
  260. $iFileId = $this->_oDb->getFileIdByHandler($mixedHandler);
  261. if (!$iFileId)
  262. return false;
  263. $aFile = $this->_oStorage->getFile($iFileId);
  264. if (!$aFile)
  265. return false;
  266. if ($this->_aObject['atime_tracking'])
  267. $this->_oDb->updateAccessTime($mixedHandler);
  268. return $this->_oStorage->getFileUrlById($iFileId);
  269. }
  270. return BX_DOL_URL_ROOT . 'image_transcoder.php?o=' . $this->_aObject['object'] . '&h=' . $mixedHandler . '&dpx=' . $this->getDevicePixelRatio() . '&t=' . time();
  271. }
  272. /**
  273. * Check if transcoded data is available. No need to call it directly, it is called automatically when it is needed.
  274. * @params $mixedHandler - image handler
  275. * @params $isCheckOutdated - check if transcoded image outdated
  276. * @return false if there is no ready transcoed image is available or it is outdated, true if image is ready
  277. */
  278. public function isImageReady ($mixedHandler, $isCheckOutdated = true)
  279. {
  280. $sMethodImageReady = 'isImageReady_' . $this->_aObject['source_type'];
  281. return $this->$sMethodImageReady($mixedHandler, $isCheckOutdated);
  282. }
  283. /**
  284. * Transcode image, no need to call it directly, it is called automatically when it is needed.
  285. * @params $mixedHandler - image handler
  286. * @params $iProfileId - optional profile id, to assign transcoded image to, usually it is NOT assigned to any particular profile, so just leave it default
  287. * @return true on success, false on error
  288. */
  289. public function transcode ($mixedHandler, $iProfileId = 0)
  290. {
  291. $sExtChange = false;
  292. // create tmp file locally
  293. $sMethodStoreFile = 'storeFileLocally_' . $this->_aObject['source_type'];
  294. $sTmpFile = $this->$sMethodStoreFile($mixedHandler);
  295. if (!$sTmpFile)
  296. return false;
  297. // appply filters to tmp file
  298. $this->initFilters ();
  299. foreach ($this->_aObject['filters'] as $aParams) {
  300. $sMethodFilter = 'applyFilter_' . $aParams['filter'];
  301. if (!method_exists($this, $sMethodFilter))
  302. continue;
  303. if (!$this->$sMethodFilter($sTmpFile, $aParams['filter_params'])) {
  304. unlink($sTmpFile);
  305. return false;
  306. }
  307. if (!empty($aParams['filter_params']['force_type'])) {
  308. switch ($aParams['filter_params']['force_type']) {
  309. case 'jpeg':
  310. case 'jpg':
  311. $sExtChange = 'jpg';
  312. break;
  313. case 'png':
  314. $sExtChange = 'png';
  315. break;
  316. case 'gif':
  317. $sExtChange = 'gif';
  318. break;
  319. }
  320. }
  321. }
  322. if ($sExtChange && false !== ($iDotPos = strrpos($sTmpFile, '.'))) {
  323. $sExtOld = substr($sTmpFile, $iDotPos+1);
  324. if ($sExtOld != $sExtChange) {
  325. $sTmpFileOld = $sTmpFile;
  326. $sTmpFile = substr_replace ($sTmpFile, $sExtChange, $iDotPos+1, strlen($sExtOld));
  327. if (!rename($sTmpFileOld, $sTmpFile)) {
  328. unlink($sTmpFileOld);
  329. return false;
  330. }
  331. }
  332. }
  333. $mixedHandler = $this->processHandlerForRetinaDevice($mixedHandler);
  334. // store transcoded file in the storage
  335. $sMethodIsPrivate = 'isPrivate_' . $this->_aObject['source_type'];
  336. $isPrivate = $this->$sMethodIsPrivate($mixedHandler);
  337. $iFileId = $this->_oStorage->storeFileFromPath ($sTmpFile, $isPrivate, $iProfileId);
  338. @unlink($sTmpFile);
  339. if (!$iFileId)
  340. return false;
  341. if (!$this->_oDb->updateHandler($iFileId, $mixedHandler)) {
  342. $this->_oStorage->deleteFile($iFileId);
  343. return false;
  344. }
  345. $this->_oStorage->afterUploadCleanup($iFileId, $iProfileId);
  346. return true;
  347. }
  348. /**
  349. * Delete outdated files by last access time.
  350. * @return number of pruned/deleted files
  351. */
  352. public function prune ()
  353. {
  354. $aFiles = $this->_oDb->getFilesForPruning();
  355. if (!$aFiles)
  356. return false;
  357. $iCount = 0;
  358. foreach ($aFiles as $r)
  359. $iCount += $this->_oStorage->deleteFile($r['file_id']) ? 1 : 0;
  360. return $iCount;
  361. }
  362. public function getDevicePixelRatio ()
  363. {
  364. if (isset($_COOKIE['devicePixelRatio']) && (!isset($this->_aObject['source_params']['disable_retina']) || !$this->_aObject['source_params']['disable_retina'])) {
  365. $iDevicePixelRatio = intval($_COOKIE['devicePixelRatio']);
  366. if ($iDevicePixelRatio >= 2)
  367. return 2;
  368. }
  369. return 1;
  370. }
  371. // ---------------------------
  372. protected function isImageReady_Folder ($mixedHandlerOrig, $isCheckOutdated = true)
  373. {
  374. $mixedHandler = $this->processHandlerForRetinaDevice($mixedHandlerOrig);
  375. $iFileId = $this->_oDb->getFileIdByHandler($mixedHandler);
  376. if (!$iFileId)
  377. return false;
  378. $aFile = $this->_oStorage->getFile($iFileId);
  379. if (!$aFile)
  380. return false;
  381. if ($isCheckOutdated) { // warning, $isCheckOutdated is partially supported for Folder source type - file modification is not checked
  382. if ($this->_aObject['ts'] > $aFile['modified'] || !$this->getFilePath_Folder($mixedHandlerOrig)) { // if we changed transcoder object params or original file is deleted
  383. // delete file, so it will be recreated next time
  384. if ($this->_oStorage->deleteFile($aFile['id']))
  385. return false;
  386. }
  387. }
  388. return true;
  389. }
  390. protected function isImageReady_Storage ($mixedHandlerOrig, $isCheckOutdated = true)
  391. {
  392. $mixedHandler = $this->processHandlerForRetinaDevice($mixedHandlerOrig);
  393. $iFileId = $this->_oDb->getFileIdByHandler($mixedHandler);
  394. if (!$iFileId)
  395. return false;
  396. $aFile = $this->_oStorage->getFile($iFileId);
  397. if (!$aFile)
  398. return false;
  399. if ($isCheckOutdated) {
  400. $oStorageOriginal = BxDolStorage::getObjectInstance($this->_aObject['source_params']['object']);
  401. if ($oStorageOriginal) {
  402. $aFileOriginal = $oStorageOriginal->getFile($mixedHandlerOrig);
  403. if (!$aFileOriginal || $aFileOriginal['modified'] > $aFile['modified'] || $this->_aObject['ts'] > $aFile['modified']) { // if original file was changed OR we changed transcoder object params
  404. // delete file, so it will be recreated next time
  405. if ($this->_oStorage->deleteFile($aFile['id']))
  406. return false;
  407. }
  408. }
  409. }
  410. return true;
  411. }
  412. protected function isPrivate_Folder ($mixedHandler)
  413. {
  414. if ('no' == $this->_aObject['private'])
  415. return false;
  416. return true;
  417. }
  418. protected function isPrivate_Storage ($mixedHandler)
  419. {
  420. switch ($this->_aObject['private']) {
  421. case 'no':
  422. return false;
  423. case 'yes':
  424. return true;
  425. default:
  426. case 'auto':
  427. $oStorageOriginal = BxDolStorage::getObjectInstance($this->_aObject['source_params']['object']);
  428. if (!$oStorageOriginal)
  429. return true; // in case of error - make sure that file is not public accidentally
  430. $aFile = $oStorageOriginal->getFile($mixedHandler);
  431. return $oStorageOriginal->isFilePrivate($aFile['id']);
  432. }
  433. }
  434. protected function getFilePath_Folder ($mixedHandler)
  435. {
  436. $sPath = $this->_aObject['source_params']['path'] . $mixedHandler;
  437. if (!file_exists($sPath))
  438. $sPath = BX_DIRECTORY_PATH_ROOT . $sPath;
  439. if (!file_exists($sPath))
  440. return false;
  441. return $sPath;
  442. }
  443. protected function storeFileLocally_Folder ($mixedHandler)
  444. {
  445. $sPath = $this->getFilePath_Folder($mixedHandler);
  446. if (!$sPath)
  447. return false;
  448. $sTmpFile = $this->getTmpFilename ($mixedHandler);
  449. if (!copy($sPath, $sTmpFile))
  450. return false;
  451. return $sTmpFile;
  452. }
  453. protected function storeFileLocally_Storage ($mixedHandler)
  454. {
  455. $oStorageOriginal = BxDolStorage::getObjectInstance($this->_aObject['source_params']['object']);
  456. if (!$oStorageOriginal)
  457. return false;
  458. $aFile = $oStorageOriginal->getFile($mixedHandler);
  459. if (!$aFile)
  460. return false;
  461. $sUrl = $oStorageOriginal->getFileUrlById($mixedHandler);
  462. if (!$sUrl)
  463. return false;
  464. $sFileData = bx_file_get_contents ($sUrl);
  465. if (false === $sFileData)
  466. return false;
  467. $sTmpFile = $this->getTmpFilename ($aFile['file_name']);
  468. if (!file_put_contents($sTmpFile, $sFileData))
  469. return false;
  470. return $sTmpFile;
  471. }
  472. protected function getTmpFilename ($sOverrideName = false)
  473. {
  474. if ($sOverrideName)
  475. return BX_DIRECTORY_PATH_TMP . rand(10000, 99999) . $sOverrideName;
  476. return tempnam(BX_DIRECTORY_PATH_TMP, $this->_aObject['object']);
  477. }
  478. protected function applyFilter_Grayscale ($sFile, $aParams)
  479. {
  480. bx_import ('BxDolImageResize');
  481. $o = BxDolImageResize::getInstance();
  482. $o->removeCropOptions ();
  483. $this->_checkForceType ($o, $aParams);
  484. if (IMAGE_ERROR_SUCCESS == $o->grayscale($sFile))
  485. return true;
  486. return false;
  487. }
  488. protected function applyFilter_Resize ($sFile, $aParams)
  489. {
  490. bx_import ('BxDolImageResize');
  491. $o = BxDolImageResize::getInstance();
  492. $o->removeCropOptions ();
  493. if (isset($aParams['w']) && isset($aParams['h']))
  494. $o->setSize ($aParams['w'] * $this->getDevicePixelRatio(), $aParams['h'] * $this->getDevicePixelRatio());
  495. if (isset($aParams['crop_resize']) && $aParams['crop_resize']) {
  496. $o->setAutoCrop (true);
  497. } elseif (isset($aParams['square_resize']) && $aParams['square_resize']) {
  498. $o->setSquareResize (true);
  499. } else {
  500. $o->setSquareResize (false);
  501. }
  502. $this->_checkForceType ($o, $aParams);
  503. if (IMAGE_ERROR_SUCCESS == $o->resize($sFile))
  504. return true;
  505. return false;
  506. }
  507. protected function _checkForceType ($oImageProcessor, $aParams)
  508. {
  509. if (empty($aParams['force_type']))
  510. $aParams['force_type'] = false;
  511. switch ($aParams['force_type']) {
  512. case 'jpeg':
  513. case 'jpg':
  514. $oImageProcessor->setOutputType(IMAGE_TYPE_JPG);
  515. break;
  516. case 'png':
  517. $oImageProcessor->setOutputType(IMAGE_TYPE_PNG);
  518. break;
  519. case 'gif':
  520. $oImageProcessor->setOutputType(IMAGE_TYPE_GIF);
  521. break;
  522. default:
  523. $oImageProcessor->setOutputType(false);
  524. break;
  525. }
  526. }
  527. protected function initFilters ()
  528. {
  529. if (false !== $this->_aObject['filters']) // filters are already initilized
  530. return;
  531. // get transcoder filters
  532. $aFilters = $this->_oDb->getTranscoderFilters();
  533. $this->_aObject['filters'] = array();
  534. foreach ($aFilters as $aFilter) {
  535. if ($aFilter['filter_params'])
  536. $aFilter['filter_params'] = unserialize($aFilter['filter_params']);
  537. $this->_aObject['filters'][] = $aFilter;
  538. }
  539. }
  540. protected function clearCacheDB()
  541. {
  542. $oCacheDb = $this->_oDb->getDbCacheObject();
  543. return $oCacheDb->removeAllByPrefix('db_');
  544. }
  545. public function getDevicePixelRatioHandlerSuffix ()
  546. {
  547. $iDevicePixelRatio = $this->getDevicePixelRatio ();
  548. if ($iDevicePixelRatio >= 2)
  549. return $this->_sRetinaSuffix;
  550. return '';
  551. }
  552. protected function processHandlerForRetinaDevice ($mixedHandler)
  553. {
  554. return '' . $mixedHandler . $this->getDevicePixelRatioHandlerSuffix ();
  555. }
  556. static protected function _callFuncForObjectsArray ($mixed, $sFunc)
  557. {
  558. if (!is_array($mixed))
  559. $mixed = array($mixed);
  560. foreach ($mixed as $sObject) {
  561. $oTranscoder = self::getObjectInstance($sObject);
  562. if ($oTranscoder)
  563. $oTranscoder->$sFunc();
  564. }
  565. }
  566. }
  567. /** @} */