wxt_library-8.x-1.21/wxt_library.module
wxt_library.module
<?php
/**
* @file
* Contains wxt_library.module.
*/
use Drupal\Core\Entity\Entity\EntityViewDisplay;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
use Drupal\Core\Installer\InstallerKernel;
use Drupal\Core\StringTranslation\TranslatableMarkup;
/**
* Implements hook_help().
*/
function wxt_library_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
case 'help.page.wxt_library':
$output = '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('The WxT Library helps load the assets required to
properly leverage the Web Experience Toolkit jQuery Framework. For more
information, see the <a href=":wet_boew_documentation">online
documentation for WET-BOEW</a>.',
[':wet_boew_documentation' => 'https://wet-boew.github.io']) . '</p>';
return $output;
}
}
/**
* Implements hook_menu_links_discovered_alter().
*/
function wxt_library_menu_links_discovered_alter(&$links) {
// Conditionally add the WxT Library menu link.
if (\Drupal::moduleHandler()->moduleExists('wxt_core')) {
$links['wxt_library.settings'] = [
'title' => new TranslatableMarkup('WxT Library'),
'parent' => 'wxt_core.settings',
'route_name' => 'wxt_library.settings',
'description' => new TranslatableMarkup('Call WxT Bootstrap jQuery Framework using Drupal Libraries.'),
'menu_name' => 'admin',
'provider' => 'wxt_library',
];
}
else {
$links['wxt_library.admin'] = [
'title' => new TranslatableMarkup('WxT'),
'parent' => 'system.admin_config',
'route_name' => 'wxt.settings',
'description' => new TranslatableMarkup('Various settings for altering the behavior of WxT modules.'),
'menu_name' => 'admin',
'provider' => 'wxt_library',
];
$links['wxt_library.settings'] = [
'title' => new TranslatableMarkup('WxT Library'),
'parent' => 'wxt_library.admin',
'route_name' => 'wxt_library.settings',
'description' => new TranslatableMarkup('Call WxT Bootstrap jQuery Framework using Drupal Libraries.'),
'menu_name' => 'admin',
'provider' => 'wxt_library',
];
}
}
/**
* Implements hook_page_attachments().
*
* Use Libraries API to load the js & css files into header.
*/
function wxt_library_page_attachments(array &$page) {
// Don't add the JavaScript and CSS during installation.
if (InstallerKernel::installationAttempted()) {
return;
}
// Don't add the JavaScript and CSS on specified paths or themes.
if (!_wxt_library_check_theme() || !_wxt_library_check_url()) {
return;
}
_wxt_library_add_page_attachments($page);
}
/**
* Add JS and CSS files to the page attachments.
*
* @param array &$page
* The array to add the attachments to.
*/
function _wxt_library_add_page_attachments(array &$page): void {
$config = \Drupal::config('wxt_library.settings');
$variant = ($config->get('minimized.options')) ? 'minified' : 'source';
$wxt_libraries = _wxt_library_options() + ['wet-boew' => t('Core')];
$wxt_active = $config->get('wxt.theme');
foreach ($wxt_libraries as $wxt_library => $name) {
$min = ($variant == 'source') ? '-dev' : '';
// WxT Core.
if ($wxt_library == 'wet-boew') {
$page['#attached']['library'][] = 'wxt_library/wet-boew' . $min;
}
// WxT Theme.
elseif ($wxt_library == $wxt_active) {
$page['#attached']['library'][] = 'wxt_library/' . $wxt_active . $min;
}
}
// GCWeb messages theming.
if ($wxt_active == 'theme-gcweb' || $wxt_active == 'theme-gcweb-legacy' || $wxt_active == 'theme-gc-intranet') {
$route_name = \Drupal::service('current_route_match')->getRouteName();
if ($route_name == 'system.404') {
$page['#attached']['library'][] = 'wxt_library/' . $wxt_active . $min . '.messages';
}
}
// WxT noscript handling.
$library_discovery = \Drupal::service('library.discovery');
if ($variant == 'minified') {
$library_name = 'wet-boew.noscript';
}
else {
$library_name = 'wet-boew-dev.noscript';
}
$library = $library_discovery->getLibraryByName('wxt_library', $library_name);
if ($library['css']) {
foreach ($library['css'] as $css) {
if ($css['type'] == 'file') {
if (file_exists(DRUPAL_ROOT . '/' . $css['data'])) {
$custom_tags = [
'WxTNoScript' => [
'#tag' => 'link',
'#noscript' => TRUE,
'#attributes' => [
'rel' => 'stylesheet',
'href' => \Drupal::service('file_url_generator')->generateString($css['data']),
],
],
];
foreach ($custom_tags as $key => $value) {
$page['#attached']['html_head'][] = [$value, $key];
}
}
}
}
}
}
/**
* Verify if current theme is selected.
*/
function _wxt_library_check_theme() {
$config = \Drupal::config('wxt_library.settings');
$theme = \Drupal::theme()->getActiveTheme()->getName();
$valid_themes = $config->get('theme.themes');
$visibility = $config->get('theme.visibility');
$theme_match = in_array($theme, $valid_themes);
$theme_match = !($visibility xor $theme_match);
return $theme_match;
}
/**
* Check if wxt_library should be active for the current URL.
*
* @return bool
* TRUE if wxt_library should be active for the current page.
*/
function _wxt_library_check_url() {
// Make it possible deactivate bootstrap with
// parameter ?wxt_library=no in the url.
$query_string = \Drupal::service('request_stack')->getCurrentRequest()->query->get('wxt_library');
if (isset($query_string) && $query_string == 'no') {
return FALSE;
}
// Convert path to lowercase. This allows comparison of the same path
// with different case. Ex: /Page, /page, /PAGE.
$config = \Drupal::config('wxt_library.settings');
$pages = mb_strtolower(_wxt_library_array_to_string($config->get('url.pages')) ?? '');
// Compare the lowercase path alias (if any) and internal path.
$path = Url::fromRoute('<current>')->toString();
$path_alias = mb_strtolower(\Drupal::service('path_alias.repository')->lookupBySystemPath($path, 'en') ?? '');
$page_match = \Drupal::service('path.matcher')->matchPath($path_alias, $pages);
if ($path_alias != $path) {
$page_match = $page_match || \Drupal::service('path.matcher')->matchPath($path, $pages);
}
$page_match = $config->get('url.visibility') == 0 ? !$page_match : $page_match;
return $page_match;
}
/**
* Converts a text with lines (\n) into an array of lines.
*
* @return array
* Array with as many items as non-empty lines in the text
*/
function _wxt_library_string_to_array($text) {
$text = str_replace("\r\n", "\n", $text);
return array_filter(explode("\n", $text), 'trim');
}
/**
* Converts an array of lines into an text with lines (\n).
*
* @return string
* Text with lines
*/
function _wxt_library_array_to_string($array) {
return implode("\r\n", $array);
}
/**
* WxT theme options.
*/
function _wxt_library_options() {
return [
'theme-wet-boew' => t('WxT Usability'),
'theme-base' => t('Base'),
'theme-ogpl' => t('Open Government Platform'),
'theme-gcwu-fegc' => t('Internet (Government of Canada)'),
'theme-gc-intranet' => t('Intranet (Government of Canada)'),
'theme-gc-intranet-legacy' => t('Intranet Legacy (Government of Canada)'),
'theme-gcweb' => t('Canada.ca (Government of Canada)'),
'theme-gcweb-legacy' => t('Canada.ca Legacy (Government of Canada)'),
];
}
/**
* Gets the path of a library.
*
* @param string $name
* The machine name of a library to return the path for.
* @param string $base_path
* Whether to prefix the resulting path with base_path().
*
* @return string
* The path to the specified library or FALSE if the library wasn't found.
*/
function _wxt_library_get_path($name, $base_path = FALSE) {
$libraries = &drupal_static(__FUNCTION__);
if (!isset($libraries)) {
$libraries = _wxt_library_get_libraries();
}
$path = ($base_path ? base_path() : '');
if (!isset($libraries[$name])) {
return FALSE;
}
else {
$path .= $libraries[$name];
}
return $path;
}
/**
* Returns an array of library directories.
*
* Returns an array of library directories from the all-sites directory
* (i.e. sites/all/libraries/), the profiles directory, and site-specific
* directory (i.e. sites/somesite/libraries/). The returned array will be keyed
* by the library name. Site-specific libraries are prioritized over libraries
* in the default directories. That is, if a library with the same name appears
* in both the site-wide directory and site-specific directory, only the
* site-specific version will be listed.
*
* @return array
* A list of library directories.
*/
function _wxt_library_get_libraries() {
$searchdir = [];
// Similar to 'modules' and 'themes' directories inside an installation
// profile, installation profiles may want to place libraries into a
// 'libraries' directory.
if ($profile = \Drupal::installProfile()) {
$profile = \Drupal::service('extension.list.profile')->getPath($profile);
}
else {
$profile = 'profiles/wxt';
}
$conf_path = \Drupal::getContainer()->getParameter('site.path');
// Similar to 'modules' and 'themes' directories in the root directory,
// certain distributions may want to place libraries into a 'libraries'
// directory in Drupal's root directory.
$searchdir[] = 'libraries';
// Similar to 'modules' and 'themes' directories inside an installation
// profile, installation profiles may want to place libraries into a
// 'libraries' directory.
$searchdir[] = "$profile/libraries";
// Always search sites/all/libraries.
$searchdir[] = 'sites/all/libraries';
// Also search sites/<domain>/*.
$searchdir[] = "$conf_path/libraries";
// Retrieve list of directories.
$directories = [];
$nomask = ['CVS'];
foreach ($searchdir as $dir) {
if (is_dir($dir) && $handle = opendir($dir)) {
while (FALSE !== ($file = readdir($handle))) {
if (!in_array($file, $nomask) && $file[0] != '.') {
if (is_dir("$dir/$file")) {
$directories[$file] = "$dir/$file";
}
}
}
closedir($handle);
}
}
return $directories;
}
/**
* Implements hook_bootstrap_layouts_class_options_alter().
*/
function wxt_library_bootstrap_layouts_class_options_alter(&$classes, &$groups) {
// Add theme specific classes.
$groups['wxt_bootstrap'] = t('WxT');
$classes['wxt_bootstrap']['wb-eqht'] = t('Equal Height: @class', ['@class' => 'wb-eqht']);
}
/**
* Implements hook_preprocess_html().
*/
function wxt_library_preprocess_html(&$variables) {
// Get wxt_library config.
$config = \Drupal::config('wxt_library.settings');
$wxt_active = $config->get('wxt.theme');
$blue_intranet = $config->get('wxt.intranet_style');
if ($wxt_active == 'theme-gc-intranet' && $blue_intranet) {
$variables['attributes']['class'][] = 'intranet-blue';
}
}
/**
* Implements hook_preprocess_page().
*/
function wxt_library_preprocess_page(&$variables) {
// Get wxt_library config.
$config = \Drupal::config('wxt_library.settings');
$wxt_active = $config->get('wxt.theme');
$menu_type = $config->get('wxt.menu_type');
if ($wxt_active == 'theme-gcweb' && $menu_type) {
$variables['menu_type'] = 'horizontal';
}
else {
$variables['menu_type'] = 'default';
}
}
/**
* Returns the entity view display associated with a bundle and view mode.
*
* This is an exact copy of the deprecated entity_get_display() from Core 8.6.x
* except for one change: the default value of the $view_mode parameter.
*
* @todo Eliminate this in favor of
* Drupal::service('entity_display.repository')->getViewDisplay() in Core
* 8.8.x once that is the lowest supported version.
*
* @param string $entity_type
* The entity type.
* @param string $bundle
* The bundle.
* @param string $view_mode
* The view mode, or 'default' to retrieve the 'default' display object for
* this bundle.
*
* @return \Drupal\Core\Entity\Display\EntityViewDisplayInterface
* The entity view display associated with the view mode.
*
* @see \Drupal\Core\Entity\EntityStorageInterface::create()
* @see \Drupal\Core\Entity\EntityStorageInterface::load()
*/
function wxt_library_entity_get_display($entity_type, $bundle, $view_mode = 'default') {
// Try loading the display from configuration.
$display = EntityViewDisplay::load($entity_type . '.' . $bundle . '.' . $view_mode);
// If not found, create a fresh display object. We do not preemptively create
// new entity_view_display configuration entries for each existing entity type
// and bundle whenever a new view mode becomes available. Instead,
// configuration entries are only created when a display object is explicitly
// configured and saved.
if (!$display) {
$display = EntityViewDisplay::create([
'targetEntityType' => $entity_type,
'bundle' => $bundle,
'mode' => $view_mode,
'status' => TRUE,
]);
}
return $display;
}
