Pull merge.
[yaffs-website] / web / core / modules / system / system.module
index a1a6b715a3a6a428f99703d4764218a27a2f6318..e82e1ffd4824d08353e431c2ba7164da72dd614b 100644 (file)
@@ -9,10 +9,10 @@ use Drupal\Component\Render\PlainTextOutput;
 use Drupal\Component\Utility\UrlHelper;
 use Drupal\Core\Asset\AttachedAssetsInterface;
 use Drupal\Core\Cache\Cache;
+use Drupal\Core\Extension\Exception\UnknownExtensionException;
 use Drupal\Core\Queue\QueueGarbageCollectionInterface;
 use Drupal\Core\Database\Query\AlterableInterface;
 use Drupal\Core\Extension\Extension;
-use Drupal\Core\Extension\ExtensionDiscovery;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\KeyValueStore\KeyValueDatabaseExpirableFactory;
 use Drupal\Core\PageCache\RequestPolicyInterface;
@@ -33,6 +33,8 @@ use GuzzleHttp\Exception\RequestException;
  *
  * @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0.
  *   Use \Drupal\user\UserInterface::TIMEZONE_DEFAULT instead.
+ *
+ * @see https://www.drupal.org/node/2831620
  */
 const DRUPAL_USER_TIMEZONE_DEFAULT = 0;
 
@@ -41,6 +43,8 @@ const DRUPAL_USER_TIMEZONE_DEFAULT = 0;
  *
  * @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0.
  *   Use \Drupal\user\UserInterface::TIMEZONE_EMPTY instead.
+ *
+ * @see https://www.drupal.org/node/2831620
  */
 const DRUPAL_USER_TIMEZONE_EMPTY = 1;
 
@@ -49,6 +53,8 @@ const DRUPAL_USER_TIMEZONE_EMPTY = 1;
  *
  * @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0.
  *   Use \Drupal\user\UserInterface::TIMEZONE_SELECT instead.
+ *
+ * @see https://www.drupal.org/node/2831620
  */
 const DRUPAL_USER_TIMEZONE_SELECT = 2;
 
@@ -74,6 +80,7 @@ const DRUPAL_REQUIRED = 2;
  *   Use \Drupal\block\BlockRepositoryInterface::REGIONS_VISIBLE instead.
  *
  * @see system_region_list()
+ * @see https://www.drupal.org/node/2831620
  */
 const REGIONS_VISIBLE = 'visible';
 
@@ -84,6 +91,7 @@ const REGIONS_VISIBLE = 'visible';
  *   Use \Drupal\block\BlockRepositoryInterface::REGIONS_ALL instead.
  *
  * @see system_region_list()
+ * @see https://www.drupal.org/node/2831620
  */
 const REGIONS_ALL = 'all';
 
@@ -250,7 +258,7 @@ function system_theme() {
       'file' => 'system.admin.inc',
     ],
     'admin_block' => [
-      'variables' => ['block' => NULL],
+      'variables' => ['block' => NULL, 'attributes' => []],
       'file' => 'system.admin.inc',
     ],
     'admin_block_content' => [
@@ -268,6 +276,9 @@ function system_theme() {
       ],
       'template' => 'entity-add-list',
     ],
+    'off_canvas_page_wrapper' => [
+      'variables' => ['children' => NULL],
+    ],
   ]);
 }
 
@@ -439,7 +450,7 @@ function template_preprocess_entity_add_list(&$variables) {
  *  $form_state->setRedirectUrl(system_authorized_get_url());
  * @endcode
  *
- * @param $callback
+ * @param callable $callback
  *   The name of the function to invoke once the user authorizes the operation.
  * @param $file
  *   The full path to the file where the callback function is implemented.
@@ -603,7 +614,7 @@ function system_page_attachments(array &$page) {
   }
 
   // Get the major Drupal version.
-  list($version, ) = explode('.', \Drupal::VERSION);
+  list($version,) = explode('.', \Drupal::VERSION);
 
   // Attach default meta tags.
   $meta_default = [
@@ -756,10 +767,10 @@ function system_js_settings_alter(&$settings, AttachedAssetsInterface $assets) {
     }
     // Provide the page with information about the individual asset libraries
     // used, information not otherwise available when aggregation is enabled.
-    $minimal_libraries = $library_dependency_resolver->getMinimalRepresentativeSubset(array_merge(
+    $minimal_libraries = $library_dependency_resolver->getMinimalRepresentativeSubset(array_unique(array_merge(
       $assets->getLibraries(),
       $assets->getAlreadyLoadedLibraries()
-    ));
+    )));
     sort($minimal_libraries);
     $settings['ajaxPageState']['libraries'] = implode(',', $minimal_libraries);
   }
@@ -824,7 +835,13 @@ function system_user_login(UserInterface $account) {
   $config = \Drupal::config('system.date');
   // If the user has a NULL time zone, notify them to set a time zone.
   if (!$account->getTimezone() && $config->get('timezone.user.configurable') && $config->get('timezone.user.warn')) {
-    drupal_set_message(t('Configure your <a href=":user-edit">account time zone setting</a>.', [':user-edit' => $account->url('edit-form', ['query' => \Drupal::destination()->getAsArray(), 'fragment' => 'edit-timezone'])]));
+    \Drupal::messenger()
+      ->addStatus(t('Configure your <a href=":user-edit">account time zone setting</a>.', [
+        ':user-edit' => $account->url('edit-form', [
+          'query' => \Drupal::destination()->getAsArray(),
+          'fragment' => 'edit-timezone',
+        ]),
+      ]));
   }
 }
 
@@ -845,7 +862,7 @@ function system_user_timezone(&$form, FormStateInterface $form_state) {
     '#type' => 'select',
     '#title' => t('Time zone'),
     '#default_value' => $account->getTimezone() ? $account->getTimezone() : \Drupal::config('system.date')->get('timezone.default'),
-    '#options' => system_time_zones($account->id() != $user->id()),
+    '#options' => system_time_zones($account->id() != $user->id(), TRUE),
     '#description' => t('Select the desired local time and time zone. Dates and times throughout this site will be displayed using this time zone.'),
   ];
   $user_input = $form_state->getUserInput();
@@ -902,7 +919,7 @@ function system_check_directory($form_element, FormStateInterface $form_state) {
 
   $logger = \Drupal::logger('file system');
   if (!is_dir($directory) && !drupal_mkdir($directory, NULL, TRUE)) {
-    // If the directory does not exists and cannot be created.
+    // If the directory does not exist and cannot be created.
     $form_state->setErrorByName($form_element['#parents'][0], t('The directory %directory does not exist and could not be created.', ['%directory' => $directory]));
     $logger->error('The directory %directory does not exist and could not be created.', ['%directory' => $directory]);
   }
@@ -950,27 +967,22 @@ function system_check_directory($form_element, FormStateInterface $form_state) {
  */
 function system_get_info($type, $name = NULL) {
   if ($type == 'module') {
-    $info = &drupal_static(__FUNCTION__);
-    if (!isset($info)) {
-      if ($cache = \Drupal::cache()->get('system.module.info')) {
-        $info = $cache->data;
+    /** @var \Drupal\Core\Extension\ModuleExtensionList $module_list */
+    $module_list = \Drupal::service('extension.list.module');
+    if (isset($name)) {
+      try {
+        return $module_list->getExtensionInfo($name);
       }
-      else {
-        $data = system_rebuild_module_data();
-        foreach (\Drupal::moduleHandler()->getModuleList() as $module => $filename) {
-          if (isset($data[$module])) {
-            $info[$module] = $data[$module]->info;
-          }
-        }
-        // Store the module information in cache. This cache is cleared by
-        // calling system_rebuild_module_data(), for example, when listing
-        // modules, (un)installing modules, importing configuration, updating
-        // the site and when flushing all the caches.
-        \Drupal::cache()->set('system.module.info', $info);
+      catch (UnknownExtensionException $e) {
+        return [];
       }
     }
+    else {
+      return $module_list->getAllInstalledInfo();
+    }
   }
   else {
+    // @todo move into ThemeExtensionList https://www.drupal.org/node/2659940
     $info = [];
     $list = system_list($type);
     foreach ($list as $shortname => $item) {
@@ -978,97 +990,11 @@ function system_get_info($type, $name = NULL) {
         $info[$shortname] = $item->info;
       }
     }
-  }
-  if (isset($name)) {
-    return isset($info[$name]) ? $info[$name] : [];
-  }
-  return $info;
-}
-
-/**
- * Helper function to scan and collect module .info.yml data.
- *
- * @return \Drupal\Core\Extension\Extension[]
- *   An associative array of module information.
- */
-function _system_rebuild_module_data() {
-  $listing = new ExtensionDiscovery(\Drupal::root());
-
-  // Find installation profiles. This needs to happen before performing a
-  // module scan as the module scan requires knowing what the active profile is.
-  // @todo Remove as part of https://www.drupal.org/node/2186491.
-  $profiles = $listing->scan('profile');
-  $profile = drupal_get_profile();
-  if ($profile && isset($profiles[$profile])) {
-    // Prime the drupal_get_filename() static cache with the profile info file
-    // location so we can use drupal_get_path() on the active profile during
-    // the module scan.
-    // @todo Remove as part of https://www.drupal.org/node/2186491.
-    drupal_get_filename('profile', $profile, $profiles[$profile]->getPathname());
-  }
-
-  // Find modules.
-  $modules = $listing->scan('module');
-  // Include the installation profile in modules that are loaded.
-  if ($profile) {
-    $modules[$profile] = $profiles[$profile];
-    // Installation profile hooks are always executed last.
-    $modules[$profile]->weight = 1000;
-  }
-
-  // Set defaults for module info.
-  $defaults = [
-    'dependencies' => [],
-    'description' => '',
-    'package' => 'Other',
-    'version' => NULL,
-    'php' => DRUPAL_MINIMUM_PHP,
-  ];
-
-  // Read info files for each module.
-  foreach ($modules as $key => $module) {
-    // Look for the info file.
-    $module->info = \Drupal::service('info_parser')->parse($module->getPathname());
-
-    // Add the info file modification time, so it becomes available for
-    // contributed modules to use for ordering module lists.
-    $module->info['mtime'] = $module->getMTime();
-
-    // Merge in defaults and save.
-    $modules[$key]->info = $module->info + $defaults;
-
-    // Installation profiles are hidden by default, unless explicitly specified
-    // otherwise in the .info.yml file.
-    if ($key == $profile && !isset($modules[$key]->info['hidden'])) {
-      $modules[$key]->info['hidden'] = TRUE;
+    if (isset($name)) {
+      return isset($info[$name]) ? $info[$name] : [];
     }
-
-    // Invoke hook_system_info_alter() to give installed modules a chance to
-    // modify the data in the .info.yml files if necessary.
-    // @todo Remove $type argument, obsolete with $module->getType().
-    $type = 'module';
-    \Drupal::moduleHandler()->alter('system_info', $modules[$key]->info, $modules[$key], $type);
-  }
-
-  // It is possible that a module was marked as required by
-  // hook_system_info_alter() and modules that it depends on are not required.
-  foreach ($modules as $module) {
-    _system_rebuild_module_data_ensure_required($module, $modules);
+    return $info;
   }
-
-
-  if ($profile && isset($modules[$profile])) {
-    // The installation profile is required, if it's a valid module.
-    $modules[$profile]->info['required'] = TRUE;
-    // Add a default distribution name if the profile did not provide one.
-    // @see install_profile_info()
-    // @see drupal_install_profile_distribution_name()
-    if (!isset($modules[$profile]->info['distribution']['name'])) {
-      $modules[$profile]->info['distribution']['name'] = 'Drupal';
-    }
-  }
-
-  return $modules;
 }
 
 /**
@@ -1078,8 +1004,14 @@ function _system_rebuild_module_data() {
  *   The module info.
  * @param \Drupal\Core\Extension\Extension[] $modules
  *   The array of all module info.
+ *
+ * @deprecated in Drupal 8.5.0 and will be removed before Drupal 9.0.0. This
+ *   function is no longer used in Drupal core.
+ *
+ * @see https://www.drupal.org/node/2709919
  */
 function _system_rebuild_module_data_ensure_required($module, &$modules) {
+  @trigger_error("_system_rebuild_module_data_ensure_required() is deprecated in Drupal 8.5.0 and will be removed before Drupal 9.0.0. This function is no longer used in Drupal core. See https://www.drupal.org/node/2709919", E_USER_DEPRECATED);
   if (!empty($module->info['required'])) {
     foreach ($module->info['dependencies'] as $dependency) {
       $dependency_name = ModuleHandler::parseDependency($dependency)['name'];
@@ -1093,6 +1025,23 @@ function _system_rebuild_module_data_ensure_required($module, &$modules) {
   }
 }
 
+/**
+ * Helper function to scan and collect module .info.yml data.
+ *
+ * @return \Drupal\Core\Extension\Extension[]
+ *   An associative array of module information.
+ *
+ * @deprecated in Drupal 8.5.0 and will be removed before Drupal 9.0.0.
+ *   Use \Drupal::service('extension.list.module')->reset()->getList()
+ *   instead. Note: You probably don't need the reset() method.
+ *
+ * @see https://www.drupal.org/node/2709919
+ */
+function _system_rebuild_module_data() {
+  @trigger_error("_system_rebuild_module_data() is deprecated in Drupal 8.5.0 and will be removed before Drupal 9.0.0. Instead, you should use \\Drupal::service('extension.list.module')->reset()->getList(). See https://www.drupal.org/node/2709919", E_USER_DEPRECATED);
+  return \Drupal::service('extension.list.module')->reset()->getList();
+}
+
 /**
  * Rebuild, save, and return data about all currently available modules.
  *
@@ -1100,33 +1049,7 @@ function _system_rebuild_module_data_ensure_required($module, &$modules) {
  *   Array of all available modules and their data.
  */
 function system_rebuild_module_data() {
-  $modules_cache = &drupal_static(__FUNCTION__);
-  // Only rebuild once per request. $modules and $modules_cache cannot be
-  // combined into one variable, because the $modules_cache variable is reset by
-  // reference from system_list_reset() during the rebuild.
-  if (!isset($modules_cache)) {
-    $modules = _system_rebuild_module_data();
-    $files = [];
-    ksort($modules);
-    // Add status, weight, and schema version.
-    $installed_modules = \Drupal::config('core.extension')->get('module') ?: [];
-    foreach ($modules as $name => $module) {
-      $module->weight = isset($installed_modules[$name]) ? $installed_modules[$name] : 0;
-      $module->status = (int) isset($installed_modules[$name]);
-      $module->schema_version = SCHEMA_UNINSTALLED;
-      $files[$name] = $module->getPathname();
-    }
-    $modules = \Drupal::moduleHandler()->buildModuleDependencies($modules);
-    $modules_cache = $modules;
-
-    // Store filenames to allow drupal_get_filename() to retrieve them without
-    // having to rebuild or scan the filesystem.
-    \Drupal::state()->set('system.module.files', $files);
-    // Clear the module info cache.
-    \Drupal::cache()->delete('system.module.info');
-    drupal_static_reset('system_get_info');
-  }
-  return $modules_cache;
+  return \Drupal::service('extension.list.module')->reset()->getList();
 }
 
 /**
@@ -1355,10 +1278,15 @@ function system_mail($key, &$message, $params) {
 /**
  * Generate an array of time zones and their local time&date.
  *
- * @param $blank
+ * @param mixed $blank
  *   If evaluates true, prepend an empty time zone option to the array.
+ * @param bool $grouped
+ *   (optional) Whether the timezones should be grouped by region.
+ *
+ * @return array
+ *   An array or nested array containing time zones, keyed by the system name.
  */
-function system_time_zones($blank = NULL) {
+function system_time_zones($blank = NULL, $grouped = FALSE) {
   $zonelist = timezone_identifiers_list();
   $zones = $blank ? ['' => t('- None selected -')] : [];
   foreach ($zonelist as $zone) {
@@ -1371,6 +1299,27 @@ function system_time_zones($blank = NULL) {
   }
   // Sort the translated time zones alphabetically.
   asort($zones);
+  if ($grouped) {
+    $grouped_zones = [];
+    foreach ($zones as $key => $value) {
+      $split = explode('/', $value);
+      $city = array_pop($split);
+      $region = array_shift($split);
+      if (!empty($region)) {
+        $grouped_zones[$region][$key] = empty($split) ? $city : $city . ' (' . implode('/', $split) . ')';
+      }
+      else {
+        $grouped_zones[$key] = $value;
+      }
+    }
+    foreach ($grouped_zones as $key => $value) {
+      if (is_array($grouped_zones[$key])) {
+        asort($grouped_zones[$key]);
+      }
+    }
+    $zones = $grouped_zones;
+  }
+
   return $zones;
 }
 
@@ -1410,7 +1359,7 @@ function system_retrieve_file($url, $destination = NULL, $managed = FALSE, $repl
     $path = file_build_uri(drupal_basename($parsed_url['path']));
   }
   else {
-    if (is_dir(drupal_realpath($destination))) {
+    if (is_dir(\Drupal::service('file_system')->realpath($destination))) {
       // Prevent URIs with triple slashes when glueing parts together.
       $path = str_replace('///', '//', "$destination/") . drupal_basename($parsed_url['path']);
     }
@@ -1425,11 +1374,11 @@ function system_retrieve_file($url, $destination = NULL, $managed = FALSE, $repl
     $local = $managed ? file_save_data($data, $path, $replace) : file_unmanaged_save_data($data, $path, $replace);
   }
   catch (RequestException $exception) {
-    drupal_set_message(t('Failed to fetch file due to error "%error"', ['%error' => $exception->getMessage()]), 'error');
+    \Drupal::messenger()->addError(t('Failed to fetch file due to error "%error"', ['%error' => $exception->getMessage()]));
     return FALSE;
   }
   if (!$local) {
-    drupal_set_message(t('@remote could not be saved to @path.', ['@remote' => $url, '@path' => $path]), 'error');
+    \Drupal::messenger()->addError(t('@remote could not be saved to @path.', ['@remote' => $url, '@path' => $path]));
   }
 
   return $local;
@@ -1489,3 +1438,12 @@ function system_query_entity_reference_alter(AlterableInterface $query) {
   $handler = $query->getMetadata('entity_reference_selection_handler');
   $handler->entityQueryAlter($query);
 }
+
+/**
+ * Implements hook_element_info_alter().
+ */
+function system_element_info_alter(&$type) {
+  if (isset($type['page'])) {
+    $type['page']['#theme_wrappers']['off_canvas_page_wrapper'] = ['#weight' => -1000];
+  }
+}