updated core to 7.73
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Callbacks provided by the form system.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup callbacks
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Perform a single batch operation.
|
||||
*
|
||||
* Callback for batch_set().
|
||||
*
|
||||
* @param $MULTIPLE_PARAMS
|
||||
* Additional parameters specific to the batch. These are specified in the
|
||||
* array passed to batch_set().
|
||||
* @param $context
|
||||
* The batch context array, passed by reference. This contains the following
|
||||
* properties:
|
||||
* - 'finished': A float number between 0 and 1 informing the processing
|
||||
* engine of the completion level for the operation. 1 (or no value
|
||||
* explicitly set) means the operation is finished: the operation will not
|
||||
* be called again, and execution passes to the next operation or the
|
||||
* callback_batch_finished() implementation. Any other value causes this
|
||||
* operation to be called again; however it should be noted that the value
|
||||
* set here does not persist between executions of this callback: each time
|
||||
* it is set to 1 by default by the batch system.
|
||||
* - 'sandbox': This may be used by operations to persist data between
|
||||
* successive calls to the current operation. Any values set in
|
||||
* $context['sandbox'] will be there the next time this function is called
|
||||
* for the current operation. For example, an operation may wish to store a
|
||||
* pointer in a file or an offset for a large query. The 'sandbox' array key
|
||||
* is not initially set when this callback is first called, which makes it
|
||||
* useful for determining whether it is the first call of the callback or
|
||||
* not:
|
||||
* @code
|
||||
* if (empty($context['sandbox'])) {
|
||||
* // Perform set-up steps here.
|
||||
* }
|
||||
* @endcode
|
||||
* The values in the sandbox are stored and updated in the database between
|
||||
* http requests until the batch finishes processing. This avoids problems
|
||||
* if the user navigates away from the page before the batch finishes.
|
||||
* - 'message': A text message displayed in the progress page.
|
||||
* - 'results': The array of results gathered so far by the batch processing.
|
||||
* This array is highly useful for passing data between operations. After
|
||||
* all operations have finished, this is passed to callback_batch_finished()
|
||||
* where results may be referenced to display information to the end-user,
|
||||
* such as how many total items were processed.
|
||||
*/
|
||||
function callback_batch_operation($MULTIPLE_PARAMS, &$context) {
|
||||
if (!isset($context['sandbox']['progress'])) {
|
||||
$context['sandbox']['progress'] = 0;
|
||||
$context['sandbox']['current_node'] = 0;
|
||||
$context['sandbox']['max'] = db_query('SELECT COUNT(DISTINCT nid) FROM {node}')->fetchField();
|
||||
}
|
||||
|
||||
// For this example, we decide that we can safely process
|
||||
// 5 nodes at a time without a timeout.
|
||||
$limit = 5;
|
||||
|
||||
// With each pass through the callback, retrieve the next group of nids.
|
||||
$result = db_query_range("SELECT nid FROM {node} WHERE nid > %d ORDER BY nid ASC", $context['sandbox']['current_node'], 0, $limit);
|
||||
while ($row = db_fetch_array($result)) {
|
||||
|
||||
// Here we actually perform our processing on the current node.
|
||||
$node = node_load($row['nid'], NULL, TRUE);
|
||||
$node->value1 = $options1;
|
||||
$node->value2 = $options2;
|
||||
node_save($node);
|
||||
|
||||
// Store some result for post-processing in the finished callback.
|
||||
$context['results'][] = check_plain($node->title);
|
||||
|
||||
// Update our progress information.
|
||||
$context['sandbox']['progress']++;
|
||||
$context['sandbox']['current_node'] = $node->nid;
|
||||
$context['message'] = t('Now processing %node', array('%node' => $node->title));
|
||||
}
|
||||
|
||||
// Inform the batch engine that we are not finished,
|
||||
// and provide an estimation of the completion level we reached.
|
||||
if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
|
||||
$context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Complete a batch process.
|
||||
*
|
||||
* Callback for batch_set().
|
||||
*
|
||||
* This callback may be specified in a batch to perform clean-up operations, or
|
||||
* to analyze the results of the batch operations.
|
||||
*
|
||||
* @param $success
|
||||
* A boolean indicating whether the batch has completed successfully.
|
||||
* @param $results
|
||||
* The value set in $context['results'] by callback_batch_operation().
|
||||
* @param $operations
|
||||
* If $success is FALSE, contains the operations that remained unprocessed.
|
||||
*/
|
||||
function callback_batch_finished($success, $results, $operations) {
|
||||
if ($success) {
|
||||
// Here we do something meaningful with the results.
|
||||
$message = t("!count items were processed.", array(
|
||||
'!count' => count($results),
|
||||
));
|
||||
$message .= theme('item_list', array('items' => $results));
|
||||
drupal_set_message($message);
|
||||
}
|
||||
else {
|
||||
// An error occurred.
|
||||
// $operations contains the operations that remained unprocessed.
|
||||
$error_operation = reset($operations);
|
||||
$message = t('An error occurred while processing %error_operation with arguments: @arguments', array(
|
||||
'%error_operation' => $error_operation[0],
|
||||
'@arguments' => print_r($error_operation[1], TRUE)
|
||||
));
|
||||
drupal_set_message($message, 'error');
|
||||
}
|
||||
}
|
||||
+86
-36
@@ -56,13 +56,8 @@ function image_gd_settings_validate($form, &$form_state) {
|
||||
* A boolean indicating if the GD toolkit is available on this machine.
|
||||
*/
|
||||
function image_gd_check_settings() {
|
||||
if ($check = get_extension_funcs('gd')) {
|
||||
if (in_array('imagegd2', $check)) {
|
||||
// GD2 support is available.
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
// GD2 support is available.
|
||||
return function_exists('imagegd2');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -121,38 +116,62 @@ function image_gd_rotate(stdClass $image, $degrees, $background = NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$width = $image->info['width'];
|
||||
$height = $image->info['height'];
|
||||
// PHP 5.5 GD bug: https://bugs.php.net/bug.php?id=65148: To prevent buggy
|
||||
// behavior on negative multiples of 90 degrees we convert any negative
|
||||
// angle to a positive one between 0 and 360 degrees.
|
||||
$degrees -= floor($degrees / 360) * 360;
|
||||
|
||||
// Convert the hexadecimal background value to a color index value.
|
||||
// Convert the hexadecimal background value to a RGBA array.
|
||||
if (isset($background)) {
|
||||
$rgb = array();
|
||||
for ($i = 16; $i >= 0; $i -= 8) {
|
||||
$rgb[] = (($background >> $i) & 0xFF);
|
||||
}
|
||||
$background = imagecolorallocatealpha($image->resource, $rgb[0], $rgb[1], $rgb[2], 0);
|
||||
$background = array(
|
||||
'red' => $background >> 16 & 0xFF,
|
||||
'green' => $background >> 8 & 0xFF,
|
||||
'blue' => $background & 0xFF,
|
||||
'alpha' => 0,
|
||||
);
|
||||
}
|
||||
// Set the background color as transparent if $background is NULL.
|
||||
else {
|
||||
// Get the current transparent color.
|
||||
$background = imagecolortransparent($image->resource);
|
||||
|
||||
// If no transparent colors, use white.
|
||||
if ($background == 0) {
|
||||
$background = imagecolorallocatealpha($image->resource, 255, 255, 255, 0);
|
||||
}
|
||||
// Background color is not specified: use transparent white as background.
|
||||
$background = array(
|
||||
'red' => 255,
|
||||
'green' => 255,
|
||||
'blue' => 255,
|
||||
'alpha' => 127
|
||||
);
|
||||
}
|
||||
|
||||
// Store the color index for the background as that is what GD uses.
|
||||
$background_idx = imagecolorallocatealpha($image->resource, $background['red'], $background['green'], $background['blue'], $background['alpha']);
|
||||
|
||||
// Images are assigned a new color palette when rotating, removing any
|
||||
// transparency flags. For GIF images, keep a record of the transparent color.
|
||||
if ($image->info['extension'] == 'gif') {
|
||||
$transparent_index = imagecolortransparent($image->resource);
|
||||
if ($transparent_index != 0) {
|
||||
$transparent_gif_color = imagecolorsforindex($image->resource, $transparent_index);
|
||||
// GIF does not work with a transparency channel, but can define 1 color
|
||||
// in its palette to act as transparent.
|
||||
|
||||
// Get the current transparent color, if any.
|
||||
$gif_transparent_id = imagecolortransparent($image->resource);
|
||||
if ($gif_transparent_id !== -1) {
|
||||
// The gif already has a transparent color set: remember it to set it on
|
||||
// the rotated image as well.
|
||||
$transparent_gif_color = imagecolorsforindex($image->resource, $gif_transparent_id);
|
||||
|
||||
if ($background['alpha'] >= 127) {
|
||||
// We want a transparent background: use the color already set to act
|
||||
// as transparent, as background.
|
||||
$background_idx = $gif_transparent_id;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// The gif does not currently have a transparent color set.
|
||||
if ($background['alpha'] >= 127) {
|
||||
// But as the background is transparent, it should get one.
|
||||
$transparent_gif_color = $background;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$image->resource = imagerotate($image->resource, 360 - $degrees, $background);
|
||||
$image->resource = imagerotate($image->resource, 360 - $degrees, $background_idx);
|
||||
|
||||
// GIFs need to reassign the transparent color after performing the rotate.
|
||||
if (isset($transparent_gif_color)) {
|
||||
@@ -234,7 +253,24 @@ function image_gd_desaturate(stdClass $image) {
|
||||
function image_gd_load(stdClass $image) {
|
||||
$extension = str_replace('jpg', 'jpeg', $image->info['extension']);
|
||||
$function = 'imagecreatefrom' . $extension;
|
||||
return (function_exists($function) && $image->resource = $function($image->source));
|
||||
if (function_exists($function) && $image->resource = $function($image->source)) {
|
||||
if (imageistruecolor($image->resource)) {
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
// Convert indexed images to truecolor, copying the image to a new
|
||||
// truecolor resource, so that filters work correctly and don't result
|
||||
// in unnecessary dither.
|
||||
$resource = image_gd_create_tmp($image, $image->info['width'], $image->info['height']);
|
||||
if ($resource) {
|
||||
imagecopy($resource, $image->resource, 0, 0, 0, 0, imagesx($resource), imagesy($resource));
|
||||
imagedestroy($image->resource);
|
||||
$image->resource = $resource;
|
||||
}
|
||||
}
|
||||
return (bool) $image->resource;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -302,17 +338,31 @@ function image_gd_create_tmp(stdClass $image, $width, $height) {
|
||||
$res = imagecreatetruecolor($width, $height);
|
||||
|
||||
if ($image->info['extension'] == 'gif') {
|
||||
// Grab transparent color index from image resource.
|
||||
// Find out if a transparent color is set, will return -1 if no
|
||||
// transparent color has been defined in the image.
|
||||
$transparent = imagecolortransparent($image->resource);
|
||||
|
||||
if ($transparent >= 0) {
|
||||
// The original must have a transparent color, allocate to the new image.
|
||||
$transparent_color = imagecolorsforindex($image->resource, $transparent);
|
||||
$transparent = imagecolorallocate($res, $transparent_color['red'], $transparent_color['green'], $transparent_color['blue']);
|
||||
// Find out the number of colors in the image palette. It will be 0 for
|
||||
// truecolor images.
|
||||
$palette_size = imagecolorstotal($image->resource);
|
||||
if ($palette_size == 0 || $transparent < $palette_size) {
|
||||
// Set the transparent color in the new resource, either if it is a
|
||||
// truecolor image or if the transparent color is part of the palette.
|
||||
// Since the index of the transparency color is a property of the
|
||||
// image rather than of the palette, it is possible that an image
|
||||
// could be created with this index set outside the palette size (see
|
||||
// http://stackoverflow.com/a/3898007).
|
||||
$transparent_color = imagecolorsforindex($image->resource, $transparent);
|
||||
$transparent = imagecolorallocate($res, $transparent_color['red'], $transparent_color['green'], $transparent_color['blue']);
|
||||
|
||||
// Flood with our new transparent color.
|
||||
imagefill($res, 0, 0, $transparent);
|
||||
imagecolortransparent($res, $transparent);
|
||||
// Flood with our new transparent color.
|
||||
imagefill($res, 0, 0, $transparent);
|
||||
imagecolortransparent($res, $transparent);
|
||||
}
|
||||
else {
|
||||
imagefill($res, 0, 0, imagecolorallocate($res, 255, 255, 255));
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif ($image->info['extension'] == 'png') {
|
||||
@@ -346,7 +396,7 @@ function image_gd_create_tmp(stdClass $image, $width, $height) {
|
||||
*/
|
||||
function image_gd_get_info(stdClass $image) {
|
||||
$details = FALSE;
|
||||
$data = getimagesize($image->source);
|
||||
$data = @getimagesize($image->source);
|
||||
|
||||
if (isset($data) && is_array($data)) {
|
||||
$extensions = array('1' => 'gif', '2' => 'jpg', '3' => 'png');
|
||||
|
||||
@@ -111,18 +111,18 @@ function hook_language_types_info_alter(array &$language_types) {
|
||||
*
|
||||
* @return
|
||||
* An associative array of language negotiation provider definitions. The keys
|
||||
* are provider identifiers, and the values are associative arrays definining
|
||||
* are provider identifiers, and the values are associative arrays defining
|
||||
* each provider, with the following elements:
|
||||
* - types: An array of allowed language types. If a language negotiation
|
||||
* provider does not specify which language types it should be used with, it
|
||||
* will be available for all the configurable language types.
|
||||
* - callbacks: An associative array of functions that will be called to
|
||||
* perform various tasks. Possible elements are:
|
||||
* - negotiation: (required) Name of the callback function that determines
|
||||
* the language value.
|
||||
* - language_switch: (optional) Name of the callback function that
|
||||
* determines links for a language switcher block associated with this
|
||||
* provider. See language_switcher_url() for an example.
|
||||
* - language: (required) Name of the callback function that determines the
|
||||
* language value.
|
||||
* - switcher: (optional) Name of the callback function that determines
|
||||
* links for a language switcher block associated with this provider. See
|
||||
* language_switcher_url() for an example.
|
||||
* - url_rewrite: (optional) Name of the callback function that provides URL
|
||||
* rewriting, if needed by this provider.
|
||||
* - file: The file where callback functions are defined (this file will be
|
||||
|
||||
@@ -309,7 +309,7 @@ function system_theme_enable() {
|
||||
}
|
||||
drupal_goto('admin/appearance');
|
||||
}
|
||||
return drupal_access_denied();
|
||||
return MENU_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -337,7 +337,7 @@ function system_theme_disable() {
|
||||
}
|
||||
drupal_goto('admin/appearance');
|
||||
}
|
||||
return drupal_access_denied();
|
||||
return MENU_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -383,7 +383,7 @@ function system_theme_default() {
|
||||
}
|
||||
drupal_goto('admin/appearance');
|
||||
}
|
||||
return drupal_access_denied();
|
||||
return MENU_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -572,9 +572,10 @@ function system_theme_settings($form, &$form_state, $key = '') {
|
||||
// Process the theme and all its base themes.
|
||||
foreach ($theme_keys as $theme) {
|
||||
// Include the theme-settings.php file.
|
||||
$filename = DRUPAL_ROOT . '/' . str_replace("/$theme.info", '', $themes[$theme]->filename) . '/theme-settings.php';
|
||||
if (file_exists($filename)) {
|
||||
require_once $filename;
|
||||
$theme_settings_path = drupal_get_path('theme', $theme) . '/theme-settings.php';
|
||||
if (file_exists(DRUPAL_ROOT . '/' . $theme_settings_path)) {
|
||||
require_once DRUPAL_ROOT . '/' . $theme_settings_path;
|
||||
$form_state['build_info']['files'][] = $theme_settings_path;
|
||||
}
|
||||
|
||||
// Call theme-specific settings.
|
||||
@@ -640,13 +641,13 @@ function system_theme_settings_validate($form, &$form_state) {
|
||||
|
||||
// If the user provided a path for a logo or favicon file, make sure a file
|
||||
// exists at that path.
|
||||
if ($form_state['values']['logo_path']) {
|
||||
if (!empty($form_state['values']['logo_path'])) {
|
||||
$path = _system_theme_settings_validate_path($form_state['values']['logo_path']);
|
||||
if (!$path) {
|
||||
form_set_error('logo_path', t('The custom logo path is invalid.'));
|
||||
}
|
||||
}
|
||||
if ($form_state['values']['favicon_path']) {
|
||||
if (!empty($form_state['values']['favicon_path'])) {
|
||||
$path = _system_theme_settings_validate_path($form_state['values']['favicon_path']);
|
||||
if (!$path) {
|
||||
form_set_error('favicon_path', t('The custom favicon path is invalid.'));
|
||||
@@ -703,14 +704,16 @@ function system_theme_settings_submit($form, &$form_state) {
|
||||
|
||||
// If the user uploaded a new logo or favicon, save it to a permanent location
|
||||
// and use it in place of the default theme-provided file.
|
||||
if ($file = $values['logo_upload']) {
|
||||
if (!empty($values['logo_upload'])) {
|
||||
$file = $values['logo_upload'];
|
||||
unset($values['logo_upload']);
|
||||
$filename = file_unmanaged_copy($file->uri);
|
||||
$values['default_logo'] = 0;
|
||||
$values['logo_path'] = $filename;
|
||||
$values['toggle_logo'] = 1;
|
||||
}
|
||||
if ($file = $values['favicon_upload']) {
|
||||
if (!empty($values['favicon_upload'])) {
|
||||
$file = $values['favicon_upload'];
|
||||
unset($values['favicon_upload']);
|
||||
$filename = file_unmanaged_copy($file->uri);
|
||||
$values['default_favicon'] = 0;
|
||||
@@ -950,7 +953,11 @@ function system_sort_modules_by_info_name($a, $b) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Array sorting callback; sorts modules or themes by their name.
|
||||
* Sorts themes by their names, with the default theme listed first.
|
||||
*
|
||||
* Callback for uasort() within system_themes_page().
|
||||
*
|
||||
* @see system_sort_modules_by_info_name().
|
||||
*/
|
||||
function system_sort_themes($a, $b) {
|
||||
if ($a->is_default) {
|
||||
@@ -995,22 +1002,28 @@ function _system_modules_build_row($info, $extra) {
|
||||
$status_short = '';
|
||||
$status_long = '';
|
||||
|
||||
// Initialize empty arrays of long and short reasons explaining why the
|
||||
// module is incompatible.
|
||||
// Add each reason as a separate element in both the arrays.
|
||||
$reasons_short = array();
|
||||
$reasons_long = array();
|
||||
|
||||
// Check the core compatibility.
|
||||
if (!isset($info['core']) || $info['core'] != DRUPAL_CORE_COMPATIBILITY) {
|
||||
$compatible = FALSE;
|
||||
$status_short .= t('Incompatible with this version of Drupal core.');
|
||||
$status_long .= t('This version is not compatible with Drupal !core_version and should be replaced.', array('!core_version' => DRUPAL_CORE_COMPATIBILITY));
|
||||
$reasons_short[] = t('Incompatible with this version of Drupal core.');
|
||||
$reasons_long[] = t('This version is not compatible with Drupal !core_version and should be replaced.', array('!core_version' => DRUPAL_CORE_COMPATIBILITY));
|
||||
}
|
||||
|
||||
// Ensure this module is compatible with the currently installed version of PHP.
|
||||
if (version_compare(phpversion(), $info['php']) < 0) {
|
||||
$compatible = FALSE;
|
||||
$status_short .= t('Incompatible with this version of PHP');
|
||||
$reasons_short[] = t('Incompatible with this version of PHP');
|
||||
$php_required = $info['php'];
|
||||
if (substr_count($info['php'], '.') < 2) {
|
||||
$php_required .= '.*';
|
||||
}
|
||||
$status_long .= t('This module requires PHP version @php_required and is incompatible with PHP version !php_version.', array('@php_required' => $php_required, '!php_version' => phpversion()));
|
||||
$reasons_long[] = t('This module requires PHP version @php_required and is incompatible with PHP version !php_version.', array('@php_required' => $php_required, '!php_version' => phpversion()));
|
||||
}
|
||||
|
||||
// If this module is compatible, present a checkbox indicating
|
||||
@@ -1026,6 +1039,8 @@ function _system_modules_build_row($info, $extra) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
$status_short = implode(' ', $reasons_short);
|
||||
$status_long = implode(' ', $reasons_long);
|
||||
$form['enable'] = array(
|
||||
'#markup' => theme('image', array('path' => 'misc/watchdog-error.png', 'alt' => $status_short, 'title' => $status_short)),
|
||||
);
|
||||
@@ -1618,6 +1633,7 @@ function system_cron_settings() {
|
||||
$form['cron']['cron_safe_threshold'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Run cron every'),
|
||||
'#description' => t('More information about setting up scheduled tasks can be found by <a href="@url">reading the cron tutorial on drupal.org</a>.', array('@url' => url('http://drupal.org/cron'))),
|
||||
'#default_value' => variable_get('cron_safe_threshold', DRUPAL_CRON_DEFAULT_THRESHOLD),
|
||||
'#options' => array(0 => t('Never')) + drupal_map_assoc(array(3600, 10800, 21600, 43200, 86400, 604800), 'format_interval'),
|
||||
);
|
||||
@@ -1797,7 +1813,7 @@ function system_file_system_settings() {
|
||||
'#title' => t('Private file system path'),
|
||||
'#default_value' => variable_get('file_private_path', ''),
|
||||
'#maxlength' => 255,
|
||||
'#description' => t('An existing local file system path for storing private files. It should be writable by Drupal and not accessible over the web. See the online handbook for <a href="@handbook">more information about securing private files</a>.', array('@handbook' => 'http://drupal.org/documentation/modules/file')),
|
||||
'#description' => t('An existing local file system path for storing private files. It should be writable by Drupal and not accessible over the web. See the online handbook for <a href="@handbook">more information about securing private files</a>.', array('@handbook' => 'https://www.drupal.org/docs/7/core/modules/file/overview')),
|
||||
'#after_build' => array('system_check_directory'),
|
||||
);
|
||||
|
||||
@@ -1841,7 +1857,7 @@ function system_image_toolkit_settings() {
|
||||
if (count($toolkits_available) == 0) {
|
||||
variable_del('image_toolkit');
|
||||
$form['image_toolkit_help'] = array(
|
||||
'#markup' => t("No image toolkits were detected. Drupal includes support for <a href='!gd-link'>PHP's built-in image processing functions</a> but they were not detected on this system. You should consult your system administrator to have them enabled, or try using a third party toolkit.", array('gd-link' => url('http://php.net/gd'))),
|
||||
'#markup' => t("No image toolkits were detected. Drupal includes support for <a href='!gd-link'>PHP's built-in image processing functions</a> but they were not detected on this system. You should consult your system administrator to have them enabled, or try using a third party toolkit.", array('!gd-link' => url('http://php.net/gd'))),
|
||||
);
|
||||
return $form;
|
||||
}
|
||||
@@ -2187,6 +2203,11 @@ function system_add_date_format_type_form_submit($form, &$form_state) {
|
||||
* Return the date for a given format string via Ajax.
|
||||
*/
|
||||
function system_date_time_lookup() {
|
||||
// This callback is protected with a CSRF token because user input from the
|
||||
// query string is reflected in the output.
|
||||
if (!isset($_GET['token']) || !drupal_valid_token($_GET['token'], 'admin/config/regional/date-time/formats/lookup')) {
|
||||
return MENU_ACCESS_DENIED;
|
||||
}
|
||||
$result = format_date(REQUEST_TIME, 'custom', $_GET['format']);
|
||||
drupal_json_output($result);
|
||||
}
|
||||
@@ -2545,9 +2566,21 @@ function theme_system_admin_index($variables) {
|
||||
/**
|
||||
* Returns HTML for the status report.
|
||||
*
|
||||
* 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.
|
||||
* - 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.
|
||||
*
|
||||
* @ingroup themeable
|
||||
*/
|
||||
@@ -2575,8 +2608,10 @@ function theme_status_report($variables) {
|
||||
|
||||
foreach ($requirements as $requirement) {
|
||||
if (empty($requirement['#type'])) {
|
||||
$severity = $severities[isset($requirement['severity']) ? (int) $requirement['severity'] : 0];
|
||||
$severity = $severities[isset($requirement['severity']) ? (int) $requirement['severity'] : REQUIREMENT_OK];
|
||||
$severity['icon'] = '<div title="' . $severity['title'] . '"><span class="element-invisible">' . $severity['title'] . '</span></div>';
|
||||
// The requirement's 'value' key is optional, provide a default value.
|
||||
$requirement['value'] = isset($requirement['value']) ? $requirement['value'] : '';
|
||||
|
||||
// Output table row(s)
|
||||
if (!empty($requirement['description'])) {
|
||||
@@ -2631,8 +2666,8 @@ function theme_system_modules_fieldset($variables) {
|
||||
}
|
||||
$row[] = array('data' => $description, 'class' => array('description'));
|
||||
// Display links (such as help or permissions) in their own columns.
|
||||
foreach (array('help', 'permissions', 'configure') as $key) {
|
||||
$row[] = array('data' => drupal_render($module['links'][$key]), 'class' => array($key));
|
||||
foreach (array('help', 'permissions', 'configure') as $link_type) {
|
||||
$row[] = array('data' => drupal_render($module['links'][$link_type]), 'class' => array($link_type));
|
||||
}
|
||||
$rows[] = $row;
|
||||
}
|
||||
@@ -2860,13 +2895,14 @@ function system_date_time_formats() {
|
||||
* Allow users to add additional date formats.
|
||||
*/
|
||||
function system_configure_date_formats_form($form, &$form_state, $dfid = 0) {
|
||||
$ajax_path = 'admin/config/regional/date-time/formats/lookup';
|
||||
$js_settings = array(
|
||||
'type' => 'setting',
|
||||
'data' => array(
|
||||
'dateTime' => array(
|
||||
'date-format' => array(
|
||||
'text' => t('Displayed as'),
|
||||
'lookup' => url('admin/config/regional/date-time/formats/lookup'),
|
||||
'lookup' => url($ajax_path, array('query' => array('token' => drupal_get_token($ajax_path)))),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
+342
-116
@@ -84,25 +84,23 @@ function hook_hook_info_alter(&$hooks) {
|
||||
* Defaults to TRUE.
|
||||
* - load hook: The name of the hook which should be invoked by
|
||||
* DrupalDefaultEntityController:attachLoad(), for example 'node_load'.
|
||||
* - uri callback: A function taking an entity as argument and returning the
|
||||
* URI elements of the entity, e.g. 'path' and 'options'. The actual entity
|
||||
* URI can be constructed by passing these elements to url().
|
||||
* - label callback: (optional) A function taking an entity and an entity type
|
||||
* as arguments and returning the label of the entity. The entity label is
|
||||
* the main string associated with an entity; for example, the title of a
|
||||
* node or the subject of a comment. If there is an entity object property
|
||||
* that defines the label, use the 'label' element of the 'entity keys'
|
||||
* return value component to provide this information (see below). If more
|
||||
* complex logic is needed to determine the label of an entity, you can
|
||||
* instead specify a callback function here, which will be called to
|
||||
* determine the entity label. See also the entity_label() function, which
|
||||
* implements this logic.
|
||||
* - language callback: (optional) A function taking an entity and an entity
|
||||
* type as arguments and returning a language code. In most situations, when
|
||||
* needing to determine this value, inspecting a property named after the
|
||||
* 'language' element of the 'entity keys' should be enough. The language
|
||||
* callback is meant to be used primarily for temporary alterations of the
|
||||
* property value: entity-defining modules are encouraged to always define a
|
||||
* - uri callback: The name of an implementation of
|
||||
* callback_entity_info_uri().
|
||||
* - label callback: (optional) The name of an implementation of
|
||||
* callback_entity_info_label(), which returns the label of the entity. The
|
||||
* entity label is the main string associated with an entity; for example,
|
||||
* the title of a node or the subject of a comment. If there is an entity
|
||||
* object property that defines the label, then using the 'label' element of
|
||||
* the 'entity keys' return value component suffices to provide this
|
||||
* information (see below). Alternatively, specifying this callback allows
|
||||
* more complex logic to determine the label of an entity. See also the
|
||||
* entity_label() function, which implements this logic.
|
||||
* - language callback: (optional) The name of an implementation of
|
||||
* callback_entity_info_language(). In most situations, when needing to
|
||||
* determine this value, inspecting a property named after the 'language'
|
||||
* element of the 'entity keys' should be enough. The language callback is
|
||||
* meant to be used primarily for temporary alterations of the property
|
||||
* value: entity-defining modules are encouraged to always define a
|
||||
* language property, instead of using the callback as main entity language
|
||||
* source. In fact not having a language property defined is likely to
|
||||
* prevent an entity from being queried by language. Moreover, given that
|
||||
@@ -115,21 +113,21 @@ function hook_hook_info_alter(&$hooks) {
|
||||
* translation handlers. Array keys are the module names, array values
|
||||
* can be any data structure the module uses to provide field translation.
|
||||
* Any empty value disallows the module to appear as a translation handler.
|
||||
* - entity keys: An array describing how the Field API can extract the
|
||||
* information it needs from the objects of the type. Elements:
|
||||
* - entity keys: (optional) An array describing how the Field API can extract
|
||||
* the information it needs from the objects of the type. Elements:
|
||||
* - id: The name of the property that contains the primary id of the
|
||||
* entity. Every entity object passed to the Field API must have this
|
||||
* property and its value must be numeric.
|
||||
* - revision: The name of the property that contains the revision id of
|
||||
* the entity. The Field API assumes that all revision ids are unique
|
||||
* across all entities of a type. This entry can be omitted if the
|
||||
* entities of this type are not versionable.
|
||||
* entities of this type are not versionable. Defaults to an empty string.
|
||||
* - bundle: The name of the property that contains the bundle name for the
|
||||
* entity. The bundle name defines which set of fields are attached to
|
||||
* the entity (e.g. what nodes call "content type"). This entry can be
|
||||
* omitted if this entity type exposes a single bundle (all entities have
|
||||
* the same collection of fields). The name of this single bundle will be
|
||||
* the same as the entity type.
|
||||
* the same as the entity type. Defaults to an empty string.
|
||||
* - label: The name of the property that contains the entity label. For
|
||||
* example, if the entity's label is located in $entity->subject, then
|
||||
* 'subject' should be specified here. If complex logic is required to
|
||||
@@ -249,7 +247,7 @@ function hook_entity_info() {
|
||||
'custom settings' => FALSE,
|
||||
),
|
||||
'search_result' => array(
|
||||
'label' => t('Search result'),
|
||||
'label' => t('Search result highlighting input'),
|
||||
'custom settings' => FALSE,
|
||||
),
|
||||
);
|
||||
@@ -608,11 +606,13 @@ function hook_cron() {
|
||||
* @return
|
||||
* An associative array where the key is the queue name and the value is
|
||||
* again an associative array. Possible keys are:
|
||||
* - 'worker callback': The name of the function to call. It will be called
|
||||
* with one argument, the item created via DrupalQueue::createItem() in
|
||||
* hook_cron().
|
||||
* - 'worker callback': The name of an implementation of
|
||||
* callback_queue_worker().
|
||||
* - 'time': (optional) How much time Drupal should spend on calling this
|
||||
* worker in seconds. Defaults to 15.
|
||||
* - 'skip on cron': (optional) Set to TRUE to avoid being processed during
|
||||
* cron runs (for example, if you want to control all queue execution
|
||||
* manually).
|
||||
*
|
||||
* @see hook_cron()
|
||||
* @see hook_cron_queue_info_alter()
|
||||
@@ -709,9 +709,10 @@ function hook_element_info_alter(&$type) {
|
||||
/**
|
||||
* Perform cleanup tasks.
|
||||
*
|
||||
* This hook is run at the end of each page request. It is often used for
|
||||
* page logging and specialized cleanup. This hook MUST NOT print anything
|
||||
* because by the time it runs the response is already sent to the browser.
|
||||
* This hook is run at the end of most regular page requests. It is often
|
||||
* used for page logging and specialized cleanup. This hook MUST NOT print
|
||||
* anything because by the time it runs the response is already sent to
|
||||
* the browser.
|
||||
*
|
||||
* Only use this hook if your code must run even for cached page views.
|
||||
* If you have code which must run once on all non-cached pages, use
|
||||
@@ -874,7 +875,7 @@ function hook_css_alter(&$css) {
|
||||
*
|
||||
* @see ajax_render()
|
||||
*/
|
||||
function hook_ajax_render_alter($commands) {
|
||||
function hook_ajax_render_alter(&$commands) {
|
||||
// Inject any new status messages into the content area.
|
||||
$commands[] = ajax_command_prepend('#block-system-main .content', theme('status_messages'));
|
||||
}
|
||||
@@ -958,6 +959,7 @@ function hook_menu_get_item_alter(&$router_item, $path, $original_map) {
|
||||
* paths and whose values are an associative array of properties for each
|
||||
* path. (The complete list of properties is in the return value section below.)
|
||||
*
|
||||
* @section sec_callback_funcs Callback Functions
|
||||
* The definition for each path may include a page callback function, which is
|
||||
* invoked when the registered path is requested. If there is no other
|
||||
* registered path that fits the requested path better, any further path
|
||||
@@ -982,6 +984,7 @@ function hook_menu_get_item_alter(&$router_item, $path, $original_map) {
|
||||
* $jkl will be 'foo'. Note that this automatic passing of optional path
|
||||
* arguments applies only to page and theme callback functions.
|
||||
*
|
||||
* @subsection sub_callback_arguments Callback Arguments
|
||||
* In addition to optional path arguments, the page callback and other callback
|
||||
* functions may specify argument lists as arrays. These argument lists may
|
||||
* contain both fixed/hard-coded argument values and integers that correspond
|
||||
@@ -1024,6 +1027,8 @@ function hook_menu_get_item_alter(&$router_item, $path, $original_map) {
|
||||
* @endcode
|
||||
* See @link form_api Form API documentation @endlink for details.
|
||||
*
|
||||
* @section sec_path_wildcards Wildcards in Paths
|
||||
* @subsection sub_simple_wildcards Simple Wildcards
|
||||
* Wildcards within paths also work with integer substitution. For example,
|
||||
* your module could register path 'my-module/%/edit':
|
||||
* @code
|
||||
@@ -1036,6 +1041,7 @@ function hook_menu_get_item_alter(&$router_item, $path, $original_map) {
|
||||
* with 'foo' and passed to the callback function. Note that wildcards may not
|
||||
* be used as the first component.
|
||||
*
|
||||
* @subsection sub_autoload_wildcards Auto-Loader Wildcards
|
||||
* Registered paths may also contain special "auto-loader" wildcard components
|
||||
* in the form of '%mymodule_abc', where the '%' part means that this path
|
||||
* component is a wildcard, and the 'mymodule_abc' part defines the prefix for a
|
||||
@@ -1067,6 +1073,7 @@ function hook_menu_get_item_alter(&$router_item, $path, $original_map) {
|
||||
* return FALSE for the path 'node/999/edit' if a node with a node ID of 999
|
||||
* does not exist. The menu routing system will return a 404 error in this case.
|
||||
*
|
||||
* @subsection sub_argument_wildcards Argument Wildcards
|
||||
* You can also define a %wildcard_to_arg() function (for the example menu
|
||||
* entry above this would be 'mymodule_abc_to_arg()'). The _to_arg() function
|
||||
* is invoked to retrieve a value that is used in the path in place of the
|
||||
@@ -1091,6 +1098,7 @@ function hook_menu_get_item_alter(&$router_item, $path, $original_map) {
|
||||
* are called when the menu system is generating links to related paths, such
|
||||
* as the tabs for a set of MENU_LOCAL_TASK items.
|
||||
*
|
||||
* @section sec_render_tabs Rendering Menu Items As Tabs
|
||||
* You can also make groups of menu items to be rendered (by default) as tabs
|
||||
* on a page. To do that, first create one menu item of type MENU_NORMAL_ITEM,
|
||||
* with your chosen path, such as 'foo'. Then duplicate that menu item, using a
|
||||
@@ -1789,6 +1797,8 @@ function hook_form_BASE_FORM_ID_alter(&$form, &$form_state, $form_id) {
|
||||
* the $form_id input matched your module's format for dynamically-generated
|
||||
* form IDs, and if so, act appropriately.
|
||||
*
|
||||
* Third, forms defined in classes can be defined this way.
|
||||
*
|
||||
* @param $form_id
|
||||
* The unique string identifying the desired form.
|
||||
* @param $args
|
||||
@@ -1799,19 +1809,22 @@ function hook_form_BASE_FORM_ID_alter(&$form, &$form_state, $form_id) {
|
||||
* @return
|
||||
* An associative array whose keys define form_ids and whose values are an
|
||||
* associative array defining the following keys:
|
||||
* - callback: The name of the form builder function to invoke. This will be
|
||||
* used for the base form ID, for example, to target a base form using
|
||||
* hook_form_BASE_FORM_ID_alter().
|
||||
* - callback: The callable returning the form array. If it is the name of
|
||||
* the form builder function then this will be used for the base
|
||||
* form ID, for example, to target a base form using
|
||||
* hook_form_BASE_FORM_ID_alter(). Otherwise use the base_form_id key to
|
||||
* define the base form ID.
|
||||
* - callback arguments: (optional) Additional arguments to pass to the
|
||||
* function defined in 'callback', which are prepended to $args.
|
||||
* - wrapper_callback: (optional) The name of a form builder function to
|
||||
* invoke before the form builder defined in 'callback' is invoked. This
|
||||
* wrapper callback may prepopulate the $form array with form elements,
|
||||
* which will then be already contained in the $form that is passed on to
|
||||
* the form builder defined in 'callback'. For example, a wrapper callback
|
||||
* could setup wizard-alike form buttons that are the same for a variety of
|
||||
* forms that belong to the wizard, which all share the same wrapper
|
||||
* callback.
|
||||
* - base_form_id: The base form ID can be specified explicitly. This is
|
||||
* required when callback is not the name of a function.
|
||||
* - wrapper_callback: (optional) Any callable to invoke before the form
|
||||
* builder defined in 'callback' is invoked. This wrapper callback may
|
||||
* prepopulate the $form array with form elements, which will then be
|
||||
* already contained in the $form that is passed on to the form builder
|
||||
* defined in 'callback'. For example, a wrapper callback could setup
|
||||
* wizard-like form buttons that are the same for a variety of forms that
|
||||
* belong to the wizard, which all share the same wrapper callback.
|
||||
*/
|
||||
function hook_forms($form_id, $args) {
|
||||
// Simply reroute the (non-existing) $form_id 'mymodule_first_form' to
|
||||
@@ -1835,6 +1848,15 @@ function hook_forms($form_id, $args) {
|
||||
'wrapper_callback' => 'mymodule_main_form_wrapper',
|
||||
);
|
||||
|
||||
// Build a form with a static class callback.
|
||||
$forms['mymodule_class_generated_form'] = array(
|
||||
// This will call: MyClass::generateMainForm().
|
||||
'callback' => array('MyClass', 'generateMainForm'),
|
||||
// The base_form_id is required when the callback is a static function in
|
||||
// a class. This can also be used to keep newer code backwards compatible.
|
||||
'base_form_id' => 'mymodule_main_form',
|
||||
);
|
||||
|
||||
return $forms;
|
||||
}
|
||||
|
||||
@@ -1866,8 +1888,8 @@ function hook_boot() {
|
||||
*
|
||||
* This hook is not run on cached pages.
|
||||
*
|
||||
* To add CSS or JS that should be present on all pages, modules should not
|
||||
* implement this hook, but declare these files in their .info file.
|
||||
* To add CSS or JS files that should be present on all pages, modules should
|
||||
* not implement this hook, but declare these files in their .info file.
|
||||
*
|
||||
* @see hook_boot()
|
||||
*/
|
||||
@@ -1882,9 +1904,8 @@ function hook_init() {
|
||||
/**
|
||||
* Define image toolkits provided by this module.
|
||||
*
|
||||
* The file which includes each toolkit's functions must be declared as part of
|
||||
* the files array in the module .info file so that the registry will find and
|
||||
* parse it.
|
||||
* The file which includes each toolkit's functions must be included in this
|
||||
* hook.
|
||||
*
|
||||
* The toolkit's functions must be named image_toolkitname_operation().
|
||||
* where the operation may be:
|
||||
@@ -2029,6 +2050,22 @@ function hook_system_theme_info() {
|
||||
return $themes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return additional theme engines provided by modules.
|
||||
*
|
||||
* This hook is invoked from _system_rebuild_theme_data() and allows modules to
|
||||
* register additional theme engines outside of the regular 'themes/engines'
|
||||
* directories of a Drupal installation.
|
||||
*
|
||||
* @return
|
||||
* An associative array. Each key is the system name of a theme engine and
|
||||
* each value is the corresponding path to the theme engine's .engine file.
|
||||
*/
|
||||
function hook_system_theme_engine_info() {
|
||||
$theme_engines['izumi'] = drupal_get_path('module', 'mymodule') . '/izumi/izumi.engine';
|
||||
return $theme_engines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter the information parsed from module and theme .info files
|
||||
*
|
||||
@@ -2101,6 +2138,61 @@ function hook_permission() {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide online user help.
|
||||
*
|
||||
* By implementing hook_help(), a module can make documentation available to
|
||||
* the user for the module as a whole, or for specific paths. Help for
|
||||
* developers should usually be provided via function header comments in the
|
||||
* code, or in special API example files.
|
||||
*
|
||||
* The page-specific help information provided by this hook appears as a system
|
||||
* help block on that page. The module overview help information is displayed
|
||||
* by the Help module. It can be accessed from the page at admin/help or from
|
||||
* the Modules page.
|
||||
*
|
||||
* For detailed usage examples of:
|
||||
* - Module overview help, see node_help(). Module overview help should follow
|
||||
* @link https://drupal.org/node/632280 the standard help template. @endlink
|
||||
* - Page-specific help with simple paths, see dashboard_help().
|
||||
* - Page-specific help using wildcards in path and $arg, see node_help()
|
||||
* and block_help().
|
||||
*
|
||||
* @param $path
|
||||
* The router menu path, as defined in hook_menu(), for the help that is
|
||||
* being requested; e.g., 'admin/people' or 'user/register'. If the router
|
||||
* path includes a wildcard, then this will appear in $path as %, even if it
|
||||
* is a named %autoloader wildcard in the hook_menu() implementation; for
|
||||
* example, node pages would have $path equal to 'node/%' or 'node/%/view'.
|
||||
* For the help page for the module as a whole, $path will have the value
|
||||
* 'admin/help#module_name', where 'module_name" is the machine name of your
|
||||
* module.
|
||||
* @param $arg
|
||||
* An array that corresponds to the return value of the arg() function, for
|
||||
* modules that want to provide help that is specific to certain values
|
||||
* of wildcards in $path. For example, you could provide help for the path
|
||||
* 'user/1' by looking for the path 'user/%' and $arg[1] == '1'. This given
|
||||
* array should always be used rather than directly invoking arg(), because
|
||||
* your hook implementation may be called for other purposes besides building
|
||||
* the current page's help. Note that depending on which module is invoking
|
||||
* hook_help, $arg may contain only empty strings. Regardless, $arg[0] to
|
||||
* $arg[11] will always be set.
|
||||
*
|
||||
* @return
|
||||
* A localized string containing the help text.
|
||||
*/
|
||||
function hook_help($path, $arg) {
|
||||
switch ($path) {
|
||||
// Main module help for the block module
|
||||
case 'admin/help#block':
|
||||
return '<p>' . t('Blocks are boxes of content rendered into an area, or region, of a web page. The default theme Bartik, for example, implements the regions "Sidebar first", "Sidebar second", "Featured", "Content", "Header", "Footer", etc., and a block may appear in any one of these areas. The <a href="@blocks">blocks administration page</a> provides a drag-and-drop interface for assigning a block to a region, and for controlling the order of blocks within regions.', array('@blocks' => url('admin/structure/block'))) . '</p>';
|
||||
|
||||
// Help for another path in the block module
|
||||
case 'admin/structure/block':
|
||||
return '<p>' . t('This page provides a drag-and-drop interface for assigning a block to a region, and for controlling the order of blocks within regions. Since not all themes implement the same regions, or display regions in the same way, blocks are positioned on a per-theme basis. Remember that your changes will not be saved until you click the <em>Save blocks</em> button at the bottom of the page.') . '</p>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a module (or theme's) theme implementations.
|
||||
*
|
||||
@@ -2302,7 +2394,7 @@ function hook_theme_registry_alter(&$theme_registry) {
|
||||
* @return
|
||||
* The machine-readable name of the theme that should be used for the current
|
||||
* page request. The value returned from this function will only have an
|
||||
* effect if it corresponds to a currently-active theme on the site. Do not
|
||||
* effect if it corresponds to a currently-active theme on the site. Do not
|
||||
* return a value if you do not wish to set a custom theme.
|
||||
*/
|
||||
function hook_custom_theme() {
|
||||
@@ -2570,6 +2662,8 @@ function hook_flush_caches() {
|
||||
* module_enable() for a detailed description of the order in which install and
|
||||
* enable hooks are invoked.
|
||||
*
|
||||
* This hook should be implemented in a .module file, not in an .install file.
|
||||
*
|
||||
* @param $modules
|
||||
* An array of the modules that were installed.
|
||||
*
|
||||
@@ -2826,7 +2920,15 @@ function hook_file_insert($file) {
|
||||
* @see file_save()
|
||||
*/
|
||||
function hook_file_update($file) {
|
||||
$file_user = user_load($file->uid);
|
||||
// Make sure that the file name starts with the owner's user name.
|
||||
if (strpos($file->filename, $file_user->name) !== 0) {
|
||||
$old_filename = $file->filename;
|
||||
$file->filename = $file_user->name . '_' . $file->filename;
|
||||
$file->save();
|
||||
|
||||
watchdog('file', t('%source has been renamed to %destination', array('%source' => $old_filename, '%destination' => $file->filename)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2840,7 +2942,14 @@ function hook_file_update($file) {
|
||||
* @see file_copy()
|
||||
*/
|
||||
function hook_file_copy($file, $source) {
|
||||
$file_user = user_load($file->uid);
|
||||
// Make sure that the file name starts with the owner's user name.
|
||||
if (strpos($file->filename, $file_user->name) !== 0) {
|
||||
$file->filename = $file_user->name . '_' . $file->filename;
|
||||
$file->save();
|
||||
|
||||
watchdog('file', t('Copied file %source has been renamed to %destination', array('%source' => $source->filename, '%destination' => $file->filename)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2854,7 +2963,14 @@ function hook_file_copy($file, $source) {
|
||||
* @see file_move()
|
||||
*/
|
||||
function hook_file_move($file, $source) {
|
||||
$file_user = user_load($file->uid);
|
||||
// Make sure that the file name starts with the owner's user name.
|
||||
if (strpos($file->filename, $file_user->name) !== 0) {
|
||||
$file->filename = $file_user->name . '_' . $file->filename;
|
||||
$file->save();
|
||||
|
||||
watchdog('file', t('Moved file %source has been renamed to %destination', array('%source' => $source->filename, '%destination' => $file->filename)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3006,8 +3122,9 @@ function hook_file_url_alter(&$uri) {
|
||||
* status report page.
|
||||
*
|
||||
* @return
|
||||
* A keyed array of requirements. Each requirement is itself an array with
|
||||
* the following items:
|
||||
* An associative array where the keys are arbitrary but must be unique (it
|
||||
* is suggested to use the module short name as a prefix) and the values are
|
||||
* themselves associative arrays with the following elements:
|
||||
* - title: The name of the requirement.
|
||||
* - value: The current value (e.g., version, time, level, etc). During
|
||||
* install phase, this should only be used for version numbers, do not set
|
||||
@@ -3069,37 +3186,41 @@ function hook_requirements($phase) {
|
||||
/**
|
||||
* Define the current version of the database schema.
|
||||
*
|
||||
* A Drupal schema definition is an array structure representing one or
|
||||
* more tables and their related keys and indexes. A schema is defined by
|
||||
* A Drupal schema definition is an array structure representing one or more
|
||||
* tables and their related keys and indexes. A schema is defined by
|
||||
* hook_schema() which must live in your module's .install file.
|
||||
*
|
||||
* This hook is called at install and uninstall time, and in the latter
|
||||
* case, it cannot rely on the .module file being loaded or hooks being known.
|
||||
* If the .module file is needed, it may be loaded with drupal_load().
|
||||
* This hook is called at install and uninstall time, and in the latter case, it
|
||||
* cannot rely on the .module file being loaded or hooks being known. If the
|
||||
* .module file is needed, it may be loaded with drupal_load().
|
||||
*
|
||||
* The tables declared by this hook will be automatically created when
|
||||
* the module is first enabled, and removed when the module is uninstalled.
|
||||
* This happens before hook_install() is invoked, and after hook_uninstall()
|
||||
* is invoked, respectively.
|
||||
* The tables declared by this hook will be automatically created when the
|
||||
* module is first enabled, and removed when the module is uninstalled. This
|
||||
* happens before hook_install() is invoked, and after hook_uninstall() is
|
||||
* invoked, respectively.
|
||||
*
|
||||
* By declaring the tables used by your module via an implementation of
|
||||
* hook_schema(), these tables will be available on all supported database
|
||||
* engines. You don't have to deal with the different SQL dialects for table
|
||||
* creation and alteration of the supported database engines.
|
||||
*
|
||||
* See the Schema API Handbook at http://drupal.org/node/146843 for
|
||||
* details on schema definition structures.
|
||||
* See the Schema API Handbook at http://drupal.org/node/146843 for details on
|
||||
* schema definition structures. Note that foreign key definitions are for
|
||||
* documentation purposes only; foreign keys are not created in the database,
|
||||
* nor are they enforced by Drupal.
|
||||
*
|
||||
* @return
|
||||
* @return array
|
||||
* A schema definition structure array. For each element of the
|
||||
* array, the key is a table name and the value is a table structure
|
||||
* definition.
|
||||
*
|
||||
* @see hook_schema_alter()
|
||||
*
|
||||
* @ingroup schemaapi
|
||||
*/
|
||||
function hook_schema() {
|
||||
$schema['node'] = array(
|
||||
// example (partial) specification for table "node"
|
||||
// Example (partial) specification for table "node".
|
||||
'description' => 'The base table for nodes.',
|
||||
'fields' => array(
|
||||
'nid' => array(
|
||||
@@ -3138,6 +3259,8 @@ function hook_schema() {
|
||||
'nid_vid' => array('nid', 'vid'),
|
||||
'vid' => array('vid'),
|
||||
),
|
||||
// For documentation purposes only; foreign keys are not created in the
|
||||
// database.
|
||||
'foreign keys' => array(
|
||||
'node_revision' => array(
|
||||
'table' => 'node_revision',
|
||||
@@ -3165,6 +3288,8 @@ function hook_schema() {
|
||||
*
|
||||
* @param $schema
|
||||
* Nested array describing the schemas for all modules.
|
||||
*
|
||||
* @ingroup schemaapi
|
||||
*/
|
||||
function hook_schema_alter(&$schema) {
|
||||
// Add field to existing schema.
|
||||
@@ -3336,24 +3461,31 @@ function hook_install() {
|
||||
* hooks. See @link update_api Update versions of API functions @endlink for
|
||||
* details.
|
||||
*
|
||||
* If your update task is potentially time-consuming, you'll need to implement a
|
||||
* multipass update to avoid PHP timeouts. Multipass updates use the $sandbox
|
||||
* parameter provided by the batch API (normally, $context['sandbox']) to store
|
||||
* information between successive calls, and the $sandbox['#finished'] value
|
||||
* to provide feedback regarding completion level.
|
||||
* The $sandbox parameter should be used when a multipass update is needed, in
|
||||
* circumstances where running the whole update at once could cause PHP to
|
||||
* timeout. Each pass is run in a way that avoids PHP timeouts, provided each
|
||||
* pass remains under the timeout limit. To signify that an update requires
|
||||
* at least one more pass, set $sandbox['#finished'] to a number less than 1
|
||||
* (you need to do this each pass). The value of $sandbox['#finished'] will be
|
||||
* unset between passes but all other data in $sandbox will be preserved. The
|
||||
* system will stop iterating this update when $sandbox['#finished'] is left
|
||||
* unset or set to a number higher than 1. It is recommended that
|
||||
* $sandbox['#finished'] is initially set to 0, and then updated each pass to a
|
||||
* number between 0 and 1 that represents the overall % completed for this
|
||||
* update, finishing with 1.
|
||||
*
|
||||
* See the batch operations page for more information on how to use the
|
||||
* @link http://drupal.org/node/180528 Batch API. @endlink
|
||||
* See the @link batch Batch operations topic @endlink for more information on
|
||||
* how to use the Batch API.
|
||||
*
|
||||
* @param $sandbox
|
||||
* @param array $sandbox
|
||||
* Stores information for multipass updates. See above for more information.
|
||||
*
|
||||
* @throws DrupalUpdateException, PDOException
|
||||
* @throws DrupalUpdateException|PDOException
|
||||
* In case of error, update hooks should throw an instance of DrupalUpdateException
|
||||
* with a meaningful message for the user. If a database query fails for whatever
|
||||
* reason, it will throw a PDOException.
|
||||
*
|
||||
* @return
|
||||
* @return string|null
|
||||
* Optionally, update hooks may return a translated string that will be
|
||||
* displayed to the user after the update has completed. If no message is
|
||||
* returned, no message will be presented to the user.
|
||||
@@ -3597,8 +3729,9 @@ function hook_registry_files_alter(&$files, $modules) {
|
||||
*
|
||||
* Any tasks you define here will be run, in order, after the installer has
|
||||
* finished the site configuration step but before it has moved on to the
|
||||
* final import of languages and the end of the installation. You can have any
|
||||
* number of custom tasks to perform during this phase.
|
||||
* final import of languages and the end of the installation. This is invoked
|
||||
* by install_tasks(). You can have any number of custom tasks to perform
|
||||
* during this phase.
|
||||
*
|
||||
* Each task you define here corresponds to a callback function which you must
|
||||
* separately define and which is called when your task is run. This function
|
||||
@@ -3638,66 +3771,61 @@ function hook_registry_files_alter(&$files, $modules) {
|
||||
* inspect later. It is important to remove any temporary variables using
|
||||
* variable_del() before your last task has completed and control is handed
|
||||
* back to the installer.
|
||||
*
|
||||
*
|
||||
* @param array $install_state
|
||||
* An array of information about the current installation state.
|
||||
*
|
||||
* @return
|
||||
* @return array
|
||||
* A keyed array of tasks the profile will perform during the final stage of
|
||||
* the installation. Each key represents the name of a function (usually a
|
||||
* function defined by this profile, although that is not strictly required)
|
||||
* that is called when that task is run. The values are associative arrays
|
||||
* containing the following key-value pairs (all of which are optional):
|
||||
* - 'display_name'
|
||||
* The human-readable name of the task. This will be displayed to the
|
||||
* user while the installer is running, along with a list of other tasks
|
||||
* that are being run. Leave this unset to prevent the task from
|
||||
* appearing in the list.
|
||||
* - 'display'
|
||||
* This is a boolean which can be used to provide finer-grained control
|
||||
* over whether or not the task will display. This is mostly useful for
|
||||
* tasks that are intended to display only under certain conditions; for
|
||||
* these tasks, you can set 'display_name' to the name that you want to
|
||||
* display, but then use this boolean to hide the task only when certain
|
||||
* conditions apply.
|
||||
* - 'type'
|
||||
* A string representing the type of task. This parameter has three
|
||||
* possible values:
|
||||
* - 'normal': This indicates that the task will be treated as a regular
|
||||
* callback function, which does its processing and optionally returns
|
||||
* HTML output. This is the default behavior which is used when 'type' is
|
||||
* not set.
|
||||
* - 'batch': This indicates that the task function will return a batch
|
||||
* API definition suitable for batch_set(). The installer will then take
|
||||
* care of automatically running the task via batch processing.
|
||||
* - 'form': This indicates that the task function will return a standard
|
||||
* - display_name: The human-readable name of the task. This will be
|
||||
* displayed to the user while the installer is running, along with a list
|
||||
* of other tasks that are being run. Leave this unset to prevent the task
|
||||
* from appearing in the list.
|
||||
* - display: This is a boolean which can be used to provide finer-grained
|
||||
* control over whether or not the task will display. This is mostly useful
|
||||
* for tasks that are intended to display only under certain conditions;
|
||||
* for these tasks, you can set 'display_name' to the name that you want to
|
||||
* display, but then use this boolean to hide the task only when certain
|
||||
* conditions apply.
|
||||
* - type: A string representing the type of task. This parameter has three
|
||||
* possible values:
|
||||
* - normal: (default) This indicates that the task will be treated as a
|
||||
* regular callback function, which does its processing and optionally
|
||||
* returns HTML output.
|
||||
* - batch: This indicates that the task function will return a batch API
|
||||
* definition suitable for batch_set(). The installer will then take care
|
||||
* of automatically running the task via batch processing.
|
||||
* - form: This indicates that the task function will return a standard
|
||||
* form API definition (and separately define validation and submit
|
||||
* handlers, as appropriate). The installer will then take care of
|
||||
* automatically directing the user through the form submission process.
|
||||
* - 'run'
|
||||
* A constant representing the manner in which the task will be run. This
|
||||
* parameter has three possible values:
|
||||
* - INSTALL_TASK_RUN_IF_NOT_COMPLETED: This indicates that the task will
|
||||
* run once during the installation of the profile. This is the default
|
||||
* behavior which is used when 'run' is not set.
|
||||
* - INSTALL_TASK_SKIP: This indicates that the task will not run during
|
||||
* - run: A constant representing the manner in which the task will be run.
|
||||
* This parameter has three possible values:
|
||||
* - INSTALL_TASK_RUN_IF_NOT_COMPLETED: (default) This indicates that the
|
||||
* task will run once during the installation of the profile.
|
||||
* - INSTALL_TASK_SKIP: This indicates that the task will not run during
|
||||
* the current installation page request. It can be used to skip running
|
||||
* an installation task when certain conditions are met, even though the
|
||||
* task may still show on the list of installation tasks presented to the
|
||||
* user.
|
||||
* - INSTALL_TASK_RUN_IF_REACHED: This indicates that the task will run
|
||||
* on each installation page request that reaches it. This is rarely
|
||||
* - INSTALL_TASK_RUN_IF_REACHED: This indicates that the task will run on
|
||||
* each installation page request that reaches it. This is rarely
|
||||
* necessary for an installation profile to use; it is primarily used by
|
||||
* the Drupal installer for bootstrap-related tasks.
|
||||
* - 'function'
|
||||
* Normally this does not need to be set, but it can be used to force the
|
||||
* installer to call a different function when the task is run (rather
|
||||
* than the function whose name is given by the array key). This could be
|
||||
* used, for example, to allow the same function to be called by two
|
||||
* different tasks.
|
||||
* - function: Normally this does not need to be set, but it can be used to
|
||||
* force the installer to call a different function when the task is run
|
||||
* (rather than the function whose name is given by the array key). This
|
||||
* could be used, for example, to allow the same function to be called by
|
||||
* two different tasks.
|
||||
*
|
||||
* @see install_state_defaults()
|
||||
* @see batch_set()
|
||||
* @see hook_install_tasks_alter()
|
||||
* @see install_tasks()
|
||||
*/
|
||||
function hook_install_tasks(&$install_state) {
|
||||
// Here, we define a variable to allow tasks to indicate that a particular,
|
||||
@@ -3800,6 +3928,8 @@ function hook_html_head_alter(&$head_elements) {
|
||||
/**
|
||||
* Alter the full list of installation tasks.
|
||||
*
|
||||
* This hook is invoked on the install profile in install_tasks().
|
||||
*
|
||||
* @param $tasks
|
||||
* An array of all available installation tasks, including those provided by
|
||||
* Drupal core. You can modify this array to change or replace any part of
|
||||
@@ -3807,6 +3937,9 @@ function hook_html_head_alter(&$head_elements) {
|
||||
* is selected.
|
||||
* @param $install_state
|
||||
* An array of information about the current installation state.
|
||||
*
|
||||
* @see hook_install_tasks()
|
||||
* @see install_tasks()
|
||||
*/
|
||||
function hook_install_tasks_alter(&$tasks, $install_state) {
|
||||
// Replace the "Choose language" installation task provided by Drupal core
|
||||
@@ -4071,7 +4204,7 @@ function hook_date_format_types_alter(&$types) {
|
||||
* declared in an implementation of hook_date_format_types().
|
||||
* - 'format': A PHP date format string to use when formatting dates. It
|
||||
* can contain any of the formatting options described at
|
||||
* http://php.net/manual/en/function.date.php
|
||||
* http://php.net/manual/function.date.php
|
||||
* - 'locales': (optional) An array of 2 and 5 character locale codes,
|
||||
* defining which locales this format applies to (for example, 'en',
|
||||
* 'en-us', etc.). If your date format is not language-specific, leave this
|
||||
@@ -4688,6 +4821,99 @@ function hook_filetransfer_info_alter(&$filetransfer_info) {
|
||||
* @} End of "addtogroup hooks".
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup callbacks
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Work on a single queue item.
|
||||
*
|
||||
* Callback for hook_cron_queue_info().
|
||||
*
|
||||
* @param $queue_item_data
|
||||
* The data that was passed to DrupalQueueInterface::createItem() when the
|
||||
* item was queued.
|
||||
*
|
||||
* @throws Exception
|
||||
* The worker callback may throw an exception to indicate there was a problem.
|
||||
* The cron process will log the exception, and leave the item in the queue to
|
||||
* be processed again later.
|
||||
*
|
||||
* @see drupal_cron_run()
|
||||
*/
|
||||
function callback_queue_worker($queue_item_data) {
|
||||
$node = node_load($queue_item_data);
|
||||
$node->title = 'Updated title';
|
||||
node_save($node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the URI for an entity.
|
||||
*
|
||||
* Callback for hook_entity_info().
|
||||
*
|
||||
* @param $entity
|
||||
* The entity to return the URI for.
|
||||
*
|
||||
* @return
|
||||
* An associative array with the following elements:
|
||||
* - 'path': The URL path for the entity.
|
||||
* - 'options': (optional) An array of options for the url() function.
|
||||
* The actual entity URI can be constructed by passing these elements to
|
||||
* url().
|
||||
*/
|
||||
function callback_entity_info_uri($entity) {
|
||||
return array(
|
||||
'path' => 'node/' . $entity->nid,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the label of an entity.
|
||||
*
|
||||
* Callback for hook_entity_info().
|
||||
*
|
||||
* @param $entity
|
||||
* The entity for which to generate the label.
|
||||
* @param $entity_type
|
||||
* The entity type; e.g., 'node' or 'user'.
|
||||
*
|
||||
* @return
|
||||
* An unsanitized string with the label of the entity.
|
||||
*
|
||||
* @see entity_label()
|
||||
*/
|
||||
function callback_entity_info_label($entity, $entity_type) {
|
||||
return empty($entity->title) ? 'Untitled entity' : $entity->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the language code of the entity.
|
||||
*
|
||||
* Callback for hook_entity_info().
|
||||
*
|
||||
* The language callback is meant to be used primarily for temporary alterations
|
||||
* of the property value.
|
||||
*
|
||||
* @param $entity
|
||||
* The entity for which to return the language.
|
||||
* @param $entity_type
|
||||
* The entity type; e.g., 'node' or 'user'.
|
||||
*
|
||||
* @return
|
||||
* The language code for the language of the entity.
|
||||
*
|
||||
* @see entity_language()
|
||||
*/
|
||||
function callback_entity_info_language($entity, $entity_type) {
|
||||
return $entity->language;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} End of "addtogroup callbacks".
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup update_api Update versions of API functions
|
||||
* @{
|
||||
|
||||
@@ -38,10 +38,10 @@ class ArchiverTar implements ArchiverInterface {
|
||||
|
||||
public function extract($path, Array $files = array()) {
|
||||
if ($files) {
|
||||
$this->tar->extractList($files, $path);
|
||||
$this->tar->extractList($files, $path, '', FALSE, FALSE);
|
||||
}
|
||||
else {
|
||||
$this->tar->extract($path);
|
||||
$this->tar->extract($path, FALSE, FALSE);
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
*/
|
||||
/* Animated throbber */
|
||||
html.js input.form-autocomplete {
|
||||
background-position: 0% 2px;
|
||||
background-position: 0% center;
|
||||
}
|
||||
html.js input.throbbing {
|
||||
background-position: 0% -18px;
|
||||
background-position: 0% center;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,12 +31,13 @@
|
||||
}
|
||||
/* Animated throbber */
|
||||
html.js input.form-autocomplete {
|
||||
background-image: url(../../misc/throbber.gif);
|
||||
background-position: 100% 2px; /* LTR */
|
||||
background-image: url(../../misc/throbber-inactive.png);
|
||||
background-position: 100% center; /* LTR */
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
html.js input.throbbing {
|
||||
background-position: 100% -18px; /* LTR */
|
||||
background-image: url(../../misc/throbber-active.gif);
|
||||
background-position: 100% center; /* LTR */
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -164,7 +165,7 @@ table.sticky-header {
|
||||
display: inline-block;
|
||||
}
|
||||
.ajax-progress .throbber {
|
||||
background: transparent url(../../misc/throbber.gif) no-repeat 0px -18px;
|
||||
background: transparent url(../../misc/throbber-active.gif) no-repeat 0px center;
|
||||
float: left; /* LTR */
|
||||
height: 15px;
|
||||
margin: 2px;
|
||||
|
||||
@@ -12,8 +12,7 @@ files[] = system.test
|
||||
required = TRUE
|
||||
configure = admin/config/system
|
||||
|
||||
; Information added by drupal.org packaging script on 2013-04-03
|
||||
version = "7.22"
|
||||
; Information added by Drupal.org packaging script on 2020-09-16
|
||||
version = "7.73"
|
||||
project = "drupal"
|
||||
datestamp = "1365027012"
|
||||
|
||||
datestamp = "1600272641"
|
||||
|
||||
+213
-13
@@ -6,12 +6,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test and report Drupal installation requirements.
|
||||
*
|
||||
* @param $phase
|
||||
* The current system installation phase.
|
||||
* @return
|
||||
* An array of system requirements.
|
||||
* Implements hook_requirements().
|
||||
*/
|
||||
function system_requirements($phase) {
|
||||
global $base_url;
|
||||
@@ -165,7 +160,7 @@ function system_requirements($phase) {
|
||||
if (empty($drivers)) {
|
||||
$database_ok = FALSE;
|
||||
$pdo_message = $t('Your web server does not appear to support any common PDO database extensions. Check with your hosting provider to see if they support PDO (PHP Data Objects) and offer any databases that <a href="@drupal-databases">Drupal supports</a>.', array(
|
||||
'@drupal-databases' => 'http://drupal.org/node/270#database',
|
||||
'@drupal-databases' => 'https://www.drupal.org/requirements/database',
|
||||
));
|
||||
}
|
||||
// Make sure the native PDO extension is available, not the older PEAR
|
||||
@@ -201,6 +196,12 @@ function system_requirements($phase) {
|
||||
);
|
||||
}
|
||||
|
||||
// Test database-specific multi-byte UTF-8 related requirements.
|
||||
$charset_requirements = _system_check_db_utf8mb4_requirements($phase);
|
||||
if (!empty($charset_requirements)) {
|
||||
$requirements['database_charset'] = $charset_requirements;
|
||||
}
|
||||
|
||||
// Test PHP memory_limit
|
||||
$memory_limit = ini_get('memory_limit');
|
||||
$requirements['php_memory_limit'] = array(
|
||||
@@ -208,7 +209,7 @@ function system_requirements($phase) {
|
||||
'value' => $memory_limit == -1 ? t('-1 (Unlimited)') : $memory_limit,
|
||||
);
|
||||
|
||||
if ($memory_limit && $memory_limit != -1 && parse_size($memory_limit) < parse_size(DRUPAL_MINIMUM_PHP_MEMORY_LIMIT)) {
|
||||
if (!drupal_check_memory_limit(DRUPAL_MINIMUM_PHP_MEMORY_LIMIT, $memory_limit)) {
|
||||
$description = '';
|
||||
if ($phase == 'install') {
|
||||
$description = $t('Consider increasing your PHP memory limit to %memory_minimum_limit to help prevent errors in the installation process.', array('%memory_minimum_limit' => DRUPAL_MINIMUM_PHP_MEMORY_LIMIT));
|
||||
@@ -258,6 +259,39 @@ function system_requirements($phase) {
|
||||
$requirements['settings.php']['title'] = $t('Configuration file');
|
||||
}
|
||||
|
||||
// Test the contents of the .htaccess files.
|
||||
if ($phase == 'runtime') {
|
||||
// Try to write the .htaccess files first, to prevent false alarms in case
|
||||
// (for example) the /tmp directory was wiped.
|
||||
file_ensure_htaccess();
|
||||
$htaccess_files['public://.htaccess'] = array(
|
||||
'title' => $t('Public files directory'),
|
||||
'directory' => variable_get('file_public_path', conf_path() . '/files'),
|
||||
);
|
||||
if ($private_files_directory = variable_get('file_private_path')) {
|
||||
$htaccess_files['private://.htaccess'] = array(
|
||||
'title' => $t('Private files directory'),
|
||||
'directory' => $private_files_directory,
|
||||
);
|
||||
}
|
||||
$htaccess_files['temporary://.htaccess'] = array(
|
||||
'title' => $t('Temporary files directory'),
|
||||
'directory' => variable_get('file_temporary_path', file_directory_temp()),
|
||||
);
|
||||
foreach ($htaccess_files as $htaccess_file => $info) {
|
||||
// Check for the string which was added to the recommended .htaccess file
|
||||
// in the latest security update.
|
||||
if (!file_exists($htaccess_file) || !($contents = @file_get_contents($htaccess_file)) || strpos($contents, 'Drupal_Security_Do_Not_Remove_See_SA_2013_003') === FALSE) {
|
||||
$requirements[$htaccess_file] = array(
|
||||
'title' => $info['title'],
|
||||
'value' => $t('Not fully protected'),
|
||||
'severity' => REQUIREMENT_ERROR,
|
||||
'description' => $t('See <a href="@url">@url</a> for information about the recommended .htaccess file which should be added to the %directory directory to help protect against arbitrary code execution.', array('@url' => 'http://drupal.org/SA-CORE-2013-003', '%directory' => $info['directory'])),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Report cron status.
|
||||
if ($phase == 'runtime') {
|
||||
// Cron warning threshold defaults to two days.
|
||||
@@ -489,6 +523,75 @@ function system_requirements($phase) {
|
||||
return $requirements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the requirements for multi-byte UTF-8 support are met.
|
||||
*
|
||||
* @param string $phase
|
||||
* The hook_requirements() stage.
|
||||
*
|
||||
* @return array
|
||||
* A requirements array with the result of the charset check.
|
||||
*/
|
||||
function _system_check_db_utf8mb4_requirements($phase) {
|
||||
global $install_state;
|
||||
// In the requirements check of the installer, skip the utf8mb4 check unless
|
||||
// the database connection info has been preconfigured by hand with valid
|
||||
// information before running the installer, as otherwise we cannot get a
|
||||
// valid database connection object.
|
||||
if (isset($install_state['settings_verified']) && !$install_state['settings_verified']) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$connection = Database::getConnection();
|
||||
$t = get_t();
|
||||
$requirements['title'] = $t('Database 4 byte UTF-8 support');
|
||||
|
||||
$utf8mb4_configurable = $connection->utf8mb4IsConfigurable();
|
||||
$utf8mb4_active = $connection->utf8mb4IsActive();
|
||||
$utf8mb4_supported = $connection->utf8mb4IsSupported();
|
||||
$driver = $connection->driver();
|
||||
$documentation_url = 'https://www.drupal.org/node/2754539';
|
||||
|
||||
if ($utf8mb4_active) {
|
||||
if ($utf8mb4_supported) {
|
||||
if ($phase != 'install' && $utf8mb4_configurable && !variable_get('drupal_all_databases_are_utf8mb4', FALSE)) {
|
||||
// Supported, active, and configurable, but not all database tables
|
||||
// have been converted yet.
|
||||
$requirements['value'] = $t('Enabled, but database tables need conversion');
|
||||
$requirements['description'] = $t('Please convert all database tables to utf8mb4 prior to enabling it in settings.php. See the <a href="@url">documentation on adding 4 byte UTF-8 support</a> for more information.', array('@url' => $documentation_url));
|
||||
$requirements['severity'] = REQUIREMENT_ERROR;
|
||||
}
|
||||
else {
|
||||
// Supported, active.
|
||||
$requirements['value'] = $t('Enabled');
|
||||
$requirements['description'] = $t('4 byte UTF-8 for @driver is enabled.', array('@driver' => $driver));
|
||||
$requirements['severity'] = REQUIREMENT_OK;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Not supported, active.
|
||||
$requirements['value'] = $t('Not supported');
|
||||
$requirements['description'] = $t('4 byte UTF-8 for @driver is activated, but not supported on your system. Please turn this off in settings.php, or ensure that all database-related requirements are met. See the <a href="@url">documentation on adding 4 byte UTF-8 support</a> for more information.', array('@driver' => $driver, '@url' => $documentation_url));
|
||||
$requirements['severity'] = REQUIREMENT_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($utf8mb4_supported) {
|
||||
// Supported, not active.
|
||||
$requirements['value'] = $t('Not enabled');
|
||||
$requirements['description'] = $t('4 byte UTF-8 for @driver is not activated, but it is supported on your system. It is recommended that you enable this to allow 4-byte UTF-8 input such as emojis, Asian symbols and mathematical symbols to be stored correctly. See the <a href="@url">documentation on adding 4 byte UTF-8 support</a> for more information.', array('@driver' => $driver, '@url' => $documentation_url));
|
||||
$requirements['severity'] = REQUIREMENT_INFO;
|
||||
}
|
||||
else {
|
||||
// Not supported, not active.
|
||||
$requirements['value'] = $t('Disabled');
|
||||
$requirements['description'] = $t('4 byte UTF-8 for @driver is disabled. See the <a href="@url">documentation on adding 4 byte UTF-8 support</a> for more information.', array('@driver' => $driver, '@url' => $documentation_url));
|
||||
$requirements['severity'] = REQUIREMENT_INFO;
|
||||
}
|
||||
}
|
||||
return $requirements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_install().
|
||||
*/
|
||||
@@ -504,6 +607,9 @@ function system_install() {
|
||||
module_list(TRUE);
|
||||
module_implements('', FALSE, TRUE);
|
||||
|
||||
// Ensure the schema versions are not based on a previous module list.
|
||||
drupal_static_reset('drupal_get_schema_versions');
|
||||
|
||||
// Load system theme data appropriately.
|
||||
system_rebuild_theme_data();
|
||||
|
||||
@@ -516,7 +622,7 @@ function system_install() {
|
||||
->execute();
|
||||
|
||||
// Populate the cron key variable.
|
||||
$cron_key = drupal_hash_base64(drupal_random_bytes(55));
|
||||
$cron_key = drupal_random_key();
|
||||
variable_set('cron_key', $cron_key);
|
||||
}
|
||||
|
||||
@@ -772,6 +878,7 @@ function system_schema() {
|
||||
'type' => 'varchar',
|
||||
'length' => 100,
|
||||
'not null' => TRUE,
|
||||
'binary' => TRUE,
|
||||
),
|
||||
'type' => array(
|
||||
'description' => 'The date format type, e.g. medium.',
|
||||
@@ -830,6 +937,7 @@ function system_schema() {
|
||||
'filesize' => array(
|
||||
'description' => 'The size of the file in bytes.',
|
||||
'type' => 'int',
|
||||
'size' => 'big',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
@@ -1743,7 +1851,7 @@ function system_update_7000() {
|
||||
* Generate a cron key and save it in the variables table.
|
||||
*/
|
||||
function system_update_7001() {
|
||||
variable_set('cron_key', drupal_hash_base64(drupal_random_bytes(55)));
|
||||
variable_set('cron_key', drupal_random_key());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1983,7 +2091,7 @@ function system_update_7013() {
|
||||
$timezone = 'UTC';
|
||||
}
|
||||
variable_set('date_default_timezone', $timezone);
|
||||
drupal_set_message('The default time zone has been set to <em>' . check_plain($timezone) . '</em>. Check the ' . l('date and time configuration page', 'admin/config/regional/settings') . ' to configure it correctly.', 'warning');
|
||||
drupal_set_message(format_string('The default time zone has been set to %timezone. Check the <a href="@config-url">date and time configuration page</a> to configure it correctly.', array('%timezone' => $timezone, '@config-url' => url('admin/config/regional/settings'))), 'warning');
|
||||
// Remove temporary override.
|
||||
variable_del('date_temporary_timezone');
|
||||
}
|
||||
@@ -2762,7 +2870,7 @@ function system_update_7061(&$sandbox) {
|
||||
if (!db_table_exists('system_update_7061')) {
|
||||
$table = array(
|
||||
'description' => t('Stores temporary data for system_update_7061.'),
|
||||
'fields' => array('vid' => array('type' => 'int')),
|
||||
'fields' => array('vid' => array('type' => 'int', 'not null' => TRUE)),
|
||||
'primary key' => array('vid'),
|
||||
);
|
||||
db_create_table('system_update_7061', $table);
|
||||
@@ -2774,6 +2882,16 @@ function system_update_7061(&$sandbox) {
|
||||
->from($query)
|
||||
->execute();
|
||||
|
||||
// Retrieve a list of duplicate files with the same filepath. Only the
|
||||
// most-recently uploaded of these will be moved to the new {file_managed}
|
||||
// table (and all references will be updated to point to it), since
|
||||
// duplicate file URIs are not allowed in Drupal 7.
|
||||
// Since the Drupal 6 to 7 upgrade path leaves the {files} table behind
|
||||
// after it's done, custom or contributed modules which need to migrate
|
||||
// file references of their own can use a similar query to determine the
|
||||
// file IDs that duplicate filepaths were mapped to.
|
||||
$sandbox['duplicate_filepath_fids_to_use'] = db_query("SELECT filepath, MAX(fid) FROM {files} GROUP BY filepath HAVING COUNT(*) > 1")->fetchAllKeyed();
|
||||
|
||||
// Initialize batch update information.
|
||||
$sandbox['progress'] = 0;
|
||||
$sandbox['last_vid_processed'] = -1;
|
||||
@@ -2803,6 +2921,16 @@ function system_update_7061(&$sandbox) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If this file has a duplicate filepath, replace it with the
|
||||
// most-recently uploaded file that has the same filepath.
|
||||
if (isset($sandbox['duplicate_filepath_fids_to_use'][$file['filepath']]) && $record->fid != $sandbox['duplicate_filepath_fids_to_use'][$file['filepath']]) {
|
||||
$file = db_select('files', 'f')
|
||||
->fields('f', array('fid', 'uid', 'filename', 'filepath', 'filemime', 'filesize', 'status', 'timestamp'))
|
||||
->condition('f.fid', $sandbox['duplicate_filepath_fids_to_use'][$file['filepath']])
|
||||
->execute()
|
||||
->fetchAssoc();
|
||||
}
|
||||
|
||||
// Add in the file information from the upload table.
|
||||
$file['description'] = $record->description;
|
||||
$file['display'] = $record->list;
|
||||
@@ -2825,7 +2953,14 @@ function system_update_7061(&$sandbox) {
|
||||
// We will convert filepaths to URI using the default scheme
|
||||
// and stripping off the existing file directory path.
|
||||
$file['uri'] = $scheme . preg_replace('!^' . preg_quote($basename) . '!', '', $file['filepath']);
|
||||
$file['uri'] = file_stream_wrapper_uri_normalize($file['uri']);
|
||||
// Normalize the URI but don't call file_stream_wrapper_uri_normalize()
|
||||
// directly, since that is a higher-level API function which invokes
|
||||
// hooks while validating the scheme, and those will not work during
|
||||
// the upgrade. Instead, use a simpler version that just assumes the
|
||||
// scheme from above is already valid.
|
||||
if (($file_uri_scheme = file_uri_scheme($file['uri'])) && ($file_uri_target = file_uri_target($file['uri']))) {
|
||||
$file['uri'] = $file_uri_scheme . '://' . $file_uri_target;
|
||||
}
|
||||
unset($file['filepath']);
|
||||
// Insert into the file_managed table.
|
||||
// Each fid should only be stored once in file_managed.
|
||||
@@ -3106,6 +3241,71 @@ function system_update_7078() {
|
||||
), array('unique keys' => array('formats' => array('format', 'type'))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the 'filesize' column in {file_managed} to a bigint.
|
||||
*/
|
||||
function system_update_7079() {
|
||||
$spec = array(
|
||||
'description' => 'The size of the file in bytes.',
|
||||
'type' => 'int',
|
||||
'size' => 'big',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
);
|
||||
db_change_field('file_managed', 'filesize', 'filesize', $spec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the 'format' column in {date_format_locale} to case sensitive varchar.
|
||||
*/
|
||||
function system_update_7080() {
|
||||
$spec = array(
|
||||
'description' => 'The date format string.',
|
||||
'type' => 'varchar',
|
||||
'length' => 100,
|
||||
'not null' => TRUE,
|
||||
'binary' => TRUE,
|
||||
);
|
||||
db_change_field('date_format_locale', 'format', 'format', $spec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the Drupal 6 default install profile if it is still in the database.
|
||||
*/
|
||||
function system_update_7081() {
|
||||
// Sites which used the default install profile in Drupal 6 and then updated
|
||||
// to Drupal 7.44 or earlier will still have a record of this install profile
|
||||
// in the database that needs to be deleted.
|
||||
db_delete('system')
|
||||
->condition('filename', 'profiles/default/default.profile')
|
||||
->condition('type', 'module')
|
||||
->condition('status', 0)
|
||||
->condition('schema_version', 0)
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add 'jquery-extend-3.4.0.js' to the 'jquery' library.
|
||||
*/
|
||||
function system_update_7082() {
|
||||
// Empty update to force a rebuild of hook_library() and JS aggregates.
|
||||
}
|
||||
|
||||
/**
|
||||
* Add 'jquery-html-prefilter-3.5.0-backport.js' to the 'jquery' library.
|
||||
*/
|
||||
function system_update_7083() {
|
||||
// Empty update to force a rebuild of hook_library() and JS aggregates.
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuild JavaScript aggregates to include 'ajax.js' fix for Chrome 83.
|
||||
*/
|
||||
function system_update_7084() {
|
||||
// Empty update to force a rebuild of JS aggregates.
|
||||
}
|
||||
|
||||
/**
|
||||
* @} End of "defgroup updates-7.x-extra".
|
||||
* The next series of updates should start at 8000.
|
||||
|
||||
@@ -105,7 +105,7 @@ Drupal.behaviors.dateTime = {
|
||||
// Attach keyup handler to custom format inputs.
|
||||
$('input' + source, context).once('date-time').keyup(function () {
|
||||
var input = $(this);
|
||||
var url = fieldSettings.lookup + (/\?q=/.test(fieldSettings.lookup) ? '&format=' : '?format=') + encodeURIComponent(input.val());
|
||||
var url = fieldSettings.lookup + (/\?/.test(fieldSettings.lookup) ? '&format=' : '?format=') + encodeURIComponent(input.val());
|
||||
$.getJSON(url, function (data) {
|
||||
$(suffix).empty().append(' ' + fieldSettings.text + ': <em>' + data + '</em>');
|
||||
});
|
||||
|
||||
@@ -31,7 +31,7 @@ class DefaultMailSystem implements MailSystemInterface {
|
||||
/**
|
||||
* Send an e-mail message, using Drupal variables and default settings.
|
||||
*
|
||||
* @see http://php.net/manual/en/function.mail.php
|
||||
* @see http://php.net/manual/function.mail.php
|
||||
* @see drupal_mail()
|
||||
*
|
||||
* @param $message
|
||||
@@ -70,7 +70,9 @@ class DefaultMailSystem implements MailSystemInterface {
|
||||
// hosts. The return value of this method will still indicate whether mail
|
||||
// was sent successfully.
|
||||
if (!isset($_SERVER['WINDIR']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Win32') === FALSE) {
|
||||
if (isset($message['Return-Path']) && !ini_get('safe_mode')) {
|
||||
// We validate the return path, unless it is equal to the site mail, which
|
||||
// we assume to be safe.
|
||||
if (isset($message['Return-Path']) && !ini_get('safe_mode') && (variable_get('site_mail', ini_get('sendmail_from')) === $message['Return-Path'] || self::_isShellSafe($message['Return-Path']))) {
|
||||
// On most non-Windows systems, the "-f" option to the sendmail command
|
||||
// is used to set the Return-Path. There is no space between -f and
|
||||
// the value of the return path.
|
||||
@@ -109,6 +111,36 @@ class DefaultMailSystem implements MailSystemInterface {
|
||||
}
|
||||
return $mail_result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disallows potentially unsafe shell characters.
|
||||
*
|
||||
* Functionally similar to PHPMailer::isShellSafe() which resulted from
|
||||
* CVE-2016-10045. Note that escapeshellarg and escapeshellcmd are inadequate
|
||||
* for this purpose.
|
||||
*
|
||||
* @param string $string
|
||||
* The string to be validated.
|
||||
*
|
||||
* @return bool
|
||||
* True if the string is shell-safe.
|
||||
*
|
||||
* @see https://github.com/PHPMailer/PHPMailer/issues/924
|
||||
* @see https://github.com/PHPMailer/PHPMailer/blob/v5.2.21/class.phpmailer.php#L1430
|
||||
*
|
||||
* @todo Rename to ::isShellSafe() and/or discuss whether this is the correct
|
||||
* location for this helper.
|
||||
*/
|
||||
protected static function _isShellSafe($string) {
|
||||
if (escapeshellcmd($string) !== $string || !in_array(escapeshellarg($string), array("'$string'", "\"$string\""))) {
|
||||
return FALSE;
|
||||
}
|
||||
if (preg_match('/[^a-zA-Z0-9@_\-.]/', $string) !== 0) {
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+106
-29
@@ -242,6 +242,7 @@ function system_permission() {
|
||||
),
|
||||
'access site reports' => array(
|
||||
'title' => t('View site reports'),
|
||||
'restrict access' => TRUE,
|
||||
),
|
||||
'block IP addresses' => array(
|
||||
'title' => t('Block IP addresses'),
|
||||
@@ -322,6 +323,10 @@ function system_element_info() {
|
||||
'#group_callback' => 'drupal_group_css',
|
||||
'#aggregate_callback' => 'drupal_aggregate_css',
|
||||
);
|
||||
$types['scripts'] = array(
|
||||
'#items' => array(),
|
||||
'#pre_render' => array('drupal_pre_render_scripts'),
|
||||
);
|
||||
|
||||
// Input elements.
|
||||
$types['submit'] = array(
|
||||
@@ -358,7 +363,7 @@ function system_element_info() {
|
||||
'#size' => 60,
|
||||
'#maxlength' => 128,
|
||||
'#autocomplete_path' => FALSE,
|
||||
'#process' => array('ajax_process_form'),
|
||||
'#process' => array('form_process_autocomplete', 'ajax_process_form'),
|
||||
'#theme' => 'textfield',
|
||||
'#theme_wrappers' => array('form_element'),
|
||||
);
|
||||
@@ -373,6 +378,9 @@ function system_element_info() {
|
||||
'#element_validate' => array('form_validate_machine_name'),
|
||||
'#theme' => 'textfield',
|
||||
'#theme_wrappers' => array('form_element'),
|
||||
// Use the same value callback as for textfields; this ensures that we only
|
||||
// get string values.
|
||||
'#value_callback' => 'form_type_textfield_value',
|
||||
);
|
||||
$types['password'] = array(
|
||||
'#input' => TRUE,
|
||||
@@ -381,6 +389,9 @@ function system_element_info() {
|
||||
'#process' => array('ajax_process_form'),
|
||||
'#theme' => 'password',
|
||||
'#theme_wrappers' => array('form_element'),
|
||||
// Use the same value callback as for textfields; this ensures that we only
|
||||
// get string values.
|
||||
'#value_callback' => 'form_type_textfield_value',
|
||||
);
|
||||
$types['password_confirm'] = array(
|
||||
'#input' => TRUE,
|
||||
@@ -1175,6 +1186,10 @@ function system_library() {
|
||||
'version' => '1.4.4',
|
||||
'js' => array(
|
||||
'misc/jquery.js' => array('group' => JS_LIBRARY, 'weight' => -20),
|
||||
// These include security fixes, so assign a weight that makes them load
|
||||
// as soon after jquery.js is loaded as possible.
|
||||
'misc/jquery-extend-3.4.0.js' => array('group' => JS_LIBRARY, 'weight' => -19),
|
||||
'misc/jquery-html-prefilter-3.5.0-backport.js' => array('group' => JS_LIBRARY, 'weight' => -19),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -2023,7 +2038,6 @@ function system_user_timezone(&$form, &$form_state) {
|
||||
'#description' => t('Select the desired local time and time zone. Dates and times throughout this site will be displayed using this time zone.'),
|
||||
);
|
||||
if (!isset($account->timezone) && $account->uid == $user->uid && empty($form_state['input']['timezone'])) {
|
||||
$form['timezone']['#description'] = t('Your time zone setting will be automatically detected if possible. Confirm the selection and click save.');
|
||||
$form['timezone']['timezone']['#attributes'] = array('class' => array('timezone-detect'));
|
||||
drupal_add_js('misc/timezone.js');
|
||||
}
|
||||
@@ -2398,9 +2412,17 @@ function _system_rebuild_module_data() {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add the info file modification time, so it becomes available for
|
||||
// contributed modules to use for ordering module lists.
|
||||
$module->info['mtime'] = filemtime(dirname($module->uri) . '/' . $module->name . '.info');
|
||||
|
||||
// Merge in defaults and save.
|
||||
$modules[$key]->info = $module->info + $defaults;
|
||||
|
||||
// The "name" key is required, but to avoid a fatal error in the menu system
|
||||
// we set a reasonable default if it is not provided.
|
||||
$modules[$key]->info += array('name' => $key);
|
||||
|
||||
// Prefix stylesheets and scripts with module path.
|
||||
$path = dirname($module->uri);
|
||||
if (isset($module->info['stylesheets'])) {
|
||||
@@ -2507,6 +2529,16 @@ function _system_rebuild_theme_data() {
|
||||
|
||||
// Find theme engines
|
||||
$engines = drupal_system_listing('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.engine$/', 'themes/engines');
|
||||
// Allow modules to add further theme engines.
|
||||
if ($module_engines = module_invoke_all('system_theme_engine_info')) {
|
||||
foreach ($module_engines as $name => $theme_engine_path) {
|
||||
$engines[$name] = (object) array(
|
||||
'uri' => $theme_engine_path,
|
||||
'filename' => basename($theme_engine_path),
|
||||
'name' => $name,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Set defaults for theme info.
|
||||
$defaults = array(
|
||||
@@ -2536,6 +2568,14 @@ function _system_rebuild_theme_data() {
|
||||
$themes[$key]->filename = $theme->uri;
|
||||
$themes[$key]->info = drupal_parse_info_file($theme->uri) + $defaults;
|
||||
|
||||
// The "name" key is required, but to avoid a fatal error in the menu system
|
||||
// we set a reasonable default if it is not provided.
|
||||
$themes[$key]->info += array('name' => $key);
|
||||
|
||||
// Add the info file modification time, so it becomes available for
|
||||
// contributed modules to use for ordering theme lists.
|
||||
$themes[$key]->info['mtime'] = filemtime($theme->uri);
|
||||
|
||||
// Invoke hook_system_info_alter() to give installed modules a chance to
|
||||
// modify the data in the .info files if necessary.
|
||||
$type = 'theme';
|
||||
@@ -2683,10 +2723,17 @@ function system_find_base_themes($themes, $key, $used_keys = array()) {
|
||||
* @param $show
|
||||
* Possible values: REGIONS_ALL or REGIONS_VISIBLE. Visible excludes hidden
|
||||
* regions.
|
||||
* @return
|
||||
* An array of regions in the form $region['name'] = 'description'.
|
||||
* @param bool $labels
|
||||
* (optional) Boolean to specify whether the human readable machine names
|
||||
* should be returned or not. Defaults to TRUE, but calling code can set
|
||||
* this to FALSE for better performance, if it only needs machine names.
|
||||
*
|
||||
* @return array
|
||||
* An associative array of regions in the form $region['name'] = 'description'
|
||||
* if $labels is set to TRUE, or $region['name'] = 'name', if $labels is set
|
||||
* to FALSE.
|
||||
*/
|
||||
function system_region_list($theme_key, $show = REGIONS_ALL) {
|
||||
function system_region_list($theme_key, $show = REGIONS_ALL, $labels = TRUE) {
|
||||
$themes = list_themes();
|
||||
if (!isset($themes[$theme_key])) {
|
||||
return array();
|
||||
@@ -2697,10 +2744,14 @@ function system_region_list($theme_key, $show = REGIONS_ALL) {
|
||||
// If requested, suppress hidden regions. See block_admin_display_form().
|
||||
foreach ($info['regions'] as $name => $label) {
|
||||
if ($show == REGIONS_ALL || !isset($info['regions_hidden']) || !in_array($name, $info['regions_hidden'])) {
|
||||
$list[$name] = t($label);
|
||||
if ($labels) {
|
||||
$list[$name] = t($label);
|
||||
}
|
||||
else {
|
||||
$list[$name] = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
@@ -2721,16 +2772,27 @@ function system_system_info_alter(&$info, $file, $type) {
|
||||
*
|
||||
* @param $theme
|
||||
* The name of a theme.
|
||||
*
|
||||
* @return
|
||||
* A string that is the region name.
|
||||
*/
|
||||
function system_default_region($theme) {
|
||||
$regions = array_keys(system_region_list($theme, REGIONS_VISIBLE));
|
||||
return isset($regions[0]) ? $regions[0] : '';
|
||||
$regions = system_region_list($theme, REGIONS_VISIBLE, FALSE);
|
||||
return $regions ? reset($regions) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Add default buttons to a form and set its prefix.
|
||||
* Sets up a form to save information automatically.
|
||||
*
|
||||
* This function adds a submit handler and a submit button to a form array. The
|
||||
* submit function saves all the data in the form, using variable_set(), to
|
||||
* variables named the same as the keys in the form array. Note that this means
|
||||
* you should normally prefix your form array keys with your module name, so
|
||||
* that they are unique when passed into variable_set().
|
||||
*
|
||||
* If you need to manipulate the data in a custom manner, you can either put
|
||||
* your own submission handler in the form array before calling this function,
|
||||
* or just use your own submission handler instead of calling this function.
|
||||
*
|
||||
* @param $form
|
||||
* An associative array containing the structure of the form.
|
||||
@@ -2739,6 +2801,7 @@ function system_default_region($theme) {
|
||||
* The form structure.
|
||||
*
|
||||
* @see system_settings_form_submit()
|
||||
*
|
||||
* @ingroup forms
|
||||
*/
|
||||
function system_settings_form($form) {
|
||||
@@ -2757,7 +2820,7 @@ function system_settings_form($form) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the system_settings_form.
|
||||
* Form submission handler for system_settings_form().
|
||||
*
|
||||
* If you want node type configure style handling of your checkboxes,
|
||||
* add an array_filter value to your form.
|
||||
@@ -2782,7 +2845,7 @@ function system_settings_form_submit($form, &$form_state) {
|
||||
function _system_sort_requirements($a, $b) {
|
||||
if (!isset($a['weight'])) {
|
||||
if (!isset($b['weight'])) {
|
||||
return strcmp($a['title'], $b['title']);
|
||||
return strcasecmp($a['title'], $b['title']);
|
||||
}
|
||||
return -$b['weight'];
|
||||
}
|
||||
@@ -2838,7 +2901,7 @@ function confirm_form($form, $question, $path, $description = NULL, $yes = NULL,
|
||||
|
||||
// Prepare cancel link.
|
||||
if (isset($_GET['destination'])) {
|
||||
$options = drupal_parse_url(urldecode($_GET['destination']));
|
||||
$options = drupal_parse_url($_GET['destination']);
|
||||
}
|
||||
elseif (is_array($path)) {
|
||||
$options = $path;
|
||||
@@ -3023,8 +3086,20 @@ function system_cron() {
|
||||
}
|
||||
}
|
||||
|
||||
$core = array('cache', 'cache_path', 'cache_filter', 'cache_page', 'cache_form', 'cache_menu');
|
||||
$cache_tables = array_merge(module_invoke_all('flush_caches'), $core);
|
||||
// Delete expired cache entries.
|
||||
// Avoid invoking hook_flush_cashes() on every cron run because some modules
|
||||
// use this hook to perform expensive rebuilding operations (which are only
|
||||
// designed to happen on full cache clears), rather than just returning a
|
||||
// list of cache tables to be cleared.
|
||||
$cache_object = cache_get('system_cache_tables');
|
||||
if (empty($cache_object)) {
|
||||
$core = array('cache', 'cache_path', 'cache_filter', 'cache_page', 'cache_form', 'cache_menu');
|
||||
$cache_tables = array_merge(module_invoke_all('flush_caches'), $core);
|
||||
cache_set('system_cache_tables', $cache_tables);
|
||||
}
|
||||
else {
|
||||
$cache_tables = $cache_object->data;
|
||||
}
|
||||
foreach ($cache_tables as $table) {
|
||||
cache_clear_all(NULL, $table);
|
||||
}
|
||||
@@ -3272,7 +3347,7 @@ function system_goto_action_form($context) {
|
||||
$form['url'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('URL'),
|
||||
'#description' => t('The URL to which the user should be redirected. This can be an internal URL like node/1234 or an external URL like http://drupal.org.'),
|
||||
'#description' => t('The URL to which the user should be redirected. This can be an internal path like node/1234 or an external URL like http://example.com.'),
|
||||
'#default_value' => isset($context['url']) ? $context['url'] : '',
|
||||
'#required' => TRUE,
|
||||
);
|
||||
@@ -3309,7 +3384,8 @@ function system_goto_action($entity, $context) {
|
||||
*/
|
||||
function system_block_ip_action() {
|
||||
$ip = ip_address();
|
||||
db_insert('blocked_ips')
|
||||
db_merge('blocked_ips')
|
||||
->key(array('ip' => $ip))
|
||||
->fields(array('ip' => $ip))
|
||||
->execute();
|
||||
watchdog('action', 'Banned IP address %ip', array('%ip' => $ip));
|
||||
@@ -3374,7 +3450,7 @@ function system_timezone($abbreviation = '', $offset = -1, $is_daylight_saving_t
|
||||
* @ingroup themeable
|
||||
*/
|
||||
function theme_system_powered_by() {
|
||||
return '<span>' . t('Powered by <a href="@poweredby">Drupal</a>', array('@poweredby' => 'http://drupal.org')) . '</span>';
|
||||
return '<span>' . t('Powered by <a href="@poweredby">Drupal</a>', array('@poweredby' => 'https://www.drupal.org')) . '</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3411,30 +3487,32 @@ function system_image_toolkits() {
|
||||
/**
|
||||
* Attempts to get a file using drupal_http_request and to store it locally.
|
||||
*
|
||||
* @param $url
|
||||
* @param string $url
|
||||
* The URL of the file to grab.
|
||||
*
|
||||
* @param $destination
|
||||
* @param string $destination
|
||||
* Stream wrapper URI specifying where the file should be placed. If a
|
||||
* directory path is provided, the file is saved into that directory under
|
||||
* its original name. If the path contains a filename as well, that one will
|
||||
* be used instead.
|
||||
* If this value is omitted, the site's default files scheme will be used,
|
||||
* usually "public://".
|
||||
*
|
||||
* @param $managed boolean
|
||||
* @param bool $managed
|
||||
* If this is set to TRUE, the file API hooks will be invoked and the file is
|
||||
* registered in the database.
|
||||
*
|
||||
* @param $replace boolean
|
||||
* @param int $replace
|
||||
* Replace behavior when the destination file already exists:
|
||||
* - FILE_EXISTS_REPLACE: Replace the existing file.
|
||||
* - FILE_EXISTS_RENAME: Append _{incrementing number} until the filename is
|
||||
* unique.
|
||||
* - FILE_EXISTS_ERROR: Do nothing and return FALSE.
|
||||
*
|
||||
* @return
|
||||
* On success the location the file was saved to, FALSE on failure.
|
||||
* @return mixed
|
||||
* One of these possibilities:
|
||||
* - If it succeeds and $managed is FALSE, the location where the file was
|
||||
* saved.
|
||||
* - If it succeeds and $managed is TRUE, a \Drupal\file\FileInterface
|
||||
* object which describes the file.
|
||||
* - If it fails, FALSE.
|
||||
*/
|
||||
function system_retrieve_file($url, $destination = NULL, $managed = FALSE, $replace = FILE_EXISTS_RENAME) {
|
||||
$parsed_url = parse_url($url);
|
||||
@@ -3469,8 +3547,7 @@ function system_retrieve_file($url, $destination = NULL, $managed = FALSE, $repl
|
||||
function system_page_alter(&$page) {
|
||||
// Find all non-empty page regions, and add a theme wrapper function that
|
||||
// allows them to be consistently themed.
|
||||
$regions = system_region_list($GLOBALS['theme']);
|
||||
foreach (array_keys($regions) as $region) {
|
||||
foreach (system_region_list($GLOBALS['theme'], REGIONS_ALL, FALSE) as $region) {
|
||||
if (!empty($page[$region])) {
|
||||
$page[$region]['#theme_wrappers'][] = 'region';
|
||||
$page[$region]['#region'] = $region;
|
||||
|
||||
@@ -97,13 +97,6 @@ class DrupalQueue {
|
||||
}
|
||||
|
||||
interface DrupalQueueInterface {
|
||||
/**
|
||||
* Start working with a queue.
|
||||
*
|
||||
* @param $name
|
||||
* Arbitrary string. The name of the queue to work with.
|
||||
*/
|
||||
public function __construct($name);
|
||||
|
||||
/**
|
||||
* Add a queue item and store it directly to the queue.
|
||||
@@ -238,7 +231,7 @@ class SystemQueue implements DrupalReliableQueueInterface {
|
||||
// until an item is successfully claimed or we are reasonably sure there
|
||||
// are no unclaimed items left.
|
||||
while (TRUE) {
|
||||
$item = db_query_range('SELECT data, item_id FROM {queue} q WHERE expire = 0 AND name = :name ORDER BY created ASC', 0, 1, array(':name' => $this->name))->fetchObject();
|
||||
$item = db_query_range('SELECT data, item_id FROM {queue} q WHERE expire = 0 AND name = :name ORDER BY created, item_id ASC', 0, 1, array(':name' => $this->name))->fetchObject();
|
||||
if ($item) {
|
||||
// Try to update the item. Only one thread can succeed in UPDATEing the
|
||||
// same row. We cannot rely on REQUEST_TIME because items might be
|
||||
@@ -315,6 +308,12 @@ class MemoryQueue implements DrupalQueueInterface {
|
||||
*/
|
||||
protected $id_sequence;
|
||||
|
||||
/**
|
||||
* Start working with a queue.
|
||||
*
|
||||
* @param $name
|
||||
* Arbitrary string. The name of the queue to work with.
|
||||
*/
|
||||
public function __construct($name) {
|
||||
$this->queue = array();
|
||||
$this->id_sequence = 0;
|
||||
@@ -327,6 +326,7 @@ class MemoryQueue implements DrupalQueueInterface {
|
||||
$item->created = time();
|
||||
$item->expire = 0;
|
||||
$this->queue[$item->item_id] = $item;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public function numberOfItems() {
|
||||
|
||||
+1855
-1197
File diff suppressed because it is too large
Load Diff
+529
-145
File diff suppressed because it is too large
Load Diff
@@ -24,7 +24,7 @@ class ModuleUpdater extends Updater implements DrupalUpdaterInterface {
|
||||
* found on your system, and if there was a copy in sites/all, we'd see it.
|
||||
*/
|
||||
public function getInstallDirectory() {
|
||||
if ($relative_path = drupal_get_path('module', $this->name)) {
|
||||
if ($this->isInstalled() && ($relative_path = drupal_get_path('module', $this->name))) {
|
||||
$relative_path = dirname($relative_path);
|
||||
}
|
||||
else {
|
||||
@@ -34,7 +34,7 @@ class ModuleUpdater extends Updater implements DrupalUpdaterInterface {
|
||||
}
|
||||
|
||||
public function isInstalled() {
|
||||
return (bool) drupal_get_path('module', $this->name);
|
||||
return (bool) drupal_get_filename('module', $this->name, NULL, FALSE);
|
||||
}
|
||||
|
||||
public static function canUpdateDirectory($directory) {
|
||||
@@ -109,7 +109,7 @@ class ThemeUpdater extends Updater implements DrupalUpdaterInterface {
|
||||
* found on your system, and if there was a copy in sites/all, we'd see it.
|
||||
*/
|
||||
public function getInstallDirectory() {
|
||||
if ($relative_path = drupal_get_path('theme', $this->name)) {
|
||||
if ($this->isInstalled() && ($relative_path = drupal_get_path('theme', $this->name))) {
|
||||
$relative_path = dirname($relative_path);
|
||||
}
|
||||
else {
|
||||
@@ -119,7 +119,7 @@ class ThemeUpdater extends Updater implements DrupalUpdaterInterface {
|
||||
}
|
||||
|
||||
public function isInstalled() {
|
||||
return (bool) drupal_get_path('theme', $this->name);
|
||||
return (bool) drupal_get_filename('theme', $this->name, NULL, FALSE);
|
||||
}
|
||||
|
||||
static function canUpdateDirectory($directory) {
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
name = Cron Queue test
|
||||
description = 'Support module for the cron queue runner.'
|
||||
package = Testing
|
||||
version = VERSION
|
||||
core = 7.x
|
||||
hidden = TRUE
|
||||
|
||||
; Information added by Drupal.org packaging script on 2020-09-16
|
||||
version = "7.73"
|
||||
project = "drupal"
|
||||
datestamp = "1600272641"
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implements hook_cron_queue_info().
|
||||
*/
|
||||
function cron_queue_test_cron_queue_info() {
|
||||
$queues['cron_queue_test_exception'] = array(
|
||||
'worker callback' => 'cron_queue_test_exception',
|
||||
);
|
||||
$queues['cron_queue_test_callback'] = array(
|
||||
'worker callback' => array('CronQueueTestCallbackClass', 'foo'),
|
||||
);
|
||||
|
||||
return $queues;
|
||||
}
|
||||
|
||||
function cron_queue_test_exception($item) {
|
||||
throw new Exception('That is not supposed to happen.');
|
||||
}
|
||||
|
||||
class CronQueueTestCallbackClass {
|
||||
|
||||
static public function foo() {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
name = System Cron Test
|
||||
description = 'Support module for testing the system_cron().'
|
||||
package = Testing
|
||||
version = VERSION
|
||||
core = 7.x
|
||||
hidden = TRUE
|
||||
|
||||
; Information added by Drupal.org packaging script on 2020-09-16
|
||||
version = "7.73"
|
||||
project = "drupal"
|
||||
datestamp = "1600272641"
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Helper module for CronRunTestCase::testCronCacheExpiration().
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_flush_caches().
|
||||
*/
|
||||
function system_cron_test_flush_caches() {
|
||||
// Set a variable to indicate that this hook was invoked.
|
||||
variable_set('system_cron_test_flush_caches', 1);
|
||||
return array();
|
||||
}
|
||||
@@ -62,6 +62,8 @@
|
||||
*
|
||||
* @see theme()
|
||||
* @see hook_theme()
|
||||
* @see hooks
|
||||
* @see callbacks
|
||||
*
|
||||
* @} End of "defgroup themeable".
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user