Webylon 3.1 API Docs
  • Package
  • Class
  • Tree
  • Deprecated
  • Download
Version: current
  • 3.2
  • 3.1

Packages

  • auth
  • Booking
  • cart
    • shipping
    • steppedcheckout
  • Catalog
  • cms
    • assets
    • batchaction
    • batchactions
    • bulkloading
    • comments
    • content
    • core
    • export
    • newsletter
    • publishers
    • reports
    • security
    • tasks
  • Dashboard
  • DataObjectManager
  • event
  • faq
  • forms
    • actions
    • core
    • fields-basic
    • fields-dataless
    • fields-datetime
    • fields-files
    • fields-formatted
    • fields-formattedinput
    • fields-relational
    • fields-structural
    • transformations
    • validators
  • googlesitemaps
  • guestbook
  • installer
  • newsletter
  • None
  • photo
    • gallery
  • PHP
  • polls
  • recaptcha
  • sapphire
    • api
    • bulkloading
    • control
    • core
    • cron
    • dev
    • email
    • fields-formattedinput
    • filesystem
    • formatters
    • forms
    • i18n
    • integration
    • misc
    • model
    • parsers
    • search
    • security
    • tasks
    • testing
    • tools
    • validation
    • view
    • widgets
  • seo
    • open
      • graph
  • sfDateTimePlugin
  • spamprotection
  • stealth
    • captha
  • subsites
  • userform
    • pagetypes
  • userforms
  • webylon
  • widgets

Classes

  • Archive
  • File
  • Filesystem
  • FlushGeneratedImagesTask
  • FLV
  • Folder
  • Folder_UnusedAssetsField
  • GD
  • Image
  • Image_Cached
  • MediawebPage_Image
  • MP3
  • SaveFileSizeTask
  • TarballArchive
  • Upload
  • Upload_Validator
  • VideoFile
  1 <?php
  2 /**
  3  * Represents an image attached to a page.
  4  * @package sapphire
  5  * @subpackage filesystem
  6  */
  7 class Image extends File {
  8     
  9     const ORIENTATION_SQUARE = 0;
 10     const ORIENTATION_PORTRAIT = 1;
 11     const ORIENTATION_LANDSCAPE = 2;
 12     
 13     static $casting = array(
 14         'Tag' => 'HTMLText',
 15     );
 16 
 17     // форматы преобразования для которых при равенстве размеров картинки совпадают
 18     static $safeGenerateFormats = array('SetRatioSize', 'SetSize', 'SetWidth', 'SetHeight', 'croppedimage');
 19 
 20     /**
 21      * The width of an image thumbnail in a strip.
 22      * @var int
 23      */
 24     public static $strip_thumbnail_width = 50;
 25     
 26     /**
 27      * The height of an image thumbnail in a strip.
 28      * @var int
 29      */
 30     public static $strip_thumbnail_height = 50;
 31     
 32     /**
 33      * The width of an image thumbnail in the CMS.
 34      * @var int
 35      */
 36     public static $cms_thumbnail_width = 100;
 37     
 38     /**
 39      * The height of an image thumbnail in the CMS.
 40      */
 41     public static $cms_thumbnail_height = 100;
 42     
 43     /**
 44      * The width of an image thumbnail in the Asset section.
 45      */
 46     public static $asset_thumbnail_width = 100;
 47     
 48     /**
 49      * The height of an image thumbnail in the Asset section.
 50      */
 51     public static $asset_thumbnail_height = 100;
 52     
 53     /**
 54      * The width of an image preview in the Asset section.
 55      */
 56     public static $asset_preview_width = 400;
 57     
 58     /**
 59      * The height of an image preview in the Asset section.
 60      */
 61     public static $asset_preview_height = 200;
 62     
 63     /**
 64      * Set up template methods to access the transformations generated by 'generate' methods.
 65      */
 66     public function defineMethods() {
 67         $methodNames = $this->allMethodNames();
 68         foreach($methodNames as $methodName) {
 69             if(substr($methodName,0,8) == 'generate') {
 70                 $this->addWrapperMethod(substr($methodName,8), 'getFormattedImage');
 71             }
 72         }
 73         
 74         parent::defineMethods();
 75     }
 76     
 77     /**
 78      * An image exists if it has a filename.
 79      * @return boolean
 80      */
 81     public function exists() {
 82         if(isset($this->record["Filename"])) {
 83             return true;
 84         }       
 85     }
 86 
 87     /**
 88      * Get the relative URL for this Image.
 89      * Overwrites File->URL() which returns an absolute URL.
 90      * 
 91      * @todo Refactor to return absolute URL like {@link File}
 92      * @uses Director::baseURL()
 93      * @return string
 94      */
 95 /* !!! absent in 2.4.0
 96     function getURL() {
 97         return $this->Filename;//Director::baseURL() . $this->Filename;
 98     }
 99 */  
100     /**
101      * Return an XHTML img tag for this Image.
102      * @return string
103      */
104     function getTag() {
105         if(file_exists(Director::baseFolder() . '/' . $this->Filename)) {
106             $url = $this->getURL(); // !!! absolute url
107             $title = ($this->Title) ? $this->Title : $this->Filename;
108             if($this->Title) {
109                 $title = Convert::raw2att($this->Title);
110             } else {
111                 if(preg_match("/([^\/]*)\.[a-zA-Z0-9]{1,6}$/", $title, $matches)) $title = Convert::raw2att($matches[1]);
112             }
113             return "<img src=\"$url\" alt=\"$title\" />";
114         }
115     }
116     
117     /**
118      * Return an XHTML img tag for this Image.
119      * @return string
120      */
121     function forTemplate() {
122         return $this->getTag();
123     }
124 
125     function loadUploadedImage($tmpFile) {
126         if(!is_array($tmpFile)) {
127             user_error("Image::loadUploadedImage() Not passed an array.  Most likely, the form hasn't got the right enctype", E_USER_ERROR);
128         }
129         
130         if(!$tmpFile['size']) {
131             return;
132         }
133         
134         $class = $this->class;
135 
136         // Create a folder      
137         if(!file_exists(ASSETS_PATH)) {
138             mkdir(ASSETS_PATH, Filesystem::$folder_create_mask);
139         }
140         
141         if(!file_exists(ASSETS_PATH . "/$class")) {
142             mkdir(ASSETS_PATH . "/$class", Filesystem::$folder_create_mask);
143         }
144 
145         // Generate default filename
146         $file = Convert::rus2lat($tmpFile['name']);
147         $file = str_replace(' ', '-',$file);
148         $file = ereg_replace('[^A-Za-z0-9+.-]+','',$file);
149         $file = ereg_replace('-+', '-',$file);
150         if(!$file) {
151             $file = "file.jpg";
152         }
153         
154         $file = ASSETS_PATH . "/$class/$file";
155         
156         while(file_exists(BASE_PATH . "/$file")) {
157             $i = $i ? ($i+1) : 2;
158             $oldFile = $file;
159             $file = ereg_replace('[0-9]*(\.[^.]+$)',$i . '\\1', $file);
160             if($oldFile == $file && $i > 2) user_error("Couldn't fix $file with $i", E_USER_ERROR);
161         }
162         
163         if(file_exists($tmpFile['tmp_name']) && copy($tmpFile['tmp_name'], BASE_PATH . "/$file")) {
164             // Remove the old images
165 
166             $this->deleteFormattedImages();
167             return true;
168         }
169     }
170     
171     public function SetWidth($width) {
172         return $this->getFormattedImage('SetWidth', $width);
173     }
174     
175     public function SetHeight($height) {
176         return $this->getFormattedImage('SetHeight', $height);
177     }
178     
179     public function SetSize($width, $height) {
180         return $this->getFormattedImage('SetSize', $width, $height);
181     }
182     
183     public function SetRatioSize($width, $height) {
184         return $this->getFormattedImage('SetRatioSize', $width, $height);
185     }
186     
187     public function generateSetRatioSize(GD $gd, $width, $height) {
188         return $gd->resizeRatio($width, $height);
189     }
190     
191     /**
192      * Resize this Image by width, keeping aspect ratio. Use in templates with $SetWidth.
193      * @return GD
194      */
195     public function generateSetWidth(GD $gd, $width) {
196         return $gd->resizeByWidth($width);
197     }
198     
199     /**
200      * Resize this Image by height, keeping aspect ratio. Use in templates with $SetHeight.
201      * @return GD
202      */
203     public function generateSetHeight(GD $gd, $height){
204         return $gd->resizeByHeight($height);
205     }
206     
207     /**
208      * Resize this Image by both width and height, using padded resize. Use in templates with $SetSize.
209      * @return GD
210      */
211     public function generateSetSize(GD $gd, $width, $height) {
212         return $gd->paddedResize($width, $height);
213     }
214     
215     public function CMSThumbnail() {
216         return $this->getFormattedImage('CMSThumbnail');
217     }
218     
219     /**
220      * Resize this image for the CMS. Use in templates with $CMSThumbnail.
221      * @return GD
222      */
223     function generateCMSThumbnail(GD $gd) {
224         return $gd->paddedResize($this->stat('cms_thumbnail_width'),$this->stat('cms_thumbnail_height'));
225     }
226     
227     /**
228      * Resize this image for preview in the Asset section. Use in templates with $AssetLibraryPreview.
229      * @return GD
230      */
231     function generateAssetLibraryPreview(GD $gd) {
232         return $gd->paddedResize($this->stat('asset_preview_width'),$this->stat('asset_preview_height'));
233     }
234     
235     /**
236      * Resize this image for thumbnail in the Asset section. Use in templates with $AssetLibraryThumbnail.
237      * @return GD
238      */
239     function generateAssetLibraryThumbnail(GD $gd) {
240         return $gd->paddedResize($this->stat('asset_thumbnail_width'),$this->stat('asset_thumbnail_height'));
241     }
242     
243     /**
244      * Resize this image for use as a thumbnail in a strip. Use in templates with $StripThumbnail.
245      * @return GD
246      */
247     function generateStripThumbnail(GD $gd) {
248         return $gd->croppedResize($this->stat('strip_thumbnail_width'),$this->stat('strip_thumbnail_height'));
249     }
250     
251     function generatePaddedImage(GD $gd, $width, $height) {
252         return $gd->paddedResize($width, $height);
253     }
254 
255     /**
256      * Return an image object representing the image in the given format.
257      * This image will be generated using generateFormattedImage().
258      * The generated image is cached, to flush the cache append ?flush=1 to your URL.
259      * @param string $format The name of the format.
260      * @param string $arg1 An argument to pass to the generate function.
261      * @param string $arg2 A second argument to pass to the generate function.
262      * @return Image_Cached
263      */
264     function getFormattedImage($format, $arg1 = null, $arg2 = null) {
265         if($this->ID && $this->Filename && Director::fileExists($this->Filename)) {
266             $cacheFile = $this->cacheFilename($format, $arg1, $arg2);
267 
268             if(!file_exists(Director::baseFolder().'/'.$cacheFile) || isset($_GET['flush'])) {
269                 $this->generateFormattedImage($format, $arg1, $arg2);
270             }
271             
272             $cached = new Image_Cached($cacheFile);
273             // Pass through the title so the templates can use it
274             $cached->Title = $this->Title;
275             return $cached;
276         }
277     }
278     
279     /**
280      * Return the filename for the cached image, given it's format name and arguments.
281      * @param string $format The format name.
282      * @param string $arg1 The first argument passed to the generate function.
283      * @param string $arg2 The second argument passed to the generate function.
284      * @return string
285      */
286     function cacheFilename($format, $arg1 = null, $arg2 = null) {
287         $folder = $this->ParentID ? $this->Parent()->Filename : ASSETS_DIR . "/";
288         
289         $format = $format.$arg1.$arg2;
290         
291         return $folder . "_resampled/$format-" . $this->Name;
292     }
293     
294     /**
295      * Generate an image on the specified format. It will save the image
296      * at the location specified by cacheFilename(). The image will be generated
297      * using the specific 'generate' method for the specified format.
298      * @param string $format Name of the format to generate.
299      * @param string $arg1 Argument to pass to the generate method.
300      * @param string $arg2 A second argument to pass to the generate method.
301      */
302     function generateFormattedImage($format, $arg1 = null, $arg2 = null) {
303         $cacheFile = $this->cacheFilename($format, $arg1, $arg2);
304     
305         $gd = new GD(Director::baseFolder().'/' . $this->Filename);
306         
307         if($gd->hasGD()){
308             $generateFunc = "generate$format";      
309             if($this->hasMethod($generateFunc)){
310                 $gd2 = $this->$generateFunc($gd, $arg1, $arg2);
311                 if($gd2){
312                     // если картинки совпадают - просто копируем (на unix-like можно делать symlink)
313                     if (array_search($format, Image::$safeGenerateFormats) !== false
314                         && $gd->getWidth() == $gd2->getWidth() && $gd->getHeight() == $gd2->getHeight()
315                         ) {
316                         $gd2->makeDir(dirname(Director::baseFolder().'/' . $cacheFile));
317                         copy(Director::baseFolder().'/' . $this->Filename, Director::baseFolder().'/' . $cacheFile);
318                         @chmod(Director::baseFolder().'/' . $cacheFile, 0664);
319                     }
320                     else {
321                         $gd2->writeTo(Director::baseFolder().'/' . $cacheFile);
322                     }
323                 }
324     
325             } else {
326                 USER_ERROR("Image::generateFormattedImage - Image $format function not found.",E_USER_WARNING);
327             }
328         }
329     }
330     
331     /**
332      * Generate a resized copy of this image with the given width & height.
333      * Use in templates with $ResizedImage.
334      */
335     function generateResizedImage($gd, $width, $height) {
336         if(is_numeric($gd) || !$gd){
337             USER_ERROR("Image::generateFormattedImage - generateResizedImage is being called by legacy code or gd is not set.",E_USER_WARNING);
338         }else{
339             return $gd->resize($width, $height);
340         }
341     }
342 
343     /**
344      * Generate a resized copy of this image with the given width & height, cropping to maintain aspect ratio.
345      * Use in templates with $CroppedImage
346      */
347     function generateCroppedImage($gd, $width, $height) {
348         return $gd->croppedResize($width, $height);
349     }
350     
351     /**
352      * Generate a rotateв Clockwise image
353      * Use in templates with $RotateClockwise
354      */
355     public function generateRotateClockwise(GD $gd) {
356         return $gd->rotate(90);
357     }
358 
359     /**
360      * Generate a rotateв CounterClockwise image
361      * Use in templates with $RotateCounterClockwise
362      */
363     public function generateRotateCounterClockwise(GD $gd) {
364         return $gd->rotate(270);
365     }
366 
367     /**
368      * Remove all of the formatted cached images for this image.
369      * @return int The number of formatted images deleted
370      */
371     public function deleteFormattedImages() {
372             
373         if(!$this->Filename) return 0;
374         $numDeleted = 0;
375         $folder = $this->ParentID ? $this->Parent()->Filename : ASSETS_DIR . '/';
376         $name = $this->Name;
377         
378         if ($this->isChanged('ParentID')) {
379             $folder = dirname($this->getField('Filename')) . '/';
380             $name = basename($this->getField('Filename'));
381         }
382         
383         $cacheDir = Director::getAbsFile($folder . '_resampled/');
384         if(!is_dir($cacheDir)) return 0;
385 
386         $this->extend('deleteFormattedImages', $numDeleted);        
387         
388         $cachedFiles = array();
389         if($handle = opendir($cacheDir)) {
390             while(($file = readdir($handle)) !== false) {
391                 // save files not starting with a dot && ending with $this->Name
392                 if(substr($file, 0, 1) != '.' 
393                     && substr_compare($file, $name, -strlen($name), strlen($name)) == 0
394                     && is_file($cacheDir . $file)
395                 ) {
396                     $cachedFiles[] = $file;
397                 }
398             }
399             closedir($handle);
400         }
401         if (count($cachedFiles) == 0) return 0;
402 
403         $methodNames = $this->allMethodNames();
404         $generateFuncs = array();
405         foreach($methodNames as $methodName) {
406             if(substr($methodName, 0, 8) == 'generate') {
407                 $format = substr($methodName, 8);
408                 $generateFuncs[] = $format;
409             }
410         }
411         // All generate functions may appear any number of times in the image cache name.
412         $generateFuncs = implode('|', $generateFuncs);
413         $pattern = "/^(({$generateFuncs})(\d+)?-)+".preg_quote($name)."$/i";
414 
415         foreach(preg_grep($pattern, $cachedFiles) as $cfile) {
416             if(file_exists($cacheDir . $cfile)) {
417                 unlink($cacheDir . $cfile);
418                 $numDeleted++;
419             }
420         }       
421         return $numDeleted;
422     }
423      
424     /**
425      * Get the dimensions of this Image.
426      * @param string $dim If this is equal to "string", return the dimensions in string form,
427      * if it is 0 return the height, if it is 1 return the width.
428      * @return string|int
429      */
430     function getDimensions($dim = "string") {
431         if($this->getField('Filename')) {
432             $imagefile = Director::baseFolder() . '/' . $this->getField('Filename');
433             if(file_exists($imagefile)) {
434                 $size = getimagesize($imagefile);
435                 return ($dim === "string") ? "$size[0]x$size[1]" : $size[$dim];
436             } else {
437                 return ($dim === "string") ? "file '$imagefile' not found" : null;
438             }
439         }
440     }
441 
442     /**
443      * Get the width of this image.
444      * @return int
445      */
446     function getWidth() {
447         return $this->getDimensions(0);
448     }
449     
450     /**
451      * Get the height of this image.
452      * @return int
453      */
454     function getHeight() {
455         return $this->getDimensions(1);
456     }
457     
458     /**
459      * Get the orientation of this image.
460      * @return ORIENTATION_SQUARE | ORIENTATION_PORTRAIT | ORIENTATION_LANDSCAPE
461      */
462     function getOrientation() {
463         $width = $this->getWidth();
464         $height = $this->getHeight();
465         if($width > $height) {
466             return self::ORIENTATION_LANDSCAPE;
467         } elseif($height > $width) {
468             return self::ORIENTATION_PORTRAIT;
469         } else {
470             return self::ORIENTATION_SQUARE;
471         }
472     }
473     
474     /**
475      * Возвращает содержимое файла
476      * Требуется для SVG-формата
477      * 
478      * @return string
479      */ 
480     function getSVGContent() {
481         if (strtoupper($this->getExtension()) == 'SVG') {
482             if(file_exists($this->getFullPath())) {
483                 return file_get_contents($this->getFullPath());             
484             }
485         }
486         return false;
487     }
488 
489     protected function onBeforeDelete() { 
490         parent::onBeforeDelete(); 
491         $this->deleteFormattedImages();
492     }
493     
494     //При перемещении Image удаляем его Formatted Images
495     protected function resetFilename($renamePhysicalFile = true) {
496         $this->deleteFormattedImages();     
497         parent::resetFilename($renamePhysicalFile);
498     }
499 }
500 
501 /**
502  * A resized / processed {@link Image} object.
503  * When Image object are processed or resized, a suitable Image_Cached object is returned, pointing to the
504  * cached copy of the processed image.
505  * @package sapphire
506  * @subpackage filesystem
507  */
508 class Image_Cached extends Image {
509     /**
510      * Create a new cached image.
511      * @param string $filename The filename of the image.
512      * @param boolean $isSingleton This this to true if this is a singleton() object, a stub for calling methods.  Singletons
513      * don't have their defaults set.
514      */
515     public function __construct($filename = null, $isSingleton = false) {
516         parent::__construct(array(), $isSingleton);
517         $this->Filename = $filename;
518     }
519     
520     public function getRelativePath() {
521         return $this->getField('Filename');
522     }
523     
524     // Prevent this from doing anything
525     public function requireTable() {
526         
527     }
528     
529     public function debug() {
530         return "Image_Cached object for $this->Filename";
531     }
532 }
533 
534 
[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the Silverstripe Forums to ask development related questions. -
Webylon 3.1 API Docs API documentation generated by ApiGen 2.8.0