Version 1
[yaffs-website] / web / modules / contrib / crop / src / Entity / Crop.php
1 <?php
2
3 namespace Drupal\crop\Entity;
4
5 use Drupal\Core\Entity\ContentEntityBase;
6 use Drupal\Core\Entity\EntityStorageInterface;
7 use Drupal\Core\Entity\EntityTypeInterface;
8 use Drupal\Core\Field\BaseFieldDefinition;
9 use Drupal\crop\CropInterface;
10 use Drupal\crop\EntityProviderNotFoundException;
11
12 /**
13  * Defines the crop entity class.
14  *
15  * @ContentEntityType(
16  *   id = "crop",
17  *   label = @Translation("Crop"),
18  *   bundle_label = @Translation("Crop type"),
19  *   handlers = {
20  *     "storage" = "Drupal\crop\CropStorage",
21  *     "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
22  *     "access" = "Drupal\Core\Entity\EntityAccessControlHandler",
23  *     "form" = {
24  *       "default" = "Drupal\Core\Entity\ContentEntityForm",
25  *       "delete" = "Drupal\Core\Entity\ContentEntityConfirmFormBase",
26  *       "edit" = "Drupal\Core\Entity\ContentEntityForm"
27  *     },
28  *     "translation" = "Drupal\content_translation\ContentTranslationHandler"
29  *   },
30  *   base_table = "crop",
31  *   data_table = "crop_field_data",
32  *   revision_table = "crop_revision",
33  *   revision_data_table = "crop_field_revision",
34  *   fieldable = TRUE,
35  *   translatable = TRUE,
36  *   render_cache = FALSE,
37  *   entity_keys = {
38  *     "id" = "cid",
39  *     "bundle" = "type",
40  *     "revision" = "vid",
41  *     "langcode" = "langcode",
42  *     "uuid" = "uuid"
43  *   },
44  *   bundle_entity_type = "crop_type",
45  *   permission_granularity = "entity_type",
46  *   admin_permission = "administer crop",
47  *   links = {
48  *   }
49  * )
50  */
51 class Crop extends ContentEntityBase implements CropInterface {
52
53   /**
54    * {@inheritdoc}
55    */
56   public function position() {
57     return [
58       'x' => (int) $this->x->value,
59       'y' => (int) $this->y->value,
60     ];
61   }
62
63   /**
64    * {@inheritdoc}
65    */
66   public function setPosition($x, $y) {
67     $this->x = $x;
68     $this->y = $y;
69
70     return $this;
71   }
72
73   /**
74    * {@inheritdoc}
75    */
76   public function anchor() {
77     return [
78       'x' => (int) ($this->x->value - ($this->width->value / 2)),
79       'y' => (int) ($this->y->value - ($this->height->value / 2)),
80     ];
81   }
82
83   /**
84    * {@inheritdoc}
85    */
86   public function size() {
87     return [
88       'width' => (int) $this->width->value,
89       'height' => (int) $this->height->value,
90     ];
91   }
92
93   /**
94    * {@inheritdoc}
95    */
96   public function setSize($width, $height) {
97     $this->width = $width;
98     $this->height = $height;
99     return $this;
100   }
101
102   /**
103    * {@inheritdoc}
104    */
105   public function provider() {
106     /** @var \Drupal\crop\EntityProviderManager $plugin_manager */
107     $plugin_manager = \Drupal::service('plugin.manager.crop.entity_provider');
108
109     if (!$plugin_manager->hasDefinition($this->entity_type->value)) {
110       throw new EntityProviderNotFoundException(t('Entity provider @id not found.', ['@id' => $this->entity_type->value]));
111     }
112
113     return $plugin_manager->createInstance($this->entity_type->value);
114   }
115
116   /**
117    * {@inheritdoc}
118    */
119   public static function cropExists($uri, $type = NULL) {
120     $query = \Drupal::entityQuery('crop')
121       ->condition('uri', $uri);
122     if ($type) {
123       $query->condition('type', $type);
124     }
125     return (bool) $query->execute();
126   }
127
128   /**
129    * {@inheritdoc}
130    */
131   public static function findCrop($uri, $type) {
132     $query = \Drupal::entityQuery('crop')
133       ->condition('uri', $uri);
134     if ($type) {
135       $query->condition('type', $type);
136     }
137     $crop = $query->sort('cid')
138       ->range(0, 1)
139       ->execute();
140
141     return $crop ? \Drupal::entityTypeManager()->getStorage('crop')->load(current($crop)) : NULL;
142   }
143
144   /**
145    * {@inheritdoc}
146    */
147   public function preSave(EntityStorageInterface $storage) {
148     parent::preSave($storage);
149
150     // If no revision author has been set explicitly, make the current user
151     // revision author.
152     if (!$this->get('revision_uid')->entity) {
153       $this->set('revision_uid', \Drupal::currentUser()->id());
154     }
155
156     // Try to set URI if not yet defined.
157     if (empty($this->uri->value) && !empty($this->entity_type->value) && !empty($this->entity_id->value)) {
158       $entity = \Drupal::entityTypeManager()->getStorage($this->entity_type->value)->load($this->entity_id->value);
159       if ($uri = $this->provider()->uri($entity)) {
160         $this->set('uri', $uri);
161       }
162     }
163   }
164
165   /**
166    * {@inheritdoc}
167    */
168   public function preSaveRevision(EntityStorageInterface $storage, \stdClass $record) {
169     parent::preSaveRevision($storage, $record);
170
171     if (!$this->isNewRevision() && isset($this->original) && (!isset($record->revision_log) || $record->revision_log === '')) {
172       // If we are updating an existing crop without adding a new revision, we
173       // need to make sure $entity->revision_log is reset whenever it is empty.
174       // Therefore, this code allows us to avoid clobbering an existing log
175       // entry with an empty one.
176       $record->revision_log = $this->original->revision_log->value;
177     }
178   }
179
180   /**
181    * {@inheritdoc}
182    */
183   public function postSave(EntityStorageInterface $storage, $update = TRUE) {
184     parent::postSave($storage, $update);
185
186     // If you are manually generating your image derivatives instead of waiting
187     // for them to be generated on the fly, because you are using a cloud
188     // storage service (like S3), then you may not want your image derivatives
189     // to be flushed. If they are you could end up serving 404s during the time
190     // between the crop entity being saved and the image derivative being
191     // manually generated and pushed to your cloud storage service. In that
192     // case, set this configuration variable to false.
193     $flush_derivative_images = \Drupal::config('crop.settings')->get('flush_derivative_images');
194     if ($flush_derivative_images) {
195       image_path_flush($this->uri->value);
196     }
197   }
198
199   /**
200    * {@inheritdoc}
201    */
202   public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
203     $fields = [];
204
205     $fields['cid'] = BaseFieldDefinition::create('integer')
206       ->setLabel(t('Crop ID'))
207       ->setDescription(t('The crop ID.'))
208       ->setReadOnly(TRUE)
209       ->setSetting('unsigned', TRUE);
210
211     $fields['uuid'] = BaseFieldDefinition::create('uuid')
212       ->setLabel(t('UUID'))
213       ->setDescription(t('The crop UUID.'))
214       ->setReadOnly(TRUE);
215
216     $fields['vid'] = BaseFieldDefinition::create('integer')
217       ->setLabel(t('Revision ID'))
218       ->setDescription(t('The crop revision ID.'))
219       ->setReadOnly(TRUE)
220       ->setSetting('unsigned', TRUE);
221
222     $fields['type'] = BaseFieldDefinition::create('entity_reference')
223       ->setLabel(t('Type'))
224       ->setDescription(t('The crop type.'))
225       ->setSetting('target_type', 'crop_type')
226       ->setReadOnly(TRUE);
227
228     $fields['langcode'] = BaseFieldDefinition::create('language')
229       ->setLabel(t('Language code'))
230       ->setDescription(t('The node language code.'))
231       ->setRevisionable(TRUE);
232
233     $fields['entity_id'] = BaseFieldDefinition::create('integer')
234       ->setLabel(t('Entity ID'))
235       ->setDescription(t('ID of entity crop belongs to.'))
236       ->setSetting('unsigned', TRUE)
237       ->setRevisionable(TRUE)
238       ->setReadOnly(TRUE);
239
240     $fields['entity_type'] = BaseFieldDefinition::create('string')
241       ->setLabel(t('Entity type'))
242       ->setDescription(t('The type of entity crop belongs to.'))
243       ->setRevisionable(TRUE)
244       ->setReadOnly(TRUE);
245
246     // Denormalized information, which is calculated in storage plugin for a
247     // given entity type. Saved here for performance reasons in image effects.
248     // ---
249     // TODO - we are not enforcing uniqueness on this as we want to support more
250     // crops per same image/image_style combination. However, image effect
251     // operates with image URI only, which means we have no mechanism to
252     // distinguish between multiple crops in there. If we really want to
253     // support multiple crops we'll need to override core at least,
254     // in \Drupal\Core\Image\ImageFactory and \Drupal\Core\Image\Image.
255     // Let's leave this for now and simply load based on URI only.
256     // We can use some semi-smart approach in case there are multiple crops
257     // with same URI for now (first created, last created, ...).
258     $fields['uri'] = BaseFieldDefinition::create('uri')
259       ->setLabel(t('URI'))
260       ->setDescription(t('The URI of the image crop belongs to.'))
261       ->setRevisionable(TRUE)
262       ->setTranslatable(TRUE)
263       ->setSetting('max_length', 255);
264
265     $fields['height'] = BaseFieldDefinition::create('integer')
266       ->setLabel(t('Height'))
267       ->setDescription(t('The crop height.'))
268       ->setRevisionable(TRUE)
269       ->setTranslatable(TRUE)
270       ->setReadOnly(TRUE)
271       ->setSetting('unsigned', TRUE);
272
273     $fields['width'] = BaseFieldDefinition::create('integer')
274       ->setLabel(t('Width'))
275       ->setDescription(t('The crop width.'))
276       ->setRevisionable(TRUE)
277       ->setTranslatable(TRUE)
278       ->setReadOnly(TRUE)
279       ->setSetting('unsigned', TRUE);
280
281     $fields['x'] = BaseFieldDefinition::create('integer')
282       ->setLabel(t('X coordinate'))
283       ->setDescription(t("The crop's X coordinate."))
284       ->setRevisionable(TRUE)
285       ->setTranslatable(TRUE)
286       ->setReadOnly(TRUE)
287       ->setSetting('unsigned', TRUE);
288
289     $fields['y'] = BaseFieldDefinition::create('integer')
290       ->setLabel(t('Y coordinate'))
291       ->setDescription(t("The crop's Y coordinate."))
292       ->setRevisionable(TRUE)
293       ->setTranslatable(TRUE)
294       ->setReadOnly(TRUE)
295       ->setSetting('unsigned', TRUE);
296
297     $fields['revision_timestamp'] = BaseFieldDefinition::create('created')
298       ->setLabel(t('Revision timestamp'))
299       ->setDescription(t('The time that the current revision was created.'))
300       ->setQueryable(FALSE)
301       ->setRevisionable(TRUE);
302
303     $fields['revision_uid'] = BaseFieldDefinition::create('entity_reference')
304       ->setLabel(t('Revision author ID'))
305       ->setDescription(t('The user ID of the author of the current revision.'))
306       ->setSetting('target_type', 'user')
307       ->setQueryable(FALSE)
308       ->setRevisionable(TRUE);
309
310     $fields['revision_log'] = BaseFieldDefinition::create('string_long')
311       ->setLabel(t('Revision Log'))
312       ->setDescription(t('The log entry explaining the changes in this revision.'))
313       ->setRevisionable(TRUE)
314       ->setTranslatable(TRUE);
315
316     return $fields;
317   }
318
319 }