Pull merge.
[yaffs-website] / web / core / lib / Drupal / Core / Image / Image.php
1 <?php
2
3 namespace Drupal\Core\Image;
4
5 use Drupal\Core\ImageToolkit\ImageToolkitInterface;
6
7 /**
8  * Defines an image object to represent an image file.
9  *
10  * @see \Drupal\Core\ImageToolkit\ImageToolkitInterface
11  * @see \Drupal\image\ImageEffectInterface
12  *
13  * @ingroup image
14  */
15 class Image implements ImageInterface {
16
17   /**
18    * Path of the image file.
19    *
20    * @var string
21    */
22   protected $source = '';
23
24   /**
25    * An image toolkit object.
26    *
27    * @var \Drupal\Core\ImageToolkit\ImageToolkitInterface
28    */
29   protected $toolkit;
30
31   /**
32    * File size in bytes.
33    *
34    * @var int
35    */
36   protected $fileSize;
37
38   /**
39    * Constructs a new Image object.
40    *
41    * @param \Drupal\Core\ImageToolkit\ImageToolkitInterface $toolkit
42    *   The image toolkit.
43    * @param string|null $source
44    *   (optional) The path to an image file, or NULL to construct the object
45    *   with no image source.
46    */
47   public function __construct(ImageToolkitInterface $toolkit, $source = NULL) {
48     $this->toolkit = $toolkit;
49     if ($source) {
50       $this->source = $source;
51       $this->getToolkit()->setSource($this->source);
52       // Defer image file validity check to the toolkit.
53       if ($this->getToolkit()->parseFile()) {
54         $this->fileSize = filesize($this->source);
55       }
56     }
57   }
58
59   /**
60    * {@inheritdoc}
61    */
62   public function isValid() {
63     return $this->getToolkit()->isValid();
64   }
65
66   /**
67    * {@inheritdoc}
68    */
69   public function getHeight() {
70     return $this->getToolkit()->getHeight();
71   }
72
73   /**
74    * {@inheritdoc}
75    */
76   public function getWidth() {
77     return $this->getToolkit()->getWidth();
78   }
79
80   /**
81    * {@inheritdoc}
82    */
83   public function getFileSize() {
84     return $this->fileSize;
85   }
86
87   /**
88    * {@inheritdoc}
89    */
90   public function getMimeType() {
91     return $this->getToolkit()->getMimeType();
92   }
93
94   /**
95    * {@inheritdoc}
96    */
97   public function getSource() {
98     return $this->source;
99   }
100
101   /**
102    * {@inheritdoc}
103    */
104   public function getToolkitId() {
105     return $this->getToolkit()->getPluginId();
106   }
107
108   /**
109    * {@inheritdoc}
110    */
111   public function getToolkit() {
112     return $this->toolkit;
113   }
114
115   /**
116    * {@inheritdoc}
117    */
118   public function save($destination = NULL) {
119     // Return immediately if the image is not valid.
120     if (!$this->isValid()) {
121       return FALSE;
122     }
123
124     $destination = $destination ?: $this->getSource();
125     if ($return = $this->getToolkit()->save($destination)) {
126       // Clear the cached file size and refresh the image information.
127       clearstatcache(TRUE, $destination);
128       $this->fileSize = filesize($destination);
129       $this->source = $destination;
130
131       // @todo Use File utility when https://www.drupal.org/node/2050759 is in.
132       if ($this->chmod($destination)) {
133         return $return;
134       }
135     }
136     return FALSE;
137   }
138
139   /**
140    * {@inheritdoc}
141    */
142   public function apply($operation, array $arguments = []) {
143     return $this->getToolkit()->apply($operation, $arguments);
144   }
145
146   /**
147    * {@inheritdoc}
148    */
149   public function createNew($width, $height, $extension = 'png', $transparent_color = '#ffffff') {
150     return $this->apply('create_new', ['width' => $width, 'height' => $height, 'extension' => $extension, 'transparent_color' => $transparent_color]);
151   }
152
153   /**
154    * {@inheritdoc}
155    */
156   public function convert($extension) {
157     return $this->apply('convert', ['extension' => $extension]);
158   }
159
160   /**
161    * {@inheritdoc}
162    */
163   public function crop($x, $y, $width, $height = NULL) {
164     return $this->apply('crop', ['x' => $x, 'y' => $y, 'width' => $width, 'height' => $height]);
165   }
166
167   /**
168    * {@inheritdoc}
169    */
170   public function desaturate() {
171     return $this->apply('desaturate', []);
172   }
173
174   /**
175    * {@inheritdoc}
176    */
177   public function resize($width, $height) {
178     return $this->apply('resize', ['width' => $width, 'height' => $height]);
179   }
180
181   /**
182    * {@inheritdoc}
183    */
184   public function rotate($degrees, $background = NULL) {
185     return $this->apply('rotate', ['degrees' => $degrees, 'background' => $background]);
186   }
187
188   /**
189    * {@inheritdoc}
190    */
191   public function scaleAndCrop($width, $height) {
192     return $this->apply('scale_and_crop', ['width' => $width, 'height' => $height]);
193   }
194
195   /**
196    * {@inheritdoc}
197    */
198   public function scale($width, $height = NULL, $upscale = FALSE) {
199     return $this->apply('scale', ['width' => $width, 'height' => $height, 'upscale' => $upscale]);
200   }
201
202   /**
203    * Provides a wrapper for drupal_chmod() to allow unit testing.
204    *
205    * @param string $uri
206    *   A string containing a URI file, or directory path.
207    * @param int $mode
208    *   Integer value for the permissions. Consult PHP chmod() documentation for
209    *   more information.
210    *
211    * @see drupal_chmod()
212    *
213    * @todo Remove when https://www.drupal.org/node/2050759 is in.
214    *
215    * @return bool
216    *   TRUE for success, FALSE in the event of an error.
217    */
218   protected function chmod($uri, $mode = NULL) {
219     return drupal_chmod($uri, $mode);
220   }
221
222 }