Completed
Push — 8.x-1.x ( 1cad11...29cacf )
by Janez
34:33 queued 10s
created

Crop::cropExists()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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