b82348ec70454587f136cf11201e028e7e368a06
[yaffs-website] / web / core / modules / image / src / Tests / ImageFieldDefaultImagesTest.php
1 <?php
2
3 namespace Drupal\image\Tests;
4
5 use Drupal\Component\Utility\Unicode;
6 use Drupal\Core\Entity\Entity\EntityViewDisplay;
7 use Drupal\field\Entity\FieldConfig;
8 use Drupal\file\Entity\File;
9 use Drupal\field\Entity\FieldStorageConfig;
10
11 /**
12  * Tests setting up default images both to the field and field storage.
13  *
14  * @group image
15  */
16 class ImageFieldDefaultImagesTest extends ImageFieldTestBase {
17
18   /**
19    * Modules to enable.
20    *
21    * @var array
22    */
23   public static $modules = ['field_ui'];
24
25   /**
26    * Tests CRUD for fields and field storages with default images.
27    */
28   public function testDefaultImages() {
29     $node_storage = $this->container->get('entity.manager')->getStorage('node');
30     // Create files to use as the default images.
31     $files = $this->drupalGetTestFiles('image');
32     // Create 10 files so the default image fids are not a single value.
33     for ($i = 1; $i <= 10; $i++) {
34       $filename = $this->randomMachineName() . "$i";
35       $desired_filepath = 'public://' . $filename;
36       file_unmanaged_copy($files[0]->uri, $desired_filepath, FILE_EXISTS_ERROR);
37       $file = File::create(['uri' => $desired_filepath, 'filename' => $filename, 'name' => $filename]);
38       $file->save();
39     }
40     $default_images = [];
41     foreach (['field_storage', 'field', 'field2', 'field_storage_new', 'field_new', 'field_storage_private', 'field_private'] as $image_target) {
42       $file = File::create((array) array_pop($files));
43       $file->save();
44       $default_images[$image_target] = $file;
45     }
46
47     // Create an image field storage and add a field to the article content
48     // type.
49     $field_name = strtolower($this->randomMachineName());
50     $storage_settings['default_image'] = [
51       'uuid' => $default_images['field_storage']->uuid(),
52       'alt' => '',
53       'title' => '',
54       'width' => 0,
55       'height' => 0,
56     ];
57     $field_settings['default_image'] = [
58       'uuid' => $default_images['field']->uuid(),
59       'alt' => '',
60       'title' => '',
61       'width' => 0,
62       'height' => 0,
63     ];
64     $widget_settings = [
65       'preview_image_style' => 'medium',
66     ];
67     $field = $this->createImageField($field_name, 'article', $storage_settings, $field_settings, $widget_settings);
68
69     // The field default image id should be 2.
70     $this->assertEqual($field->getSetting('default_image')['uuid'], $default_images['field']->uuid());
71
72     // Also test \Drupal\field\Entity\FieldConfig::getSettings().
73     $this->assertEqual($field->getSettings()['default_image']['uuid'], $default_images['field']->uuid());
74
75     $field_storage = $field->getFieldStorageDefinition();
76
77     // The field storage default image id should be 1.
78     $this->assertEqual($field_storage->getSetting('default_image')['uuid'], $default_images['field_storage']->uuid());
79
80     // Also test \Drupal\field\Entity\FieldStorageConfig::getSettings().
81     $this->assertEqual($field_storage->getSettings()['default_image']['uuid'], $default_images['field_storage']->uuid());
82
83     // Add another field with another default image to the page content type.
84     $field2 = FieldConfig::create([
85       'field_storage' => $field_storage,
86       'bundle' => 'page',
87       'label' => $field->label(),
88       'required' => $field->isRequired(),
89       'settings' => [
90         'default_image' => [
91           'uuid' => $default_images['field2']->uuid(),
92           'alt' => '',
93           'title' => '',
94           'width' => 0,
95           'height' => 0,
96         ],
97       ],
98     ]);
99     $field2->save();
100
101     $widget_settings = entity_get_form_display('node', $field->getTargetBundle(), 'default')->getComponent($field_name);
102     entity_get_form_display('node', 'page', 'default')
103       ->setComponent($field_name, $widget_settings)
104       ->save();
105     entity_get_display('node', 'page', 'default')
106       ->setComponent($field_name)
107       ->save();
108
109     // Confirm the defaults are present on the article field storage settings
110     // form.
111     $field_id = $field->id();
112     $this->drupalGet("admin/structure/types/manage/article/fields/$field_id/storage");
113     $this->assertFieldByXpath(
114       '//input[@name="settings[default_image][uuid][fids]"]',
115       $default_images['field_storage']->id(),
116       format_string(
117         'Article image field storage default equals expected file ID of @fid.',
118         ['@fid' => $default_images['field_storage']->id()]
119       )
120     );
121     // Confirm the defaults are present on the article field edit form.
122     $this->drupalGet("admin/structure/types/manage/article/fields/$field_id");
123     $this->assertFieldByXpath(
124       '//input[@name="settings[default_image][uuid][fids]"]',
125       $default_images['field']->id(),
126       format_string(
127         'Article image field default equals expected file ID of @fid.',
128         ['@fid' => $default_images['field']->id()]
129       )
130     );
131
132     // Confirm the defaults are present on the page field storage settings form.
133     $this->drupalGet("admin/structure/types/manage/page/fields/$field_id/storage");
134     $this->assertFieldByXpath(
135       '//input[@name="settings[default_image][uuid][fids]"]',
136       $default_images['field_storage']->id(),
137       format_string(
138         'Page image field storage default equals expected file ID of @fid.',
139         ['@fid' => $default_images['field_storage']->id()]
140       )
141     );
142     // Confirm the defaults are present on the page field edit form.
143     $field2_id = $field2->id();
144     $this->drupalGet("admin/structure/types/manage/page/fields/$field2_id");
145     $this->assertFieldByXpath(
146       '//input[@name="settings[default_image][uuid][fids]"]',
147       $default_images['field2']->id(),
148       format_string(
149         'Page image field default equals expected file ID of @fid.',
150         ['@fid' => $default_images['field2']->id()]
151       )
152     );
153
154     // Confirm that the image default is shown for a new article node.
155     $article = $this->drupalCreateNode(['type' => 'article']);
156     $article_built = $this->drupalBuildEntityView($article);
157     $this->assertEqual(
158       $article_built[$field_name][0]['#item']->target_id,
159       $default_images['field']->id(),
160       format_string(
161         'A new article node without an image has the expected default image file ID of @fid.',
162         ['@fid' => $default_images['field']->id()]
163       )
164     );
165
166     // Also check that the field renders without warnings when the label is
167     // hidden.
168     EntityViewDisplay::load('node.article.default')
169       ->setComponent($field_name, ['label' => 'hidden', 'type' => 'image'])
170       ->save();
171     $this->drupalGet('node/' . $article->id());
172
173     // Confirm that the image default is shown for a new page node.
174     $page = $this->drupalCreateNode(['type' => 'page']);
175     $page_built = $this->drupalBuildEntityView($page);
176     $this->assertEqual(
177       $page_built[$field_name][0]['#item']->target_id,
178       $default_images['field2']->id(),
179       format_string(
180         'A new page node without an image has the expected default image file ID of @fid.',
181         ['@fid' => $default_images['field2']->id()]
182       )
183     );
184
185     // Upload a new default for the field storage.
186     $default_image_settings = $field_storage->getSetting('default_image');
187     $default_image_settings['uuid'] = $default_images['field_storage_new']->uuid();
188     $field_storage->setSetting('default_image', $default_image_settings);
189     $field_storage->save();
190
191     // Confirm that the new default is used on the article field storage
192     // settings form.
193     $this->drupalGet("admin/structure/types/manage/article/fields/$field_id/storage");
194     $this->assertFieldByXpath(
195       '//input[@name="settings[default_image][uuid][fids]"]',
196       $default_images['field_storage_new']->id(),
197       format_string(
198         'Updated image field storage default equals expected file ID of @fid.',
199         ['@fid' => $default_images['field_storage_new']->id()]
200       )
201     );
202
203     // Reload the nodes and confirm the field defaults are used.
204     $node_storage->resetCache([$article->id(), $page->id()]);
205     $article_built = $this->drupalBuildEntityView($article = $node_storage->load($article->id()));
206     $page_built = $this->drupalBuildEntityView($page = $node_storage->load($page->id()));
207     $this->assertEqual(
208       $article_built[$field_name][0]['#item']->target_id,
209       $default_images['field']->id(),
210       format_string(
211         'An existing article node without an image has the expected default image file ID of @fid.',
212         ['@fid' => $default_images['field']->id()]
213       )
214     );
215     $this->assertEqual(
216       $page_built[$field_name][0]['#item']->target_id,
217       $default_images['field2']->id(),
218       format_string(
219         'An existing page node without an image has the expected default image file ID of @fid.',
220         ['@fid' => $default_images['field2']->id()]
221       )
222     );
223
224     // Upload a new default for the article's field.
225     $default_image_settings = $field->getSetting('default_image');
226     $default_image_settings['uuid'] = $default_images['field_new']->uuid();
227     $field->setSetting('default_image', $default_image_settings);
228     $field->save();
229
230     // Confirm the new field default is used on the article field admin form.
231     $this->drupalGet("admin/structure/types/manage/article/fields/$field_id");
232     $this->assertFieldByXpath(
233       '//input[@name="settings[default_image][uuid][fids]"]',
234       $default_images['field_new']->id(),
235       format_string(
236         'Updated article image field default equals expected file ID of @fid.',
237         ['@fid' => $default_images['field_new']->id()]
238       )
239     );
240
241     // Reload the nodes.
242     $node_storage->resetCache([$article->id(), $page->id()]);
243     $article_built = $this->drupalBuildEntityView($article = $node_storage->load($article->id()));
244     $page_built = $this->drupalBuildEntityView($page = $node_storage->load($page->id()));
245
246     // Confirm the article uses the new default.
247     $this->assertEqual(
248       $article_built[$field_name][0]['#item']->target_id,
249       $default_images['field_new']->id(),
250       format_string(
251         'An existing article node without an image has the expected default image file ID of @fid.',
252         ['@fid' => $default_images['field_new']->id()]
253       )
254     );
255     // Confirm the page remains unchanged.
256     $this->assertEqual(
257       $page_built[$field_name][0]['#item']->target_id,
258       $default_images['field2']->id(),
259       format_string(
260         'An existing page node without an image has the expected default image file ID of @fid.',
261         ['@fid' => $default_images['field2']->id()]
262       )
263     );
264
265     // Confirm the default image is shown on the node form.
266     $file = File::load($default_images['field_new']->id());
267     $this->drupalGet('node/add/article');
268     $this->assertRaw($file->getFilename());
269
270     // Remove the field default from articles.
271     $default_image_settings = $field->getSetting('default_image');
272     $default_image_settings['uuid'] = 0;
273     $field->setSetting('default_image', $default_image_settings);
274     $field->save();
275
276     // Confirm the article field default has been removed.
277     $this->drupalGet("admin/structure/types/manage/article/fields/$field_id");
278     $this->assertFieldByXpath(
279       '//input[@name="settings[default_image][uuid][fids]"]',
280       '',
281       'Updated article image field default has been successfully removed.'
282     );
283
284     // Reload the nodes.
285     $node_storage->resetCache([$article->id(), $page->id()]);
286     $article_built = $this->drupalBuildEntityView($article = $node_storage->load($article->id()));
287     $page_built = $this->drupalBuildEntityView($page = $node_storage->load($page->id()));
288     // Confirm the article uses the new field storage (not field) default.
289     $this->assertEqual(
290       $article_built[$field_name][0]['#item']->target_id,
291       $default_images['field_storage_new']->id(),
292       format_string(
293         'An existing article node without an image has the expected default image file ID of @fid.',
294         ['@fid' => $default_images['field_storage_new']->id()]
295       )
296     );
297     // Confirm the page remains unchanged.
298     $this->assertEqual(
299       $page_built[$field_name][0]['#item']->target_id,
300       $default_images['field2']->id(),
301       format_string(
302         'An existing page node without an image has the expected default image file ID of @fid.',
303         ['@fid' => $default_images['field2']->id()]
304       )
305     );
306
307     $non_image = $this->drupalGetTestFiles('text');
308     $this->drupalPostForm(NULL, ['files[settings_default_image_uuid]' => \Drupal::service('file_system')->realpath($non_image[0]->uri)], t("Upload"));
309     $this->assertText('The specified file text-0.txt could not be uploaded.');
310     $this->assertText('Only files with the following extensions are allowed: png gif jpg jpeg.');
311
312     // Confirm the default image is shown on the node form.
313     $file = File::load($default_images['field_storage_new']->id());
314     $this->drupalGet('node/add/article');
315     $this->assertRaw($file->getFilename());
316
317     // Change the default image for the field storage and also change the upload
318     // destination to the private filesystem at the same time.
319     $default_image_settings = $field_storage->getSetting('default_image');
320     $default_image_settings['uuid'] = $default_images['field_storage_private']->uuid();
321     $field_storage->setSetting('default_image', $default_image_settings);
322     $field_storage->setSetting('uri_scheme', 'private');
323     $field_storage->save();
324
325     // Confirm that the new default is used on the article field storage
326     // settings form.
327     $this->drupalGet("admin/structure/types/manage/article/fields/$field_id/storage");
328     $this->assertFieldByXpath(
329       '//input[@name="settings[default_image][uuid][fids]"]',
330       $default_images['field_storage_private']->id(),
331       format_string(
332         'Updated image field storage default equals expected file ID of @fid.',
333         ['@fid' => $default_images['field_storage_private']->id()]
334       )
335     );
336
337     // Upload a new default for the article's field after setting the field
338     // storage upload destination to 'private'.
339     $default_image_settings = $field->getSetting('default_image');
340     $default_image_settings['uuid'] = $default_images['field_private']->uuid();
341     $field->setSetting('default_image', $default_image_settings);
342     $field->save();
343
344     // Confirm the new field field default is used on the article field
345     // admin form.
346     $this->drupalGet("admin/structure/types/manage/article/fields/$field_id");
347     $this->assertFieldByXpath(
348       '//input[@name="settings[default_image][uuid][fids]"]',
349       $default_images['field_private']->id(),
350       format_string(
351         'Updated article image field default equals expected file ID of @fid.',
352         ['@fid' => $default_images['field_private']->id()]
353       )
354     );
355   }
356
357   /**
358    * Tests image field and field storage having an invalid default image.
359    */
360   public function testInvalidDefaultImage() {
361     $field_storage = FieldStorageConfig::create([
362       'field_name' => Unicode::strtolower($this->randomMachineName()),
363       'entity_type' => 'node',
364       'type' => 'image',
365       'settings' => [
366         'default_image' => [
367           'uuid' => 100000,
368         ]
369       ],
370     ]);
371     $field_storage->save();
372     $settings = $field_storage->getSettings();
373     // The non-existent default image should not be saved.
374     $this->assertNull($settings['default_image']['uuid']);
375
376     $field = FieldConfig::create([
377       'field_storage' => $field_storage,
378       'bundle' => 'page',
379       'label' => $this->randomMachineName(),
380       'settings' => [
381         'default_image' => [
382           'uuid' => 100000,
383         ]
384       ],
385     ]);
386     $field->save();
387     $settings = $field->getSettings();
388     // The non-existent default image should not be saved.
389     $this->assertNull($settings['default_image']['uuid']);
390   }
391
392 }