/** * Auto Orientation operations test. */ public function doTestAutoOrientOperations() { $image_factory = $this->container->get('image.factory'); $test_data = [['test_file' => drupal_get_path('module', 'image_effects') . '/misc/portrait-painting.jpg', 'original_width' => 640, 'original_height' => 480, 'derivative_width' => 200, 'derivative_height' => 267], ['test_file' => drupal_get_path('module', 'simpletest') . '/files/image-test.jpg', 'original_width' => 40, 'original_height' => 20, 'derivative_width' => 200, 'derivative_height' => 100], ['test_file' => drupal_get_path('module', 'simpletest') . '/files/image-1.png', 'original_width' => 360, 'original_height' => 240, 'derivative_width' => 200, 'derivative_height' => 133]]; foreach ($test_data as $data) { // Get expected URIs. $original_uri = file_unmanaged_copy($data['test_file'], 'public://', FILE_EXISTS_RENAME); $generated_uri = 'public://styles/image_effects_test/public/' . \Drupal::service('file_system')->basename($original_uri); // Test source image dimensions. $image = $image_factory->get($original_uri); $this->assertEqual($data['original_width'], $image->getWidth()); $this->assertEqual($data['original_height'], $image->getHeight()); // Load Image Style and get expected derivative URL. $image_style = ImageStyle::load('image_effects_test'); $url = file_url_transform_relative($image_style->buildUrl($original_uri)); // Check that ::transformDimensions returns expected dimensions. $variables = array('#theme' => 'image_style', '#style_name' => 'image_effects_test', '#uri' => $original_uri, '#width' => $image->getWidth(), '#height' => $image->getHeight()); $this->assertEqual('<img src="' . $url . '" width="' . $data['derivative_width'] . '" height="' . $data['derivative_height'] . '" alt="" class="image-style-image-effects-test" />', $this->getImageTag($variables)); // Check that ::applyEffect generates image with expected dimensions. $image_style->createDerivative($original_uri, $image_style->buildUri($original_uri)); $image = $image_factory->get($generated_uri); $this->assertEqual($data['derivative_width'], $image->getWidth()); $this->assertEqual($data['derivative_height'], $image->getHeight()); } }
/** * Tests embedded users on node pages. */ function testPictureOnNodeComment() { $this->drupalLogin($this->webUser); // Save a new picture. $image = current($this->drupalGetTestFiles('image')); $file = $this->saveUserPicture($image); $node = $this->drupalCreateNode(array('type' => 'article')); // Enable user pictures on nodes. $this->config('system.theme.global')->set('features.node_user_picture', TRUE)->save(); $image_style_id = $this->config('core.entity_view_display.user.user.compact')->get('content.user_picture.settings.image_style'); $style = ImageStyle::load($image_style_id); $image_url = file_url_transform_relative($style->buildUrl($file->getfileUri())); $alt_text = 'Profile picture for user ' . $this->webUser->getUsername(); // Verify that the image is displayed on the node page. $this->drupalGet('node/' . $node->id()); $elements = $this->cssSelect('.node__meta .field--name-user-picture img[alt="' . $alt_text . '"][src="' . $image_url . '"]'); $this->assertEqual(count($elements), 1, 'User picture with alt text found on node page.'); // Enable user pictures on comments, instead of nodes. $this->config('system.theme.global')->set('features.node_user_picture', FALSE)->set('features.comment_user_picture', TRUE)->save(); $edit = array('comment_body[0][value]' => $this->randomString()); $this->drupalPostForm('comment/reply/node/' . $node->id() . '/comment', $edit, t('Save')); $elements = $this->cssSelect('.comment__meta .field--name-user-picture img[alt="' . $alt_text . '"][src="' . $image_url . '"]'); $this->assertEqual(count($elements), 1, 'User picture with alt text found on the comment.'); // Disable user pictures on comments and nodes. $this->config('system.theme.global')->set('features.node_user_picture', FALSE)->set('features.comment_user_picture', FALSE)->save(); $this->drupalGet('node/' . $node->id()); $this->assertNoRaw(file_uri_target($file->getFileUri()), 'User picture not found on node and comment.'); }
/** * {@inheritdoc} */ public function process($text, $langcode) { $result = new FilterProcessResult($text); if (stristr($text, 'data-entity-type="file"') !== FALSE) { $dom = Html::load($text); $xpath = new \DOMXPath($dom); $processed_uuids = array(); foreach ($xpath->query('//*[@data-entity-type="file" and @data-entity-uuid]') as $node) { $uuid = $node->getAttribute('data-entity-uuid'); // If there is a 'src' attribute, set it to the file entity's current // URL. This ensures the URL works even after the file location changes. if ($node->hasAttribute('src')) { $file = $this->entityManager->loadEntityByUuid('file', $uuid); if ($file) { $node->setAttribute('src', file_url_transform_relative(file_create_url($file->getFileUri()))); } } // Only process the first occurrence of each file UUID. if (!isset($processed_uuids[$uuid])) { $processed_uuids[$uuid] = TRUE; $file = $this->entityManager->loadEntityByUuid('file', $uuid); if ($file) { $result->addCacheTags($file->getCacheTags()); } } } $result->setProcessedText(Html::serialize($dom)); } return $result; }
/** * {@inheritdoc} */ public function viewElements(FieldItemListInterface $items, $langcode) { $elements = array(); foreach ($this->getEntitiesToView($items, $langcode) as $delta => $file) { $elements[$delta] = array('#markup' => file_url_transform_relative(file_create_url($file->getFileUri())), '#cache' => array('tags' => $file->getCacheTags())); } return $elements; }
/** * Tests that an image with the srcset and widths is output correctly. */ function testThemeImageWithSrcsetWidth() { // Test with multipliers. $widths = array(rand(0, 500) . 'w', rand(500, 1000) . 'w'); $image = array('#theme' => 'image', '#srcset' => array(array('uri' => $this->testImages[0], 'width' => $widths[0]), array('uri' => $this->testImages[1], 'width' => $widths[1])), '#width' => rand(0, 1000) . 'px', '#height' => rand(0, 500) . 'px', '#alt' => $this->randomMachineName(), '#title' => $this->randomMachineName()); $this->render($image); // Make sure the srcset attribute has the correct value. $this->assertRaw(file_url_transform_relative(file_create_url($this->testImages[0])) . ' ' . $widths[0] . ', ' . file_url_transform_relative(file_create_url($this->testImages[1])) . ' ' . $widths[1], 'Correct output for image with srcset attribute and width descriptors.'); }
/** * Set canvas operations test. */ public function doTestSetCanvasOperations() { $image_factory = $this->container->get('image.factory'); $test_file = drupal_get_path('module', 'simpletest') . '/files/image-test.png'; $original_uri = file_unmanaged_copy($test_file, 'public://', FILE_EXISTS_RENAME); $generated_uri = 'public://styles/image_effects_test/public/' . \Drupal::service('file_system')->basename($original_uri); // Test EXACT size canvas. $effect = ['id' => 'image_effects_set_canvas', 'data' => ['canvas_size' => 'exact', 'canvas_color][container][transparent' => FALSE, 'canvas_color][container][hex' => '#FF00FF', 'canvas_color][container][opacity' => 100, 'exact][width' => '200%', 'exact][height' => '200%']]; $uuid = $this->addEffectToTestStyle($effect); // Load Image Style. $image_style = ImageStyle::load('image_effects_test'); // Check that ::transformDimensions returns expected dimensions. $image = $image_factory->get($original_uri); $this->assertEqual(40, $image->getWidth()); $this->assertEqual(20, $image->getHeight()); $url = file_url_transform_relative($image_style->buildUrl($original_uri)); $variables = array('#theme' => 'image_style', '#style_name' => 'image_effects_test', '#uri' => $original_uri, '#width' => $image->getWidth(), '#height' => $image->getHeight()); $this->assertEqual('<img src="' . $url . '" width="80" height="40" alt="" class="image-style-image-effects-test" />', $this->getImageTag($variables)); // Check that ::applyEffect generates image with expected canvas. $image_style->createDerivative($original_uri, $image_style->buildUri($original_uri)); $image = $image_factory->get($generated_uri, 'gd'); $this->assertEqual(80, $image->getWidth()); $this->assertEqual(40, $image->getHeight()); $this->assertTrue($this->colorsAreEqual($this->fuchsia, $this->getPixelColor($image, 0, 0))); $this->assertTrue($this->colorsAreEqual($this->fuchsia, $this->getPixelColor($image, 79, 0))); $this->assertTrue($this->colorsAreEqual($this->fuchsia, $this->getPixelColor($image, 0, 39))); $this->assertTrue($this->colorsAreEqual($this->fuchsia, $this->getPixelColor($image, 79, 39))); // Remove effect. $this->removeEffectFromTestStyle($uuid); // Test RELATIVE size canvas. $effect = ['id' => 'image_effects_set_canvas', 'data' => ['canvas_size' => 'relative', 'canvas_color][container][transparent' => FALSE, 'canvas_color][container][hex' => '#FFFF00', 'canvas_color][container][opacity' => 100, 'relative][right' => 10, 'relative][left' => 20, 'relative][top' => 30, 'relative][bottom' => 40]]; $uuid = $this->addEffectToTestStyle($effect); // Load Image Style. $image_style = ImageStyle::load('image_effects_test'); // Check that ::transformDimensions returns expected dimensions. $image = $image_factory->get($original_uri); $this->assertEqual(40, $image->getWidth()); $this->assertEqual(20, $image->getHeight()); $url = file_url_transform_relative($image_style->buildUrl($original_uri)); $variables = array('#theme' => 'image_style', '#style_name' => 'image_effects_test', '#uri' => $original_uri, '#width' => $image->getWidth(), '#height' => $image->getHeight()); $this->assertEqual('<img src="' . $url . '" width="70" height="90" alt="" class="image-style-image-effects-test" />', $this->getImageTag($variables)); // Check that ::applyEffect generates image with expected canvas. $image_style->createDerivative($original_uri, $image_style->buildUri($original_uri)); $image = $image_factory->get($generated_uri, 'gd'); $this->assertEqual(70, $image->getWidth()); $this->assertEqual(90, $image->getHeight()); $this->assertTrue($this->colorsAreEqual($this->yellow, $this->getPixelColor($image, 0, 0))); $this->assertTrue($this->colorsAreEqual($this->yellow, $this->getPixelColor($image, 69, 0))); $this->assertTrue($this->colorsAreEqual($this->yellow, $this->getPixelColor($image, 0, 89))); $this->assertTrue($this->colorsAreEqual($this->yellow, $this->getPixelColor($image, 69, 89))); // Remove effect. $this->removeEffectFromTestStyle($uuid); }
/** * Tests relative, root-relative, protocol-relative and absolute URLs. */ public function testUrlHandling() { // Only the plain_text text format is available by default, which escapes // all HTML. FilterFormat::create(['format' => 'full_html', 'name' => 'Full HTML', 'filters' => []])->save(); $defaults = ['type' => 'article', 'promote' => 1]; $this->drupalCreateNode($defaults + ['body' => ['value' => '<p><a href="' . file_url_transform_relative(file_create_url('public://root-relative')) . '">Root-relative URL</a></p>', 'format' => 'full_html']]); $protocol_relative_url = substr(file_create_url('public://protocol-relative'), strlen(\Drupal::request()->getScheme() . ':')); $this->drupalCreateNode($defaults + ['body' => ['value' => '<p><a href="' . $protocol_relative_url . '">Protocol-relative URL</a></p>', 'format' => 'full_html']]); $absolute_url = file_create_url('public://absolute'); $this->drupalCreateNode($defaults + ['body' => ['value' => '<p><a href="' . $absolute_url . '">Absolute URL</a></p>', 'format' => 'full_html']]); $this->drupalGet('rss.xml'); $this->assertRaw(file_create_url('public://root-relative'), 'Root-relative URL is transformed to absolute.'); $this->assertRaw($protocol_relative_url, 'Protocol-relative URL is left untouched.'); $this->assertRaw($absolute_url, 'Absolute URL is left untouched.'); }
/** * Method tests CKEditor image buttons. */ public function testImageButtonDisplay() { $this->drupalLogin($this->admin_user); // Install the Arabic language (which is RTL) and configure as the default. $edit = []; $edit['predefined_langcode'] = 'ar'; $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add language')); $edit = ['site_default_language' => 'ar']; $this->drupalPostForm('admin/config/regional/language', $edit, t('Save configuration')); // Once the default language is changed, go to the tested text format // configuration page. $this->drupalGet('admin/config/content/formats/manage/full_html'); // Check if any image button is loaded in CKEditor json. $json_encode = function ($html) { return trim(Json::encode($html), '"'); }; $markup = $json_encode(file_url_transform_relative(file_create_url('core/modules/ckeditor/js/plugins/drupalimage/image.png'))); $this->assertRaw($markup); }
/** * {@inheritdoc} */ public static function preRenderButton($element) { $element['#attributes']['type'] = 'image'; Element::setAttributes($element, array('id', 'name', 'value')); $element['#attributes']['src'] = file_url_transform_relative(file_create_url($element['#src'])); if (!empty($element['#title'])) { $element['#attributes']['alt'] = $element['#title']; $element['#attributes']['title'] = $element['#title']; } $element['#attributes']['class'][] = 'image-button'; if (!empty($element['#button_type'])) { $element['#attributes']['class'][] = 'image-button--' . $element['#button_type']; } $element['#attributes']['class'][] = 'js-form-submit'; $element['#attributes']['class'][] = 'form-submit'; if (!empty($element['#attributes']['disabled'])) { $element['#attributes']['class'][] = 'is-disabled'; } return $element; }
/** * Test the field formatter with a file field and file upload widget. */ public function testFile() { // Create a test node with an image file. $this->createNodeWithFile(); $node = $this->node; $xml_path = 'juicebox/xml/field/node/' . $node->id() . '/' . $this->instFieldName . '/full'; $xml_url = \Drupal::url('juicebox.xml_field', array('entityType' => 'node', 'entityId' => $node->id(), 'fieldName' => $this->instFieldName, 'displayName' => 'full')); // Get the urls to the test image and thumb derivative used by default. $uri = \Drupal\file\Entity\File::load($node->{$this->instFieldName}[0]->target_id)->getFileUri(); $test_image_url = entity_load('image_style', 'juicebox_medium')->buildUrl($uri); $test_thumb_url = entity_load('image_style', 'juicebox_square_thumb')->buildUrl($uri); // Check for correct embed markup as anon user. $this->drupalLogout(); $this->drupalGet('node/' . $node->id()); $this->assertRaw(trim(json_encode(array('configUrl' => $xml_url)), '{}"'), 'Gallery setting found in Drupal.settings.'); $this->assertRaw('id="node--' . $node->id() . '--' . str_replace('_', '-', $this->instFieldName) . '--full"', 'Embed code wrapper found.'); $this->assertRaw(Html::escape(file_url_transform_relative($test_image_url)), 'Test image found in embed code'); // Check for correct XML. $this->drupalGet($xml_path); $this->assertRaw('<?xml version="1.0" encoding="UTF-8"?>', 'Valid XML detected.'); $this->assertRaw('imageURL="' . Html::escape($test_image_url), 'Test image found in XML.'); $this->assertRaw('thumbURL="' . Html::escape($test_thumb_url), 'Test thumbnail found in XML.'); $this->assertRaw('<juicebox gallerywidth="100%" galleryheight="100%" backgroundcolor="#222222" textcolor="rgba(255,255,255,1)" thumbframecolor="rgba(255,255,255,.5)" showopenbutton="TRUE" showexpandbutton="TRUE" showthumbsbutton="TRUE" usethumbdots="FALSE" usefullscreenexpand="FALSE">', 'Expected default configuration options set in XML.'); }
/** * Processes raw profile configuration of a user. */ public static function processUserConf(array $conf, AccountProxyInterface $user) { // Convert MB to bytes $conf['maxsize'] *= 1048576; $conf['quota'] *= 1048576; // Set root uri and url $conf['root_uri'] = $conf['scheme'] . '://'; // file_create_url requires a filepath for some schemes like private:// $conf['root_url'] = preg_replace('@/(?:%2E|\\.)$@i', '', file_create_url($conf['root_uri'] . '.')); // Convert to relative if (!\Drupal::config('imce.settings')->get('abs_urls')) { $conf['root_url'] = file_url_transform_relative($conf['root_url']); } $conf['token'] = $user->isAnonymous() ? 'anon' : \Drupal::csrfToken()->get('imce'); // Process folders $conf['folders'] = static::processUserFolders($conf['folders'], $user); // Call plugin processors \Drupal::service('plugin.manager.imce.plugin')->processUserConf($conf, $user); return $conf; }
/** * {@inheritdoc} */ public function submitForm(array &$form, array &$form_state) { $response = new AjaxResponse(); // Convert any uploaded files from the FID values to data-editor-file-uuid // attributes. if (!empty($form_state['values']['fid'][0])) { $file = file_load($form_state['values']['fid'][0]); $file_url = file_create_url($file->getFileUri()); // Transform absolute image URLs to relative image URLs: prevent problems // on multisite set-ups and prevent mixed content errors. $file_url = file_url_transform_relative($file_url); $form_state['values']['attributes']['src'] = $file_url; $form_state['values']['attributes']['data-editor-file-uuid'] = $file->uuid(); } if (form_get_errors($form_state)) { unset($form['#prefix'], $form['#suffix']); $status_messages = array('#theme' => 'status_messages'); $output = drupal_render($form); $output = '<div>' . drupal_render($status_messages) . $output . '</div>'; $response->addCommand(new HtmlCommand('#editor-image-dialog-form', $output)); } else { $response->addCommand(new EditorDialogSave($form_state['values'])); $response->addCommand(new CloseModalDialogCommand()); } return $response; }
/** * Tests usage of the image style theme function. */ function testImageStyleTheme() { /** @var \Drupal\Core\Render\RendererInterface $renderer */ $renderer = $this->container->get('renderer'); // Create an image. $files = $this->drupalGetTestFiles('image'); $file = reset($files); $original_uri = file_unmanaged_copy($file->uri, 'public://', FILE_EXISTS_RENAME); // Create a style. $style = ImageStyle::create(array('name' => 'image_test', 'label' => 'Test')); $style->save(); $url = file_url_transform_relative($style->buildUrl($original_uri)); // Create the base element that we'll use in the tests below. $base_element = array('#theme' => 'image_style', '#style_name' => 'image_test', '#uri' => $original_uri); $element = $base_element; $this->setRawContent($renderer->renderRoot($element)); $elements = $this->xpath('//img[@class="image-style-image-test" and @src=:url and @alt=""]', array(':url' => $url)); $this->assertEqual(count($elements), 1, 'theme_image_style() renders an image correctly.'); // Test using theme_image_style() with a NULL value for the alt option. $element = $base_element; $element['#alt'] = NULL; $this->setRawContent($renderer->renderRoot($element)); $elements = $this->xpath('//img[@class="image-style-image-test" and @src=:url]', array(':url' => $url)); $this->assertEqual(count($elements), 1, 'theme_image_style() renders an image correctly with a NULL value for the alt option.'); }
protected function getDefaultContentsCssConfig() { return array(file_url_transform_relative(file_create_url('core/modules/ckeditor/css/ckeditor-iframe.css')), file_url_transform_relative(file_create_url('core/modules/system/css/components/align.module.css'))); }
/** * Tests the Color module functionality using the given theme. * * @param string $theme * The machine name of the theme being tested. * @param array $test_values * An associative array of test settings (i.e. 'Main background', 'Text * color', 'Color set', etc) for the theme which being tested. */ function _testColor($theme, $test_values) { $this->config('system.theme')->set('default', $theme)->save(); $settings_path = 'admin/appearance/settings/' . $theme; $this->drupalLogin($this->bigUser); $this->drupalGet($settings_path); $this->assertResponse(200); $this->assertUniqueText('Color set'); $edit['scheme'] = ''; $edit[$test_values['palette_input']] = '#123456'; $this->drupalPostForm($settings_path, $edit, t('Save configuration')); $this->drupalGet('<front>'); $stylesheets = $this->config('color.theme.' . $theme)->get('stylesheets'); foreach ($stylesheets as $stylesheet) { $this->assertPattern('|' . file_url_transform_relative(file_create_url($stylesheet)) . '|', 'Make sure the color stylesheet is included in the content. (' . $theme . ')'); $stylesheet_content = join("\n", file($stylesheet)); $this->assertTrue(strpos($stylesheet_content, 'color: #123456') !== FALSE, 'Make sure the color we changed is in the color stylesheet. (' . $theme . ')'); } $this->drupalGet($settings_path); $this->assertResponse(200); $edit['scheme'] = $test_values['scheme']; $this->drupalPostForm($settings_path, $edit, t('Save configuration')); $this->drupalGet('<front>'); $stylesheets = $this->config('color.theme.' . $theme)->get('stylesheets'); foreach ($stylesheets as $stylesheet) { $stylesheet_content = join("\n", file($stylesheet)); $this->assertTrue(strpos($stylesheet_content, 'color: ' . $test_values['scheme_color']) !== FALSE, 'Make sure the color we changed is in the color stylesheet. (' . $theme . ')'); } // Test with aggregated CSS turned on. $config = $this->config('system.performance'); $config->set('css.preprocess', 1); $config->save(); $this->drupalGet('<front>'); $stylesheets = \Drupal::state()->get('drupal_css_cache_files') ?: array(); $stylesheet_content = ''; foreach ($stylesheets as $uri) { $stylesheet_content .= join("\n", file(drupal_realpath($uri))); } $this->assertTrue(strpos($stylesheet_content, 'public://') === FALSE, 'Make sure the color paths have been translated to local paths. (' . $theme . ')'); $config->set('css.preprocess', 0); $config->save(); }
/** * Tests for image field settings. */ function testImageFieldSettings() { /** @var \Drupal\Core\Render\RendererInterface $renderer */ $renderer = $this->container->get('renderer'); $node_storage = $this->container->get('entity.manager')->getStorage('node'); $test_image = current($this->drupalGetTestFiles('image')); list(, $test_image_extension) = explode('.', $test_image->filename); $field_name = strtolower($this->randomMachineName()); $field_settings = array('alt_field' => 1, 'file_extensions' => $test_image_extension, 'max_filesize' => '50 KB', 'max_resolution' => '100x100', 'min_resolution' => '10x10', 'title_field' => 1); $widget_settings = array('preview_image_style' => 'medium'); $field = $this->createImageField($field_name, 'article', array(), $field_settings, $widget_settings); // Verify that the min/max resolution set on the field are properly // extracted, and displayed, on the image field's configuration form. $this->drupalGet('admin/structure/types/manage/article/fields/' . $field->id()); $this->assertFieldByName('settings[max_resolution][x]', '100', 'Expected max resolution X value of 100.'); $this->assertFieldByName('settings[max_resolution][y]', '100', 'Expected max resolution Y value of 100.'); $this->assertFieldByName('settings[min_resolution][x]', '10', 'Expected min resolution X value of 10.'); $this->assertFieldByName('settings[min_resolution][y]', '10', 'Expected min resolution Y value of 10.'); $this->drupalGet('node/add/article'); $this->assertText(t('50 KB limit.'), 'Image widget max file size is displayed on article form.'); $this->assertText(t('Allowed types: @extensions.', array('@extensions' => $test_image_extension)), 'Image widget allowed file types displayed on article form.'); $this->assertText(t('Images must be larger than 10x10 pixels. Images larger than 100x100 pixels will be resized.'), 'Image widget allowed resolution displayed on article form.'); // We have to create the article first and then edit it because the alt // and title fields do not display until the image has been attached. // Create alt text for the image. $alt = $this->randomMachineName(); $nid = $this->uploadNodeImage($test_image, $field_name, 'article', $alt); $this->drupalGet('node/' . $nid . '/edit'); $this->assertFieldByName($field_name . '[0][alt]', '', 'Alt field displayed on article form.'); $this->assertFieldByName($field_name . '[0][title]', '', 'Title field displayed on article form.'); // Verify that the attached image is being previewed using the 'medium' // style. $node_storage->resetCache(array($nid)); $node = $node_storage->load($nid); $file = $node->{$field_name}->entity; $url = file_url_transform_relative(file_create_url(ImageStyle::load('medium')->buildUrl($file->getFileUri()))); $this->assertTrue($this->cssSelect('img[width=40][height=20][class=image-style-medium][src="' . $url . '"]')); // Add alt/title fields to the image and verify that they are displayed. $image = array('#theme' => 'image', '#uri' => $file->getFileUri(), '#alt' => $alt, '#title' => $this->randomMachineName(), '#width' => 40, '#height' => 20); $edit = array($field_name . '[0][alt]' => $image['#alt'], $field_name . '[0][title]' => $image['#title']); $this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save and keep published')); $default_output = str_replace("\n", NULL, $renderer->renderRoot($image)); $this->assertRaw($default_output, 'Image displayed using user supplied alt and title attributes.'); // Verify that alt/title longer than allowed results in a validation error. $test_size = 2000; $edit = array($field_name . '[0][alt]' => $this->randomMachineName($test_size), $field_name . '[0][title]' => $this->randomMachineName($test_size)); $this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save and keep published')); $schema = $field->getFieldStorageDefinition()->getSchema(); $this->assertRaw(t('Alternative text cannot be longer than %max characters but is currently %length characters long.', array('%max' => $schema['columns']['alt']['length'], '%length' => $test_size))); $this->assertRaw(t('Title cannot be longer than %max characters but is currently %length characters long.', array('%max' => $schema['columns']['title']['length'], '%length' => $test_size))); // Set cardinality to unlimited and add upload a second image. // The image widget is extending on the file widget, but the image field // type does not have the 'display_field' setting which is expected by // the file widget. This resulted in notices before when cardinality is not // 1, so we need to make sure the file widget prevents these notices by // providing all settings, even if they are not used. // @see FileWidget::formMultipleElements(). $this->drupalPostForm('admin/structure/types/manage/article/fields/node.article.' . $field_name . '/storage', array('cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED), t('Save field settings')); $edit = array('files[' . $field_name . '_1][]' => drupal_realpath($test_image->uri)); $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Save and keep published')); // Add the required alt text. $this->drupalPostForm(NULL, [$field_name . '[1][alt]' => $alt], t('Save and keep published')); $this->assertText(format_string('Article @title has been updated.', array('@title' => $node->getTitle()))); // Assert ImageWidget::process() calls FieldWidget::process(). $this->drupalGet('node/' . $node->id() . '/edit'); $edit = array('files[' . $field_name . '_2][]' => drupal_realpath($test_image->uri)); $this->drupalPostAjaxForm(NULL, $edit, $field_name . '_2_upload_button'); $this->assertNoRaw('<input multiple type="file" id="edit-' . strtr($field_name, '_', '-') . '-2-upload" name="files[' . $field_name . '_2][]" size="22" class="js-form-file form-file">'); $this->assertRaw('<input multiple type="file" id="edit-' . strtr($field_name, '_', '-') . '-3-upload" name="files[' . $field_name . '_3][]" size="22" class="js-form-file form-file">'); }
/** * Test configuration options that are specific to the Juicebox field * formatter. */ public function testFieldFormatterConf() { $node = $this->node; // Do a set of control requests as an anon user that will also prime any // caches. $this->drupalGet('node/' . $node->id()); $this->assertResponse(200, 'Control request of test node was successful.'); $this->drupalGet('juicebox/xml/field/node/' . $node->id() . '/' . $this->instFieldName . '/full'); $this->assertResponse(200, 'Control request of XML was successful.'); // Alter field formatter specific settings to contain custom values. $this->drupalLogin($this->webUser); $this->drupalPostAjaxForm('admin/structure/types/manage/' . $this->instBundle . '/display', array(), $this->instFieldName . '_settings_edit', NULL, array(), array(), 'entity-view-display-edit-form'); $edit = array('fields[' . $this->instFieldName . '][settings_edit_form][settings][image_style]' => '', 'fields[' . $this->instFieldName . '][settings_edit_form][settings][thumb_style]' => 'thumbnail', 'fields[' . $this->instFieldName . '][settings_edit_form][settings][caption_source]' => 'alt', 'fields[' . $this->instFieldName . '][settings_edit_form][settings][title_source]' => 'title'); $this->drupalPostForm(NULL, $edit, t('Save')); $this->assertText(t('Your settings have been saved.'), 'Gallery configuration changes saved.'); // Get the urls to the image and thumb derivatives expected. $uri = \Drupal\file\Entity\File::load($node->{$this->instFieldName}[0]->target_id)->getFileUri(); $test_formatted_image_url = file_create_url($uri); $test_formatted_thumb_url = entity_load('image_style', 'thumbnail')->buildUrl($uri); // Check for correct embed markup as anon user. $this->drupalLogout(); $this->drupalGet('node/' . $node->id()); $this->assertRaw(Html::escape(file_url_transform_relative($test_formatted_image_url)), 'Test styled image found in embed code'); // Check for correct XML. $this->drupalGet('juicebox/xml/field/node/' . $node->id() . '/' . $this->instFieldName . '/full'); $this->assertRaw('imageURL="' . Html::escape($test_formatted_image_url), 'Test styled image found in XML.'); $this->assertRaw('thumbURL="' . Html::escape($test_formatted_thumb_url), 'Test styled thumbnail found in XML.'); // Note the intended title and caption text does not contain any block-level // tags as long as the global title and caption output filter is working. // So this acts as a test for that feature as well. $this->assertRaw('<title><![CDATA[Some title text for field ' . $this->instFieldName . ' on node ' . $node->id() . ']]></title>', 'Image title text found in XML'); $this->assertRaw('<caption><![CDATA[Some alt text for field ' . $this->instFieldName . ' on node ' . $node->id() . ' <strong>with formatting</strong>]]></caption>', 'Image caption text found in XML'); // Now that we have title and caption data set, also ensure this text can // be found in search results. First we update the search index by marking // our test node as dirty and running cron. $this->drupalLogin($this->webUser); $this->drupalPostForm('node/' . $node->id() . '/edit', array(), t('Save and keep published')); $this->cronRun(); $this->drupalPostForm('search', array('keys' => '"Some title text"'), t('Search')); $this->assertText('Test Juicebox Gallery Node', 'Juicebox node found in search for title text.'); // The Juicebox javascript should have been excluded from the search results // page. $this->assertNoRaw('"configUrl":"', 'Juicebox Drupal.settings vars not included on search result page.'); }
/** * {@inheritdoc} */ public function viewElements(FieldItemListInterface $items, $langcode) { $elements = array(); $files = $this->getEntitiesToView($items, $langcode); // Early opt-out if the field is empty. if (empty($files)) { return $elements; } $url = NULL; // Check if the formatter involves a link. if ($this->getSetting('image_link') == 'content') { $entity = $items->getEntity(); if (!$entity->isNew()) { $url = $entity->urlInfo(); } } elseif ($this->getSetting('image_link') == 'file') { $link_file = TRUE; } // Collect cache tags to be added for each item in the field. $responsive_image_style = $this->responsiveImageStyleStorage->load($this->getSetting('responsive_image_style')); $image_styles_to_load = array(); $cache_tags = []; if ($responsive_image_style) { $cache_tags = Cache::mergeTags($cache_tags, $responsive_image_style->getCacheTags()); $image_styles_to_load = $responsive_image_style->getImageStyleIds(); } $image_styles = $this->imageStyleStorage->loadMultiple($image_styles_to_load); foreach ($image_styles as $image_style) { $cache_tags = Cache::mergeTags($cache_tags, $image_style->getCacheTags()); } foreach ($files as $delta => $file) { // Link the <picture> element to the original file. if (isset($link_file)) { $url = file_url_transform_relative(file_create_url($file->getFileUri())); } // Extract field item attributes for the theme function, and unset them // from the $item so that the field template does not re-render them. $item = $file->_referringItem; $item_attributes = $item->_attributes; unset($item->_attributes); $elements[$delta] = array('#theme' => 'responsive_image_formatter', '#item' => $item, '#item_attributes' => $item_attributes, '#responsive_image_style_id' => $responsive_image_style ? $responsive_image_style->id() : '', '#url' => $url, '#cache' => array('tags' => $cache_tags)); } return $elements; }
/** * {@inheritdoc} */ public function getJSSettings(Editor $editor) { $settings = array(); // Get the settings for all enabled plugins, even the internal ones. $enabled_plugins = array_keys($this->ckeditorPluginManager->getEnabledPluginFiles($editor, TRUE)); foreach ($enabled_plugins as $plugin_id) { $plugin = $this->ckeditorPluginManager->createInstance($plugin_id); $settings += $plugin->getConfig($editor); } // Fall back on English if no matching language code was found. $display_langcode = 'en'; // Map the interface language code to a CKEditor translation if interface // translation is enabled. if ($this->moduleHandler->moduleExists('locale')) { $ckeditor_langcodes = $this->getLangcodes(); $language_interface = $this->languageManager->getCurrentLanguage(); if (isset($ckeditor_langcodes[$language_interface->getId()])) { $display_langcode = $ckeditor_langcodes[$language_interface->getId()]; } } // Next, set the most fundamental CKEditor settings. $external_plugin_files = $this->ckeditorPluginManager->getEnabledPluginFiles($editor); $settings += array('toolbar' => $this->buildToolbarJSSetting($editor), 'contentsCss' => $this->buildContentsCssJSSetting($editor), 'extraPlugins' => implode(',', array_keys($external_plugin_files)), 'language' => $display_langcode, 'stylesSet' => FALSE); // Finally, set Drupal-specific CKEditor settings. $root_relative_file_url = function ($uri) { return file_url_transform_relative(file_create_url($uri)); }; $settings += array('drupalExternalPlugins' => array_map($root_relative_file_url, $external_plugin_files)); // Parse all CKEditor plugin JavaScript files for translations. if ($this->moduleHandler->moduleExists('locale')) { locale_js_translate(array_values($external_plugin_files)); } ksort($settings); return $settings; }
/** * Tests the automatic/magic calling of toString() on objects, if exists. */ public function testTwigFileUrls() { $this->drupalGet('/twig-theme-test/file-url'); $filepath = file_url_transform_relative(file_create_url('core/modules/system/tests/modules/twig_theme_test/twig_theme_test.js')); $this->assertRaw('<div>file_url: ' . $filepath . '</div>'); }
/** * {@inheritdoc} */ public function getFunctions() { return [new \Twig_SimpleFunction('render_var', array($this, 'renderVar')), new \Twig_SimpleFunction('url', array($this, 'getUrl'), array('is_safe_callback' => array($this, 'isUrlGenerationSafe'))), new \Twig_SimpleFunction('path', array($this, 'getPath'), array('is_safe_callback' => array($this, 'isUrlGenerationSafe'))), new \Twig_SimpleFunction('link', array($this, 'getLink')), new \Twig_SimpleFunction('file_url', function ($uri) { return file_url_transform_relative(file_create_url($uri)); }), new \Twig_SimpleFunction('attach_library', [$this, 'attachLibrary']), new \Twig_SimpleFunction('active_theme_path', [$this, 'getActiveThemePath']), new \Twig_SimpleFunction('active_theme', [$this, 'getActiveTheme'])]; }
/** * Test file_url_transform_relative(). */ function testRelativeFileURL() { // Disable file_test.module's hook_file_url_alter() implementation. \Drupal::state()->set('file_test.hook_file_url_alter', NULL); // Create a mock Request for file_url_transform_relative(). $request = Request::create($GLOBALS['base_url']); $this->container->get('request_stack')->push($request); \Drupal::setContainer($this->container); // Shipped file. $filepath = 'core/assets/vendor/jquery/jquery.min.js'; $url = file_create_url($filepath); $this->assertIdentical(base_path() . $filepath, file_url_transform_relative($url)); // Managed file. $uri = $this->createUri(); $url = file_create_url($uri); $public_directory_path = \Drupal::service('stream_wrapper_manager')->getViaScheme('public')->getDirectoryPath(); $this->assertIdentical(base_path() . $public_directory_path . '/' . rawurlencode(drupal_basename($uri)), file_url_transform_relative($url)); }
static function component_url($components_path = NULL) { $key = Drupal::state()->get('system.css_js_query_string'); $components_path = $components_path ?? Settings::get('webcomponents_path'); return file_url_transform_relative(file_create_url($components_path)) . '?' . $key; }
/** * Locate all images in a piece of text that need replacing. * * An array of settings that will be used to identify which images need * updating. Includes the following: * * - image_locations: An array of acceptable image locations. * of the following values: "remote". Remote image will be downloaded and * saved locally. This procedure is intensive as the images need to * be retrieved to have their dimensions checked. * * @param string $text * The text to be updated with the new img src tags. * * @return array $images * An list of images. */ private function getImages($text) { $dom = Html::load($text); $xpath = new \DOMXPath($dom); /** @var \DOMNode $node */ foreach ($xpath->query('//img') as $node) { $file = $this->entityRepository->loadEntityByUuid('file', $node->getAttribute('data-entity-uuid')); // If the image hasn't an uuid then don't try to resize it. if (is_null($file)) { continue; } $image = $this->imageFactory->get($node->getAttribute('src')); // Checking if the image needs to be resized. if ($image->getWidth() == $node->getAttribute('width') && $image->getHeight() == $node->getAttribute('height')) { continue; } $target = file_uri_target($file->getFileUri()); $dirname = dirname($target) != '.' ? dirname($target) . '/' : ''; $info = pathinfo($file->getFileUri()); $resize_file_path = 'public://resize/' . $dirname . $info['filename'] . '-' . $node->getAttribute('width') . 'x' . $node->getAttribute('height') . '.' . $info['extension']; // Checking if the image was already resized: if (file_exists($resize_file_path)) { $node->setAttribute('src', file_url_transform_relative(file_create_url($resize_file_path))); continue; } // Delete this when https://www.drupal.org/node/2211657#comment-11510213 // be fixed. $dirname = $this->fileSystem->dirname($resize_file_path); if (!file_exists($dirname)) { file_prepare_directory($dirname, FILE_CREATE_DIRECTORY); } // Checks if the resize filter exists if is not then create it. $copy = file_unmanaged_copy($file->getFileUri(), $resize_file_path, FILE_EXISTS_REPLACE); $copy_image = $this->imageFactory->get($copy); $copy_image->resize($node->getAttribute('width'), $node->getAttribute('height')); $copy_image->save(); $node->setAttribute('src', file_url_transform_relative(file_create_url($copy))); } return Html::serialize($dom); }
/** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { $response = new AjaxResponse(); // Convert any uploaded files from the FID values to data-entity-uuid // attributes and set data-entity-type to 'file'. $fid = $form_state->getValue(array('fid', 0)); if (!empty($fid)) { $file = $this->fileStorage->load($fid); $file_url = file_create_url($file->getFileUri()); // Transform absolute image URLs to relative image URLs: prevent problems // on multisite set-ups and prevent mixed content errors. $file_url = file_url_transform_relative($file_url); $form_state->setValue(array('attributes', 'src'), $file_url); $form_state->setValue(array('attributes', 'data-entity-uuid'), $file->uuid()); $form_state->setValue(array('attributes', 'data-entity-type'), 'file'); } // When the alt attribute is set to two double quotes, transform it to the // empty string: two double quotes signify "empty alt attribute". See above. if (trim($form_state->getValue(array('attributes', 'alt'))) === '""') { $form_state->setValue(array('attributes', 'alt'), ''); } if ($form_state->getErrors()) { unset($form['#prefix'], $form['#suffix']); $form['status_messages'] = ['#type' => 'status_messages', '#weight' => -10]; $response->addCommand(new HtmlCommand('#editor-image-dialog-form', $form)); } else { $response->addCommand(new EditorDialogSave($form_state->getValues())); $response->addCommand(new CloseModalDialogCommand()); } return $response; }
/** * Tests image style configuration import that does a delete. */ function testConfigImport() { // Create a new style. $style_name = strtolower($this->randomMachineName(10)); $style_label = $this->randomString(); $style = entity_create('image_style', array('name' => $style_name, 'label' => $style_label)); $style->save(); // Create an image field that uses the new style. $field_name = strtolower($this->randomMachineName(10)); $this->createImageField($field_name, 'article'); entity_get_display('node', 'article', 'default')->setComponent($field_name, array('type' => 'image', 'settings' => array('image_style' => $style_name)))->save(); // Create a new node with an image attached. $test_image = current($this->drupalGetTestFiles('image')); $nid = $this->uploadNodeImage($test_image, $field_name, 'article', $this->randomMachineName()); $node = Node::load($nid); // Get node field original image URI. $fid = $node->get($field_name)->target_id; $original_uri = File::load($fid)->getFileUri(); // Test that image is displayed using newly created style. $this->drupalGet('node/' . $nid); $this->assertRaw(file_url_transform_relative($style->buildUrl($original_uri)), format_string('Image displayed using style @style.', array('@style' => $style_name))); // Copy config to sync, and delete the image style. $sync = $this->container->get('config.storage.sync'); $active = $this->container->get('config.storage'); // Remove the image field from the display, to avoid a dependency error // during import. EntityViewDisplay::load('node.article.default')->removeComponent($field_name)->save(); $this->copyConfig($active, $sync); $sync->delete('image.style.' . $style_name); $this->configImporter()->import(); $this->assertFalse(ImageStyle::load($style_name), 'Style deleted after config import.'); $this->assertEqual($this->getImageCount($style), 0, 'Image style was flushed after being deleted by config import.'); }
/** * Tests JavaScript files that have querystrings attached get added right. */ function testAddJsFileWithQueryString() { $build['#attached']['library'][] = 'common_test/querystring'; $assets = AttachedAssets::createFromRenderArray($build); $css = $this->assetResolver->getCssAssets($assets, FALSE); $js = $this->assetResolver->getJsAssets($assets, FALSE)[1]; $this->assertTrue(array_key_exists('core/modules/system/tests/modules/common_test/querystring.css?arg1=value1&arg2=value2', $css), 'CSS file with query string is correctly added.'); $this->assertTrue(array_key_exists('core/modules/system/tests/modules/common_test/querystring.js?arg1=value1&arg2=value2', $js), 'JavaScript file with query string is correctly added.'); $css_render_array = \Drupal::service('asset.css.collection_renderer')->render($css); $rendered_css = $this->renderer->renderPlain($css_render_array); $js_render_array = \Drupal::service('asset.js.collection_renderer')->render($js); $rendered_js = $this->renderer->renderPlain($js_render_array); $query_string = $this->container->get('state')->get('system.css_js_query_string') ?: '0'; $this->assertNotIdentical(strpos($rendered_css, '<link rel="stylesheet" href="' . str_replace('&', '&', file_url_transform_relative(file_create_url('core/modules/system/tests/modules/common_test/querystring.css?arg1=value1&arg2=value2'))) . '&' . $query_string . '" media="all" />'), FALSE, 'CSS file with query string gets version query string correctly appended..'); $this->assertNotIdentical(strpos($rendered_js, '<script src="' . str_replace('&', '&', file_url_transform_relative(file_create_url('core/modules/system/tests/modules/common_test/querystring.js?arg1=value1&arg2=value2'))) . '&' . $query_string . '"></script>'), FALSE, 'JavaScript file with query string gets version query string correctly appended.'); }
/** * Get the results from a test and store them in the class array $results. */ function getTestResults() { $results = array(); if ($this->parse()) { if ($details = $this->getResultFieldSet()) { // Code assumes this is the only test in group. $results['summary'] = $this->asText($details->div->div[1]); $results['name'] = $this->asText($details->summary); $results['assertions'] = array(); $tbody = $details->div->table->tbody; foreach ($tbody->tr as $row) { $assertion = array(); $assertion['message'] = $this->asText($row->td[0]); $assertion['type'] = $this->asText($row->td[1]); $assertion['file'] = $this->asText($row->td[2]); $assertion['line'] = $this->asText($row->td[3]); $assertion['function'] = $this->asText($row->td[4]); $ok_url = file_url_transform_relative(file_create_url('core/misc/icons/73b355/check.svg')); $assertion['status'] = $row->td[5]->img['src'] == $ok_url ? 'Pass' : 'Fail'; $results['assertions'][] = $assertion; } } } $this->childTestResults = $results; }
/** * Tests responsive image formatters linked to the file or node. * * @param string $link_type * The link type to test. Either 'file' or 'content'. */ private function assertResponsiveImageFieldFormattersLink($link_type) { $field_name = Unicode::strtolower($this->randomMachineName()); $field_settings = array('alt_field_required' => 0); $this->createImageField($field_name, 'article', array('uri_scheme' => 'public'), $field_settings); // Create a new node with an image attached. $test_image = current($this->drupalGetTestFiles('image')); // Test the image linked to file formatter. $display_options = array('type' => 'responsive_image', 'settings' => array('image_link' => $link_type, 'responsive_image_style' => 'style_one')); entity_get_display('node', 'article', 'default')->setComponent($field_name, $display_options)->save(); // Ensure that preview works. $this->previewNodeImage($test_image, $field_name, 'article'); // Look for a picture tag in the preview output $this->assertPattern('/picture/'); $nid = $this->uploadNodeImage($test_image, $field_name, 'article'); $this->container->get('entity.manager')->getStorage('node')->resetCache(array($nid)); $node = Node::load($nid); // Use the responsive image formatter linked to file formatter. $display_options = array('type' => 'responsive_image', 'settings' => array('image_link' => $link_type, 'responsive_image_style' => 'style_one')); entity_get_display('node', 'article', 'default')->setComponent($field_name, $display_options)->save(); // Create a derivative so at least one MIME type will be known. $large_style = ImageStyle::load('large'); $image_uri = File::load($node->{$field_name}->target_id)->getFileUri(); $large_style->createDerivative($image_uri, $large_style->buildUri($image_uri)); // Output should contain all image styles and all breakpoints. $this->drupalGet('node/' . $nid); $this->removeWhiteSpace(); switch ($link_type) { case 'file': // Make sure the link to the file is present. $this->assertPattern('/<a(.*?)href="' . preg_quote(file_url_transform_relative(file_create_url($image_uri)), '/') . '"(.*?)><picture/'); break; case 'content': // Make sure the link to the node is present. $this->assertPattern('/<a(.*?)href="' . preg_quote($node->url(), '/') . '"(.*?)><picture/'); break; } }
/** * Test the theme settings form. */ function testThemeSettings() { // Ensure invalid theme settings form URLs return a proper 404. $this->drupalGet('admin/appearance/settings/bartik'); $this->assertResponse(404, 'The theme settings form URL for a uninstalled theme could not be found.'); $this->drupalGet('admin/appearance/settings/' . $this->randomMachineName()); $this->assertResponse(404, 'The theme settings form URL for a non-existent theme could not be found.'); $this->assertTrue(\Drupal::service('theme_installer')->install(['stable'])); $this->drupalGet('admin/appearance/settings/stable'); $this->assertResponse(404, 'The theme settings form URL for a hidden theme is unavailable.'); // Specify a filesystem path to be used for the logo. $file = current($this->drupalGetTestFiles('image')); $file_relative = strtr($file->uri, array('public:/' => PublicStream::basePath())); $default_theme_path = 'core/themes/classy'; $supported_paths = array($file->uri => array('form' => file_uri_target($file->uri), 'src' => file_url_transform_relative(file_create_url($file->uri))), file_uri_target($file->uri) => array('form' => file_uri_target($file->uri), 'src' => file_url_transform_relative(file_create_url($file->uri))), $file_relative => array('form' => $file_relative, 'src' => file_url_transform_relative(file_create_url($file->uri))), 'core/misc/druplicon.png' => array('form' => 'core/misc/druplicon.png', 'src' => base_path() . 'core/misc/druplicon.png'), $default_theme_path . '/logo.svg' => array('form' => $default_theme_path . '/logo.svg', 'src' => base_path() . $default_theme_path . '/logo.svg')); foreach ($supported_paths as $input => $expected) { $edit = array('default_logo' => FALSE, 'logo_path' => $input); $this->drupalPostForm('admin/appearance/settings', $edit, t('Save configuration')); $this->assertNoText('The custom logo path is invalid.'); $this->assertFieldByName('logo_path', $expected['form']); // Verify logo path examples. $elements = $this->xpath('//div[contains(@class, :item)]/div[@class=:description]/code', array(':item' => 'js-form-item-logo-path', ':description' => 'description')); // Expected default values (if all else fails). $implicit_public_file = 'logo.svg'; $explicit_file = 'public://logo.svg'; $local_file = $default_theme_path . '/logo.svg'; // Adjust for fully qualified stream wrapper URI in public filesystem. if (file_uri_scheme($input) == 'public') { $implicit_public_file = file_uri_target($input); $explicit_file = $input; $local_file = strtr($input, array('public:/' => PublicStream::basePath())); } elseif (file_uri_scheme($input) !== FALSE) { $explicit_file = $input; } elseif ($input == file_uri_target($file->uri)) { $implicit_public_file = $input; $explicit_file = 'public://' . $input; $local_file = PublicStream::basePath() . '/' . $input; } $this->assertEqual((string) $elements[0], $implicit_public_file); $this->assertEqual((string) $elements[1], $explicit_file); $this->assertEqual((string) $elements[2], $local_file); // Verify the actual 'src' attribute of the logo being output in a site // branding block. $this->drupalPlaceBlock('system_branding_block', ['region' => 'header']); $this->drupalGet(''); $elements = $this->xpath('//header//a[@rel=:rel]/img', array(':rel' => 'home')); $this->assertEqual((string) $elements[0]['src'], $expected['src']); } $unsupported_paths = array('public://whatever.png', 'private://whatever.png', 'temporary://whatever.png', 'public:/whatever.png', '://whatever.png', ':whatever.png', 'public://', 'whatever.png', PublicStream::basePath() . '/whatever.png', '/' . PublicStream::basePath() . '/whatever.png', 'core/misc/whatever.png', '/core/misc/whatever.png', drupal_realpath($file->uri)); $this->drupalGet('admin/appearance/settings'); foreach ($unsupported_paths as $path) { $edit = array('default_logo' => FALSE, 'logo_path' => $path); $this->drupalPostForm(NULL, $edit, t('Save configuration')); $this->assertText('The custom logo path is invalid.'); } // Upload a file to use for the logo. $edit = array('default_logo' => FALSE, 'logo_path' => '', 'files[logo_upload]' => drupal_realpath($file->uri)); $this->drupalPostForm('admin/appearance/settings', $edit, t('Save configuration')); $fields = $this->xpath($this->constructFieldXpath('name', 'logo_path')); $uploaded_filename = 'public://' . $fields[0]['value']; $this->drupalPlaceBlock('system_branding_block', ['region' => 'header']); $this->drupalGet(''); $elements = $this->xpath('//header//a[@rel=:rel]/img', array(':rel' => 'home')); $this->assertEqual($elements[0]['src'], file_url_transform_relative(file_create_url($uploaded_filename))); $this->container->get('theme_handler')->install(array('bartik')); // Ensure only valid themes are listed in the local tasks. $this->drupalPlaceBlock('local_tasks_block', ['region' => 'header']); $this->drupalGet('admin/appearance/settings'); $theme_handler = \Drupal::service('theme_handler'); $this->assertLink($theme_handler->getName('classy')); $this->assertLink($theme_handler->getName('bartik')); $this->assertNoLink($theme_handler->getName('stable')); // If a hidden theme is an admin theme it should be viewable. \Drupal::configFactory()->getEditable('system.theme')->set('admin', 'stable')->save(); \Drupal::service('router.builder')->rebuildIfNeeded(); $this->drupalPlaceBlock('local_tasks_block', ['region' => 'header', 'theme' => 'stable']); $this->drupalGet('admin/appearance/settings'); $this->assertLink($theme_handler->getName('stable')); $this->drupalGet('admin/appearance/settings/stable'); $this->assertResponse(200, 'The theme settings form URL for a hidden theme that is the admin theme is available.'); }