PageRenderTime 58ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/components/com_jce/editor/tiny_mce/plugins/imgmanager_ext/classes/imgmanager.php

https://bitbucket.org/organicdevelopment/joomla-2.5
PHP | 872 lines | 565 code | 174 blank | 133 comment | 120 complexity | 2707de3824b3afc01d7aaf21a7d142d5 MD5 | raw file
Possible License(s): LGPL-3.0, GPL-2.0, MIT, BSD-3-Clause, LGPL-2.1
  1. <?php
  2. /**
  3. * @package JCE
  4. * @copyright Copyright Š 2009-2011 Ryan Demmer. All rights reserved.
  5. * @license GNU/GPL 2 or later - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  6. * JCE is free software. This version may have been modified pursuant
  7. * to the GNU General Public License, and as distributed it includes or
  8. * is derivative of works licensed under the GNU General Public License or
  9. * other free or open source software licenses.
  10. */
  11. defined('_JEXEC') or die('RESTRICTED');
  12. // set as an extension parent
  13. define('_WF_EXT', 1);
  14. // Load class dependencies
  15. wfimport('editor.libraries.classes.manager');
  16. wfimport('editor.libraries.classes.extensions.popups');
  17. // load image processor class
  18. require_once (dirname(__FILE__) . DS . 'editor.php');
  19. class WFImageManagerPlugin extends WFMediaManager {
  20. var $_filetypes = 'images=jpg,jpeg,png,gif';
  21. var $_edit = 0;
  22. /**
  23. * @access protected
  24. */
  25. function __construct() {
  26. if(JRequest::getCmd('action') == 'thumbnail') {
  27. WFToken::checkToken() or die('RESTRICTED');
  28. $file = JRequest::getVar('img');
  29. // check file path
  30. WFUtility::checkPath($file);
  31. if($file && preg_match('/\.(jpg|jpeg|png|gif|tiff|bmp)$/i', $file)) {
  32. return $this->createCacheThumb(rawurldecode($file));
  33. }
  34. }
  35. parent::__construct();
  36. // get browser
  37. $browser = $this->getBrowser();
  38. $request = WFRequest::getInstance();
  39. if($browser->getFilesystem()->get('local')) {
  40. $this->set('_edit', 1);
  41. }
  42. // Check GD
  43. if(!function_exists('gd_info')) {
  44. $this->set('_edit', 0);
  45. }
  46. if(JRequest::getCmd('dialog', 'plugin') == 'plugin') {
  47. // add browser events
  48. $browser->addEvent('onGetItems', array($this, 'onGetItems'));
  49. $browser->addEvent('onUpload', array($this, 'onUpload'));
  50. $browser->addEvent('onFilesDelete', array($this, 'onFilesDelete'));
  51. // Setup plugin XHR callback functions
  52. $request->setRequest(array($this, 'getDimensions'));
  53. $request->setRequest(array($this, 'getThumbnailDimensions'));
  54. $request->setRequest(array($this, 'getThumbnails'));
  55. if($this->getParam('imgmanager_ext.thumbnail_editor', 1)) {
  56. $request->setRequest(array($this, 'createThumbnail'));
  57. $request->setRequest(array($this, 'deleteThumbnail'));
  58. }
  59. } else {
  60. $request->setRequest(array($this, 'saveEdit'));
  61. }
  62. }
  63. /**
  64. * Returns a reference to a editor object
  65. *
  66. * This method must be invoked as:
  67. * <pre> $browser =JCE::getInstance();</pre>
  68. *
  69. * @access public
  70. * @return JCE The editor object.
  71. * @since 1.5
  72. */
  73. function & getInstance() {
  74. static $instance;
  75. if(!is_object($instance)) {
  76. $instance = new WFImageManagerPlugin();
  77. }
  78. return $instance;
  79. }
  80. function canEdit() {
  81. return $this->get('_edit') === 1;
  82. }
  83. /**
  84. * Display the plugin
  85. */
  86. function display() {
  87. $browser = $this->getBrowser();
  88. $document = WFDocument::getInstance();
  89. if(JRequest::getCmd('dialog', 'plugin') == 'plugin') {
  90. $browser->addAction('view_mode', '', 'switchMode', WFText::_('WF_IMGMANAGER_EXT_CHANGE_MODE'));
  91. if($this->canEdit()) {
  92. $request = WFRequest::getInstance();
  93. if($this->getParam('imgmanager_ext.image_editor', 1)) {
  94. $browser->addButton('file', 'image_editor', array('action' => 'editImage', 'title' => WFText::_('WF_BUTTON_EDIT_IMAGE'), 'restrict' => 'jpg,jpeg,png'));
  95. }
  96. if($this->getParam('imgmanager_ext.thumbnail_editor', 1)) {
  97. $browser->addButton('file', 'thumb_create', array('action' => 'createThumbnail', 'title' => WFText::_('WF_BUTTON_CREATE_THUMBNAIL'), 'trigger' => true));
  98. $browser->addButton('file', 'thumb_delete', array('action' => 'deleteThumbnail', 'title' => WFText::_('WF_BUTTON_DELETE_THUMBNAIL'), 'trigger' => true));
  99. }
  100. }
  101. if($this->getParam('imgmanager_ext.insert_multiple', 1)) {
  102. $browser->addButton('file', 'insert_multiple', array('action' => 'selectMultiple', 'title' => WFText::_('WF_BUTTON_INSERT_MULTIPLE'), 'multiple' => true, 'single' => false));
  103. }
  104. // get parent display data
  105. parent::display();
  106. // create new tabs instance
  107. $tabs = WFTabs::getInstance(array('base_path' => WF_EDITOR_PLUGIN));
  108. // Add tabs
  109. $tabs->addTab('image');
  110. $tabs->addTab('rollover', $this->getParam('tabs_rollover', 1));
  111. $tabs->addTab('advanced', $this->getParam('tabs_advanced', 1));
  112. // Load Popups instance
  113. $popups = WFPopupsExtension::getInstance(array(
  114. // map src value to popup link href
  115. 'map' => array('href' => 'popup_src'),
  116. // set text to false
  117. 'text' => false)
  118. );
  119. $popups->addTemplate('popup');
  120. $popups->display();
  121. $document->addScript(array('canvas', 'imgmanager'), 'plugins');
  122. $document->addStyleSheet(array('imgmanager'), 'plugins');
  123. // load settings
  124. $document->addScriptDeclaration('ImageManagerDialog.settings=' . json_encode($this->getSettings()) . ';');
  125. } else {
  126. if($this->getParam('imgmanager_ext.image_editor', 1) == 0) {
  127. JError::raiseError(403, WFText::_('RESTRICTED'));
  128. }
  129. $view = $this->getView();
  130. $view->setLayout('editor');
  131. $view->addTemplatePath(WF_EDITOR_PLUGIN . DS . 'tmpl');
  132. $lists = array();
  133. $lists['resize'] = $this->getPresetsList('resize');
  134. $lists['crop'] = $this->getPresetsList('crop');
  135. $view->assign('lists', $lists);
  136. $document->setTitle(WFText::_('WF_IMGMANAGER_EXT_TITLE') . '::' . WFText::_('WF_IMGMANAGER_EXT_EDITOR_TITLE'));
  137. $wf = WFEditorPlugin::getInstance();
  138. // bypass parent and use plugin view
  139. $wf->display();
  140. // get UI Theme
  141. $theme = $this->getParam('editor.dialog_theme', 'jce');
  142. $document->addScript(array('canvas', 'editor'), 'plugins');
  143. $document->addStyleSheet(array('editor.css'), 'plugins');
  144. $document->addScriptDeclaration('tinyMCEPopup.onInit.add(EditorDialog.init, EditorDialog);');
  145. }
  146. $document->addScript(array('transform'), 'plugins');
  147. $document->addStyleSheet(array('transform'), 'plugins');
  148. }
  149. function getPresetsList($type) {
  150. $list = array();
  151. switch ($type) {
  152. case 'resize' :
  153. $list = explode(',', $this->getParam('imgmanager_ext.resize_presets', '320x240,640x480,800x600,1024x768', '', 'string', false));
  154. break;
  155. case 'crop' :
  156. $list = explode(',', $this->getParam('imgmanager_ext.crop_presets', '4:3,16:9,20:30,320x240,240x320,640x480,480x640,800x600,1024x768', '', 'string', false));
  157. break;
  158. }
  159. return $list;
  160. }
  161. function isFtp() {
  162. // Initialize variables
  163. jimport('joomla.client.helper');
  164. $FTPOptions = JClientHelper::getCredentials('ftp');
  165. return $FTPOptions['enabled'] == 1;
  166. }
  167. function getImageEditor() {
  168. static $editor;
  169. if(!is_object($editor)) {
  170. $editor = new WFImageEditor( array('ftp' => $this->isFtp(), 'edit' => $this->canEdit()));
  171. }
  172. return $editor;
  173. }
  174. /**
  175. * Manipulate file and folder list
  176. *
  177. * @param file/folder array reference
  178. * @param mode variable list/images
  179. * @since 1.5
  180. */
  181. function onGetItems(&$result) {
  182. $files = $result['files'];
  183. $nfiles = array();
  184. // clean cache
  185. $this->cleanCacheDir();
  186. $browser = $this->getBrowser();
  187. $filesystem = $browser->getFileSystem();
  188. foreach($files as $file) {
  189. $thumbnail = $this->getThumbnail($file['id']);
  190. $classes = '';
  191. $preview = '';
  192. $properties = array();
  193. $trigger = array();
  194. // add transform trigger
  195. $trigger[] = 'transform';
  196. // add thumbnail properties
  197. if($thumbnail && $thumbnail != $file['id']) {
  198. $classes = ' thumbnail';
  199. $properties['thumbnail'] = WFUtility::makePath($filesystem->getRootDir(), $thumbnail);
  200. $trigger[] = 'thumb_delete';
  201. } else {
  202. $trigger[] = 'thumb_create';
  203. }
  204. // add trigger properties
  205. $properties['trigger'] = implode(',', $trigger);
  206. $file = array_merge($file, array('classes' => $file['classes'] . $classes, 'properties' => array_merge($file['properties'], $properties)));
  207. $nfiles[] = $file;
  208. }
  209. $result['files'] = $nfiles;
  210. }
  211. function checkMem($pixels) {
  212. // calculate memory limit as 20% of available memory
  213. $limit = round(max(intval(ini_get('memory_limit')), intval(get_cfg_var('memory_limit'))) * 1048576 * 0.20);
  214. if ($limit < $pixels) {
  215. return false;
  216. }
  217. return true;
  218. }
  219. function onUpload($file) {
  220. $browser = $this->getBrowser();
  221. $editor = $this->getImageEditor();
  222. $params = $this->getParams(array('key' => 'imgmanager_ext'));
  223. // Resize
  224. $resize = JRequest::getInt('upload_resize_state', 0);
  225. // Thumbnail
  226. $thumbnail = JRequest::getInt('upload_thumbnail_state', 0);
  227. $dim = @getimagesize($file);
  228. if($dim) {
  229. $w = $dim[0];
  230. $h = $dim[1];
  231. if($resize && $this->checkAccess('upload_resize_state')) {
  232. $rw = JRequest::getInt('upload_resize_width');
  233. $rh = JRequest::getInt('upload_resize_height');
  234. $rq = $params->get('resize_quality', 80, false);
  235. // need at least one value
  236. if ($rw || $rh) {
  237. // calculate width if not set
  238. if (!$rw) {
  239. $rw = round($rh / $w * $h, 0);
  240. }
  241. // calculate height if not set
  242. if (!$rh) {
  243. $rh = round($rw / $w * $h, 0);
  244. }
  245. }
  246. // get scale based on aspect ratio
  247. $scale = ($w > $h) ? $rw / $w : $rh / $h;
  248. if($scale < 1) {
  249. //if ($this->checkMem($w * $h)) {
  250. if(!$editor->resize($file, null, $rw, $rh, $rq)) {
  251. $browser->setResult(WFText::_('WF_IMGMANAGER_EXT_RESIZE_ERROR'), 'error');
  252. }
  253. //}
  254. }
  255. }
  256. if($thumbnail && $this->checkAccess('upload_thumbnail_state')) {
  257. $tw = JRequest::getInt('upload_thumbnail_width');
  258. $th = JRequest::getInt('upload_thumbnail_height');
  259. $tq = $params->get('thumbnail_quality', 80, false);
  260. // need at least one value
  261. if ($tw || $th) {
  262. // calculate width if not set
  263. if (!$tw) {
  264. $tw = round($th / $dim[1] * $dim[0], 0);
  265. }
  266. // calculate height if not set
  267. if (!$th) {
  268. $th = round($tw / $dim[0] * $dim[1], 0);
  269. }
  270. // Make relative
  271. $file = str_replace($browser->getBaseDir(), '', $file);
  272. $coords = array(
  273. 'sx' => null,
  274. 'sy' => null,
  275. 'sw' => null,
  276. 'sh' => null
  277. );
  278. if (JRequest::getInt('upload_thumbnail_crop', 0)) {
  279. $coords = $this->cropThumbnail($dim[0], $dim[1], $tw, $th);
  280. }
  281. //if ($this->checkMem($w * $h)) {
  282. if(!$this->createThumbnail($file, $tw, $th, $tq, $coords['sx'], $coords['sy'], $coords['sw'], $coords['sh'])) {
  283. $browser->setResult(WFText::_('WF_IMGMANAGER_EXT_THUMBNAIL_ERROR'), 'error');
  284. }
  285. //}
  286. }
  287. }
  288. }
  289. return $browser->getResult();
  290. }
  291. function onFilesDelete($file) {
  292. $browser = $this->getBrowser();
  293. if(file_exists(WFUtility::makePath($browser->getBaseDir(), $this->getThumbPath($file)))) {
  294. return $this->deleteThumbnail($file);
  295. }
  296. return $browser->getResult();
  297. }
  298. function getDimensions($file) {
  299. $base = strpos(rawurldecode($file), $this->getBase()) === false ? $this->getBaseDir() : JPATH_ROOT;
  300. $path = WFUtility::makePath($base, rawurldecode($file));
  301. $h = array('width' => '', 'height' => '');
  302. if(file_exists($path)) {
  303. $dim = @getimagesize($path);
  304. $h = array('width' => $dim[0], 'height' => $dim[1]);
  305. }
  306. return $h;
  307. }
  308. function getThumbnailDimensions($file) {
  309. return $this->getDimensions($this->getThumbPath($file));
  310. }
  311. function toRelative($file) {
  312. return WFUtility::makePath(str_replace(JPATH_ROOT . DS, '', dirname(JPath::clean($file))), basename($file));
  313. }
  314. /**
  315. * Check for the thumbnail for a given file
  316. * @param string $relative The relative path of the file
  317. * @return The thumbnail URL or false if none.
  318. */
  319. function getThumbnail($relative) {
  320. // get browser
  321. $browser = $this->getBrowser();
  322. $filesystem = $browser->getFileSystem();
  323. $params = $this->getParams(array('key' => 'imgmanager_ext'));
  324. $path = WFUtility::makePath($browser->getBaseDir(), $relative);
  325. $dim = @getimagesize($path);
  326. $dir = WFUtility::makePath(str_replace("\\", "/", dirname($relative)), $params->get('thumbnail_folder', 'thumbnails'));
  327. $thumbnail = WFUtility::makePath($dir, $this->getThumbName($relative));
  328. // Image has a thumbnail prefix
  329. if(strpos($relative, $params->get('thumbnail_prefix', 'thumb_', false)) === 0) {
  330. return $relative;
  331. }
  332. // The original image is smaller than a thumbnail so just return the url to the original image.
  333. if($dim[0] <= $params->get('thumbnail_size', 120) && $dim[1] <= $params->get('thumbnail_size', 90)) {
  334. return $relative;
  335. }
  336. //check for thumbnails, if exists return the thumbnail url
  337. if(file_exists(WFUtility::makePath($browser->getBaseDir(), $thumbnail))) {
  338. return $thumbnail;
  339. }
  340. return false;
  341. }
  342. function getThumbnails($files) {
  343. $browser = $this->getBrowser();
  344. jimport('joomla.filesystem.file');
  345. $thumbnails = array();
  346. foreach($files as $file) {
  347. $thumbnails[$file['name']] = $this->getCacheThumb(WFUtility::makePath($browser->getBaseDir(), $file['url']), true, 50, 50, JFile::getExt($file['name']), 50);
  348. }
  349. return $thumbnails;
  350. }
  351. function getThumbPath($file) {
  352. return WFUtility::makePath($this->getThumbDir($file, false), $this->getThumbName($file));
  353. }
  354. /**
  355. * Get an image's thumbnail file name
  356. * @param string $file the full path to the image file
  357. * @return string of the thumbnail file
  358. */
  359. function getThumbName($file) {
  360. return $this->getParam('imgmanager_ext.thumbnail_prefix', 'thumb_', '', 'string', false) . basename($file);
  361. }
  362. function getThumbDir($file, $create) {
  363. $browser = $this->getBrowser();
  364. $filesystem = $browser->getFileSystem();
  365. $dir = WFUtility::makePath(str_replace("\\", "/", dirname($file)), $this->getParam('imgmanager_ext.thumbnail_folder', 'thumbnails'));
  366. if($create && !$filesystem->exists($dir)) {
  367. $filesystem->createFolder(dirname($dir), basename($dir));
  368. }
  369. return $dir;
  370. }
  371. function saveEdit() {
  372. // check for image editor access
  373. if (!$this->checkAccess('image_editor', 1)) {
  374. JError::raiseError(403, 'RESTRICTED ACCESS');
  375. }
  376. $editor = $this->getImageEditor();
  377. $browser = $this->getBrowser();
  378. $args = func_get_args();
  379. // file src
  380. $file = array_shift($args);
  381. // check file
  382. WFUtility::checkPath($file);
  383. // file name
  384. $name = array_shift($args);
  385. // check name
  386. WFUtility::checkPath($name);
  387. // check for extension in destination name
  388. if (preg_match('#\.(php|php(3|4|5)|phtml|pl|py|jsp|asp|htm|html|shtml|sh|cgi)\b#i', $name)) {
  389. JError::raiseError(403, 'INVALID FILE NAME');
  390. }
  391. // edit data
  392. $props = array_shift($args);
  393. // exif data
  394. $exif = null;
  395. $data = JRequest::getVar('data', '', 'POST', 'STRING', JREQUEST_ALLOWRAW);
  396. if (preg_match('#^data:image\/(jpeg|jpg|png|bmp);base64#', $data)) {
  397. // replace spaces
  398. $data = str_replace(' ', '+', $data);
  399. // remove header
  400. $data = substr($data, strpos($data, ",") + 1);
  401. // decode data
  402. $data = base64_decode($data);
  403. $src = WFUtility::makePath(JPATH_SITE, $file);
  404. $dest = dirname($src) . DS . basename($name);
  405. // get exif data from orignal file
  406. if(preg_match('#\.jp(eg|g)$#i', basename($file)) && basename($file) == basename($dest)) {
  407. // load exif classes
  408. require_once (dirname(__FILE__) . DS . 'pel' . DS . 'PelJpeg.php');
  409. $jpeg = new PelJpeg($src);
  410. $exif = $jpeg->getExif();
  411. }
  412. if(!JFile::write($dest, $data)) {
  413. $browser->setResult(WFText::_('WF_IMGMANAGER_EXT_ERROR'), 'error');
  414. } else {
  415. $browser->setResult(basename($dest), 'files');
  416. if($exif && basename($file) == basename($dest)) {
  417. $pel = new PelDataWindow($data);
  418. if(PelJpeg::isValid($pel)) {
  419. $jpeg = new PelJpeg();
  420. $jpeg->load($pel);
  421. /*$dim = @getimagesize($dest);
  422. if ($dim) {
  423. $tiff = $exif->getTiff();
  424. $ifd0 = $tiff->getIfd();
  425. $width = $ifd0->getEntry(PelTag::IMAGE_WIDTH);
  426. $height = $ifd0->getEntry(PelTag::IMAGE_LENGTH);
  427. $width->setValue($dim[0]);
  428. $height->setValue($dim[1]);
  429. }*/
  430. $jpeg->setExif($exif);
  431. $jpeg->saveFile($dest);
  432. }
  433. }
  434. }
  435. } else {
  436. $browser->setResult(WFText::_('WF_IMGMANAGER_EXT_ERROR'), 'error');
  437. }
  438. return $browser->getResult();
  439. }
  440. function cropThumbnail($sw, $sh, $dw, $dh) {
  441. $sx = 0;
  442. $sy = 0;
  443. $w = $dw;
  444. $h = $dh;
  445. // check ratio
  446. if($sw / $sh != $dw / $dh) {
  447. if($w / $h > $sw / $w) {
  448. $h = $h * ($sw / $w);
  449. $w = $sw;
  450. if($h > $sh) {
  451. $w = $w * ($sh / $h);
  452. $h = $sh;
  453. }
  454. } else {
  455. $w = $w * ($sh / $h);
  456. $h = $sh;
  457. if($w > $sw) {
  458. $h = $h * ($sw / $w);
  459. $w = $sw;
  460. }
  461. }
  462. if($w < $sw) {
  463. $sx = floor(($sw - $w) / 2);
  464. } else {
  465. $sx = 0;
  466. }
  467. if($h < $sh) {
  468. $sy = floor(($sh - $h) / 2);
  469. } else {
  470. $sy = 0;
  471. }
  472. }
  473. return array('sx' => $sx, 'sy' => $sy, 'sw' => $w, 'sh' => $h);
  474. }
  475. /**
  476. * Create a thumbnail
  477. * @param string $file relative path of the image
  478. * @param string $width thumbnail width
  479. * @param string $height thumbnail height
  480. * @param string $quality thumbnail quality (%)
  481. * @param string $mode thumbnail mode
  482. */
  483. function createThumbnail($file, $width = null, $height = null, $quality = 100, $sx = null, $sy = null, $sw = null, $sh = null) {
  484. if (!$this->checkAccess('thumbnail_editor', 1) && !$this->checkAccess('upload_thumbnail', 1)) {
  485. JError::raiseError(403, 'RESTRICTED ACCESS');
  486. }
  487. // check path
  488. WFUtility::checkPath($file);
  489. $browser = $this->getBrowser();
  490. $filesystem = $browser->getFileSystem();
  491. $editor = $this->getImageEditor();
  492. $thumb = WFUtility::makePath($this->getThumbDir($file, true), $this->getThumbName($file));
  493. $data = JRequest::getVar('data', '', 'POST', 'STRING', JREQUEST_ALLOWRAW);
  494. if($data) {
  495. if (preg_match('#data:image\/(jpeg|jpg|png|bmp);base64#', $data)) {
  496. // replace spaces
  497. $data = str_replace(' ', '+', $data);
  498. // remove header
  499. $data = substr($data, strpos($data, ",") + 1);
  500. // decode data
  501. $data = base64_decode($data);
  502. // write to file
  503. if(!$filesystem->write($thumb, $data)) {
  504. $browser->setResult(WFText::_('WF_IMGMANAGER_EXT_THUMBNAIL_CREATE_ERROR'), 'error');
  505. }
  506. } else {
  507. $browser->setResult(WFText::_('WF_IMGMANAGER_EXT_THUMBNAIL_CREATE_ERROR'), 'error');
  508. }
  509. } else {
  510. if ($this->canEdit()) {
  511. $path = WFUtility::makePath($browser->getBaseDir(), $file);
  512. $thumb = WFUtility::makePath($browser->getBaseDir(), $thumb);
  513. if(!$editor->resize($path, $thumb, $width, $height, $quality, $sx, $sy, $sw, $sh)) {
  514. $browser->setResult(WFText::_('WF_IMGMANAGER_EXT_THUMBNAIL_CREATE_ERROR'), 'error');
  515. }
  516. }
  517. }
  518. return $browser->getResult();
  519. }
  520. function deleteThumbnail($file) {
  521. if (!$this->checkAccess('thumbnail_editor', 1)) {
  522. JError::raiseError(403, 'RESTRICTED ACCESS');
  523. }
  524. // check path
  525. WFUtility::checkPath($file);
  526. $browser = $this->getBrowser();
  527. $filesystem = $browser->getFileSystem();
  528. $dir = $this->getThumbDir($file, false);
  529. if($browser->deleteItem($this->getThumbPath($file))) {
  530. if($filesystem->countFiles($dir) == 0 && $filesystem->countFolders($dir) == 0) {
  531. if(!$browser->deleteItem($dir)) {
  532. $browser->setResult(WFText::_('WF_IMGMANAGER_EXT_THUMBNAIL_FOLDER_DELETE_ERROR'), 'error');
  533. }
  534. }
  535. }
  536. return $browser->getResult();
  537. }
  538. function getCacheDirectory() {
  539. $app = JFactory::getApplication();
  540. jimport('joomla.filesystem.folder');
  541. $cache = $app->getCfg('tmp_path');
  542. $dir = $this->getParam('imgmanager_ext.cache', $cache, '', 'string', false);
  543. // get absolute path
  544. $dir = realpath(JPath::clean($dir));
  545. /*if(strpos(JPath::clean($dir), JPath::clean(JPATH_ROOT)) === false) {
  546. $dir = WFUtility::makePath(JPATH_ROOT, $dir);
  547. }*/
  548. if(!JFolder::exists($dir)) {
  549. if(@JFolder::create($dir)) {
  550. return $dir;
  551. }
  552. }
  553. return $dir;
  554. }
  555. function cleanCacheDir() {
  556. jimport('joomla.filesystem.folder');
  557. jimport('joomla.filesystem.file');
  558. $params = $this->getParams(array('key' => 'imgmanager_ext'));
  559. $cache_max_size = intval($params->get('cache_size', 10, false)) * 1024 * 1024;
  560. $cache_max_age = intval($params->get('cache_age', 30, false)) * 86400;
  561. $cache_max_files = intval($params->get('cache_files', 0, false));
  562. if($cache_max_age > 0 || $cache_max_size > 0 || $cache_max_files > 0) {
  563. $path = $this->getCacheDirectory();
  564. $files = JFolder::files($path, '^(wf_thumb_cache_)([a-z0-9]+)\.(jpg|jpeg|gif|png)$');
  565. $num = count($files);
  566. $size = 0;
  567. $cutofftime = time() - 3600;
  568. if($num) {
  569. foreach($files as $file) {
  570. $file = WFUtility::makePath($path, $file);
  571. if(is_file($file)) {
  572. $ftime = @fileatime($file);
  573. $fsize = @filesize($file);
  574. if($fsize == 0 && $ftime < $cutofftime) {
  575. @JFile::delete($file);
  576. }
  577. if($cache_max_files > 0) {
  578. if($num > $cache_max_files) {
  579. @JFile::delete($file);
  580. $num--;
  581. }
  582. }
  583. if($cache_max_age > 0) {
  584. if($ftime < (time() - $cache_max_age)) {
  585. @JFile::delete($file);
  586. }
  587. }
  588. if($cache_max_files > 0) {
  589. if(($size + $fsize) > $cache_max_size) {
  590. @JFile::delete($file);
  591. }
  592. }
  593. }
  594. }
  595. }
  596. }
  597. return true;
  598. }
  599. function redirectThumb($file, $mime) {
  600. if(is_file($file)) {
  601. header("Content-length: " . filesize($file));
  602. header("Content-type: " . $mime);
  603. header("Location: " . $this->toRelative($file));
  604. }
  605. }
  606. function outputImage($file, $mime) {
  607. header("Content-length: " . filesize($file));
  608. header("Content-type: " . $mime);
  609. ob_clean();
  610. flush();
  611. @readfile($file);
  612. exit ;
  613. }
  614. function getCacheThumbPath($file, $width, $height) {
  615. jimport('joomla.filesystem.file');
  616. $mtime = @filemtime($file);
  617. $thumb = 'wf_thumb_cache_' . md5(basename(JFile::stripExt($file)) . $mtime . $width . $height) . '.' . JFile::getExt($file);
  618. return WFUtility::makePath($this->getCacheDirectory(), $thumb);
  619. }
  620. function createCacheThumb($file) {
  621. jimport('joomla.filesystem.file');
  622. $browser = $this->getBrowser();
  623. $editor = $this->getImageEditor();
  624. // check path
  625. WFUtility::checkPath($file);
  626. $file = WFUtility::makePath($browser->getBaseDir(), $file);
  627. // default for list thumbnails
  628. $width = 100;
  629. $height = 100;
  630. $quality = 75;
  631. $data = @getimagesize($file);
  632. $mime = $data['mime'];
  633. if(($data[0] < $width && $data[1] < $height)) {
  634. return $this->outputImage($file, $mime);
  635. }
  636. // try exif thumbnail
  637. if ($mime == 'image/jpeg' || $mime == 'image/tiff') {
  638. $exif = exif_thumbnail($file, $width, $height, $type);
  639. if ($exif !== false) {
  640. header("Content-type: " . image_type_to_mime_type($type));
  641. die($exif);
  642. }
  643. }
  644. $thumb = $this->getCacheThumbPath($file, $width, $height);
  645. if(JFile::exists($thumb)) {
  646. return $this->outputImage($thumb, $mime);
  647. }
  648. $coords = $this->cropThumbnail($dim[0], $dim[1], $width, $height);
  649. if ($this->checkMem($dim[0] * $dim[1])) {
  650. if($editor->resize($file, $thumb, $width, $height, $quality, $coords['sx'], $coords['sy'], $coords['sw'], $coords['sh'])) {
  651. if(JFile::exists($thumb)) {
  652. return $this->outputImage($thumb, $mime);
  653. }
  654. }
  655. }
  656. // exit with no data
  657. exit();
  658. }
  659. function getSettings() {
  660. $params = $this->getParams(array('key' => 'imgmanager_ext'));
  661. $settings = array(
  662. 'defaults' => $this->getDefaults(),
  663. 'attributes' => array(
  664. 'dimensions' => $params->get('attributes_dimensions', 1),
  665. 'align' => $params->get('attributes_align', 1),
  666. 'margin' => $params->get('attributes_margin', 1),
  667. 'border' => $params->get('attributes_border', 1)
  668. ),
  669. 'view_mode' => $params->get('mode', 'list'),
  670. 'canEdit' => $this->canEdit(),
  671. 'cache_enable' => $params->get('cache_enable', 0)
  672. );
  673. return parent::getSettings($settings);
  674. }
  675. function getDefaults() {
  676. $params = $this->getParams(array('key' => 'imgmanager_ext'));
  677. $defaults = array(
  678. // Upload
  679. 'upload_resize' => $params->get('upload_resize', 1),
  680. 'upload_resize_state' => $params->get('upload_resize_state', 0),
  681. 'upload_resize_width' => $params->get('resize_width', 640),
  682. 'upload_resize_height' => $params->get('resize_height', 480),
  683. 'resize_quality' => $params->get('resize_quality', 100),
  684. // Thumbnails
  685. 'upload_thumbnail' => $params->get('upload_thumbnail', 1),
  686. 'upload_thumbnail_state' => $params->get('upload_thumbnail_state', 0),
  687. 'upload_thumbnail_crop' => $params->get('upload_thumbnail_crop', 0),
  688. 'thumbnail_width' => $params->get('thumbnail_width', 120),
  689. 'thumbnail_height' => $params->get('thumbnail_height', 90),
  690. 'thumbnail_quality' => $params->get('thumbnail_quality', 80)
  691. );
  692. return parent::getDefaults($defaults);
  693. }
  694. }
  695. ?>