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

crop.module::crop_file_url_alter()   C

Complexity

Conditions 7
Paths 8

Size

Total Lines 40
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 19
nc 8
nop 1
dl 0
loc 40
rs 6.7272
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @file
5
 * The Crop API Drupal module.
6
 *
7
 * Provides storage and API for image crops.
8
 */
9
10
use \Drupal\Core\Form\FormStateInterface;
11
use Drupal\Core\StreamWrapper\PublicStream;
12
use Drupal\crop\Entity\Crop;
13
use Drupal\image\Entity\ImageStyle;
14
use \Drupal\media_entity\MediaBundleInterface;
15
use \Drupal\file\FileInterface;
16
17
/**
18
 * Implements hook_theme().
19
 */
20
function crop_theme() {
21
  return [
22
    'crop_crop_summary' => [
23
      'variables' => ['data' => [], 'effect' => []],
24
    ],
25
  ];
26
}
27
28
/**
29
 * Prepares variables for crop_crop summary template.
30
 *
31
 * Default template: crop-crop-summary.twig.html.
32
 */
33
function template_preprocess_crop_crop_summary(&$variables) {
34
  if (!empty($variables['data']['crop_type'])) {
35
    $type = \Drupal::entityTypeManager()->getStorage('crop_type')->load($variables['data']['crop_type']);
36
    $variables['data']['crop_type'] = $type->label();
37
  }
38
}
39
40
/**
41
 * Implements hook_form_BASE_ID_alter().
42
 *
43
 * Adds crop configuraiton fields to media bundle form.
44
 */
45
function crop_form_media_bundle_form_alter(&$form, FormStateInterface $form_state, $form_id) {
0 ignored issues
show
Unused Code introduced by
The parameter $form_state is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $form_id is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
46
  /** @var \Drupal\media_entity\MediaBundleInterface $bundle */
47
  $bundle = $form['#entity'];
48
  $options = [];
49
  $allowed_field_types = ['file', 'image'];
50
  foreach (\Drupal::service('entity_field.manager')->getFieldDefinitions('media', $bundle->id()) as $field_name => $field) {
51
    if (in_array($field->getType(), $allowed_field_types) && !$field->getFieldStorageDefinition()->isBaseField()) {
52
      $options[$field_name] = $field->getLabel();
53
    }
54
  }
55
56
  $form['#entity_builders'][] = 'crop_media_bundle_form_builder';
57
  $form['crop'] = [
58
    '#type' => 'fieldset',
59
    '#title' => t('Crop configuration'),
60
  ];
61
62
  if (empty($options)) {
63
    $form['crop']['image_field'] = [
64
      '#type' => 'value',
65
      '#value' => NULL,
66
    ];
67
68
    $form['crop']['message'] = [
69
      '#markup' => t('There are no file or image fields on this bundle at the moment. In order to configure crop add at least one such field and come back.'),
70
    ];
71
72
    return;
73
  }
74
75
  $form['crop']['image_field'] = [
76
    '#type' => 'select',
77
    '#title' => t('Image field'),
78
    '#default_value' => $bundle->getThirdPartySetting('crop', 'image_field'),
79
    '#options' => $options,
80
    '#description' => t('Select field that stores image which needs to be cropped.'),
81
  ];
82
83
}
84
85
/**
86
 * Entity builder for Media bundle.
87
 *
88
 * Adds third party settings to Media bundle config entity.
89
 *
90
 * @see crop_form_media_bundle_form_alter()
91
 */
92
function crop_media_bundle_form_builder($entity_type, MediaBundleInterface $bundle, &$form, FormStateInterface $form_state) {
0 ignored issues
show
Unused Code introduced by
The parameter $entity_type is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $form is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
93
  $bundle->setThirdPartySetting('crop', 'image_field', $form_state->getValue('image_field'));
94
}
95
96
/**
97
 * Implements hook_ENTITY_TYPE_delete().
98
 *
99
 * Deletes orphaned crops when a file is deleted.
100
 */
101
function crop_file_delete(FileInterface $file) {
102
  // Get all crops for the file being deleted.
103
  $crops = \Drupal::entityTypeManager()
104
    ->getStorage('crop')
105
    ->loadByProperties(['uri' => $file->getFileUri()]);
106
107
  foreach ($crops as $crop) {
108
    $crop->delete();
109
  }
110
}
111
112
/**
113
 * Implements hook_file_url_alter().
114
 */
115
function crop_file_url_alter(&$uri) {
116
  // Process only files that are stored in "styles" directory.
117
  if (strpos($uri, PublicStream::basePath() . '/styles/') !== FALSE) {
118
    // Handle the case of multiple "/styles/" in URI.
119
    $uri_parts = explode('/styles/', $uri);
120
    $image_style_part = end($uri_parts);
121
    // Match image style, schema, file subdirectory and file name.
122
    preg_match("/(.*?)\/(.*?)\/(.*+)/", $image_style_part, $match);
123
    // Get the image style ID.
124
    $image_style = $match[1];
125
    // Get the file path without query parameter.
126
    $parsed_uri = parse_url($match[3]);
127
    // Get the file URI using parsed schema and file path.
128
    $file_uri = $match[2] . '://' . $parsed_uri['path'];
129
130
    /** @var \Drupal\image\Entity\ImageStyle $image_style */
131
    if (!$image_style = ImageStyle::load($image_style)) {
132
      return;
133
    }
134
135
    $crop_type = NULL;
136
    // Find whether matched image style uses "crop_type" effect.
137
    /* @var  \Drupal\image\ImageEffectInterface $effect */
138
    foreach ($image_style->getEffects() as $uuid => $effect) {
139
      $data_effect = $image_style->getEffect($uuid)->getConfiguration()['data'];
140
      if (isset($data_effect['crop_type'])) {
141
        $crop_type = $data_effect['crop_type'];
142
        break;
143
      }
144
    }
145
146
    // In case the image style uses "crop_type" effect, load the crop entity.
147
    if ($crop_type && $crop = Crop::findCrop($file_uri, $crop_type)) {
148
      // Found a crop for this image, append a hash of it to the URL,
149
      // so that browsers reload the image and CDNs and proxies can be bypassed.
150
      $shortened_hash = substr(md5(implode($crop->position()) . implode($crop->anchor())), 0, 8);
151
      $uri .= '&h=' . $shortened_hash;
152
    }
153
  }
154
}
155