/**
  * Overrides WebTestBase::setUp().
  */
 protected function setUp()
 {
     $this->isInstalled = FALSE;
     // Define information about the user 1 account.
     $this->root_user = new UserSession(array('uid' => 1, 'name' => 'admin', 'mail' => '*****@*****.**', 'pass_raw' => $this->randomMachineName()));
     // If any $settings are defined for this test, copy and prepare an actual
     // settings.php, so as to resemble a regular installation.
     if (!empty($this->settings)) {
         // Not using File API; a potential error must trigger a PHP warning.
         copy(DRUPAL_ROOT . '/sites/default/default.settings.php', DRUPAL_ROOT . '/' . $this->siteDirectory . '/settings.php');
         $this->writeSettings($this->settings);
     }
     // Note that WebTestBase::installParameters() returns form input values
     // suitable for a programmed drupal_form_submit().
     // @see WebTestBase::translatePostValues()
     $this->parameters = $this->installParameters();
     // Set up a minimal container (required by WebTestBase).
     // @see install_begin_request()
     $request = Request::create($GLOBALS['base_url'] . '/core/install.php');
     $this->container = new ContainerBuilder();
     $request_stack = new RequestStack();
     $request_stack->push($request);
     $this->container->set('request_stack', $request_stack);
     $this->container->setParameter('language.default_values', Language::$defaultValues);
     $this->container->register('language.default', 'Drupal\\Core\\Language\\LanguageDefault')->addArgument('%language.default_values%');
     $this->container->register('language_manager', 'Drupal\\Core\\Language\\LanguageManager')->addArgument(new Reference('language.default'));
     $this->container->register('string_translation', 'Drupal\\Core\\StringTranslation\\TranslationManager')->addArgument(new Reference('language_manager'));
     \Drupal::setContainer($this->container);
     $this->drupalGet($GLOBALS['base_url'] . '/core/install.php');
     // Select language.
     $this->setUpLanguage();
     // Select profile.
     $this->setUpProfile();
     // Configure settings.
     $this->setUpSettings();
     // @todo Allow test classes based on this class to act on further installer
     //   screens.
     // Configure site.
     $this->setUpSite();
     // Import new settings.php written by the installer.
     $request = Request::createFromGlobals();
     $class_loader = (require DRUPAL_ROOT . '/core/vendor/autoload.php');
     Settings::initialize(DrupalKernel::findSitePath($request), $class_loader);
     foreach ($GLOBALS['config_directories'] as $type => $path) {
         $this->configDirectories[$type] = $path;
     }
     // After writing settings.php, the installer removes write permissions
     // from the site directory. To allow drupal_generate_test_ua() to write
     // a file containing the private key for drupal_valid_test_ua(), the site
     // directory has to be writable.
     // WebTestBase::tearDown() will delete the entire test site directory.
     // Not using File API; a potential error must trigger a PHP warning.
     chmod(DRUPAL_ROOT . '/' . $this->siteDirectory, 0777);
     $this->kernel = DrupalKernel::createFromRequest($request, $class_loader, 'prod', FALSE);
     $this->kernel->prepareLegacyRequest($request);
     $this->container = $this->kernel->getContainer();
     $config = $this->container->get('config.factory');
     // Manually configure the test mail collector implementation to prevent
     // tests from sending out e-mails and collect them in state instead.
     $config->get('system.mail')->set('interface.default', 'test_mail_collector')->save();
     // When running from run-tests.sh we don't get an empty current path which
     // would indicate we're on the home page.
     $path = current_path();
     if (empty($path)) {
         _current_path('run-tests');
     }
     $this->isInstalled = TRUE;
 }
Example #2
0
 public function renderPreview($display_id, $args = array())
 {
     // Save the current path so it can be restored before returning from this function.
     $old_q = current_path();
     // Determine where the query and performance statistics should be output.
     $config = \Drupal::config('views.settings');
     $show_query = $config->get('ui.show.sql_query.enabled');
     $show_info = $config->get('ui.show.preview_information');
     $show_location = $config->get('ui.show.sql_query.where');
     $show_stats = $config->get('ui.show.performance_statistics');
     if ($show_stats) {
         $show_stats = $config->get('ui.show.sql_query.where');
     }
     $combined = $show_query && $show_stats;
     $rows = array('query' => array(), 'statistics' => array());
     $output = '';
     $errors = $this->executable->validate();
     $this->executable->destroy();
     if (empty($errors)) {
         $this->ajax = TRUE;
         $this->executable->live_preview = TRUE;
         // AJAX happens via HTTP POST but everything expects exposed data to
         // be in GET. Copy stuff but remove ajax-framework specific keys.
         // If we're clicking on links in a preview, though, we could actually
         // have some input in the query parameters, so we merge request() and
         // query() to ensure we get it all.
         $exposed_input = array_merge(\Drupal::request()->request->all(), \Drupal::request()->query->all());
         foreach (array('view_name', 'view_display_id', 'view_args', 'view_path', 'view_dom_id', 'pager_element', 'view_base_path', 'ajax_html_ids', 'ajax_page_state', 'form_id', 'form_build_id', 'form_token') as $key) {
             if (isset($exposed_input[$key])) {
                 unset($exposed_input[$key]);
             }
         }
         $this->executable->setExposedInput($exposed_input);
         if (!$this->executable->setDisplay($display_id)) {
             return t('Invalid display id @display', array('@display' => $display_id));
         }
         $this->executable->setArguments($args);
         // Store the current view URL for later use:
         if ($this->executable->display_handler->getOption('path')) {
             $path = $this->executable->getUrl();
         }
         // Make view links come back to preview.
         $this->override_path = 'admin/structure/views/view/' . $this->id() . '/preview/' . $display_id;
         // Also override the current path so we get the pager.
         $original_path = current_path();
         $q = _current_path($this->override_path);
         if ($args) {
             $q .= '/' . implode('/', $args);
             _current_path($q);
         }
         // Suppress contextual links of entities within the result set during a
         // Preview.
         // @todo We'll want to add contextual links specific to editing the View, so
         //   the suppression may need to be moved deeper into the Preview pipeline.
         views_ui_contextual_links_suppress_push();
         $show_additional_queries = $config->get('ui.show.additional_queries');
         Timer::start('entity.view.preview_form');
         if ($show_additional_queries) {
             $this->startQueryCapture();
         }
         // Execute/get the view preview.
         $preview = $this->executable->preview($display_id, $args);
         $preview = drupal_render($preview);
         if ($show_additional_queries) {
             $this->endQueryCapture();
         }
         $this->render_time = Timer::stop('entity.view.preview_form');
         views_ui_contextual_links_suppress_pop();
         // Reset variables.
         unset($this->override_path);
         _current_path($original_path);
         // Prepare the query information and statistics to show either above or
         // below the view preview.
         if ($show_info || $show_query || $show_stats) {
             // Get information from the preview for display.
             if (!empty($this->executable->build_info['query'])) {
                 if ($show_query) {
                     $query_string = $this->executable->build_info['query'];
                     // Only the sql default class has a method getArguments.
                     $quoted = array();
                     if ($this->executable->query instanceof Sql) {
                         $quoted = $query_string->getArguments();
                         $connection = Database::getConnection();
                         foreach ($quoted as $key => $val) {
                             if (is_array($val)) {
                                 $quoted[$key] = implode(', ', array_map(array($connection, 'quote'), $val));
                             } else {
                                 $quoted[$key] = $connection->quote($val);
                             }
                         }
                     }
                     $rows['query'][] = array(array('data' => array('#type' => 'inline_template', '#template' => "<strong>{% trans 'Query' %}</strong>")), array('data' => array('#type' => 'inline_template', '#template' => '<pre>{{ query }}</pre>', '#context' => array('query' => strtr($query_string, $quoted)))));
                     if (!empty($this->additionalQueries)) {
                         $queries = '<strong>' . t('These queries were run during view rendering:') . '</strong>';
                         foreach ($this->additionalQueries as $query) {
                             if ($queries) {
                                 $queries .= "\n";
                             }
                             $query_string = strtr($query['query'], $query['args']);
                             $queries .= t('[@time ms] @query', array('@time' => round($query['time'] * 100000, 1) / 100000.0, '@query' => $query_string));
                         }
                         $rows['query'][] = array(array('data' => array('#type' => 'inline_template', '#template' => "<strong>{% trans 'Other queries' %}</strong>")), SafeMarkup::set('<pre>' . $queries . '</pre>'));
                     }
                 }
                 if ($show_info) {
                     $rows['query'][] = array(array('data' => array('#type' => 'inline_template', '#template' => "<strong>{% trans 'Title' %}</strong>")), Xss::filterAdmin($this->executable->getTitle()));
                     if (isset($path)) {
                         $path = _l($path, $path);
                     } else {
                         $path = t('This display has no path.');
                     }
                     $rows['query'][] = array(SafeMarkup::set('<strong>' . t('Path') . '</strong>'), $path);
                 }
                 if ($show_stats) {
                     $rows['statistics'][] = array('<strong>' . t('Query build time') . '</strong>', t('@time ms', array('@time' => intval($this->executable->build_time * 100000) / 100)));
                     $rows['statistics'][] = array('<strong>' . t('Query execute time') . '</strong>', t('@time ms', array('@time' => intval($this->executable->execute_time * 100000) / 100)));
                     $rows['statistics'][] = array('<strong>' . t('View render time') . '</strong>', t('@time ms', array('@time' => intval($this->executable->render_time * 100000) / 100)));
                 }
                 \Drupal::moduleHandler()->alter('views_preview_info', $rows, $this->executable);
             } else {
                 // No query was run. Display that information in place of either the
                 // query or the performance statistics, whichever comes first.
                 if ($combined || $show_location === 'above') {
                     $rows['query'] = array(array(SafeMarkup::set('<strong>' . t('Query') . '</strong>'), t('No query was run')));
                 } else {
                     $rows['statistics'] = array(array(SafeMarkup::set('<strong>' . t('Query') . '</strong>'), t('No query was run')));
                 }
             }
         }
     } else {
         foreach ($errors as $display_errors) {
             foreach ($display_errors as $error) {
                 drupal_set_message($error, 'error');
             }
         }
         $preview = t('Unable to preview due to validation errors.');
     }
     // Assemble the preview, the query info, and the query statistics in the
     // requested order.
     $table = array('#type' => 'table', '#prefix' => '<div class="views-query-info">', '#suffix' => '</div>');
     if ($show_location === 'above' || $show_location === 'below') {
         if ($combined) {
             $table['#rows'] = array_merge($rows['query'], $rows['statistics']);
         } else {
             $table['#rows'] = $rows['query'];
         }
     } elseif ($show_stats === 'above' || $show_stats === 'below') {
         $table['#rows'] = $rows['statistics'];
     }
     if ($show_location === 'above' || $show_stats === 'above') {
         $output .= drupal_render($table) . $preview;
     } elseif ($show_location === 'below' || $show_stats === 'below') {
         $output .= $preview . drupal_render($table);
     }
     _current_path($old_q);
     return $output;
 }
Example #3
0
 /**
  * Sets up a Drupal site for running functional and integration tests.
  *
  * Installs Drupal with the installation profile specified in
  * \Drupal\simpletest\WebTestBase::$profile into the prefixed database.
  *
  * Afterwards, installs any additional modules specified in the static
  * \Drupal\simpletest\WebTestBase::$modules property of each class in the
  * class hierarchy.
  *
  * After installation all caches are flushed and several configuration values
  * are reset to the values of the parent site executing the test, since the
  * default values may be incompatible with the environment in which tests are
  * being executed.
  */
 protected function setUp()
 {
     // When running tests through the Simpletest UI (vs. on the command line),
     // Simpletest's batch conflicts with the installer's batch. Batch API does
     // not support the concept of nested batches (in which the nested is not
     // progressive), so we need to temporarily pretend there was no batch.
     // Backup the currently running Simpletest batch.
     $this->originalBatch = batch_get();
     // Define information about the user 1 account.
     $this->root_user = new UserSession(array('uid' => 1, 'name' => 'admin', 'mail' => '*****@*****.**', 'pass_raw' => $this->randomMachineName()));
     // Some tests (SessionTest and SessionHttpsTest) need to examine whether the
     // proper session cookies were set on a response. Because the child site
     // uses the same session name as the test runner, it is necessary to make
     // that available to test-methods.
     $this->session_name = $this->originalSessionName;
     // Reset the static batch to remove Simpletest's batch operations.
     $batch =& batch_get();
     $batch = array();
     // Get parameters for install_drupal() before removing global variables.
     $parameters = $this->installParameters();
     // Prepare installer settings that are not install_drupal() parameters.
     // Copy and prepare an actual settings.php, so as to resemble a regular
     // installation.
     // Not using File API; a potential error must trigger a PHP warning.
     $directory = DRUPAL_ROOT . '/' . $this->siteDirectory;
     copy(DRUPAL_ROOT . '/sites/default/default.settings.php', $directory . '/settings.php');
     copy(DRUPAL_ROOT . '/sites/default/default.services.yml', $directory . '/services.yml');
     // All file system paths are created by System module during installation.
     // @see system_requirements()
     // @see TestBase::prepareEnvironment()
     $settings['settings']['file_public_path'] = (object) array('value' => $this->public_files_directory, 'required' => TRUE);
     // Save the original site directory path, so that extensions in the
     // site-specific directory can still be discovered in the test site
     // environment.
     // @see \Drupal\Core\SystemListing::scan()
     $settings['settings']['test_parent_site'] = (object) array('value' => $this->originalSite, 'required' => TRUE);
     // Add the parent profile's search path to the child site's search paths.
     // @see \Drupal\Core\Extension\ExtensionDiscovery::getProfileDirectories()
     $settings['conf']['simpletest.settings']['parent_profile'] = (object) array('value' => $this->originalProfile, 'required' => TRUE);
     $this->writeSettings($settings);
     // Allow for test-specific overrides.
     $settings_testing_file = DRUPAL_ROOT . '/' . $this->originalSite . '/settings.testing.php';
     if (file_exists($settings_testing_file)) {
         // Copy the testing-specific settings.php overrides in place.
         copy($settings_testing_file, $directory . '/settings.testing.php');
         // Add the name of the testing class to settings.php and include the
         // testing specific overrides
         file_put_contents($directory . '/settings.php', "\n\$test_class = '" . get_class($this) . "';\n" . 'include DRUPAL_ROOT . \'/\' . $site_path . \'/settings.testing.php\';' . "\n", FILE_APPEND);
     }
     $settings_services_file = DRUPAL_ROOT . '/' . $this->originalSite . '/testing.services.yml';
     if (file_exists($settings_services_file)) {
         // Copy the testing-specific service overrides in place.
         copy($settings_services_file, $directory . '/services.yml');
     }
     // Since Drupal is bootstrapped already, install_begin_request() will not
     // bootstrap into DRUPAL_BOOTSTRAP_CONFIGURATION (again). Hence, we have to
     // reload the newly written custom settings.php manually.
     $class_loader = (require DRUPAL_ROOT . '/core/vendor/autoload.php');
     Settings::initialize($directory, $class_loader);
     // Execute the non-interactive installer.
     require_once DRUPAL_ROOT . '/core/includes/install.core.inc';
     install_drupal($parameters);
     // Import new settings.php written by the installer.
     Settings::initialize($directory, $class_loader);
     foreach ($GLOBALS['config_directories'] as $type => $path) {
         $this->configDirectories[$type] = $path;
     }
     // After writing settings.php, the installer removes write permissions
     // from the site directory. To allow drupal_generate_test_ua() to write
     // a file containing the private key for drupal_valid_test_ua(), the site
     // directory has to be writable.
     // TestBase::restoreEnvironment() will delete the entire site directory.
     // Not using File API; a potential error must trigger a PHP warning.
     chmod($directory, 0777);
     $request = \Drupal::request();
     $this->kernel = DrupalKernel::createFromRequest($request, $class_loader, 'prod', TRUE);
     $this->kernel->prepareLegacyRequest($request);
     // Force the container to be built from scratch instead of loaded from the
     // disk. This forces us to not accidently load the parent site.
     $container = $this->kernel->rebuildContainer();
     $config = $container->get('config.factory');
     // Manually create and configure private and temporary files directories.
     // While these could be preset/enforced in settings.php like the public
     // files directory above, some tests expect them to be configurable in the
     // UI. If declared in settings.php, they would no longer be configurable.
     file_prepare_directory($this->private_files_directory, FILE_CREATE_DIRECTORY);
     file_prepare_directory($this->temp_files_directory, FILE_CREATE_DIRECTORY);
     $config->get('system.file')->set('path.private', $this->private_files_directory)->set('path.temporary', $this->temp_files_directory)->save();
     // Manually configure the test mail collector implementation to prevent
     // tests from sending out emails and collect them in state instead.
     // While this should be enforced via settings.php prior to installation,
     // some tests expect to be able to test mail system implementations.
     $config->get('system.mail')->set('interface.default', 'test_mail_collector')->save();
     // By default, verbosely display all errors and disable all production
     // environment optimizations for all tests to avoid needless overhead and
     // ensure a sane default experience for test authors.
     // @see https://drupal.org/node/2259167
     $config->get('system.logging')->set('error_level', 'verbose')->save();
     $config->get('system.performance')->set('css.preprocess', FALSE)->set('js.preprocess', FALSE)->save();
     // Restore the original Simpletest batch.
     $batch =& batch_get();
     $batch = $this->originalBatch;
     // Collect modules to install.
     $class = get_class($this);
     $modules = array();
     while ($class) {
         if (property_exists($class, 'modules')) {
             $modules = array_merge($modules, $class::$modules);
         }
         $class = get_parent_class($class);
     }
     if ($modules) {
         $modules = array_unique($modules);
         $success = $container->get('module_handler')->install($modules, TRUE);
         $this->assertTrue($success, String::format('Enabled modules: %modules', array('%modules' => implode(', ', $modules))));
         $this->rebuildContainer();
     }
     // Reset/rebuild all data structures after enabling the modules, primarily
     // to synchronize all data structures and caches between the test runner and
     // the child site.
     // @see \Drupal\Core\DrupalKernel::bootCode()
     // @todo Test-specific setUp() methods may set up further fixtures; find a
     //   way to execute this after setUp() is done, or to eliminate it entirely.
     $this->resetAll();
     $this->kernel->prepareLegacyRequest($request);
     // Explicitly call register() again on the container registered in \Drupal.
     // @todo This should already be called through
     //   DrupalKernel::prepareLegacyRequest() -> DrupalKernel::boot() but that
     //   appears to be calling a different container.
     $this->container->get('stream_wrapper_manager')->register();
     // Temporary fix so that when running from run-tests.sh we don't get an
     // empty current path which would indicate we're on the home page.
     $path = current_path();
     if (empty($path)) {
         _current_path('run-tests');
     }
 }
 /**
  * Ensure page-front template suggestion is added when on front page.
  */
 function testFrontPageThemeSuggestion()
 {
     $original_path = _current_path();
     // Set the current path to node because theme_get_suggestions() will query
     // it to see if we are on the front page.
     \Drupal::config('system.site')->set('page.front', 'node')->save();
     _current_path('node');
     $suggestions = theme_get_suggestions(array('node'), 'page');
     // Set it back to not annoy the batch runner.
     _current_path($original_path);
     $this->assertTrue(in_array('page__front', $suggestions), 'Front page template was suggested.');
 }
 /**
  * Bootstraps the legacy global request variables.
  *
  * @param \Symfony\Component\HttpFoundation\Request $request
  *   The current request.
  *
  * @todo D8: Eliminate this entirely in favor of Request object.
  */
 protected function initializeRequestGlobals(Request $request)
 {
     // Provided by settings.php.
     global $base_url;
     // Set and derived from $base_url by this function.
     global $base_path, $base_root, $script_path;
     global $base_secure_url, $base_insecure_url;
     // @todo Refactor with the Symfony Request object.
     _current_path(request_path());
     if (isset($base_url)) {
         // Parse fixed base URL from settings.php.
         $parts = parse_url($base_url);
         if (!isset($parts['path'])) {
             $parts['path'] = '';
         }
         $base_path = $parts['path'] . '/';
         // Build $base_root (everything until first slash after "scheme://").
         $base_root = substr($base_url, 0, strlen($base_url) - strlen($parts['path']));
     } else {
         // Create base URL.
         $http_protocol = $request->isSecure() ? 'https' : 'http';
         $base_root = $http_protocol . '://' . $request->server->get('HTTP_HOST');
         $base_url = $base_root;
         // For a request URI of '/index.php/foo', $_SERVER['SCRIPT_NAME'] is
         // '/index.php', whereas $_SERVER['PHP_SELF'] is '/index.php/foo'.
         if ($dir = rtrim(dirname($request->server->get('SCRIPT_NAME')), '\\/')) {
             // Remove "core" directory if present, allowing install.php,
             // authorize.php, and others to auto-detect a base path.
             $core_position = strrpos($dir, '/core');
             if ($core_position !== FALSE && strlen($dir) - 5 == $core_position) {
                 $base_path = substr($dir, 0, $core_position);
             } else {
                 $base_path = $dir;
             }
             $base_url .= $base_path;
             $base_path .= '/';
         } else {
             $base_path = '/';
         }
     }
     $base_secure_url = str_replace('http://', 'https://', $base_url);
     $base_insecure_url = str_replace('https://', 'http://', $base_url);
     // Determine the path of the script relative to the base path, and add a
     // trailing slash. This is needed for creating URLs to Drupal pages.
     if (!isset($script_path)) {
         $script_path = '';
         // We don't expect scripts outside of the base path, but sanity check
         // anyway.
         if (strpos($request->server->get('SCRIPT_NAME'), $base_path) === 0) {
             $script_path = substr($request->server->get('SCRIPT_NAME'), strlen($base_path)) . '/';
             // If the request URI does not contain the script name, then clean URLs
             // are in effect and the script path can be similarly dropped from URL
             // generation. For servers that don't provide $_SERVER['REQUEST_URI'],
             // we do not know the actual URI requested by the client, and
             // request_uri() returns a URI with the script name, resulting in
             // non-clean URLs unless
             // there's other code that intervenes.
             if (strpos(request_uri(TRUE) . '/', $base_path . $script_path) !== 0) {
                 $script_path = '';
             }
             // @todo Temporary BC for install.php, authorize.php, and other scripts.
             //   - http://drupal.org/node/1547184
             //   - http://drupal.org/node/1546082
             if ($script_path !== 'index.php/') {
                 $script_path = '';
             }
         }
     }
 }