1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
26:
27: 28: 29: 30: 31: 32: 33:
34: class Mage_Cms_Model_Wysiwyg_Images_Storage extends Varien_Object
35: {
36: const DIRECTORY_NAME_REGEXP = '/^[a-z0-9\-\_]+$/si';
37: const THUMBS_DIRECTORY_NAME = '.thumbs';
38: const THUMB_PLACEHOLDER_PATH_SUFFIX = 'images/placeholder/thumbnail.jpg';
39:
40: 41: 42: 43: 44:
45: protected $_config;
46:
47: 48: 49: 50: 51:
52: protected $_configAsArray;
53:
54: 55: 56: 57: 58: 59:
60: public function getDirsCollection($path)
61: {
62: if (Mage::helper('core/file_storage_database')->checkDbUsage()) {
63: $subDirectories = Mage::getModel('core/file_storage_directory_database')->getSubdirectories($path);
64: foreach ($subDirectories as $directory) {
65: $fullPath = rtrim($path, DS) . DS . $directory['name'];
66: if (!file_exists($fullPath)) {
67: mkdir($fullPath, 0777, true);
68: }
69: }
70: }
71:
72: $conditions = array('reg_exp' => array(), 'plain' => array());
73:
74: foreach ($this->getConfig()->dirs->exclude->children() as $dir) {
75: $conditions[$dir->getAttribute('regexp') ? 'reg_exp' : 'plain'][(string) $dir] = true;
76: }
77:
78: foreach ($this->getConfig()->dirs->include->children() as $dir) {
79: unset($conditions['regexp'][(string) $dir], $conditions['plain'][(string) $dir]);
80: }
81:
82: $regExp = $conditions['reg_exp'] ? ('~' . implode('|', array_keys($conditions['reg_exp'])) . '~i') : null;
83: $collection = $this->getCollection($path)
84: ->setCollectDirs(true)
85: ->setCollectFiles(false)
86: ->setCollectRecursively(false);
87: $storageRootLength = strlen($this->getHelper()->getStorageRoot());
88:
89: foreach ($collection as $key => $value) {
90: $rootChildParts = explode(DIRECTORY_SEPARATOR, substr($value->getFilename(), $storageRootLength));
91:
92: if (array_key_exists($rootChildParts[0], $conditions['plain'])
93: || ($regExp && preg_match($regExp, $value->getFilename()))) {
94: $collection->removeItemByKey($key);
95: }
96: }
97:
98: return $collection;
99: }
100:
101: 102: 103: 104: 105: 106: 107:
108: public function getFilesCollection($path, $type = null)
109: {
110: if (Mage::helper('core/file_storage_database')->checkDbUsage()) {
111: $files = Mage::getModel('core/file_storage_database')->getDirectoryFiles($path);
112:
113: $fileStorageModel = Mage::getModel('core/file_storage_file');
114: foreach ($files as $file) {
115: $fileStorageModel->saveFile($file);
116: }
117: }
118:
119: $collection = $this->getCollection($path)
120: ->setCollectDirs(false)
121: ->setCollectFiles(true)
122: ->setCollectRecursively(false)
123: ->setOrder('mtime', Varien_Data_Collection::SORT_ORDER_ASC);
124:
125:
126: if ($allowed = $this->getAllowedExtensions($type)) {
127: $collection->setFilesFilter('/\.(' . implode('|', $allowed). ')$/i');
128: }
129:
130: $helper = $this->getHelper();
131:
132:
133: foreach ($collection as $item) {
134: $item->setId($helper->idEncode($item->getBasename()));
135: $item->setName($item->getBasename());
136: $item->setShortName($helper->getShortFilename($item->getBasename()));
137: $item->setUrl($helper->getCurrentUrl() . $item->getBasename());
138:
139: if ($this->isImage($item->getBasename())) {
140: $thumbUrl = $this->getThumbnailUrl($item->getFilename(), true);
141:
142: if(! $thumbUrl) {
143: $thumbUrl = Mage::getSingleton('adminhtml/url')->getUrl('*/*/thumbnail', array('file' => $item->getId()));
144: }
145:
146: $size = @getimagesize($item->getFilename());
147:
148: if (is_array($size)) {
149: $item->setWidth($size[0]);
150: $item->setHeight($size[1]);
151: }
152: } else {
153: $thumbUrl = Mage::getDesign()->getSkinBaseUrl() . self::THUMB_PLACEHOLDER_PATH_SUFFIX;
154: }
155:
156: $item->setThumbUrl($thumbUrl);
157: }
158:
159: return $collection;
160: }
161:
162: 163: 164: 165: 166: 167:
168: public function getCollection($path = null)
169: {
170: $collection = Mage::getModel('cms/wysiwyg_images_storage_collection');
171: if ($path !== null) {
172: $collection->addTargetDir($path);
173: }
174: return $collection;
175: }
176:
177: 178: 179: 180: 181: 182: 183: 184:
185: public function createDirectory($name, $path)
186: {
187: if (!preg_match(self::DIRECTORY_NAME_REGEXP, $name)) {
188: Mage::throwException(Mage::helper('cms')->__('Invalid folder name. Please, use alphanumeric characters, underscores and dashes.'));
189: }
190: if (!is_dir($path) || !is_writable($path)) {
191: $path = $this->getHelper()->getStorageRoot();
192: }
193:
194: $newPath = $path . DS . $name;
195:
196: if (file_exists($newPath)) {
197: Mage::throwException(Mage::helper('cms')->__('A directory with the same name already exists. Please try another folder name.'));
198: }
199:
200: $io = new Varien_Io_File();
201: if ($io->mkdir($newPath)) {
202: if (Mage::helper('core/file_storage_database')->checkDbUsage()) {
203: $relativePath = Mage::helper('core/file_storage_database')->getMediaRelativePath($newPath);
204: Mage::getModel('core/file_storage_directory_database')->createRecursive($relativePath);
205: }
206:
207: $result = array(
208: 'name' => $name,
209: 'short_name' => $this->getHelper()->getShortFilename($name),
210: 'path' => $newPath,
211: 'id' => $this->getHelper()->convertPathToId($newPath)
212: );
213: return $result;
214: }
215: Mage::throwException(Mage::helper('cms')->__('Cannot create new directory.'));
216: }
217:
218: 219: 220: 221: 222: 223:
224: public function deleteDirectory($path)
225: {
226:
227: $rootCmp = rtrim($this->getHelper()->getStorageRoot(), DS);
228: $pathCmp = rtrim($path, DS);
229:
230: if ($rootCmp == $pathCmp) {
231: Mage::throwException(Mage::helper('cms')->__('Cannot delete root directory %s.', $path));
232: }
233:
234: $io = new Varien_Io_File();
235:
236: if (Mage::helper('core/file_storage_database')->checkDbUsage()) {
237: Mage::getModel('core/file_storage_directory_database')->deleteDirectory($path);
238: }
239: if (!$io->rmdir($path, true)) {
240: Mage::throwException(Mage::helper('cms')->__('Cannot delete directory %s.', $path));
241: }
242:
243: if (strpos($pathCmp, $rootCmp) === 0) {
244: $io->rmdir($this->getThumbnailRoot() . DS . ltrim(substr($pathCmp, strlen($rootCmp)), '\\/'), true);
245: }
246: }
247:
248: 249: 250: 251: 252: 253:
254: public function deleteFile($target)
255: {
256: $io = new Varien_Io_File();
257: $io->rm($target);
258: Mage::helper('core/file_storage_database')->deleteFile($target);
259:
260: $thumb = $this->getThumbnailPath($target, true);
261: if ($thumb) {
262: $io->rm($thumb);
263: Mage::helper('core/file_storage_database')->deleteFile($thumb);
264: }
265: return $this;
266: }
267:
268:
269: 270: 271: 272: 273: 274: 275: 276:
277: public function uploadFile($targetPath, $type = null)
278: {
279: $uploader = new Mage_Core_Model_File_Uploader('image');
280: if ($allowed = $this->getAllowedExtensions($type)) {
281: $uploader->setAllowedExtensions($allowed);
282: }
283: $uploader->setAllowRenameFiles(true);
284: $uploader->setFilesDispersion(false);
285: $result = $uploader->save($targetPath);
286:
287: if (!$result) {
288: Mage::throwException( Mage::helper('cms')->__('Cannot upload file.') );
289: }
290:
291:
292: $this->resizeFile($targetPath . DS . $uploader->getUploadedFileName(), true);
293:
294: $result['cookie'] = array(
295: 'name' => session_name(),
296: 'value' => $this->getSession()->getSessionId(),
297: 'lifetime' => $this->getSession()->getCookieLifetime(),
298: 'path' => $this->getSession()->getCookiePath(),
299: 'domain' => $this->getSession()->getCookieDomain()
300: );
301:
302: return $result;
303: }
304:
305: 306: 307: 308: 309: 310: 311:
312: public function getThumbnailPath($filePath, $checkFile = false)
313: {
314: $mediaRootDir = $this->getHelper()->getStorageRoot();
315:
316: if (strpos($filePath, $mediaRootDir) === 0) {
317: $thumbPath = $this->getThumbnailRoot() . DS . substr($filePath, strlen($mediaRootDir));
318:
319: if (! $checkFile || is_readable($thumbPath)) {
320: return $thumbPath;
321: }
322: }
323:
324: return false;
325: }
326:
327: 328: 329: 330: 331: 332: 333:
334: public function getThumbnailUrl($filePath, $checkFile = false)
335: {
336: $mediaRootDir = $this->getHelper()->getStorageRoot();
337:
338: if (strpos($filePath, $mediaRootDir) === 0) {
339: $thumbSuffix = self::THUMBS_DIRECTORY_NAME . DS . substr($filePath, strlen($mediaRootDir));
340:
341: if (! $checkFile || is_readable($mediaRootDir . $thumbSuffix)) {
342: $randomIndex = '?rand=' . time();
343: return str_replace('\\', '/', $this->getHelper()->getBaseUrl() . $thumbSuffix) . $randomIndex;
344: }
345: }
346:
347: return false;
348: }
349:
350: 351: 352: 353: 354: 355: 356:
357: public function resizeFile($source, $keepRation = true)
358: {
359: if (!is_file($source) || !is_readable($source)) {
360: return false;
361: }
362:
363: $targetDir = $this->getThumbsPath($source);
364: $io = new Varien_Io_File();
365: if (!$io->isWriteable($targetDir)) {
366: $io->mkdir($targetDir);
367: }
368: if (!$io->isWriteable($targetDir)) {
369: return false;
370: }
371: $image = Varien_Image_Adapter::factory('GD2');
372: $image->open($source);
373: $width = $this->getConfigData('resize_width');
374: $height = $this->getConfigData('resize_height');
375: $image->keepAspectRatio($keepRation);
376: $image->resize($width, $height);
377: $dest = $targetDir . DS . pathinfo($source, PATHINFO_BASENAME);
378: $image->save($dest);
379: if (is_file($dest)) {
380: return $dest;
381: }
382: return false;
383: }
384:
385: 386: 387: 388: 389: 390:
391: public function resizeOnTheFly($filename)
392: {
393: $path = $this->getSession()->getCurrentPath();
394: if (!$path) {
395: $path = $this->getHelper()->getCurrentPath();
396: }
397: return $this->resizeFile($path . DS . $filename);
398: }
399:
400: 401: 402: 403: 404: 405:
406: public function getThumbsPath($filePath = false)
407: {
408: $mediaRootDir = Mage::getConfig()->getOptions()->getMediaDir();
409: $thumbnailDir = $this->getThumbnailRoot();
410:
411: if ($filePath && strpos($filePath, $mediaRootDir) === 0) {
412: $thumbnailDir .= DS . dirname(substr($filePath, strlen($mediaRootDir)));
413: }
414:
415: return $thumbnailDir;
416: }
417:
418: 419: 420: 421:
422: public function getHelper()
423: {
424: return Mage::helper('cms/wysiwyg_images');
425: }
426:
427: 428: 429: 430: 431:
432: public function getSession()
433: {
434: return Mage::getSingleton('adminhtml/session');
435: }
436:
437: 438: 439: 440: 441:
442: public function getConfig()
443: {
444: if (! $this->_config) {
445: $this->_config = Mage::getConfig()->getNode('cms/browser', 'adminhtml');
446: }
447:
448: return $this->_config;
449: }
450:
451: 452: 453: 454: 455:
456: public function getConfigAsArray()
457: {
458: if (! $this->_configAsArray) {
459: $this->_configAsArray = $this->getConfig()->asCanonicalArray();
460: }
461:
462: return $this->_configAsArray;
463: }
464:
465: 466: 467: 468: 469: 470: 471:
472: public function getConfigData($key, $default=false)
473: {
474: $configArray = $this->getConfigAsArray();
475: $key = (string) $key;
476:
477: return array_key_exists($key, $configArray) ? $configArray[$key] : $default;
478: }
479:
480: 481: 482: 483: 484: 485:
486: public function getAllowedExtensions($type = null)
487: {
488: $extensions = $this->getConfigData('extensions');
489:
490: if (is_string($type) && array_key_exists("{$type}_allowed", $extensions)) {
491: $allowed = $extensions["{$type}_allowed"];
492: } else {
493: $allowed = $extensions['allowed'];
494: }
495:
496: return array_keys(array_filter($allowed));
497: }
498:
499: 500: 501: 502: 503:
504: public function getThumbnailRoot()
505: {
506: return $this->getHelper()->getStorageRoot() . self::THUMBS_DIRECTORY_NAME;
507: }
508:
509: 510: 511: 512: 513: 514:
515: public function isImage($filename)
516: {
517: if (!$this->hasData('_image_extensions')) {
518: $this->setData('_image_extensions', $this->getAllowedExtensions('image'));
519: }
520: $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
521: return in_array($ext, $this->_getData('_image_extensions'));
522: }
523: }
524: