/** * {@inheritdoc} */ public function form(array $form, FormStateInterface $form_state) { $view = $this->entity; $form['#prefix'] = '<div id="views-preview-wrapper" class="views-admin clearfix">'; $form['#suffix'] = '</div>'; $form['#id'] = 'views-ui-preview-form'; $form_state->disableCache(); $form['controls']['#attributes'] = array('class' => array('clearfix')); $form['controls']['title'] = array('#prefix' => '<h2 class="view-preview-form__title">', '#markup' => $this->t('Preview'), '#suffix' => '</h2>'); // Add a checkbox controlling whether or not this display auto-previews. $form['controls']['live_preview'] = array('#type' => 'checkbox', '#id' => 'edit-displays-live-preview', '#title' => $this->t('Auto preview'), '#default_value' => \Drupal::config('views.settings')->get('ui.always_live_preview')); // Add the arguments textfield $form['controls']['view_args'] = array('#type' => 'textfield', '#title' => $this->t('Preview with contextual filters:'), '#description' => $this->t('Separate contextual filter values with a "/". For example, %example.', array('%example' => '40/12/10')), '#id' => 'preview-args'); $args = array(); if (!$form_state->isValueEmpty('view_args')) { $args = explode('/', $form_state->getValue('view_args')); } $user_input = $form_state->getUserInput(); if ($form_state->get('show_preview') || !empty($user_input['js'])) { $form['preview'] = array('#weight' => 110, '#theme_wrappers' => array('container'), '#attributes' => array('id' => 'views-live-preview'), 'preview' => $view->renderPreview($this->displayID, $args)); } $uri = $view->urlInfo('preview-form'); $uri->setRouteParameter('display_id', $this->displayID); $form['#action'] = $uri->toString(); return $form; }
/** * Returns the entity manager. * * @return \Drupal\Core\Entity\EntityManagerInterface * The entity manager service. */ protected function getEntityManager() { if (!isset($this->entityManager)) { $this->entityManager = \Drupal::entityManager(); } return $this->entityManager; }
/** * Perform validation on a stub entity. * * @param string $entity_type_id * The entity type we are stubbing. * @param string $entity_id * ID of the stubbed entity to validate. * * @return \Drupal\Core\Entity\EntityConstraintViolationListInterface * List of constraint violations identified. */ protected function validateStub($entity_type_id, $entity_id) { $controller = \Drupal::entityManager()->getStorage($entity_type_id); /** @var \Drupal\Core\Entity\ContentEntityInterface $stub_entity */ $stub_entity = $controller->load($entity_id); return $stub_entity->validate(); }
/** * {@inheritdoc} */ public function nextMail() { // Get the current mail spool row and update the internal pointer to the // next row. $return = each($this->mails); // If we're done, return false. if (!$return) { return FALSE; } $spool_data = $return['value']; // Store this spool row as processed. $this->processed[$spool_data->msid] = $spool_data; $entity = entity_load($spool_data->entity_type, $spool_data->entity_id); if (!$entity) { // If the entity load failed, set the processed status done and proceed with // the next mail. $this->processed[$spool_data->msid]->result = array('status' => SpoolStorageInterface::STATUS_DONE, 'error' => TRUE); return $this->nextMail(); } if ($spool_data->data) { $subscriber = $spool_data->data; } else { $subscriber = simplenews_subscriber_load_by_mail($spool_data->mail); } if (!$subscriber) { // If loading the subscriber failed, set the processed status done and // proceed with the next mail. $this->processed[$spool_data->msid]->result = array('status' => SpoolStorageInterface::STATUS_DONE, 'error' => TRUE); return $this->nextMail(); } $mail = new MailEntity($entity, $subscriber, \Drupal::service('simplenews.mail_cache')); // Set the langcode langcode. $this->processed[$spool_data->msid]->langcode = $mail->getEntity()->language()->getId(); return $mail; }
function setUp() { parent::setUp(); $this->drupalCreateContentType(array('type' => 'article', 'name' => 'Article')); // Create and login user. $admin_user = $this->drupalCreateUser(array('administer site configuration', 'administer languages', 'access administration pages', 'administer content types', 'administer comments', 'create article content', 'access comments', 'post comments', 'skip comment approval')); $this->drupalLogin($admin_user); // Add language. $edit = array('predefined_langcode' => 'fr'); $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add language')); // Set "Article" content type to use multilingual support. $edit = array('language_configuration[language_show]' => TRUE); $this->drupalPostForm('admin/structure/types/manage/article', $edit, t('Save content type')); // Enable content language negotiation UI. \Drupal::state()->set('language_test.content_language_type', TRUE); // Set interface language detection to user and content language detection // to URL. Disable inheritance from interface language to ensure content // language will fall back to the default language if no URL language can be // detected. $edit = array('language_interface[enabled][language-user]' => TRUE, 'language_content[enabled][language-url]' => TRUE, 'language_content[enabled][language-interface]' => FALSE); $this->drupalPostForm('admin/config/regional/language/detection', $edit, t('Save settings')); // Change user language preference, this way interface language is always // French no matter what path prefix the URLs have. $edit = array('preferred_langcode' => 'fr'); $this->drupalPostForm("user/" . $admin_user->id() . "/edit", $edit, t('Save')); // Create comment field on article. $this->container->get('comment.manager')->addDefaultField('node', 'article'); // Make comment body translatable. $field_storage = FieldStorageConfig::loadByName('comment', 'comment_body'); $field_storage->translatable = TRUE; $field_storage->save(); $this->assertTrue($field_storage->isTranslatable(), 'Comment body is translatable.'); }
/** * Confirm the config defaults show on the translations page. */ public function testConfigTranslationsExist() { // Ensure the config shows on the admin form. $this->drupalGet('admin/config/regional/config-translation'); $this->assertResponse(200); $this->assertText(t('Metatag defaults')); // Load the main metatag_defaults config translation page. $this->drupalGet('admin/config/regional/config-translation/metatag_defaults'); $this->assertResponse(200); // @todo Update this to confirm the H1 is loaded. $this->assertRaw(t('Metatag defaults')); // Load all of the Metatag defaults. $defaults = \Drupal::configFactory()->listAll('metatag.metatag_defaults'); /** @var \Drupal\Core\Config\ConfigManagerInterface $config_manager */ $config_manager = \Drupal::service('config.manager'); // Confirm each of the configs is available on the translation form. foreach ($defaults as $config_name) { if ($config_entity = $config_manager->loadConfigEntityByName($config_name)) { $this->assertText($config_entity->label()); } } // Confirm that each config translation page can be loaded. foreach ($defaults as $config_name) { if ($config_entity = $config_manager->loadConfigEntityByName($config_name)) { $this->drupalGet('admin/config/search/metatag/' . $config_entity->id() . '/translate'); $this->assertResponse(200); } else { $this->error('Unable to load a Metatag default config: ' . $config_name); } } }
/** * Tests that files in different directories take precedence as expected. */ function testDirectoryPrecedence() { // Define the module files we will search for, and the directory precedence // we expect. $expected_directories = array('drupal_system_listing_compatible_test' => array('core/profiles/testing/modules', 'core/modules/system/tests/modules')); // This test relies on two versions of the same module existing in // different places in the filesystem. Without that, the test has no // meaning, so assert their presence first. foreach ($expected_directories as $module => $directories) { foreach ($directories as $directory) { $filename = "{$directory}/{$module}/{$module}.info.yml"; $this->assertTrue(file_exists(\Drupal::root() . '/' . $filename), format_string('@filename exists.', array('@filename' => $filename))); } } // Now scan the directories and check that the files take precedence as // expected. $listing = new ExtensionDiscovery(\Drupal::root()); $listing->setProfileDirectories(array('core/profiles/testing')); $files = $listing->scan('module'); foreach ($expected_directories as $module => $directories) { $expected_directory = array_shift($directories); $expected_uri = "{$expected_directory}/{$module}/{$module}.info.yml"; $this->assertEqual($files[$module]->getPathname(), $expected_uri, format_string('Module @actual was found at @expected.', array('@actual' => $files[$module]->getPathname(), '@expected' => $expected_uri))); } }
/** * Tests migration of syslog variables to syslog.settings.yml. */ public function testSyslogSettings() { $config = $this->config('syslog.settings'); $this->assertIdentical('drupal', $config->get('identity')); $this->assertIdentical('128', $config->get('facility')); $this->assertConfigSchema(\Drupal::service('config.typed'), 'syslog.settings', $config->get()); }
/** * Test the WYSIWYG embed modal. */ public function testEmbedDialog() { // Use the modal to embed into a page. $this->drupalGet('node/add/page'); $this->find('.cke_button__video_embed')->click(); $this->assertSession()->assertWaitOnAjaxRequest(); // Assert all the form fields appear on the modal. $this->assertSession()->pageTextContains('Autoplay'); $this->assertSession()->pageTextContains('Responsive Video'); $this->assertSession()->pageTextContains('Width'); $this->assertSession()->pageTextContains('Height'); $this->assertSession()->pageTextContains('Video URL'); // Attempt to submit the modal with no values. $this->find('input[name="video_url"]')->setValue(''); $this->find('button.form-submit')->click(); $this->assertSession()->assertWaitOnAjaxRequest(); $this->assertSession()->pageTextContains('Video URL field is required.'); // Submit the form with an invalid video URL. $this->find('input[name="video_url"]')->setValue('http://example.com/'); $this->find('button.form-submit')->click(); $this->assertSession()->assertWaitOnAjaxRequest(); $this->assertSession()->pageTextContains('Could not find a video provider to handle the given URL.'); $this->assertContains('http://example.com/', $this->getSession()->getPage()->getHtml()); // Submit a valid URL. $this->find('input[name="video_url"]')->setValue('https://www.youtube.com/watch?v=iaf3Sl2r3jE&t=1553s'); $this->find('button.form-submit')->click(); $this->assertSession()->assertWaitOnAjaxRequest(); // View the source of the ckeditor and find the output. $this->find('.cke_button__source_label')->click(); $base_path = \Drupal::request()->getBasePath(); $this->assertEquals('<p>{"preview_thumbnail":"' . rtrim($base_path, '/') . '/' . $this->publicFilesDirectory . '/styles/video_embed_wysiwyg_preview/public/video_thumbnails/iaf3Sl2r3jE.jpg","video_url":"https://www.youtube.com/watch?v=iaf3Sl2r3jE&t=1553s","settings":{"responsive":1,"width":"854","height":"480","autoplay":1},"settings_summary":["Embedded Video (Responsive, autoplaying)."]}</p>', trim($this->getSession()->getPage()->find('css', '.cke_source')->getValue())); }
/** * Submits forms with select and checkbox elements via Ajax. */ function testSimpleAjaxFormValue() { // Verify form values of a select element. foreach (array('red', 'green', 'blue') as $item) { $edit = array('select' => $item); $commands = $this->drupalPostAjaxForm('ajax_forms_test_get_form', $edit, 'select'); $expected = new DataCommand('#ajax_selected_color', 'form_state_value_select', $item); $this->assertCommand($commands, $expected->render(), 'Verification of AJAX form values from a selectbox issued with a correct value.'); } // Verify form values of a checkbox element. foreach (array(FALSE, TRUE) as $item) { $edit = array('checkbox' => $item); $commands = $this->drupalPostAjaxForm('ajax_forms_test_get_form', $edit, 'checkbox'); $expected = new DataCommand('#ajax_checkbox_value', 'form_state_value_select', (int) $item); $this->assertCommand($commands, $expected->render(), 'Verification of AJAX form values from a checkbox issued with a correct value.'); } // Verify that AJAX elements with invalid callbacks return error code 500. // Ensure the test error log is empty before these tests. $this->assertNoErrorsLogged(); // We don't need to check for the X-Drupal-Ajax-Token header with these // invalid requests. $this->assertAjaxHeader = FALSE; foreach (array('null', 'empty', 'nonexistent') as $key) { $element_name = 'select_' . $key . '_callback'; $edit = array($element_name => 'red'); $commands = $this->drupalPostAjaxForm('ajax_forms_test_get_form', $edit, $element_name); $this->assertResponse(500); } // Switch this back to the default. $this->assertAjaxHeader = TRUE; // The exceptions are expected. Do not interpret them as a test failure. // Not using File API; a potential error must trigger a PHP warning. unlink(\Drupal::root() . '/' . $this->siteDirectory . '/error.log'); }
/** * Encapsulates the creation of the action's LazyPluginCollection. * * @return \Drupal\Component\Plugin\LazyPluginCollection * The action's plugin collection. */ protected function getPluginCollection() { if (!$this->pluginCollection) { $this->pluginCollection = new ActionPluginCollection(\Drupal::service('plugin.manager.action'), $this->plugin, $this->configuration); } return $this->pluginCollection; }
/** * Tests the Drupal 6 term-node revision association to Drupal 8 migration. */ public function testTermRevisionNode() { $node = \Drupal::entityManager()->getStorage('node')->loadRevision(2); $this->assertIdentical(2, count($node->vocabulary_3_i_2_)); $this->assertIdentical('4', $node->vocabulary_3_i_2_[0]->target_id); $this->assertIdentical('5', $node->vocabulary_3_i_2_[1]->target_id); }
/** * {@inheritdoc} */ public function getConstraints() { $constraint_manager = \Drupal::typedDataManager()->getValidationConstraintManager(); $constraints = parent::getConstraints(); $constraints[] = $constraint_manager->create('ComplexData', array('value' => array('Regex' => array('pattern' => '/^[+-]?((\\d+(\\.\\d*)?)|(\\.\\d+))$/i')))); return $constraints; }
/** * {@inheritdoc} */ public function setUp() { parent::setUp(); $cache_contexts_manager = $this->prophesize(CacheContextsManager::class); $cache_contexts_manager->assertValidTokens()->willReturn(TRUE); $cache_contexts_manager->reveal(); $container = new Container(); $container->set('cache_contexts_manager', $cache_contexts_manager); \Drupal::setContainer($container); $this->viewer = $this->getMock('\\Drupal\\Core\\Session\\AccountInterface'); $this->viewer->expects($this->any())->method('hasPermission')->will($this->returnValue(FALSE)); $this->viewer->expects($this->any())->method('id')->will($this->returnValue(1)); $this->owner = $this->getMock('\\Drupal\\Core\\Session\\AccountInterface'); $this->owner->expects($this->any())->method('hasPermission')->will($this->returnValueMap(array(array('administer users', FALSE), array('change own username', TRUE)))); $this->owner->expects($this->any())->method('id')->will($this->returnValue(2)); $this->admin = $this->getMock('\\Drupal\\Core\\Session\\AccountInterface'); $this->admin->expects($this->any())->method('hasPermission')->will($this->returnValue(TRUE)); $entity_type = $this->getMock('Drupal\\Core\\Entity\\EntityTypeInterface'); $this->accessControlHandler = new UserAccessControlHandler($entity_type); $module_handler = $this->getMock('Drupal\\Core\\Extension\\ModuleHandlerInterface'); $module_handler->expects($this->any())->method('getImplementations')->will($this->returnValue(array())); $this->accessControlHandler->setModuleHandler($module_handler); $this->items = $this->getMockBuilder('Drupal\\Core\\Field\\FieldItemList')->disableOriginalConstructor()->getMock(); $this->items->expects($this->any())->method('defaultAccess')->will($this->returnValue(AccessResult::allowed())); }
/** * Delete a group. */ function testDeleteGroup() { $data = array('format_type' => 'fieldset', 'label' => 'testing'); $group = $this->createGroup('node', $this->type, 'form', 'default', $data); $config_name = 'node.' . $this->type . '.form.default.' . $group->group_name; $this->drupalPostForm('admin/structure/types/manage/' . $this->type . '/groups/' . $config_name . '/delete', array(), t('Delete')); $this->assertRaw(t('The group %label has been deleted from the %type content type.', array('%label' => $group->label, '%type' => $this->type)), t('Group removal message displayed on screen.')); $display = EntityFormDisplay::load($group->entity_type . '.' . $group->bundle . '.' . $group->mode); $data = $display->getThirdPartySettings('field_group'); debug($data); // Test that group is not in the $groups array. \Drupal::entityManager()->getStorage('entity_form_display')->resetCache(); $loaded_group = field_group_load_field_group($group->group_name, 'node', $this->type, 'form', 'default'); debug($loaded_group); $this->assertNull($loaded_group, t('Group not found after deleting')); $data = array('format_type' => 'fieldset', 'label' => 'testing'); $group = $this->createGroup('node', $this->type, 'view', 'default', $data); $config_name = 'node.' . $this->type . '.view.default.' . $group->group_name; $this->drupalPostForm('admin/structure/types/manage/' . $this->type . '/groups/' . $config_name . '/delete', array(), t('Delete')); $this->assertRaw(t('The group %label has been deleted from the %type content type.', array('%label' => $group->label, '%type' => $this->type)), t('Group removal message displayed on screen.')); // Test that group is not in the $groups array. \Drupal::entityManager()->getStorage('entity_view_display')->resetCache(); $loaded_group = field_group_load_field_group($group->group_name, 'node', $this->type, 'view', 'default'); debug($loaded_group); $this->assertNull($loaded_group, t('Group not found after deleting')); }
/** * {@inheritdoc} */ public function getConstraints() { $manager = \Drupal::typedDataManager()->getValidationConstraintManager(); $constraints = parent::getConstraints(); $constraints[] = $manager->create('ComplexData', ['amount' => ['Regex' => ['pattern' => '/^[+-]?((\\d+(\\.\\d*)?)|(\\.\\d+))$/i']]]); return $constraints; }
/** * Check that the directory can be used for backup. * * @throws \BackupMigrate\Core\Exception\BackupMigrateException */ protected function checkDirectory() { // @TODO: Figure out if the file is or might be accessible via the web. $dir = $this->confGet('directory'); $is_private = strpos($dir, 'private://') === 0; // Attempt to create/prepare the directory if it is in the private directory if ($is_private) { if (!file_prepare_directory($dir, FILE_CREATE_DIRECTORY && FILE_MODIFY_PERMISSIONS)) { throw new BackupMigrateException("The backup file could not be saved to '%dir' because the directory could not be created or cannot be written to. Please make sure your private files directory is writable by the web server.", ['%dir' => $dir]); } } else { // If the file is local to the server. $real = \Drupal::service('file_system')->realpath($dir); if ($real) { // If the file is within the docroot. $in_root = strpos($real, DRUPAL_ROOT) === 0; if ($in_root && !$is_private) { throw new BackupMigrateException("The backup file could not be saved to '%dir' because that directory may be publicly accessible via the web. Please save your backups to the private file directory or a directory outside of the web root.", ['%dir' => $dir]); } } } // Do the regular exists/writable checks parent::checkDirectory(); // @TODO: Warn if the realpath cannot be resolved (because we cannot determine if the file is publicly accessible) }
/** * {@inheritdoc} */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); $form['grid_style'] = array('#prefix' => '<h4>Grid Settings</h4>', '#type' => 'select', '#title' => t('Mode'), '#description' => t('Choose grid style:'), '#options' => array('classic' => t('Classic Grid'), 'masonry' => t('Masonry Simple'), 'masonry_resize' => t('Masonry Resize')), '#default_value' => $this->options['grid_style'], '#attributes' => array('class' => array('grid-style'))); $field_options = array(); $fields = \Drupal::entityManager()->getFieldMapByFieldType('image'); foreach ($fields as $field) { foreach ($field as $key => $value) { $field_options[$key] = $key; } } $form['masonry_background'] = array('#type' => 'select', '#title' => t('Image'), '#options' => $field_options, '#default_value' => $this->options['masonry_background'], '#states' => array('visible' => array('.grid-style' => array('value' => 'masonry_resize')))); $form['grid_ratio'] = array('#type' => 'textfield', '#title' => t('Ratio'), '#description' => t('The ratio image'), '#default_value' => $this->options['grid_ratio'], '#states' => array('visible' => array('.grid-style' => array('value' => 'masonry_resize')))); $form['grid_cols_lg'] = array('#type' => 'select', '#title' => t('Large Desktop Items'), '#description' => t('Number of items on large desktop'), '#options' => array(1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5, 6 => 6, 7 => 7, 8 => 8, 9 => 9, 10 => 10, 11 => 11, 12 => 12), '#default_value' => $this->options['grid_cols_lg']); $form['grid_cols_md'] = array('#type' => 'select', '#title' => t('Desktop Items'), '#description' => t('Number of items on desktop'), '#options' => array(1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5, 6 => 6, 7 => 7, 8 => 8, 9 => 9, 10 => 10, 11 => 11, 12 => 12), '#default_value' => $this->options['grid_cols_md']); $form['grid_cols_sm'] = array('#type' => 'select', '#title' => t('Tablet Items'), '#description' => t('Number of items on tablet'), '#options' => array(1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5, 6 => 6, 7 => 7, 8 => 8, 9 => 9, 10 => 10, 11 => 11, 12 => 12), '#default_value' => $this->options['grid_cols_sm']); $form['grid_cols_xs'] = array('#type' => 'select', '#title' => t('Phone Items'), '#description' => t('Number of items on phone'), '#options' => array(1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5, 6 => 6, 7 => 7, 8 => 8, 9 => 9, 10 => 10, 11 => 11, 12 => 12), '#default_value' => $this->options['grid_cols_xs']); $form['grid_margin'] = array('#type' => 'textfield', '#title' => t('Margin'), '#description' => t('The spacing beetween items'), '#default_value' => $this->options['grid_margin'], '#field_suffix' => 'px'); $form['grid_filter'] = array('#type' => 'select', '#title' => t('Use Filter'), '#options' => array(0 => t('No'), 1 => t('Yes')), '#description' => t('Filter items by taxonomy term'), '#default_value' => $this->options['grid_filter'], '#attributes' => array('class' => array('grid-filter-option'))); $categories = array(); $categories['select'] = t('Select'); foreach (Vocabulary::loadMultiple() as $vocabulary) { $categories[$vocabulary->id()] = $vocabulary->get('name'); } $form['grid_filter_vocabulary'] = array('#type' => 'select', '#title' => t('Filter Vocabulary'), '#options' => $categories, '#description' => t('Which taxonomy vocabulary do you want to use for the filter'), '#default_value' => $this->options['grid_filter_vocabulary'], '#states' => array('visible' => array('.grid-filter-option' => array('value' => 1)))); }
/** * Gets the logger for a specific channel. * * @param string $channel * The name of the channel. Can be any string, but the general practice is * to use the name of the subsystem calling this. * * @return \Psr\Log\LoggerInterface * The logger for the given channel. * * @todo Require the use of injected services: * https://www.drupal.org/node/2733703 */ protected function getLogger($channel) { if (!$this->loggerFactory) { $this->loggerFactory = \Drupal::service('logger.factory'); } return $this->loggerFactory->get($channel); }
/** * Tests the missing content event is fired. * * @see \Drupal\Core\Config\ConfigImporter::processMissingContent() * @see \Drupal\config_import_test\EventSubscriber */ function testMissingContent() { \Drupal::state()->set('config_import_test.config_import_missing_content', TRUE); // Update a configuration entity in the sync directory to have a dependency // on two content entities that do not exist. $storage = $this->container->get('config.storage'); $sync = $this->container->get('config.storage.sync'); $entity_one = entity_create('entity_test', array('name' => 'one')); $entity_two = entity_create('entity_test', array('name' => 'two')); $entity_three = entity_create('entity_test', array('name' => 'three')); $dynamic_name = 'config_test.dynamic.dotted.default'; $original_dynamic_data = $storage->read($dynamic_name); // Entity one will be resolved by // \Drupal\config_import_test\EventSubscriber::onConfigImporterMissingContentOne(). $original_dynamic_data['dependencies']['content'][] = $entity_one->getConfigDependencyName(); // Entity two will be resolved by // \Drupal\config_import_test\EventSubscriber::onConfigImporterMissingContentTwo(). $original_dynamic_data['dependencies']['content'][] = $entity_two->getConfigDependencyName(); // Entity three will be resolved by // \Drupal\Core\Config\Importer\FinalMissingContentSubscriber. $original_dynamic_data['dependencies']['content'][] = $entity_three->getConfigDependencyName(); $sync->write($dynamic_name, $original_dynamic_data); // Import. $this->configImporter->reset()->import(); $this->assertEqual([], $this->configImporter->getErrors(), 'There were no errors during the import.'); $this->assertEqual($entity_one->uuid(), \Drupal::state()->get('config_import_test.config_import_missing_content_one'), 'The missing content event is fired during configuration import.'); $this->assertEqual($entity_two->uuid(), \Drupal::state()->get('config_import_test.config_import_missing_content_two'), 'The missing content event is fired during configuration import.'); $original_dynamic_data = $storage->read($dynamic_name); $this->assertEqual([$entity_one->getConfigDependencyName(), $entity_two->getConfigDependencyName(), $entity_three->getConfigDependencyName()], $original_dynamic_data['dependencies']['content'], 'The imported configuration entity has the missing content entity dependency.'); }
/** * Gets the current active user. * * @todo: https://drupal.org/node/2105123 put this method in * \Drupal\Core\Plugin\PluginBase instead. * * @return \Drupal\Core\Session\AccountInterface */ protected function currentUser() { if (!$this->currentUser) { $this->currentUser = \Drupal::currentUser(); } return $this->currentUser; }
protected function setUp() { parent::setUp(); node_access_test_add_field(NodeType::load('article')); node_access_rebuild(); \Drupal::state()->set('node_access_test.private', TRUE); }
/** * {@inheritdoc} */ public static function getSubscribedEvents() { // Register this listener for every event that is used by a reaction rule. $events = []; $callback = ['onRulesEvent', 100]; // If there is no state service there is nothing we can do here. This static // method could be called early when the container is built, so the state // service might no always be available. if (!\Drupal::hasService('state')) { return []; } // Since we cannot access the reaction rule config storage here we have to // use the state system to provide registered Rules events. The Reaction // Rule storage is responsible for keeping the registered events up to date // in the state system. // @see \Drupal\rules\Entity\ReactionRuleStorage $state = \Drupal::state(); $registered_event_names = $state->get('rules.registered_events'); if (!empty($registered_event_names)) { foreach ($registered_event_names as $event_name) { $events[$event_name][] = $callback; } } return $events; }
/** * Assert translations JS is added before drupal.js, because it depends on it. */ public function testLocaleTranslationJsDependencies() { // User to add and remove language. $admin_user = $this->drupalCreateUser(array('administer languages', 'access administration pages', 'translate interface')); // Add custom language. $this->drupalLogin($admin_user); // Code for the language. $langcode = 'es'; // The English name for the language. $name = $this->randomMachineName(16); // The domain prefix. $prefix = $langcode; $edit = array('predefined_langcode' => 'custom', 'langcode' => $langcode, 'label' => $name, 'direction' => LanguageInterface::DIRECTION_LTR); $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language')); // Set path prefix. $edit = array("prefix[{$langcode}]" => $prefix); $this->drupalPostForm('admin/config/regional/language/detection/url', $edit, t('Save configuration')); // This forces locale.admin.js string sources to be imported, which contains // the next translation. $this->drupalGet($prefix . '/admin/config/regional/translate'); // Translate a string in locale.admin.js to our new language. $strings = \Drupal::service('locale.storage')->getStrings(array('source' => 'Show description', 'type' => 'javascript', 'name' => 'core/modules/locale/locale.admin.js')); $string = $strings[0]; $this->drupalPostForm(NULL, ['string' => 'Show description'], t('Filter')); $edit = ['strings[' . $string->lid . '][translations][0]' => $this->randomString(16)]; $this->drupalPostForm(NULL, $edit, t('Save translations')); // Calculate the filename of the JS including the translations. $js_translation_files = \Drupal::state()->get('locale.translation.javascript'); $js_filename = $prefix . '_' . $js_translation_files[$prefix] . '.js'; // Assert translations JS is included before drupal.js. $this->assertTrue(strpos($this->content, $js_filename) < strpos($this->content, 'core/misc/drupal.js'), 'Translations are included before Drupal.t.'); }
/** * {@inheritdoc} * * The file name for the CSS or JS cache file is generated from the hash of * the aggregated contents of the files in $data. This forces proxies and * browsers to download new CSS when the CSS changes. */ public function dump($data, $file_extension) { // Prefix filename to prevent blocking by firewalls which reject files // starting with "ad*". $filename = $file_extension . '_' . Crypt::hashBase64($data) . '.' . $file_extension; // Create the css/ or js/ path within the files folder. $path = 'public://' . $file_extension; $uri = $path . '/' . $filename; // Create the CSS or JS file. file_prepare_directory($path, FILE_CREATE_DIRECTORY); if (!file_exists($uri) && !file_unmanaged_save_data($data, $uri, FILE_EXISTS_REPLACE)) { return FALSE; } // If CSS/JS gzip compression is enabled and the zlib extension is available // then create a gzipped version of this file. This file is served // conditionally to browsers that accept gzip using .htaccess rules. // It's possible that the rewrite rules in .htaccess aren't working on this // server, but there's no harm (other than the time spent generating the // file) in generating the file anyway. Sites on servers where rewrite rules // aren't working can set css.gzip to FALSE in order to skip // generating a file that won't be used. if (extension_loaded('zlib') && \Drupal::config('system.performance')->get($file_extension . '.gzip')) { if (!file_exists($uri . '.gz') && !file_unmanaged_save_data(gzencode($data, 9, FORCE_GZIP), $uri . '.gz', FILE_EXISTS_REPLACE)) { return FALSE; } } return $uri; }
/** * {@inheritdoc} */ public function isInstalled() { // Check if the module exists in the file system, regardless of whether it // is enabled or not. $modules = \Drupal::state()->get('system.module.files', array()); return isset($modules[$this->name]); }
/** * Tests the path cache. */ function testPathCache() { // Create test node. $node1 = $this->drupalCreateNode(); // Create alias. $edit = array(); $edit['source'] = '/node/' . $node1->id(); $edit['alias'] = '/' . $this->randomMachineName(8); $this->drupalPostForm('admin/config/search/path/add', $edit, t('Save')); // Check the path alias whitelist cache. $whitelist = \Drupal::cache()->get('path_alias_whitelist'); $this->assertTrue($whitelist->data['node']); $this->assertFalse($whitelist->data['admin']); // Visit the system path for the node and confirm a cache entry is // created. \Drupal::cache('data')->deleteAll(); // Make sure the path is not converted to the alias. $this->drupalGet(trim($edit['source'], '/'), array('alias' => TRUE)); $this->assertTrue(\Drupal::cache('data')->get('preload-paths:' . $edit['source']), 'Cache entry was created.'); // Visit the alias for the node and confirm a cache entry is created. \Drupal::cache('data')->deleteAll(); // @todo Remove this once https://www.drupal.org/node/2480077 lands. Cache::invalidateTags(['rendered']); $this->drupalGet(trim($edit['alias'], '/')); $this->assertTrue(\Drupal::cache('data')->get('preload-paths:' . $edit['source']), 'Cache entry was created.'); }
/** * {@inheritdoc} */ public function getConstraints() { $constraint_manager = \Drupal::typedDataManager()->getValidationConstraintManager(); $constraints = parent::getConstraints(); $constraints[] = $constraint_manager->create('ComplexData', array('value' => array('TestField' => array('value' => -1, 'message' => t('%name does not accept the value @value.', array('%name' => $this->getFieldDefinition()->getLabel(), '@value' => -1)))))); return $constraints; }
/** * Tests the "popular content" block. */ function testPopularContentBlock() { // Clear the block cache to load the Statistics module's block definitions. $this->container->get('plugin.manager.block')->clearCachedDefinitions(); // Visit a node to have something show up in the block. $node = $this->drupalCreateNode(array('type' => 'page', 'uid' => $this->blockingUser->id())); $this->drupalGet('node/' . $node->id()); // Manually calling statistics.php, simulating ajax behavior. $nid = $node->id(); $post = http_build_query(array('nid' => $nid)); $headers = array('Content-Type' => 'application/x-www-form-urlencoded'); global $base_url; $stats_path = $base_url . '/' . drupal_get_path('module', 'statistics') . '/statistics.php'; $client = \Drupal::service('http_client_factory')->fromOptions(['config/curl' => [CURLOPT_TIMEOUT => 10]]); $client->post($stats_path, array('headers' => $headers, 'body' => $post)); // Configure and save the block. $this->drupalPlaceBlock('statistics_popular_block', array('label' => 'Popular content', 'top_day_num' => 3, 'top_all_num' => 3, 'top_last_num' => 3)); // Get some page and check if the block is displayed. $this->drupalGet('user'); $this->assertText('Popular content', 'Found the popular content block.'); $this->assertText("Today's", "Found today's popular content."); $this->assertText('All time', 'Found the all time popular content.'); $this->assertText('Last viewed', 'Found the last viewed popular content.'); // statistics.module doesn't use node entities, prevent the node language // from being added to the options. $this->assertRaw(\Drupal::l($node->label(), $node->urlInfo('canonical', ['language' => NULL])), 'Found link to visited node.'); }
protected function setUp() { parent::setUp(); // Create Basic page node type. $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page')); $vocabulary = entity_create('taxonomy_vocabulary', array('name' => $this->randomMachineName(), 'description' => $this->randomMachineName(), 'vid' => Unicode::strtolower($this->randomMachineName()), 'langcode' => LanguageInterface::LANGCODE_NOT_SPECIFIED, 'help' => '', 'nodes' => array('page' => 'page'), 'weight' => mt_rand(0, 10))); $vocabulary->save(); // Create a field. $field_name = Unicode::strtolower($this->randomMachineName()); $handler_settings = array('target_bundles' => array($vocabulary->id() => $vocabulary->id()), 'auto_create' => TRUE); $this->createEntityReferenceField('node', 'page', $field_name, NULL, 'taxonomy_term', 'default', $handler_settings, FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); // Create a time in the past for the archive. $time = REQUEST_TIME - 3600; $this->addDefaultCommentField('node', 'page'); for ($i = 0; $i <= 10; $i++) { $user = $this->drupalCreateUser(); $term = $this->createTerm($vocabulary); $values = array('created' => $time, 'type' => 'page'); $values[$field_name][]['target_id'] = $term->id(); // Make every other node promoted. if ($i % 2) { $values['promote'] = TRUE; } $values['body'][]['value'] = \Drupal::l('Node ' . 1, new Url('entity.node.canonical', ['node' => 1])); $node = $this->drupalCreateNode($values); $comment = array('uid' => $user->id(), 'status' => CommentInterface::PUBLISHED, 'entity_id' => $node->id(), 'entity_type' => 'node', 'field_name' => 'comment'); entity_create('comment', $comment)->save(); } // Some views, such as the "Who's Online" view, only return results if at // least one user is logged in. $account = $this->drupalCreateUser(array()); $this->drupalLogin($account); }