Completed
Push — 8.x-1.x ( 02125d...d2ee20 )
by Alexandre
02:11
created

Crop::postSave()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 2
dl 0
loc 15
rs 9.4285
c 0
b 0
f 0
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) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $type of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
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
}
320