2015-08-18 00:00:26 +00:00
< ? php
/**
* @ file
* Admin page callbacks for the system module .
*/
use Drupal\Component\Utility\SafeMarkup ;
use Drupal\Component\Utility\Xss ;
use Drupal\Component\Utility\Html ;
use Drupal\Core\Cache\Cache ;
use Drupal\Core\Extension\Extension ;
use Drupal\Core\Render\Element ;
use Drupal\Core\Template\Attribute ;
/**
* Recursively check compatibility .
*
* @ param $incompatible
* An associative array which at the end of the check contains all
* incompatible files as the keys , their values being TRUE .
* @ param $files
* The set of files that will be tested .
* @ param \Drupal\Core\Extension\Extension $file
* The file at which the check starts .
* @ return
* Returns TRUE if an incompatible file is found , NULL ( no return value )
* otherwise .
*/
function _system_is_incompatible ( & $incompatible , $files , Extension $file ) {
if ( isset ( $incompatible [ $file -> getName ()])) {
return TRUE ;
}
// Recursively traverse required modules, looking for incompatible modules.
foreach ( $file -> requires as $requires ) {
if ( isset ( $files [ $requires ]) && _system_is_incompatible ( $incompatible , $files , $files [ $requires ])) {
$incompatible [ $file -> getName ()] = TRUE ;
return TRUE ;
}
}
}
/**
* Prepares variables for administrative content block templates .
*
* Default template : admin - block - content . html . twig .
*
* @ param $variables
* An associative array containing :
* - content : An array containing information about the block . Each element
* of the array represents an administrative menu item , and must at least
* contain the keys 'title' , 'link_path' , and 'localized_options' , which are
* passed to l () . A 'description' key may also be provided .
*/
function template_preprocess_admin_block_content ( & $variables ) {
if ( ! empty ( $variables [ 'content' ])) {
$variables [ 'compact' ] = system_admin_compact_mode ();
foreach ( $variables [ 'content' ] as $key => $item ) {
$variables [ 'content' ][ $key ][ 'link' ] = \Drupal :: l ( $item [ 'title' ], $item [ 'url' ]);
if ( ! $variables [ 'compact' ] && isset ( $item [ 'description' ])) {
2015-08-27 19:03:05 +00:00
$variables [ 'content' ][ $key ][ 'description' ] = [ '#markup' => $item [ 'description' ]];
2015-08-18 00:00:26 +00:00
}
else {
$variables [ 'content' ][ $key ][ 'description' ] = FALSE ;
}
}
}
}
/**
* Prepares variables for administrative index page templates .
*
* Default template : admin - page . html . twig .
*
* @ param $variables
* An associative array containing :
* - blocks : An array of blocks to display . Each array should include a
* 'title' , a 'description' , a formatted 'content' and a 'position' which
* will control which container it will be in . This is usually 'left' or
* 'right' .
*/
function template_preprocess_admin_page ( & $variables ) {
$variables [ 'system_compact_link' ] = array (
'#type' => 'system_compact_link' ,
);
$variables [ 'containers' ] = array ();
$stripe = 0 ;
foreach ( $variables [ 'blocks' ] as $block ) {
if ( ! empty ( $block [ 'content' ][ '#content' ])) {
if ( empty ( $block [ 'position' ])) {
// Perform automatic striping.
$block [ 'position' ] = ++ $stripe % 2 ? 'left' : 'right' ;
}
$variables [ 'containers' ][ $block [ 'position' ]][ 'blocks' ][] = array (
'#theme' => 'admin_block' ,
'#block' => $block ,
);
}
}
}
/**
* Prepares variables for admin index templates .
*
* Default template : system - admin - index . html . twig .
*
* @ param $variables
* An associative array containing :
* - menu_items : An array of modules to be displayed .
*/
function template_preprocess_system_admin_index ( & $variables ) {
$variables [ 'system_compact_link' ] = array (
'#type' => 'system_compact_link' ,
);
$variables [ 'containers' ] = array ();
$stripe = 0 ;
// Iterate over all modules.
foreach ( $variables [ 'menu_items' ] as $module => $block ) {
list ( $description , $items ) = $block ;
$position = ++ $stripe % 2 ? 'left' : 'right' ;
// Output links.
if ( count ( $items )) {
$variables [ 'containers' ][ $position ][] = array (
'#theme' => 'admin_block' ,
'#block' => array (
'position' => $position ,
'title' => $module ,
'content' => array (
'#theme' => 'admin_block_content' ,
'#content' => $items ,
),
'description' => t ( $description ),
),
);
}
}
}
/**
* Prepares variables for status report template .
*
* Default template : status - report . html . twig .
*
* This theme function is dependent on install . inc being loaded , because
* that ' s where the constants are defined .
*
* @ param $variables
* An associative array containing :
* - requirements : An array of requirements / status items . Each requirement
* is an associative array containing the following elements :
* - title : The name of the requirement .
* - value : ( optional ) The current value ( version , time , level , etc ) .
* - description : ( optional ) The description of the requirement .
* - severity : ( optional ) The requirement ' s result / severity level , one of :
* - REQUIREMENT_INFO : Status information .
* - REQUIREMENT_OK : The requirement is satisfied .
* - REQUIREMENT_WARNING : The requirement failed with a warning .
* - REQUIREMENT_ERROR : The requirement failed with an error .
*/
function template_preprocess_status_report ( & $variables ) {
$severities = array (
REQUIREMENT_INFO => array (
'title' => t ( 'Info' ),
'status' => 'info' ,
),
REQUIREMENT_OK => array (
'title' => t ( 'OK' ),
'status' => 'ok' ,
),
REQUIREMENT_WARNING => array (
'title' => t ( 'Warning' ),
'status' => 'warning' ,
),
REQUIREMENT_ERROR => array (
'title' => t ( 'Error' ),
'status' => 'error' ,
),
);
foreach ( $variables [ 'requirements' ] as $i => $requirement ) {
// Always use the explicit requirement severity, if defined. Otherwise,
// default to REQUIREMENT_OK in the installer to visually confirm that
// installation requirements are met. And default to REQUIREMENT_INFO to
// denote neutral information without special visualization.
if ( isset ( $requirement [ 'severity' ])) {
$severity = $severities [( int ) $requirement [ 'severity' ]];
}
elseif ( defined ( 'MAINTENANCE_MODE' ) && MAINTENANCE_MODE == 'install' ) {
$severity = $severities [ REQUIREMENT_OK ];
}
else {
$severity = $severities [ REQUIREMENT_INFO ];
}
$variables [ 'requirements' ][ $i ][ 'severity_title' ] = $severity [ 'title' ];
$variables [ 'requirements' ][ $i ][ 'severity_status' ] = $severity [ 'status' ];
}
}
/**
* Returns HTML for the modules form .
*
* @ param $variables
* An associative array containing :
* - form : A render element representing the form .
*
* @ ingroup themeable
*/
function theme_system_modules_details ( $variables ) {
$form = $variables [ 'form' ];
// Individual table headers.
$rows = array ();
// Iterate through all the modules, which are children of this element.
foreach ( Element :: children ( $form ) as $key ) {
// Stick the key into $module for easier access.
$module = $form [ $key ];
// Create the row for the table.
$row = array ();
// Add the checkbox into the first cell.
unset ( $module [ 'enable' ][ '#title' ]);
$module [ '#requires' ] = array_filter ( $module [ '#requires' ]);
$module [ '#required_by' ] = array_filter ( $module [ '#required_by' ]);
$requires = ! empty ( $module [ '#requires' ]);
$required_by = ! empty ( $module [ '#required_by' ]);
$version = ! empty ( $module [ 'version' ][ '#markup' ]);
$row [] = array ( 'class' => array ( 'checkbox' ), 'data' => drupal_render ( $module [ 'enable' ]));
// Add the module label and expand/collapse functionality.
$id = Html :: getUniqueId ( 'module-' . $key );
2015-09-04 20:20:09 +00:00
$col2 = [
'#type' => 'inline_template' ,
'#template' => '<label id="{{ id }}" for="{{ enable_id }}" class="module-name table-filter-text-source">{{ module_name }}</label>' ,
'#context' => [
'id' => $id ,
'enable_id' => $module [ 'enable' ][ '#id' ],
'module_name' => $module [ 'name' ],
],
];
$row [] = [ 'class' => [ 'module' ], 'data' => $col2 ];
2015-08-18 00:00:26 +00:00
// Add the description, along with any modules it requires.
$description = '' ;
$description .= '<div class="requirements">' ;
$description .= '<div class="admin-requirements">' . t ( 'Machine name: !machine-name' , array ( '!machine-name' => '<span dir="ltr" class="table-filter-text-source">' . $key . '</span>' )) . '</div>' ;
2015-09-04 20:20:09 +00:00
if ( $version ) {
$description .= '<div class="admin-requirements">' . t ( 'Version: !module-version' , array ( '!module-version' => drupal_render ( $module [ 'version' ]))) . '</div>' ;
}
if ( $requires ) {
$description .= '<div class="admin-requirements">' . t ( 'Requires: !module-list' , array ( '!module-list' => implode ( ', ' , $module [ '#requires' ]))) . '</div>' ;
}
if ( $required_by ) {
$description .= '<div class="admin-requirements">' . t ( 'Required by: !module-list' , array ( '!module-list' => implode ( ', ' , $module [ '#required_by' ]))) . '</div>' ;
2015-08-18 00:00:26 +00:00
}
$description .= '</div>' ;
$links = '' ;
foreach ( array ( 'help' , 'permissions' , 'configure' ) as $link_type ) {
$links .= drupal_render ( $module [ 'links' ][ $link_type ]);
}
if ( $links ) {
$description .= ' <div class="links">' ;
$description .= $links ;
$description .= '</div>' ;
}
2015-09-04 20:20:09 +00:00
$title = [
'#type' => 'inline_template' ,
'#template' => '<span class="text module-description">{{ module_description }}</span>' ,
'#context' => [ 'module_description' => $module [ 'description' ]],
];
2015-08-18 00:00:26 +00:00
$details = array (
'#type' => 'details' ,
2015-09-04 20:20:09 +00:00
'#title' => $title ,
2015-08-18 00:00:26 +00:00
'#attributes' => array ( 'id' => $module [ 'enable' ][ '#id' ] . '-description' ),
'#description' => $description ,
);
2015-09-04 20:20:09 +00:00
$row [] = [ 'class' => [ 'description' , 'expand' ], 'data' => $details ];
2015-08-18 00:00:26 +00:00
$rows [] = $module [ '#attributes' ] + array ( 'data' => $row );
}
$table = array (
'#type' => 'table' ,
'#header' => $form [ '#header' ],
'#rows' => $rows ,
);
return drupal_render ( $table );
}
/**
* Returns HTML for a table of currently disabled modules .
*
* @ param $variables
* An associative array containing :
* - form : A render element representing the form .
*
* @ ingroup themeable
*/
function theme_system_modules_uninstall ( $variables ) {
$form = $variables [ 'form' ];
// No theming for the confirm form.
if ( isset ( $form [ 'confirm' ])) {
return drupal_render ( $form );
}
// Table headers.
$header = array ( t ( 'Uninstall' ),
t ( 'Name' ),
t ( 'Description' ),
);
// Display table.
$rows = array ();
foreach ( Element :: children ( $form [ 'modules' ]) as $module ) {
$disabled_header = '' ;
$disabled_reasons = '' ;
// Add the modules requiring the module in question as a validation reason.
if ( ! empty ( $form [ 'modules' ][ $module ][ '#required_by' ])) {
$form [ 'modules' ][ $module ][ '#validation_reasons' ][] = \Drupal :: translation () -> translate ( 'Required by: @modules' , array ( '@modules' => implode ( ', ' , $form [ 'modules' ][ $module ][ '#required_by' ])));
}
if ( ! empty ( $form [ 'modules' ][ $module ][ '#validation_reasons' ])) {
$disabled_reasons = [
'#theme' => 'item_list' ,
'#items' => $form [ 'modules' ][ $module ][ '#validation_reasons' ],
];
$disabled_reasons = drupal_render ( $disabled_reasons );
$disabled_header = \Drupal :: translation () -> formatPlural ( count ( $form [ 'modules' ][ $module ][ '#validation_reasons' ]),
'The following reason prevents @module from being uninstalled:' ,
'The following reasons prevents @module from being uninstalled:' ,
array ( '@module' => $form [ 'modules' ][ $module ][ '#module_name' ]));
}
$rows [] = array (
array ( 'data' => drupal_render ( $form [ 'uninstall' ][ $module ]), 'align' => 'center' ),
array (
'data' => array (
'#type' => 'inline_template' ,
'#template' => '<label for="{{ module_id }}" class="module-name table-filter-text-source">{{ module_name }}</label>' ,
'#context' => array ( 'module_id' => $form [ 'uninstall' ][ $module ][ '#id' ], 'module_name' => drupal_render ( $form [ 'modules' ][ $module ][ 'name' ])),
)
),
array (
'data' => array (
'#type' => 'inline_template' ,
2015-08-27 19:03:05 +00:00
'#template' => '<span class="text module-description">{{ module_description }}</span>{% if disabled_header is not empty %}<div class="admin-requirements">{{ disabled_header }}{{ disabled_reasons }}</div>{% endif %}' ,
2015-08-18 00:00:26 +00:00
'#context' => array (
'module_description' => drupal_render ( $form [ 'modules' ][ $module ][ 'description' ]),
'disabled_header' => $disabled_header ,
'disabled_reasons' => $disabled_reasons ,
),
),
'class' => array ( 'description' ),
),
);
}
$table = array (
'#type' => 'table' ,
'#header' => $header ,
'#rows' => $rows ,
'#empty' => t ( 'No modules are available to uninstall.' ),
);
$output = drupal_render ( $form [ 'filters' ]);
$output .= drupal_render ( $table );
$output .= drupal_render_children ( $form );
return $output ;
}
/**
* Prepares variables for appearance page templates .
*
* Default template : system - themes - page . html . twig .
*
* @ param $variables
* An associative array containing :
* - theme_groups : An associative array containing groups of themes .
* - theme_group_titles : An associative array containing titles of themes .
*/
function template_preprocess_system_themes_page ( & $variables ) {
$groups = array ();
$theme_groups = $variables [ 'theme_groups' ];
$variables [ 'attributes' ][ 'id' ] = 'system-themes-page' ;
foreach ( $variables [ 'theme_group_titles' ] as $state => $title ) {
if ( ! count ( $theme_groups [ $state ])) {
// Skip this group of themes if no theme is there.
continue ;
}
// Start new theme group.
$theme_group = array ();
$theme_group [ 'state' ] = $state ;
$theme_group [ 'title' ] = $title ;
$theme_group [ 'themes' ] = array ();
$theme_group [ 'attributes' ] = new Attribute ();
foreach ( $theme_groups [ $state ] as $theme ) {
$current_theme = array ();
// Screenshot depicting the theme.
if ( $theme -> screenshot ) {
$current_theme [ 'screenshot' ] = array (
'#theme' => 'image' ,
'#uri' => $theme -> screenshot [ 'uri' ],
'#alt' => $theme -> screenshot [ 'alt' ],
'#title' => $theme -> screenshot [ 'title' ],
'#attributes' => $theme -> screenshot [ 'attributes' ],
);
}
else {
$current_theme [ 'screenshot' ] = array (
'#theme' => 'image' ,
'#uri' => drupal_get_path ( 'module' , 'system' ) . '/images/no_screenshot.png' ,
'#alt' => t ( 'No screenshot' ),
'#title' => t ( 'No screenshot' ),
'#attributes' => new Attribute ( array ( 'class' => array ( 'no-screenshot' ))),
);
}
// Localize the theme description.
$current_theme [ 'description' ] = t ( $theme -> info [ 'description' ]);
$current_theme [ 'attributes' ] = new Attribute ();
$current_theme [ 'name' ] = $theme -> info [ 'name' ];
$current_theme [ 'version' ] = isset ( $theme -> info [ 'version' ]) ? $theme -> info [ 'version' ] : '' ;
$current_theme [ 'notes' ] = $theme -> notes ;
$current_theme [ 'is_default' ] = $theme -> is_default ;
$current_theme [ 'is_admin' ] = $theme -> is_admin ;
// Make sure to provide feedback on compatibility.
$current_theme [ 'incompatible' ] = '' ;
if ( ! empty ( $theme -> incompatible_core )) {
2015-08-27 19:03:05 +00:00
$current_theme [ 'incompatible' ] = t ( " This theme is not compatible with Drupal @core_version. Check that the .info.yml file contains the correct 'core' value. " , [ '@core_version' => \Drupal :: CORE_COMPATIBILITY ]);
}
elseif ( ! empty ( $theme -> incompatible_region )) {
$current_theme [ 'incompatible' ] = t ( " This theme is missing a 'content' region. " );
2015-08-18 00:00:26 +00:00
}
elseif ( ! empty ( $theme -> incompatible_php )) {
if ( substr_count ( $theme -> info [ 'php' ], '.' ) < 2 ) {
$theme -> info [ 'php' ] .= '.*' ;
}
$current_theme [ 'incompatible' ] = t ( 'This theme requires PHP version @php_required and is incompatible with PHP version !php_version.' , array ( '@php_required' => $theme -> info [ 'php' ], '!php_version' => phpversion ()));
}
elseif ( ! empty ( $theme -> incompatible_base )) {
$current_theme [ 'incompatible' ] = t ( 'This theme requires the base theme @base_theme to operate correctly.' , array ( '@base_theme' => $theme -> info [ 'base theme' ]));
}
elseif ( ! empty ( $theme -> incompatible_engine )) {
$current_theme [ 'incompatible' ] = t ( 'This theme requires the theme engine @theme_engine to operate correctly.' , array ( '@theme_engine' => $theme -> info [ 'engine' ]));
}
// Build operation links.
$current_theme [ 'operations' ] = array (
'#theme' => 'links' ,
'#links' => $theme -> operations ,
'#attributes' => array (
'class' => array ( 'operations' , 'clearfix' ),
),
);
$theme_group [ 'themes' ][] = $current_theme ;
}
$groups [] = $theme_group ;
}
$variables [ 'theme_groups' ] = $groups ;
}