crop.module::crop_file_url_alter()   C
last analyzed

Complexity

Conditions 13
Paths 24

Size

Total Lines 60
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 13
eloc 25
nc 24
nop 1
dl 0
loc 60
rs 6.3453
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * @file
5
 * The Crop API Drupal module.
6
 *
7
 * Provides storage and API for image crops.
8
 */
9
use Drupal\Component\Utility\UrlHelper;
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_FORM_ID_alter().
42
 *
43
 * Adds crop configuration fields to media bundle form.
44
 */
45
function crop_form_media_bundle_edit_form_alter(array &$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, '/styles/') !== FALSE && preg_match('/\/styles\/(.*?)\/(.*?)\/(.+)/', $uri, $match)) {
118
    // Match image style, schema, file subdirectory and file name.
119
    // Get the image style ID.
120
    $image_style = $match[1];
121
    // Get the file path without query parameter.
122
    $parsed_uri = UrlHelper::parse($match[3]);
123
    // Get the file URI using parsed schema and file path.
124
    $file_uri = $match[2] . '://' . $parsed_uri['path'];
125
126
    // Prevent double hashing, if there is a hash argument already, do not add
127
    // it again.
128
    if (!empty($parsed_uri['query']['h'])) {
129
      return;
130
    }
131
132
    /** @var \Drupal\image\Entity\ImageStyle $image_style */
133
    if (!$image_style = ImageStyle::load($image_style)) {
134
      return;
135
    }
136
137
    $crop_type = NULL;
138
    // Find whether matched image style uses "crop_type" effect.
139
    /* @var  \Drupal\image\ImageEffectInterface $effect */
140
    foreach ($image_style->getEffects() as $uuid => $effect) {
141
      $data_effect = $image_style->getEffect($uuid)->getConfiguration()['data'];
142
      if (isset($data_effect['crop_type'])) {
143
        $crop_type = $data_effect['crop_type'];
144
        break;
145
      }
146
    }
147
148
    // In case the image style uses "crop_type" effect, load the crop entity.
149
    if ($crop_type && $crop = Crop::findCrop($file_uri, $crop_type)) {
150
      // Found a crop for this image, append a hash of it to the URL,
151
      // so that browsers reload the image and CDNs and proxies can be bypassed.
152
      $shortened_hash = substr(md5(implode($crop->position()) . implode($crop->anchor())), 0, 8);
153
154
      // If the URI has a schema and that is not http, https or data, convert
155
      // the URI to the external URL. Otherwise the appended query argument
156
      // will be encoded.
157
      // @see file_create_url()
158
      $scheme = \Drupal::service('file_system')->uriScheme($uri);
159
      if ($scheme && !in_array($scheme, ['http', 'https', 'data'])) {
160
        if ($wrapper = \Drupal::service('stream_wrapper_manager')->getViaUri($uri)) {
161
          $uri = $wrapper->getExternalUrl();
162
        }
163
      }
164
165
      // Append either with a ? or a & if there are existing query arguments.
166
      if (strpos($uri, '?') === FALSE) {
167
        $uri .= '?h=' . $shortened_hash;
168
      }
169
      else {
170
        $uri .= '&h=' . $shortened_hash;
171
      }
172
    }
173
  }
174
}
175