First commit

This commit is contained in:
Theodotos Andreou 2018-01-14 13:10:16 +00:00
commit c6e2478c40
13918 changed files with 2303184 additions and 0 deletions

126
modules/system/form.api.php Normal file
View file

@ -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');
}
}

View file

@ -0,0 +1,63 @@
<?php
/**
* @file
* Default theme implementation to display the basic html structure of a single
* Drupal page.
*
* Variables:
* - $css: An array of CSS files for the current page.
* - $language: (object) The language the site is being displayed in.
* $language->language contains its textual representation.
* $language->dir contains the language direction. It will either be 'ltr' or 'rtl'.
* - $rdf_namespaces: All the RDF namespace prefixes used in the HTML document.
* - $grddl_profile: A GRDDL profile allowing agents to extract the RDF data.
* - $head_title: A modified version of the page title, for use in the TITLE
* tag.
* - $head_title_array: (array) An associative array containing the string parts
* that were used to generate the $head_title variable, already prepared to be
* output as TITLE tag. The key/value pairs may contain one or more of the
* following, depending on conditions:
* - title: The title of the current page, if any.
* - name: The name of the site.
* - slogan: The slogan of the site, if any, and if there is no title.
* - $head: Markup for the HEAD section (including meta tags, keyword tags, and
* so on).
* - $styles: Style tags necessary to import all CSS files for the page.
* - $scripts: Script tags necessary to load the JavaScript files and settings
* for the page.
* - $page_top: Initial markup from any modules that have altered the
* page. This variable should always be output first, before all other dynamic
* content.
* - $page: The rendered page content.
* - $page_bottom: Final closing markup from any modules that have altered the
* page. This variable should always be output last, after all other dynamic
* content.
* - $classes String of classes that can be used to style contextually through
* CSS.
*
* @see template_preprocess()
* @see template_preprocess_html()
* @see template_process()
*
* @ingroup themeable
*/
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN"
"http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php print $language->language; ?>" version="XHTML+RDFa 1.0" dir="<?php print $language->dir; ?>"<?php print $rdf_namespaces; ?>>
<head profile="<?php print $grddl_profile; ?>">
<?php print $head; ?>
<title><?php print $head_title; ?></title>
<?php print $styles; ?>
<?php print $scripts; ?>
</head>
<body class="<?php print $classes; ?>" <?php print $attributes;?>>
<div id="skip-link">
<a href="#main-content" class="element-invisible element-focusable"><?php print t('Skip to main content'); ?></a>
</div>
<?php print $page_top; ?>
<?php print $page; ?>
<?php print $page_bottom; ?>
</body>
</html>

417
modules/system/image.gd.inc Normal file
View file

@ -0,0 +1,417 @@
<?php
/**
* @file
* GD2 toolkit for image manipulation within Drupal.
*/
/**
* @addtogroup image
* @{
*/
/**
* Retrieve settings for the GD2 toolkit.
*/
function image_gd_settings() {
if (image_gd_check_settings()) {
$form['status'] = array(
'#markup' => t('The GD toolkit is installed and working properly.')
);
$form['image_jpeg_quality'] = array(
'#type' => 'textfield',
'#title' => t('JPEG quality'),
'#description' => t('Define the image quality for JPEG manipulations. Ranges from 0 to 100. Higher values mean better image quality but bigger files.'),
'#size' => 10,
'#maxlength' => 3,
'#default_value' => variable_get('image_jpeg_quality', 75),
'#field_suffix' => t('%'),
);
$form['#element_validate'] = array('image_gd_settings_validate');
return $form;
}
else {
form_set_error('image_toolkit', t('The GD image toolkit requires that the GD module for PHP be installed and configured properly. For more information see <a href="@url">PHP\'s image documentation</a>.', array('@url' => 'http://php.net/image')));
return FALSE;
}
}
/**
* Validate the submitted GD settings.
*/
function image_gd_settings_validate($form, &$form_state) {
// Validate image quality range.
$value = $form_state['values']['image_jpeg_quality'];
if (!is_numeric($value) || $value < 0 || $value > 100) {
form_set_error('image_jpeg_quality', t('JPEG quality must be a number between 0 and 100.'));
}
}
/**
* Verify GD2 settings (that the right version is actually installed).
*
* @return
* A boolean indicating if the GD toolkit is available on this machine.
*/
function image_gd_check_settings() {
// GD2 support is available.
return function_exists('imagegd2');
}
/**
* Scale an image to the specified size using GD.
*
* @param $image
* An image object. The $image->resource, $image->info['width'], and
* $image->info['height'] values will be modified by this call.
* @param $width
* The new width of the resized image, in pixels.
* @param $height
* The new height of the resized image, in pixels.
* @return
* TRUE or FALSE, based on success.
*
* @see image_resize()
*/
function image_gd_resize(stdClass $image, $width, $height) {
$res = image_gd_create_tmp($image, $width, $height);
if (!imagecopyresampled($res, $image->resource, 0, 0, 0, 0, $width, $height, $image->info['width'], $image->info['height'])) {
return FALSE;
}
imagedestroy($image->resource);
// Update image object.
$image->resource = $res;
$image->info['width'] = $width;
$image->info['height'] = $height;
return TRUE;
}
/**
* Rotate an image the given number of degrees.
*
* @param $image
* An image object. The $image->resource, $image->info['width'], and
* $image->info['height'] values will be modified by this call.
* @param $degrees
* The number of (clockwise) degrees to rotate the image.
* @param $background
* An hexadecimal integer specifying the background color to use for the
* uncovered area of the image after the rotation. E.g. 0x000000 for black,
* 0xff00ff for magenta, and 0xffffff for white. For images that support
* transparency, this will default to transparent. Otherwise it will
* be white.
* @return
* TRUE or FALSE, based on success.
*
* @see image_rotate()
*/
function image_gd_rotate(stdClass $image, $degrees, $background = NULL) {
// PHP installations using non-bundled GD do not have imagerotate.
if (!function_exists('imagerotate')) {
watchdog('image', 'The image %file could not be rotated because the imagerotate() function is not available in this PHP installation.', array('%file' => $image->source));
return FALSE;
}
// 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 RGBA array.
if (isset($background)) {
$background = array(
'red' => $background >> 16 & 0xFF,
'green' => $background >> 8 & 0xFF,
'blue' => $background & 0xFF,
'alpha' => 0,
);
}
else {
// 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') {
// 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_idx);
// GIFs need to reassign the transparent color after performing the rotate.
if (isset($transparent_gif_color)) {
$background = imagecolorexactalpha($image->resource, $transparent_gif_color['red'], $transparent_gif_color['green'], $transparent_gif_color['blue'], $transparent_gif_color['alpha']);
imagecolortransparent($image->resource, $background);
}
$image->info['width'] = imagesx($image->resource);
$image->info['height'] = imagesy($image->resource);
return TRUE;
}
/**
* Crop an image using the GD toolkit.
*
* @param $image
* An image object. The $image->resource, $image->info['width'], and
* $image->info['height'] values will be modified by this call.
* @param $x
* The starting x offset at which to start the crop, in pixels.
* @param $y
* The starting y offset at which to start the crop, in pixels.
* @param $width
* The width of the cropped area, in pixels.
* @param $height
* The height of the cropped area, in pixels.
* @return
* TRUE or FALSE, based on success.
*
* @see image_crop()
*/
function image_gd_crop(stdClass $image, $x, $y, $width, $height) {
$res = image_gd_create_tmp($image, $width, $height);
if (!imagecopyresampled($res, $image->resource, 0, 0, $x, $y, $width, $height, $width, $height)) {
return FALSE;
}
// Destroy the original image and return the modified image.
imagedestroy($image->resource);
$image->resource = $res;
$image->info['width'] = $width;
$image->info['height'] = $height;
return TRUE;
}
/**
* Convert an image resource to grayscale.
*
* Note that transparent GIFs loose transparency when desaturated.
*
* @param $image
* An image object. The $image->resource value will be modified by this call.
* @return
* TRUE or FALSE, based on success.
*
* @see image_desaturate()
*/
function image_gd_desaturate(stdClass $image) {
// PHP installations using non-bundled GD do not have imagefilter.
if (!function_exists('imagefilter')) {
watchdog('image', 'The image %file could not be desaturated because the imagefilter() function is not available in this PHP installation.', array('%file' => $image->source));
return FALSE;
}
return imagefilter($image->resource, IMG_FILTER_GRAYSCALE);
}
/**
* GD helper function to create an image resource from a file.
*
* @param $image
* An image object. The $image->resource value will populated by this call.
* @return
* TRUE or FALSE, based on success.
*
* @see image_load()
*/
function image_gd_load(stdClass $image) {
$extension = str_replace('jpg', 'jpeg', $image->info['extension']);
$function = 'imagecreatefrom' . $extension;
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;
}
/**
* GD helper to write an image resource to a destination file.
*
* @param $image
* An image object.
* @param $destination
* A string file URI or path where the image should be saved.
* @return
* TRUE or FALSE, based on success.
*
* @see image_save()
*/
function image_gd_save(stdClass $image, $destination) {
$scheme = file_uri_scheme($destination);
// Work around lack of stream wrapper support in imagejpeg() and imagepng().
if ($scheme && file_stream_wrapper_valid_scheme($scheme)) {
// If destination is not local, save image to temporary local file.
$local_wrappers = file_get_stream_wrappers(STREAM_WRAPPERS_LOCAL);
if (!isset($local_wrappers[$scheme])) {
$permanent_destination = $destination;
$destination = drupal_tempnam('temporary://', 'gd_');
}
// Convert stream wrapper URI to normal path.
$destination = drupal_realpath($destination);
}
$extension = str_replace('jpg', 'jpeg', $image->info['extension']);
$function = 'image' . $extension;
if (!function_exists($function)) {
return FALSE;
}
if ($extension == 'jpeg') {
$success = $function($image->resource, $destination, variable_get('image_jpeg_quality', 75));
}
else {
// Always save PNG images with full transparency.
if ($extension == 'png') {
imagealphablending($image->resource, FALSE);
imagesavealpha($image->resource, TRUE);
}
$success = $function($image->resource, $destination);
}
// Move temporary local file to remote destination.
if (isset($permanent_destination) && $success) {
return (bool) file_unmanaged_move($destination, $permanent_destination, FILE_EXISTS_REPLACE);
}
return $success;
}
/**
* Create a truecolor image preserving transparency from a provided image.
*
* @param $image
* An image object.
* @param $width
* The new width of the new image, in pixels.
* @param $height
* The new height of the new image, in pixels.
* @return
* A GD image handle.
*/
function image_gd_create_tmp(stdClass $image, $width, $height) {
$res = imagecreatetruecolor($width, $height);
if ($image->info['extension'] == 'gif') {
// 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) {
// 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);
}
else {
imagefill($res, 0, 0, imagecolorallocate($res, 255, 255, 255));
}
}
}
elseif ($image->info['extension'] == 'png') {
imagealphablending($res, FALSE);
$transparency = imagecolorallocatealpha($res, 0, 0, 0, 127);
imagefill($res, 0, 0, $transparency);
imagealphablending($res, TRUE);
imagesavealpha($res, TRUE);
}
else {
imagefill($res, 0, 0, imagecolorallocate($res, 255, 255, 255));
}
return $res;
}
/**
* Get details about an image.
*
* @param $image
* An image object.
* @return
* FALSE, if the file could not be found or is not an image. Otherwise, a
* keyed array containing information about the image:
* - "width": Width, in pixels.
* - "height": Height, in pixels.
* - "extension": Commonly used file extension for the image.
* - "mime_type": MIME type ('image/jpeg', 'image/gif', 'image/png').
*
* @see image_get_info()
*/
function image_gd_get_info(stdClass $image) {
$details = FALSE;
$data = @getimagesize($image->source);
if (isset($data) && is_array($data)) {
$extensions = array('1' => 'gif', '2' => 'jpg', '3' => 'png');
$extension = isset($extensions[$data[2]]) ? $extensions[$data[2]] : '';
$details = array(
'width' => $data[0],
'height' => $data[1],
'extension' => $extension,
'mime_type' => $data['mime'],
);
}
return $details;
}
/**
* @} End of "addtogroup image".
*/

View file

@ -0,0 +1,186 @@
<?php
/**
* @file
* Hooks provided by the base system for language support.
*/
/**
* @addtogroup hooks
* @{
*/
/**
* Allows modules to act after language initialization has been performed.
*
* This is primarily needed to provide translation for configuration variables
* in the proper bootstrap phase. Variables are user-defined strings and
* therefore should not be translated via t(), since the source string can
* change without notice and any previous translation would be lost. Moreover,
* since variables can be used in the bootstrap phase, we need a bootstrap hook
* to provide a translation early enough to avoid misalignments between code
* using the original values and code using the translated values. However
* modules implementing hook_boot() should be aware that language initialization
* did not happen yet and thus they cannot rely on translated variables.
*/
function hook_language_init() {
global $language, $conf;
switch ($language->language) {
case 'it':
$conf['site_name'] = 'Il mio sito Drupal';
break;
case 'fr':
$conf['site_name'] = 'Mon site Drupal';
break;
}
}
/**
* Perform alterations on language switcher links.
*
* A language switcher link may need to point to a different path or use a
* translated link text before going through l(), which will just handle the
* path aliases.
*
* @param $links
* Nested array of links keyed by language code.
* @param $type
* The language type the links will switch.
* @param $path
* The current path.
*/
function hook_language_switch_links_alter(array &$links, $type, $path) {
global $language;
if ($type == LANGUAGE_TYPE_CONTENT && isset($links[$language->language])) {
foreach ($links[$language->language] as $link) {
$link['attributes']['class'][] = 'active-language';
}
}
}
/**
* Define language types.
*
* @return
* An associative array of language type definitions. The keys are the
* identifiers, which are also used as names for global variables representing
* the types in the bootstrap phase. The values are associative arrays that
* may contain the following elements:
* - name: The human-readable language type identifier.
* - description: A description of the language type.
* - fixed: A fixed array of language negotiation provider identifiers to use
* to initialize this language. Defining this key makes the language type
* non-configurable, so it will always use the specified providers in the
* given priority order. Omit to make the language type configurable.
*
* @see hook_language_types_info_alter()
* @ingroup language_negotiation
*/
function hook_language_types_info() {
return array(
'custom_language_type' => array(
'name' => t('Custom language'),
'description' => t('A custom language type.'),
),
'fixed_custom_language_type' => array(
'fixed' => array('custom_language_provider'),
),
);
}
/**
* Perform alterations on language types.
*
* @param $language_types
* Array of language type definitions.
*
* @see hook_language_types_info()
* @ingroup language_negotiation
*/
function hook_language_types_info_alter(array &$language_types) {
if (isset($language_types['custom_language_type'])) {
$language_types['custom_language_type_custom']['description'] = t('A far better description.');
}
}
/**
* Define language negotiation providers.
*
* @return
* An associative array of language negotiation provider definitions. The keys
* 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:
* - 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
* included before the callbacks are invoked).
* - weight: The default weight of the provider.
* - name: The translated human-readable name for the provider.
* - description: A translated longer description of the provider.
* - config: An internal path pointing to the provider's configuration page.
* - cache: The value Drupal's page cache should be set to for the current
* provider to be invoked.
*
* @see hook_language_negotiation_info_alter()
* @ingroup language_negotiation
*/
function hook_language_negotiation_info() {
return array(
'custom_language_provider' => array(
'callbacks' => array(
'language' => 'custom_language_provider_callback',
'switcher' => 'custom_language_switcher_callback',
'url_rewrite' => 'custom_language_url_rewrite_callback',
),
'file' => drupal_get_path('module', 'custom') . '/custom.module',
'weight' => -4,
'types' => array('custom_language_type'),
'name' => t('Custom language negotiation provider'),
'description' => t('This is a custom language negotiation provider.'),
'cache' => 0,
),
);
}
/**
* Perform alterations on language negoiation providers.
*
* @param $language_providers
* Array of language negotiation provider definitions.
*
* @see hook_language_negotiation_info()
* @ingroup language_negotiation
*/
function hook_language_negotiation_info_alter(array &$language_providers) {
if (isset($language_providers['custom_language_provider'])) {
$language_providers['custom_language_provider']['config'] = 'admin/config/regional/language/configure/custom-language-provider';
}
}
/**
* Perform alterations on the language fallback candidates.
*
* @param $fallback_candidates
* An array of language codes whose order will determine the language fallback
* order.
*/
function hook_language_fallback_candidates_alter(array &$fallback_candidates) {
$fallback_candidates = array_reverse($fallback_candidates);
}
/**
* @} End of "addtogroup hooks".
*/

View file

@ -0,0 +1,95 @@
<?php
/**
* @file
* Default theme implementation to display a single Drupal page while offline.
*
* All the available variables are mirrored in html.tpl.php and page.tpl.php.
* Some may be blank but they are provided for consistency.
*
* @see template_preprocess()
* @see template_preprocess_maintenance_page()
*
* @ingroup themeable
*/
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php print $language->language ?>" lang="<?php print $language->language ?>" dir="<?php print $language->dir ?>">
<head>
<title><?php print $head_title; ?></title>
<?php print $head; ?>
<?php print $styles; ?>
<?php print $scripts; ?>
</head>
<body class="<?php print $classes; ?>">
<div id="page">
<div id="header">
<div id="logo-title">
<?php if (!empty($logo)): ?>
<a href="<?php print $base_path; ?>" title="<?php print t('Home'); ?>" rel="home" id="logo">
<img src="<?php print $logo; ?>" alt="<?php print t('Home'); ?>" />
</a>
<?php endif; ?>
<div id="name-and-slogan">
<?php if (!empty($site_name)): ?>
<h1 id="site-name">
<a href="<?php print $base_path ?>" title="<?php print t('Home'); ?>" rel="home"><span><?php print $site_name; ?></span></a>
</h1>
<?php endif; ?>
<?php if (!empty($site_slogan)): ?>
<div id="site-slogan"><?php print $site_slogan; ?></div>
<?php endif; ?>
</div> <!-- /name-and-slogan -->
</div> <!-- /logo-title -->
<?php if (!empty($header)): ?>
<div id="header-region">
<?php print $header; ?>
</div>
<?php endif; ?>
</div> <!-- /header -->
<div id="container" class="clearfix">
<?php if (!empty($sidebar_first)): ?>
<div id="sidebar-first" class="column sidebar">
<?php print $sidebar_first; ?>
</div> <!-- /sidebar-first -->
<?php endif; ?>
<div id="main" class="column"><div id="main-squeeze">
<div id="content">
<?php if (!empty($title)): ?><h1 class="title" id="page-title"><?php print $title; ?></h1><?php endif; ?>
<?php if (!empty($messages)): print $messages; endif; ?>
<div id="content-content" class="clearfix">
<?php print $content; ?>
</div> <!-- /content-content -->
</div> <!-- /content -->
</div></div> <!-- /main-squeeze /main -->
<?php if (!empty($sidebar_second)): ?>
<div id="sidebar-second" class="column sidebar">
<?php print $sidebar_second; ?>
</div> <!-- /sidebar-second -->
<?php endif; ?>
</div> <!-- /container -->
<div id="footer-wrapper">
<div id="footer">
<?php if (!empty($footer)): print $footer; endif; ?>
</div> <!-- /footer -->
</div> <!-- /footer-wrapper -->
</div> <!-- /page -->
</body>
</html>

156
modules/system/page.tpl.php Normal file
View file

@ -0,0 +1,156 @@
<?php
/**
* @file
* Default theme implementation to display a single Drupal page.
*
* The doctype, html, head and body tags are not in this template. Instead they
* can be found in the html.tpl.php template in this directory.
*
* Available variables:
*
* General utility variables:
* - $base_path: The base URL path of the Drupal installation. At the very
* least, this will always default to /.
* - $directory: The directory the template is located in, e.g. modules/system
* or themes/bartik.
* - $is_front: TRUE if the current page is the front page.
* - $logged_in: TRUE if the user is registered and signed in.
* - $is_admin: TRUE if the user has permission to access administration pages.
*
* Site identity:
* - $front_page: The URL of the front page. Use this instead of $base_path,
* when linking to the front page. This includes the language domain or
* prefix.
* - $logo: The path to the logo image, as defined in theme configuration.
* - $site_name: The name of the site, empty when display has been disabled
* in theme settings.
* - $site_slogan: The slogan of the site, empty when display has been disabled
* in theme settings.
*
* Navigation:
* - $main_menu (array): An array containing the Main menu links for the
* site, if they have been configured.
* - $secondary_menu (array): An array containing the Secondary menu links for
* the site, if they have been configured.
* - $breadcrumb: The breadcrumb trail for the current page.
*
* Page content (in order of occurrence in the default page.tpl.php):
* - $title_prefix (array): An array containing additional output populated by
* modules, intended to be displayed in front of the main title tag that
* appears in the template.
* - $title: The page title, for use in the actual HTML content.
* - $title_suffix (array): An array containing additional output populated by
* modules, intended to be displayed after the main title tag that appears in
* the template.
* - $messages: HTML for status and error messages. Should be displayed
* prominently.
* - $tabs (array): Tabs linking to any sub-pages beneath the current page
* (e.g., the view and edit tabs when displaying a node).
* - $action_links (array): Actions local to the page, such as 'Add menu' on the
* menu administration interface.
* - $feed_icons: A string of all feed icons for the current page.
* - $node: The node object, if there is an automatically-loaded node
* associated with the page, and the node ID is the second argument
* in the page's path (e.g. node/12345 and node/12345/revisions, but not
* comment/reply/12345).
*
* Regions:
* - $page['help']: Dynamic help text, mostly for admin pages.
* - $page['highlighted']: Items for the highlighted content region.
* - $page['content']: The main content of the current page.
* - $page['sidebar_first']: Items for the first sidebar.
* - $page['sidebar_second']: Items for the second sidebar.
* - $page['header']: Items for the header region.
* - $page['footer']: Items for the footer region.
*
* @see template_preprocess()
* @see template_preprocess_page()
* @see template_process()
* @see html.tpl.php
*
* @ingroup themeable
*/
?>
<div id="page-wrapper"><div id="page">
<div id="header"><div class="section clearfix">
<?php if ($logo): ?>
<a href="<?php print $front_page; ?>" title="<?php print t('Home'); ?>" rel="home" id="logo">
<img src="<?php print $logo; ?>" alt="<?php print t('Home'); ?>" />
</a>
<?php endif; ?>
<?php if ($site_name || $site_slogan): ?>
<div id="name-and-slogan">
<?php if ($site_name): ?>
<?php if ($title): ?>
<div id="site-name"><strong>
<a href="<?php print $front_page; ?>" title="<?php print t('Home'); ?>" rel="home"><span><?php print $site_name; ?></span></a>
</strong></div>
<?php else: /* Use h1 when the content title is empty */ ?>
<h1 id="site-name">
<a href="<?php print $front_page; ?>" title="<?php print t('Home'); ?>" rel="home"><span><?php print $site_name; ?></span></a>
</h1>
<?php endif; ?>
<?php endif; ?>
<?php if ($site_slogan): ?>
<div id="site-slogan"><?php print $site_slogan; ?></div>
<?php endif; ?>
</div> <!-- /#name-and-slogan -->
<?php endif; ?>
<?php print render($page['header']); ?>
</div></div> <!-- /.section, /#header -->
<?php if ($main_menu || $secondary_menu): ?>
<div id="navigation"><div class="section">
<?php print theme('links__system_main_menu', array('links' => $main_menu, 'attributes' => array('id' => 'main-menu', 'class' => array('links', 'inline', 'clearfix')), 'heading' => t('Main menu'))); ?>
<?php print theme('links__system_secondary_menu', array('links' => $secondary_menu, 'attributes' => array('id' => 'secondary-menu', 'class' => array('links', 'inline', 'clearfix')), 'heading' => t('Secondary menu'))); ?>
</div></div> <!-- /.section, /#navigation -->
<?php endif; ?>
<?php if ($breadcrumb): ?>
<div id="breadcrumb"><?php print $breadcrumb; ?></div>
<?php endif; ?>
<?php print $messages; ?>
<div id="main-wrapper"><div id="main" class="clearfix">
<div id="content" class="column"><div class="section">
<?php if ($page['highlighted']): ?><div id="highlighted"><?php print render($page['highlighted']); ?></div><?php endif; ?>
<a id="main-content"></a>
<?php print render($title_prefix); ?>
<?php if ($title): ?><h1 class="title" id="page-title"><?php print $title; ?></h1><?php endif; ?>
<?php print render($title_suffix); ?>
<?php if ($tabs): ?><div class="tabs"><?php print render($tabs); ?></div><?php endif; ?>
<?php print render($page['help']); ?>
<?php if ($action_links): ?><ul class="action-links"><?php print render($action_links); ?></ul><?php endif; ?>
<?php print render($page['content']); ?>
<?php print $feed_icons; ?>
</div></div> <!-- /.section, /#content -->
<?php if ($page['sidebar_first']): ?>
<div id="sidebar-first" class="column sidebar"><div class="section">
<?php print render($page['sidebar_first']); ?>
</div></div> <!-- /.section, /#sidebar-first -->
<?php endif; ?>
<?php if ($page['sidebar_second']): ?>
<div id="sidebar-second" class="column sidebar"><div class="section">
<?php print render($page['sidebar_second']); ?>
</div></div> <!-- /.section, /#sidebar-second -->
<?php endif; ?>
</div></div> <!-- /#main, /#main-wrapper -->
<div id="footer"><div class="section">
<?php print render($page['footer']); ?>
</div></div> <!-- /.section, /#footer -->
</div></div> <!-- /#page, /#page-wrapper -->

View file

@ -0,0 +1,35 @@
<?php
/**
* @file
* Default theme implementation to display a region.
*
* Available variables:
* - $content: The content for this region, typically blocks.
* - $classes: String of classes that can be used to style contextually through
* CSS. It can be manipulated through the variable $classes_array from
* preprocess functions. The default values can be one or more of the following:
* - region: The current template type, i.e., "theming hook".
* - region-[name]: The name of the region with underscores replaced with
* dashes. For example, the page_top region would have a region-page-top class.
* - $region: The name of the region variable as defined in the theme's .info file.
*
* Helper variables:
* - $classes_array: Array of html class attribute values. It is flattened
* into a string within the variable $classes.
* - $is_admin: Flags true when the current user is an administrator.
* - $is_front: Flags true when presented in the front page.
* - $logged_in: Flags true when the current user is a logged-in member.
*
* @see template_preprocess()
* @see template_preprocess_region()
* @see template_process()
*
* @ingroup themeable
*/
?>
<?php if ($content): ?>
<div class="<?php print $classes; ?>">
<?php print $content; ?>
</div>
<?php endif; ?>

View file

@ -0,0 +1,86 @@
/**
* @file
* RTL styles for administration pages.
*/
/**
* Administration blocks.
*/
div.admin-panel .body {
padding: 0 8px 2px 4px;
}
div.admin .left {
float: right;
margin-left: 0;
margin-right: 1em;
}
div.admin .right {
float: left;
margin-left: 1em;
margin-right: 0;
}
div.admin .expert-link {
margin-right: 0;
margin-left: 1em;
padding-right: 0;
padding-left: 4px;
text-align: left;
}
/**
* Status report.
*/
table.system-status-report td.status-icon {
padding-left: 0;
padding-right: 6px;
}
table.system-status-report tr.merge-up td {
padding: 0 28px 8px 6px;
}
/**
* Appearance page.
*/
table.screenshot {
margin-left: 1em;
}
.system-themes-list-enabled .theme-selector .screenshot,
.system-themes-list-enabled .theme-selector .no-screenshot {
float: right;
margin: 0 0 0 20px;
}
.system-themes-list-disabled .theme-selector {
float: right;
padding: 20px 0 20px 20px;
}
.theme-selector .operations li {
border-right: none;
border-left: 1px solid #cdcdcd;
float: right;
}
.theme-selector .operations li.last {
border-left: none;
padding: 0 0.7em 0 0;
}
.theme-selector .operations li.first {
padding: 0 0 0 0.7em;
}
/**
* Exposed filters.
*/
.exposed-filters .filters {
float: right;
margin-left: 1em;
margin-right: 0;
}
.exposed-filters .form-item label {
float: right;
}
/* Current filters */
.exposed-filters .additional-filters {
float: right;
margin-left: 1em;
margin-right: 0;
}

View file

@ -0,0 +1,271 @@
/**
* @file
* Styles for administration pages.
*/
/**
* Administration blocks.
*/
div.admin-panel {
margin: 0;
padding: 5px 5px 15px 5px;
}
div.admin-panel .description {
margin: 0 0 3px;
padding: 2px 0 3px 0;
}
div.admin-panel .body {
padding: 0 4px 2px 8px; /* LTR */
}
div.admin {
padding-top: 15px;
}
div.admin .left {
float: left; /* LTR */
width: 47%;
margin-left: 1em; /* LTR */
}
div.admin .right {
float: right; /* LTR */
width: 47%;
margin-right: 1em; /* LTR */
}
div.admin .expert-link {
text-align: right; /* LTR */
margin-right: 1em; /* LTR */
padding-right: 4px; /* LTR */
}
/**
* Markup generated by theme_system_compact_link().
*/
.compact-link {
margin: 0 0 0.5em 0;
}
/**
* Quick inline admin links.
*/
small .admin-link:before {
content: '[';
}
small .admin-link:after {
content: ']';
}
/**
* Modules page.
*/
#system-modules div.incompatible {
font-weight: bold;
}
div.admin-requirements,
div.admin-required {
font-size: 0.9em;
color: #444;
}
span.admin-disabled {
color: #800;
}
span.admin-enabled {
color: #080;
}
span.admin-missing {
color: #f00;
}
a.module-link {
display: block;
padding: 1px 0 1px 20px; /* LTR */
white-space: nowrap;
}
a.module-link-help {
background: url(../../misc/help.png) 0 50% no-repeat; /* LTR */
}
a.module-link-permissions {
background: url(../../misc/permissions.png) 0 50% no-repeat; /* LTR */
}
a.module-link-configure {
background: url(../../misc/configure.png) 0 50% no-repeat; /* LTR */
}
.module-help {
margin-left: 1em; /* LTR */
float: right; /* LTR */
}
/**
* Status report.
*/
table.system-status-report td {
padding: 6px;
vertical-align: middle;
}
table.system-status-report tr.merge-up td {
padding: 0 6px 8px 28px; /* LTR */
}
table.system-status-report td.status-icon {
width: 16px;
padding-right: 0; /* LTR */
}
table.system-status-report td.status-icon div {
background-repeat: no-repeat;
height: 16px;
width: 16px;
}
table.system-status-report tr.error td.status-icon div {
background-image: url(../../misc/message-16-error.png);
}
table.system-status-report tr.warning td.status-icon div {
background-image: url(../../misc/message-16-warning.png);
}
tr.merge-down,
tr.merge-down td {
border-bottom-width: 0 !important;
}
tr.merge-up,
tr.merge-up td {
border-top-width: 0 !important;
}
/**
* Theme settings.
*/
.theme-settings-left {
float: left;
width: 49%;
}
.theme-settings-right {
float: right;
width: 49%;
}
.theme-settings-bottom {
clear: both;
}
/**
* Appearance page.
*/
table.screenshot {
margin-right: 1em; /* LTR */
}
.theme-info h2 {
margin-bottom: 0;
}
.theme-info p {
margin-top: 0;
}
.system-themes-list {
margin-bottom: 20px;
}
.system-themes-list-disabled {
border-top: 1px solid #cdcdcd;
padding-top: 20px;
}
.system-themes-list h2 {
margin: 0;
}
.theme-selector {
padding-top: 20px;
}
.theme-selector .screenshot,
.theme-selector .no-screenshot {
border: 1px solid #e0e0d8;
padding: 2px;
vertical-align: bottom;
width: 294px;
height: 219px;
line-height: 219px;
text-align: center;
}
.theme-default .screenshot {
border: 1px solid #aaa;
}
.system-themes-list-enabled .theme-selector .screenshot,
.system-themes-list-enabled .theme-selector .no-screenshot {
float: left; /* LTR */
margin: 0 20px 0 0; /* LTR */
}
.system-themes-list-disabled .theme-selector .screenshot,
.system-themes-list-disabled .theme-selector .no-screenshot {
width: 194px;
height: 144px;
line-height: 144px;
}
.theme-selector h3 {
font-weight: normal;
}
.theme-default h3 {
font-weight: bold;
}
.system-themes-list-enabled .theme-selector h3 {
margin-top: 0;
}
.system-themes-list-disabled .theme-selector {
width: 300px;
float: left; /* LTR */
padding: 20px 20px 20px 0; /* LTR */
}
.system-themes-list-enabled .theme-info {
max-width: 940px;
}
.system-themes-list-disabled .theme-info {
min-height: 170px;
}
.theme-selector .incompatible {
margin-top: 10px;
font-weight: bold;
}
.theme-selector .operations {
margin: 10px 0 0 0;
padding: 0;
}
.theme-selector .operations li {
float: left; /* LTR */
margin: 0;
padding: 0 0.7em;
list-style-type: none;
border-right: 1px solid #cdcdcd; /* LTR */
}
.theme-selector .operations li.last {
padding: 0 0 0 0.7em; /* LTR */
border-right: none; /* LTR */
}
.theme-selector .operations li.first {
padding: 0 0.7em 0 0; /* LTR */
}
#system-themes-admin-form {
clear: left;
}
/**
* Exposed filters.
*/
.exposed-filters .filters {
float: left; /* LTR */
margin-right: 1em; /* LTR */
width: 25em; /* IE6 */
}
.exposed-filters .form-item {
margin: 0 0 0.1em 0;
padding: 0;
}
.exposed-filters .form-item label {
float: left; /* LTR */
font-weight: normal;
width: 10em;
}
.exposed-filters .form-select {
width: 14em;
}
/* Current filters */
.exposed-filters .current-filters {
margin-bottom: 1em;
}
.exposed-filters .current-filters .placeholder {
font-style: normal;
font-weight: bold;
}
.exposed-filters .additional-filters {
float: left; /* LTR */
margin-right: 1em; /* LTR */
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,139 @@
<?php
/**
* @file
* Archiver implementations provided by the system module.
*/
/**
* Archiver for .tar files.
*/
class ArchiverTar implements ArchiverInterface {
/**
* The underlying Archive_Tar instance that does the heavy lifting.
*
* @var Archive_Tar
*/
protected $tar;
public function __construct($file_path) {
$this->tar = new Archive_Tar($file_path);
}
public function add($file_path) {
$this->tar->add($file_path);
return $this;
}
public function remove($file_path) {
// @todo Archive_Tar doesn't have a remove operation
// so we'll have to simulate it somehow, probably by
// creating a new archive with everything but the removed
// file.
return $this;
}
public function extract($path, Array $files = array()) {
if ($files) {
$this->tar->extractList($files, $path);
}
else {
$this->tar->extract($path);
}
return $this;
}
public function listContents() {
$files = array();
foreach ($this->tar->listContent() as $file_data) {
$files[] = $file_data['filename'];
}
return $files;
}
/**
* Retrieve the tar engine itself.
*
* In some cases it may be necessary to directly access the underlying
* Archive_Tar object for implementation-specific logic. This is for advanced
* use only as it is not shared by other implementations of ArchiveInterface.
*
* @return
* The Archive_Tar object used by this object.
*/
public function getArchive() {
return $this->tar;
}
}
/**
* Archiver for .zip files.
*
* @link http://php.net/zip
*/
class ArchiverZip implements ArchiverInterface {
/**
* The underlying ZipArchive instance that does the heavy lifting.
*
* @var ZipArchive
*/
protected $zip;
public function __construct($file_path) {
$this->zip = new ZipArchive();
if ($this->zip->open($file_path) !== TRUE) {
// @todo: This should be an interface-specific exception some day.
throw new Exception(t('Cannot open %file_path', array('%file_path' => $file_path)));
}
}
public function add($file_path) {
$this->zip->addFile($file_path);
return $this;
}
public function remove($file_path) {
$this->zip->deleteName($file_path);
return $this;
}
public function extract($path, Array $files = array()) {
if ($files) {
$this->zip->extractTo($path, $files);
}
else {
$this->zip->extractTo($path);
}
return $this;
}
public function listContents() {
$files = array();
for ($i=0; $i < $this->zip->numFiles; $i++) {
$files[] = $this->zip->getNameIndex($i);
}
return $files;
}
/**
* Retrieve the zip engine itself.
*
* In some cases it may be necessary to directly access the underlying
* ZipArchive object for implementation-specific logic. This is for advanced
* use only as it is not shared by other implementations of ArchiveInterface.
*
* @return
* The ZipArchive object used by this object.
*/
public function getArchive() {
return $this->zip;
}
}

View file

@ -0,0 +1,58 @@
/**
* @file
* Generic theme-independent base styles.
*/
/**
* Autocomplete.
*/
/* Animated throbber */
html.js input.form-autocomplete {
background-position: 0% center;
}
html.js input.throbbing {
background-position: 0% center;
}
/**
* Progress bar.
*/
.progress .percentage {
float: left;
}
.progress-disabled {
float: right;
}
.ajax-progress {
float: right;
}
.ajax-progress .throbber {
float: right;
}
/**
* TableDrag behavior.
*/
.draggable a.tabledrag-handle {
float: right;
margin-right: -1em;
margin-left: 0;
}
a.tabledrag-handle .handle {
margin: -0.4em 0.5em;
padding: 0.42em 0.5em;
}
div.indentation {
float: right;
margin: -0.4em -0.4em -0.4em 0.2em;
padding: 0.42em 0.6em 0.42em 0;
}
div.tree-child,
div.tree-child-last {
background-position: -65px center;
}
.tabledrag-toggle-weight-wrapper {
text-align: left;
}

View file

@ -0,0 +1,271 @@
/**
* @file
* Generic theme-independent base styles.
*/
/**
* Autocomplete.
*
* @see autocomplete.js
*/
/* Suggestion list */
#autocomplete {
border: 1px solid;
overflow: hidden;
position: absolute;
z-index: 100;
}
#autocomplete ul {
list-style: none;
list-style-image: none;
margin: 0;
padding: 0;
}
#autocomplete li {
background: #fff;
color: #000;
cursor: default;
white-space: pre;
zoom: 1; /* IE7 */
}
/* Animated throbber */
html.js input.form-autocomplete {
background-image: url(../../misc/throbber-inactive.png);
background-position: 100% center; /* LTR */
background-repeat: no-repeat;
}
html.js input.throbbing {
background-image: url(../../misc/throbber-active.gif);
background-position: 100% center; /* LTR */
}
/**
* Collapsible fieldsets.
*
* @see collapse.js
*/
html.js fieldset.collapsed {
border-bottom-width: 0;
border-left-width: 0;
border-right-width: 0;
height: 1em;
}
html.js fieldset.collapsed .fieldset-wrapper {
display: none;
}
fieldset.collapsible {
position: relative;
}
fieldset.collapsible .fieldset-legend {
display: block;
}
/**
* Resizable textareas.
*
* @see textarea.js
*/
.form-textarea-wrapper textarea {
display: block;
margin: 0;
width: 100%;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
.resizable-textarea .grippie {
background: #eee url(../../misc/grippie.png) no-repeat center 2px;
border: 1px solid #ddd;
border-top-width: 0;
cursor: s-resize;
height: 9px;
overflow: hidden;
}
/**
* TableDrag behavior.
*
* @see tabledrag.js
*/
body.drag {
cursor: move;
}
.draggable a.tabledrag-handle {
cursor: move;
float: left; /* LTR */
height: 1.7em;
margin-left: -1em; /* LTR */
overflow: hidden;
text-decoration: none;
}
a.tabledrag-handle:hover {
text-decoration: none;
}
a.tabledrag-handle .handle {
background: url(../../misc/draggable.png) no-repeat 6px 9px;
height: 13px;
margin: -0.4em 0.5em; /* LTR */
padding: 0.42em 0.5em; /* LTR */
width: 13px;
}
a.tabledrag-handle-hover .handle {
background-position: 6px -11px;
}
div.indentation {
float: left; /* LTR */
height: 1.7em;
margin: -0.4em 0.2em -0.4em -0.4em; /* LTR */
padding: 0.42em 0 0.42em 0.6em; /* LTR */
width: 20px;
}
div.tree-child {
background: url(../../misc/tree.png) no-repeat 11px center; /* LTR */
}
div.tree-child-last {
background: url(../../misc/tree-bottom.png) no-repeat 11px center; /* LTR */
}
div.tree-child-horizontal {
background: url(../../misc/tree.png) no-repeat -11px center;
}
.tabledrag-toggle-weight-wrapper {
text-align: right; /* LTR */
}
/**
* TableHeader behavior.
*
* @see tableheader.js
*/
table.sticky-header {
background-color: #fff;
margin-top: 0;
}
/**
* Progress behavior.
*
* @see progress.js
*/
/* Bar */
.progress .bar {
background-color: #fff;
border: 1px solid;
}
.progress .filled {
background-color: #000;
height: 1.5em;
width: 5px;
}
.progress .percentage {
float: right; /* LTR */
}
/* Throbber */
.ajax-progress {
display: inline-block;
}
.ajax-progress .throbber {
background: transparent url(../../misc/throbber-active.gif) no-repeat 0px center;
float: left; /* LTR */
height: 15px;
margin: 2px;
width: 15px;
}
.ajax-progress .message {
padding-left: 20px;
}
tr .ajax-progress .throbber {
margin: 0 2px;
}
.ajax-progress-bar {
width: 16em;
}
/**
* Inline items.
*/
.container-inline div,
.container-inline label {
display: inline;
}
/* Fieldset contents always need to be rendered as block. */
.container-inline .fieldset-wrapper {
display: block;
}
/**
* Prevent text wrapping.
*/
.nowrap {
white-space: nowrap;
}
/**
* For anything you want to hide on page load when JS is enabled, so
* that you can use the JS to control visibility and avoid flicker.
*/
html.js .js-hide {
display: none;
}
/**
* Hide elements from all users.
*
* Used for elements which should not be immediately displayed to any user. An
* example would be a collapsible fieldset that will be expanded with a click
* from a user. The effect of this class can be toggled with the jQuery show()
* and hide() functions.
*/
.element-hidden {
display: none;
}
/**
* Hide elements visually, but keep them available for screen-readers.
*
* Used for information required for screen-reader users to understand and use
* the site where visual display is undesirable. Information provided in this
* manner should be kept concise, to avoid unnecessary burden on the user.
* "!important" is used to prevent unintentional overrides.
*/
.element-invisible {
position: absolute !important;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
clip: rect(1px, 1px, 1px, 1px);
overflow: hidden;
height: 1px;
}
/**
* The .element-focusable class extends the .element-invisible class to allow
* the element to be focusable when navigated to via the keyboard.
*/
.element-invisible.element-focusable:active,
.element-invisible.element-focusable:focus {
position: static !important;
clip: auto;
overflow: visible;
height: auto;
}
/**
* Markup free clearing.
*
* @see http://perishablepress.com/press/2009/12/06/new-clearfix-hack
*/
.clearfix:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
/* IE6 */
* html .clearfix {
height: 1%;
}
/* IE7 */
*:first-child + html .clearfix {
min-height: 1%;
}

View file

@ -0,0 +1,19 @@
(function ($) {
/**
* Checks to see if the cron should be automatically run.
*/
Drupal.behaviors.cronCheck = {
attach: function(context, settings) {
if (settings.cronCheck || false) {
$('body').once('cron-check', function() {
// Only execute the cron check if its the right time.
if (Math.round(new Date().getTime() / 1000.0) > settings.cronCheck) {
$.get(settings.basePath + 'system/run-cron-check');
}
});
}
}
};
})(jQuery);

View file

@ -0,0 +1,19 @@
name = System
description = Handles general site configuration for administrators.
package = Core
version = VERSION
core = 7.x
files[] = system.archiver.inc
files[] = system.mail.inc
files[] = system.queue.inc
files[] = system.tar.inc
files[] = system.updater.inc
files[] = system.test
required = TRUE
configure = admin/config/system
; Information added by Drupal.org packaging script on 2017-06-21
version = "7.56"
project = "drupal"
datestamp = "1498069849"

File diff suppressed because it is too large Load diff

140
modules/system/system.js Normal file
View file

@ -0,0 +1,140 @@
(function ($) {
/**
* Show/hide the 'Email site administrator when updates are available' checkbox
* on the install page.
*/
Drupal.hideEmailAdministratorCheckbox = function () {
// Make sure the secondary box is shown / hidden as necessary on page load.
if ($('#edit-update-status-module-1').is(':checked')) {
$('.form-item-update-status-module-2').show();
}
else {
$('.form-item-update-status-module-2').hide();
}
// Toggle the display as necessary when the checkbox is clicked.
$('#edit-update-status-module-1').change( function () {
$('.form-item-update-status-module-2').toggle();
});
};
/**
* Internal function to check using Ajax if clean URLs can be enabled on the
* settings page.
*
* This function is not used to verify whether or not clean URLs
* are currently enabled.
*/
Drupal.behaviors.cleanURLsSettingsCheck = {
attach: function (context, settings) {
// This behavior attaches by ID, so is only valid once on a page.
// Also skip if we are on an install page, as Drupal.cleanURLsInstallCheck will handle
// the processing.
if (!($('#edit-clean-url').length) || $('#edit-clean-url.install').once('clean-url').length) {
return;
}
var url = settings.basePath + 'admin/config/search/clean-urls/check';
$.ajax({
url: location.protocol + '//' + location.host + url,
dataType: 'json',
success: function () {
// Check was successful. Redirect using a "clean URL". This will force the form that allows enabling clean URLs.
location = settings.basePath +"admin/config/search/clean-urls";
}
});
}
};
/**
* Internal function to check using Ajax if clean URLs can be enabled on the
* install page.
*
* This function is not used to verify whether or not clean URLs
* are currently enabled.
*/
Drupal.cleanURLsInstallCheck = function () {
var url = location.protocol + '//' + location.host + Drupal.settings.basePath + 'admin/config/search/clean-urls/check';
// Submit a synchronous request to avoid database errors associated with
// concurrent requests during install.
$.ajax({
async: false,
url: url,
dataType: 'json',
success: function () {
// Check was successful.
$('#edit-clean-url').attr('value', 1);
}
});
};
/**
* When a field is filled out, apply its value to other fields that will likely
* use the same value. In the installer this is used to populate the
* administrator e-mail address with the same value as the site e-mail address.
*/
Drupal.behaviors.copyFieldValue = {
attach: function (context, settings) {
for (var sourceId in settings.copyFieldValue) {
$('#' + sourceId, context).once('copy-field-values').bind('blur', function () {
// Get the list of target fields.
var targetIds = settings.copyFieldValue[sourceId];
// Add the behavior to update target fields on blur of the primary field.
for (var delta in targetIds) {
var targetField = $('#' + targetIds[delta]);
if (targetField.val() == '') {
targetField.val(this.value);
}
}
});
}
}
};
/**
* Show/hide custom format sections on the regional settings page.
*/
Drupal.behaviors.dateTime = {
attach: function (context, settings) {
for (var fieldName in settings.dateTime) {
if (settings.dateTime.hasOwnProperty(fieldName)) {
(function (fieldSettings, fieldName) {
var source = '#edit-' + fieldName;
var suffix = source + '-suffix';
// Attach keyup handler to custom format inputs.
$('input' + source, context).once('date-time').keyup(function () {
var input = $(this);
var url = fieldSettings.lookup + (/\?/.test(fieldSettings.lookup) ? '&format=' : '?format=') + encodeURIComponent(input.val());
$.getJSON(url, function (data) {
$(suffix).empty().append(' ' + fieldSettings.text + ': <em>' + data + '</em>');
});
});
})(settings.dateTime[fieldName], fieldName);
}
}
}
};
/**
* Show/hide settings for page caching depending on whether page caching is
* enabled or not.
*/
Drupal.behaviors.pageCache = {
attach: function (context, settings) {
$('#edit-cache-0', context).change(function () {
$('#page-compression-wrapper').hide();
$('#cache-error').hide();
});
$('#edit-cache-1', context).change(function () {
$('#page-compression-wrapper').show();
$('#cache-error').hide();
});
$('#edit-cache-2', context).change(function () {
$('#page-compression-wrapper').show();
$('#cache-error').show();
});
}
};
})(jQuery);

View file

@ -0,0 +1,133 @@
<?php
/**
* @file
* Drupal core implementations of MailSystemInterface.
*/
/**
* The default Drupal mail backend using PHP's mail function.
*/
class DefaultMailSystem implements MailSystemInterface {
/**
* Concatenate and wrap the e-mail body for plain-text mails.
*
* @param $message
* A message array, as described in hook_mail_alter().
*
* @return
* The formatted $message.
*/
public function format(array $message) {
// Join the body array into one string.
$message['body'] = implode("\n\n", $message['body']);
// Convert any HTML to plain-text.
$message['body'] = drupal_html_to_text($message['body']);
// Wrap the mail body for sending.
$message['body'] = drupal_wrap_mail($message['body']);
return $message;
}
/**
* Send an e-mail message, using Drupal variables and default settings.
*
* @see http://php.net/manual/function.mail.php
* @see drupal_mail()
*
* @param $message
* A message array, as described in hook_mail_alter().
* @return
* TRUE if the mail was successfully accepted, otherwise FALSE.
*/
public function mail(array $message) {
// If 'Return-Path' isn't already set in php.ini, we pass it separately
// as an additional parameter instead of in the header.
// However, if PHP's 'safe_mode' is on, this is not allowed.
if (isset($message['headers']['Return-Path']) && !ini_get('safe_mode')) {
$return_path_set = strpos(ini_get('sendmail_path'), ' -f');
if (!$return_path_set) {
$message['Return-Path'] = $message['headers']['Return-Path'];
unset($message['headers']['Return-Path']);
}
}
$mimeheaders = array();
foreach ($message['headers'] as $name => $value) {
$mimeheaders[] = $name . ': ' . mime_header_encode($value);
}
$line_endings = variable_get('mail_line_endings', MAIL_LINE_ENDINGS);
// Prepare mail commands.
$mail_subject = mime_header_encode($message['subject']);
// Note: e-mail uses CRLF for line-endings. PHP's API requires LF
// on Unix and CRLF on Windows. Drupal automatically guesses the
// line-ending format appropriate for your system. If you need to
// override this, adjust $conf['mail_line_endings'] in settings.php.
$mail_body = preg_replace('@\r?\n@', $line_endings, $message['body']);
// For headers, PHP's API suggests that we use CRLF normally,
// but some MTAs incorrectly replace LF with CRLF. See #234403.
$mail_headers = join("\n", $mimeheaders);
// We suppress warnings and notices from mail() because of issues on some
// 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')) {
// 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.
$mail_result = @mail(
$message['to'],
$mail_subject,
$mail_body,
$mail_headers,
'-f' . $message['Return-Path']
);
}
else {
// The optional $additional_parameters argument to mail() is not
// allowed if safe_mode is enabled. Passing any value throws a PHP
// warning and makes mail() return FALSE.
$mail_result = @mail(
$message['to'],
$mail_subject,
$mail_body,
$mail_headers
);
}
}
else {
// On Windows, PHP will use the value of sendmail_from for the
// Return-Path header.
$old_from = ini_get('sendmail_from');
ini_set('sendmail_from', $message['Return-Path']);
$mail_result = @mail(
$message['to'],
$mail_subject,
$mail_body,
$mail_headers
);
ini_set('sendmail_from', $old_from);
}
return $mail_result;
}
}
/**
* A mail sending implementation that captures sent messages to a variable.
*
* This class is for running tests or for development.
*/
class TestingMailSystem extends DefaultMailSystem implements MailSystemInterface {
/**
* Accept an e-mail message and store it in a variable.
*
* @param $message
* An e-mail message.
*/
public function mail(array $message) {
$captured_emails = variable_get('drupal_test_email_collector', array());
$captured_emails[] = $message;
variable_set('drupal_test_email_collector', $captured_emails);
return TRUE;
}
}

View file

@ -0,0 +1,55 @@
/**
* Update styles
*/
#update-results {
margin-top: 3em;
padding: 0.25em;
border: 1px solid #ccc;
background: #eee;
font-size: smaller;
}
#update-results h2 {
margin-top: 0.25em;
}
#update-results h4 {
margin-bottom: 0.25em;
}
#update-results li.none {
color: #888;
font-style: italic;
}
#update-results li.failure strong {
color: #b63300;
}
/**
* Authorize.php styles
*/
.connection-settings-update-filetransfer-default-wrapper {
float: left;
}
#edit-submit-connection {
clear: both;
}
.filetransfer {
display: none;
clear: both;
}
#edit-connection-settings-change-connection-type {
margin: 2.6em 0.5em 0em 1em;
}
/**
* Installation task list
*/
ol.task-list li.active {
font-weight: bold;
}
/**
* Installation clean URLs
*/
#clean-url.install {
display: none;
}

View file

@ -0,0 +1,37 @@
/**
* @file
* RTL styles for menus and navigation markup.
*/
ul.menu {
text-align:right;
}
ul.menu li {
margin: 0 0.5em 0 0;
}
ul li.collapsed {
list-style-image: url(../../misc/menu-collapsed-rtl.png);
}
li.expanded,
li.collapsed,
li.leaf {
padding: 0.2em 0 0 0.5em;
}
/**
* Markup generated by theme_menu_local_tasks().
*/
ul.primary {
padding: 0 1em 0 0;
}
ul.primary li a {
margin-right: 5px;
margin-left: 0.5em;
}
ul.secondary li {
border-left: 1px solid #ccc;
border-right: none;
display: inline;
padding: 0 1em;
}

View file

@ -0,0 +1,116 @@
/**
* @file
* Styles for menus and navigation markup.
*/
/**
* Markup generated by theme_menu_tree().
*/
ul.menu {
border: none;
list-style: none;
text-align: left; /* LTR */
}
ul.menu li {
margin: 0 0 0 0.5em; /* LTR */
}
ul li.expanded {
list-style-image: url(../../misc/menu-expanded.png);
list-style-type: circle;
}
ul li.collapsed {
list-style-image: url(../../misc/menu-collapsed.png); /* LTR */
list-style-type: disc;
}
ul li.leaf {
list-style-image: url(../../misc/menu-leaf.png);
list-style-type: square;
}
li.expanded,
li.collapsed,
li.leaf {
padding: 0.2em 0.5em 0 0; /* LTR */
margin: 0;
}
li a.active {
color: #000;
}
td.menu-disabled {
background: #ccc;
}
/**
* Markup generated by theme_links().
*/
ul.inline,
ul.links.inline {
display: inline;
padding-left: 0;
}
ul.inline li {
display: inline;
list-style-type: none;
padding: 0 0.5em;
}
/**
* Markup generated by theme_breadcrumb().
*/
.breadcrumb {
padding-bottom: 0.5em;
}
/**
* Markup generated by theme_menu_local_tasks().
*/
ul.primary {
border-bottom: 1px solid #bbb;
border-collapse: collapse;
height: auto;
line-height: normal;
list-style: none;
margin: 5px;
padding: 0 0 0 1em; /* LTR */
white-space: nowrap;
}
ul.primary li {
display: inline;
}
ul.primary li a {
background-color: #ddd;
border-color: #bbb;
border-style: solid solid none solid;
border-width: 1px;
height: auto;
margin-right: 0.5em; /* LTR */
padding: 0 1em;
text-decoration: none;
}
ul.primary li.active a {
background-color: #fff;
border: 1px solid #bbb;
border-bottom: 1px solid #fff;
}
ul.primary li a:hover {
background-color: #eee;
border-color: #ccc;
border-bottom-color: #eee;
}
ul.secondary {
border-bottom: 1px solid #bbb;
padding: 0.5em 1em;
margin: 5px;
}
ul.secondary li {
border-right: 1px solid #ccc; /* LTR */
display: inline;
padding: 0 1em;
}
ul.secondary a {
padding: 0;
text-decoration: none;
}
ul.secondary a.active {
border-bottom: 4px solid #999;
}

View file

@ -0,0 +1,13 @@
/**
* @file
* RTL Styles for system messages.
*/
div.messages {
background-position: 99% 8px;
padding: 10px 50px 10px 10px;
}
div.messages ul {
margin: 0 1em 0 0;
}

View file

@ -0,0 +1,63 @@
/**
* @file
* Styles for system messages.
*/
div.messages {
background-position: 8px 8px; /* LTR */
background-repeat: no-repeat;
border: 1px solid;
margin: 6px 0;
padding: 10px 10px 10px 50px; /* LTR */
}
div.status {
background-image: url(../../misc/message-24-ok.png);
border-color: #be7;
}
div.status,
.ok {
color: #234600;
}
div.status,
table tr.ok {
background-color: #f8fff0;
}
div.warning {
background-image: url(../../misc/message-24-warning.png);
border-color: #ed5;
}
div.warning,
.warning {
color: #840;
}
div.warning,
table tr.warning {
background-color: #fffce5;
}
div.error {
background-image: url(../../misc/message-24-error.png);
border-color: #ed541d;
}
div.error,
.error {
color: #8c2e0b;
}
div.error,
table tr.error {
background-color: #fef5f1;
}
div.error p.error {
color: #333;
}
div.messages ul {
margin: 0 0 0 1em; /* LTR */
padding: 0;
}
div.messages ul li {
list-style-image: none;
}

4079
modules/system/system.module Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,371 @@
<?php
/**
* @file
* Queue functionality.
*/
/**
* @defgroup queue Queue operations
* @{
* Queue items to allow later processing.
*
* The queue system allows placing items in a queue and processing them later.
* The system tries to ensure that only one consumer can process an item.
*
* Before a queue can be used it needs to be created by
* DrupalQueueInterface::createQueue().
*
* Items can be added to the queue by passing an arbitrary data object to
* DrupalQueueInterface::createItem().
*
* To process an item, call DrupalQueueInterface::claimItem() and specify how
* long you want to have a lease for working on that item. When finished
* processing, the item needs to be deleted by calling
* DrupalQueueInterface::deleteItem(). If the consumer dies, the item will be
* made available again by the DrupalQueueInterface implementation once the
* lease expires. Another consumer will then be able to receive it when calling
* DrupalQueueInterface::claimItem(). Due to this, the processing code should
* be aware that an item might be handed over for processing more than once.
*
* The $item object used by the DrupalQueueInterface can contain arbitrary
* metadata depending on the implementation. Systems using the interface should
* only rely on the data property which will contain the information passed to
* DrupalQueueInterface::createItem(). The full queue item returned by
* DrupalQueueInterface::claimItem() needs to be passed to
* DrupalQueueInterface::deleteItem() once processing is completed.
*
* There are two kinds of queue backends available: reliable, which preserves
* the order of messages and guarantees that every item will be executed at
* least once. The non-reliable kind only does a best effort to preserve order
* in messages and to execute them at least once but there is a small chance
* that some items get lost. For example, some distributed back-ends like
* Amazon SQS will be managing jobs for a large set of producers and consumers
* where a strict FIFO ordering will likely not be preserved. Another example
* would be an in-memory queue backend which might lose items if it crashes.
* However, such a backend would be able to deal with significantly more writes
* than a reliable queue and for many tasks this is more important. See
* aggregator_cron() for an example of how to effectively utilize a
* non-reliable queue. Another example is doing Twitter statistics -- the small
* possibility of losing a few items is insignificant next to power of the
* queue being able to keep up with writes. As described in the processing
* section, regardless of the queue being reliable or not, the processing code
* should be aware that an item might be handed over for processing more than
* once (because the processing code might time out before it finishes).
*/
/**
* Factory class for interacting with queues.
*/
class DrupalQueue {
/**
* Returns the queue object for a given name.
*
* The following variables can be set by variable_set or $conf overrides:
* - queue_class_$name: the class to be used for the queue $name.
* - queue_default_class: the class to use when queue_class_$name is not
* defined. Defaults to SystemQueue, a reliable backend using SQL.
* - queue_default_reliable_class: the class to use when queue_class_$name is
* not defined and the queue_default_class is not reliable. Defaults to
* SystemQueue.
*
* @param $name
* Arbitrary string. The name of the queue to work with.
* @param $reliable
* TRUE if the ordering of items and guaranteeing every item executes at
* least once is important, FALSE if scalability is the main concern.
*
* @return
* The queue object for a given name.
*/
public static function get($name, $reliable = FALSE) {
static $queues;
if (!isset($queues[$name])) {
$class = variable_get('queue_class_' . $name, NULL);
if (!$class) {
$class = variable_get('queue_default_class', 'SystemQueue');
}
$object = new $class($name);
if ($reliable && !$object instanceof DrupalReliableQueueInterface) {
$class = variable_get('queue_default_reliable_class', 'SystemQueue');
$object = new $class($name);
}
$queues[$name] = $object;
}
return $queues[$name];
}
}
interface DrupalQueueInterface {
/**
* Add a queue item and store it directly to the queue.
*
* @param $data
* Arbitrary data to be associated with the new task in the queue.
* @return
* TRUE if the item was successfully created and was (best effort) added
* to the queue, otherwise FALSE. We don't guarantee the item was
* committed to disk etc, but as far as we know, the item is now in the
* queue.
*/
public function createItem($data);
/**
* Retrieve the number of items in the queue.
*
* This is intended to provide a "best guess" count of the number of items in
* the queue. Depending on the implementation and the setup, the accuracy of
* the results of this function may vary.
*
* e.g. On a busy system with a large number of consumers and items, the
* result might only be valid for a fraction of a second and not provide an
* accurate representation.
*
* @return
* An integer estimate of the number of items in the queue.
*/
public function numberOfItems();
/**
* Claim an item in the queue for processing.
*
* @param $lease_time
* How long the processing is expected to take in seconds, defaults to an
* hour. After this lease expires, the item will be reset and another
* consumer can claim the item. For idempotent tasks (which can be run
* multiple times without side effects), shorter lease times would result
* in lower latency in case a consumer fails. For tasks that should not be
* run more than once (non-idempotent), a larger lease time will make it
* more rare for a given task to run multiple times in cases of failure,
* at the cost of higher latency.
* @return
* On success we return an item object. If the queue is unable to claim an
* item it returns false. This implies a best effort to retrieve an item
* and either the queue is empty or there is some other non-recoverable
* problem.
*/
public function claimItem($lease_time = 3600);
/**
* Delete a finished item from the queue.
*
* @param $item
* The item returned by DrupalQueueInterface::claimItem().
*/
public function deleteItem($item);
/**
* Release an item that the worker could not process, so another
* worker can come in and process it before the timeout expires.
*
* @param $item
* @return boolean
*/
public function releaseItem($item);
/**
* Create a queue.
*
* Called during installation and should be used to perform any necessary
* initialization operations. This should not be confused with the
* constructor for these objects, which is called every time an object is
* instantiated to operate on a queue. This operation is only needed the
* first time a given queue is going to be initialized (for example, to make
* a new database table or directory to hold tasks for the queue -- it
* depends on the queue implementation if this is necessary at all).
*/
public function createQueue();
/**
* Delete a queue and every item in the queue.
*/
public function deleteQueue();
}
/**
* Reliable queue interface.
*
* Classes implementing this interface preserve the order of messages and
* guarantee that every item will be executed at least once.
*/
interface DrupalReliableQueueInterface extends DrupalQueueInterface {
}
/**
* Default queue implementation.
*/
class SystemQueue implements DrupalReliableQueueInterface {
/**
* The name of the queue this instance is working with.
*
* @var string
*/
protected $name;
public function __construct($name) {
$this->name = $name;
}
public function createItem($data) {
// During a Drupal 6.x to 7.x update, drupal_get_schema() does not contain
// the queue table yet, so we cannot rely on drupal_write_record().
$query = db_insert('queue')
->fields(array(
'name' => $this->name,
'data' => serialize($data),
// We cannot rely on REQUEST_TIME because many items might be created
// by a single request which takes longer than 1 second.
'created' => time(),
));
return (bool) $query->execute();
}
public function numberOfItems() {
return db_query('SELECT COUNT(item_id) FROM {queue} WHERE name = :name', array(':name' => $this->name))->fetchField();
}
public function claimItem($lease_time = 30) {
// Claim an item by updating its expire fields. If claim is not successful
// another thread may have claimed the item in the meantime. Therefore loop
// 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, 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
// claimed by a single consumer which runs longer than 1 second. If we
// continue to use REQUEST_TIME instead of the current time(), we steal
// time from the lease, and will tend to reset items before the lease
// should really expire.
$update = db_update('queue')
->fields(array(
'expire' => time() + $lease_time,
))
->condition('item_id', $item->item_id)
->condition('expire', 0);
// If there are affected rows, this update succeeded.
if ($update->execute()) {
$item->data = unserialize($item->data);
return $item;
}
}
else {
// No items currently available to claim.
return FALSE;
}
}
}
public function releaseItem($item) {
$update = db_update('queue')
->fields(array(
'expire' => 0,
))
->condition('item_id', $item->item_id);
return $update->execute();
}
public function deleteItem($item) {
db_delete('queue')
->condition('item_id', $item->item_id)
->execute();
}
public function createQueue() {
// All tasks are stored in a single database table (which is created when
// Drupal is first installed) so there is nothing we need to do to create
// a new queue.
}
public function deleteQueue() {
db_delete('queue')
->condition('name', $this->name)
->execute();
}
}
/**
* Static queue implementation.
*
* This allows "undelayed" variants of processes relying on the Queue
* interface. The queue data resides in memory. It should only be used for
* items that will be queued and dequeued within a given page request.
*/
class MemoryQueue implements DrupalQueueInterface {
/**
* The queue data.
*
* @var array
*/
protected $queue;
/**
* Counter for item ids.
*
* @var int
*/
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;
}
public function createItem($data) {
$item = new stdClass();
$item->item_id = $this->id_sequence++;
$item->data = $data;
$item->created = time();
$item->expire = 0;
$this->queue[$item->item_id] = $item;
return TRUE;
}
public function numberOfItems() {
return count($this->queue);
}
public function claimItem($lease_time = 30) {
foreach ($this->queue as $key => $item) {
if ($item->expire == 0) {
$item->expire = time() + $lease_time;
$this->queue[$key] = $item;
return $item;
}
}
return FALSE;
}
public function deleteItem($item) {
unset($this->queue[$item->item_id]);
}
public function releaseItem($item) {
if (isset($this->queue[$item->item_id]) && $this->queue[$item->item_id]->expire != 0) {
$this->queue[$item->item_id]->expire = 0;
return TRUE;
}
return FALSE;
}
public function createQueue() {
// Nothing needed here.
}
public function deleteQueue() {
$this->queue = array();
$this->id_sequence = 0;
}
}
/**
* @} End of "defgroup queue".
*/

File diff suppressed because it is too large Load diff

3065
modules/system/system.test Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,53 @@
/**
* @file
* RTL styles for common markup.
*/
/**
* HTML elements.
*/
th {
text-align: right;
padding-left: 1em;
padding-right: 0;
}
/**
* Markup generated by theme_item_list().
*/
.item-list ul li {
margin: 0 1.5em 0.25em 0;
}
/**
* Markup generated by theme_more_link().
*/
.more-link {
text-align: left;
}
/**
* Markup generated by theme_more_help_link().
*/
.more-help-link {
text-align: left;
}
.more-help-link a {
background-position: 100% 50%;
padding: 1px 20px 1px 0;
}
/**
* Collapsible fieldsets.
*/
html.js fieldset.collapsible .fieldset-legend {
background-position: 98% 75%;
padding-left: 0;
padding-right: 15px;
}
html.js fieldset.collapsed .fieldset-legend {
background-image: url(../../misc/menu-collapsed-rtl.png);
background-position: 98% 50%;
}

View file

@ -0,0 +1,239 @@
/**
* @file
* Basic styling for common markup.
*/
/**
* HTML elements.
*/
fieldset {
margin-bottom: 1em;
padding: 0.5em;
}
form {
margin: 0;
padding: 0;
}
hr {
border: 1px solid gray;
height: 1px;
}
img {
border: 0;
}
table {
border-collapse: collapse;
}
th {
border-bottom: 3px solid #ccc;
padding-right: 1em; /* LTR */
text-align: left; /* LTR */
}
tbody {
border-top: 1px solid #ccc;
}
tr.even,
tr.odd {
background-color: #eee;
border-bottom: 1px solid #ccc;
padding: 0.1em 0.6em;
}
/**
* Markup generated by theme_tablesort_indicator().
*/
th.active img {
display: inline;
}
td.active {
background-color: #ddd;
}
/**
* Markup generated by theme_item_list().
*/
.item-list .title {
font-weight: bold;
}
.item-list ul {
margin: 0 0 0.75em 0;
padding: 0;
}
.item-list ul li {
margin: 0 0 0.25em 1.5em; /* LTR */
padding: 0;
}
/**
* Markup generated by Form API.
*/
.form-item,
.form-actions {
margin-top: 1em;
margin-bottom: 1em;
}
tr.odd .form-item,
tr.even .form-item {
margin-top: 0;
margin-bottom: 0;
white-space: nowrap;
}
.form-item .description {
font-size: 0.85em;
}
label {
display: block;
font-weight: bold;
}
label.option {
display: inline;
font-weight: normal;
}
.form-checkboxes .form-item,
.form-radios .form-item {
margin-top: 0.4em;
margin-bottom: 0.4em;
}
.form-type-radio .description,
.form-type-checkbox .description {
margin-left: 2.4em;
}
input.form-checkbox,
input.form-radio {
vertical-align: middle;
}
.marker,
.form-required {
color: #f00;
}
.form-item input.error,
.form-item textarea.error,
.form-item select.error {
border: 2px solid red;
}
/**
* Inline items.
*/
.container-inline .form-actions,
.container-inline.form-actions {
margin-top: 0;
margin-bottom: 0;
}
/**
* Markup generated by theme_more_link().
*/
.more-link {
text-align: right; /* LTR */
}
/**
* Markup generated by theme_more_help_link().
*/
.more-help-link {
text-align: right; /* LTR */
}
.more-help-link a {
background: url(../../misc/help.png) 0 50% no-repeat; /* LTR */
padding: 1px 0 1px 20px; /* LTR */
}
/**
* Markup generated by theme_pager().
*/
.item-list .pager {
clear: both;
text-align: center;
}
.item-list .pager li {
background-image: none;
display: inline;
list-style-type: none;
padding: 0.5em;
}
.pager-current {
font-weight: bold;
}
/**
* Autocomplete.
*
* @see autocomplete.js
*/
/* Suggestion list */
#autocomplete li.selected {
background: #0072b9;
color: #fff;
}
/**
* Collapsible fieldsets.
*
* @see collapse.js
*/
html.js fieldset.collapsible .fieldset-legend {
background: url(../../misc/menu-expanded.png) 5px 65% no-repeat; /* LTR */
padding-left: 15px; /* LTR */
}
html.js fieldset.collapsed .fieldset-legend {
background-image: url(../../misc/menu-collapsed.png); /* LTR */
background-position: 5px 50%; /* LTR */
}
.fieldset-legend span.summary {
color: #999;
font-size: 0.9em;
margin-left: 0.5em;
}
/**
* TableDrag behavior.
*
* @see tabledrag.js
*/
tr.drag {
background-color: #fffff0;
}
tr.drag-previous {
background-color: #ffd;
}
.tabledrag-toggle-weight {
font-size: 0.9em;
}
body div.tabledrag-changed-warning {
margin-bottom: 0.5em;
}
/**
* TableSelect behavior.
*
* @see tableselect.js
*/
tr.selected td {
background: #ffc;
}
td.checkbox,
th.checkbox {
text-align: center;
}
/**
* Progress bar.
*
* @see progress.js
*/
.progress {
font-weight: bold;
}
.progress .bar {
background: #ccc;
border-color: #666;
margin: 0 0.2em;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
}
.progress .filled {
background: #0072b9 url(../../misc/progress.gif);
}

View file

@ -0,0 +1,269 @@
<?php
/**
* @file
* Builds placeholder replacement tokens system-wide data.
*
* This file handles tokens for the global 'site' token type, as well as
* 'date' and 'file' tokens.
*/
/**
* Implements hook_token_info().
*/
function system_token_info() {
$types['site'] = array(
'name' => t("Site information"),
'description' => t("Tokens for site-wide settings and other global information."),
);
$types['date'] = array(
'name' => t("Dates"),
'description' => t("Tokens related to times and dates."),
);
$types['file'] = array(
'name' => t("Files"),
'description' => t("Tokens related to uploaded files."),
'needs-data' => 'file',
);
// Site-wide global tokens.
$site['name'] = array(
'name' => t("Name"),
'description' => t("The name of the site."),
);
$site['slogan'] = array(
'name' => t("Slogan"),
'description' => t("The slogan of the site."),
);
$site['mail'] = array(
'name' => t("Email"),
'description' => t("The administrative email address for the site."),
);
$site['url'] = array(
'name' => t("URL"),
'description' => t("The URL of the site's front page."),
);
$site['url-brief'] = array(
'name' => t("URL (brief)"),
'description' => t("The URL of the site's front page without the protocol."),
);
$site['login-url'] = array(
'name' => t("Login page"),
'description' => t("The URL of the site's login page."),
);
// Date related tokens.
$date['short'] = array(
'name' => t("Short format"),
'description' => t("A date in 'short' format. (%date)", array('%date' => format_date(REQUEST_TIME, 'short'))),
);
$date['medium'] = array(
'name' => t("Medium format"),
'description' => t("A date in 'medium' format. (%date)", array('%date' => format_date(REQUEST_TIME, 'medium'))),
);
$date['long'] = array(
'name' => t("Long format"),
'description' => t("A date in 'long' format. (%date)", array('%date' => format_date(REQUEST_TIME, 'long'))),
);
$date['custom'] = array(
'name' => t("Custom format"),
'description' => t("A date in a custom format. See !php-date for details.", array('!php-date' => l(t('the PHP documentation'), 'http://php.net/manual/en/function.date.php'))),
);
$date['since'] = array(
'name' => t("Time-since"),
'description' => t("A date in 'time-since' format. (%date)", array('%date' => format_interval(REQUEST_TIME - 360, 2))),
);
$date['raw'] = array(
'name' => t("Raw timestamp"),
'description' => t("A date in UNIX timestamp format (%date)", array('%date' => REQUEST_TIME)),
);
// File related tokens.
$file['fid'] = array(
'name' => t("File ID"),
'description' => t("The unique ID of the uploaded file."),
);
$file['name'] = array(
'name' => t("File name"),
'description' => t("The name of the file on disk."),
);
$file['path'] = array(
'name' => t("Path"),
'description' => t("The location of the file relative to Drupal root."),
);
$file['mime'] = array(
'name' => t("MIME type"),
'description' => t("The MIME type of the file."),
);
$file['size'] = array(
'name' => t("File size"),
'description' => t("The size of the file."),
);
$file['url'] = array(
'name' => t("URL"),
'description' => t("The web-accessible URL for the file."),
);
$file['timestamp'] = array(
'name' => t("Timestamp"),
'description' => t("The date the file was most recently changed."),
'type' => 'date',
);
$file['owner'] = array(
'name' => t("Owner"),
'description' => t("The user who originally uploaded the file."),
'type' => 'user',
);
return array(
'types' => $types,
'tokens' => array(
'site' => $site,
'date' => $date,
'file' => $file,
),
);
}
/**
* Implements hook_tokens().
*/
function system_tokens($type, $tokens, array $data = array(), array $options = array()) {
$url_options = array('absolute' => TRUE);
if (isset($options['language'])) {
$url_options['language'] = $options['language'];
$language_code = $options['language']->language;
}
else {
$language_code = NULL;
}
$sanitize = !empty($options['sanitize']);
$replacements = array();
if ($type == 'site') {
foreach ($tokens as $name => $original) {
switch ($name) {
case 'name':
$site_name = variable_get('site_name', 'Drupal');
$replacements[$original] = $sanitize ? check_plain($site_name) : $site_name;
break;
case 'slogan':
$slogan = variable_get('site_slogan', '');
$replacements[$original] = $sanitize ? check_plain($slogan) : $slogan;
break;
case 'mail':
$replacements[$original] = variable_get('site_mail', '');
break;
case 'url':
$replacements[$original] = url('<front>', $url_options);
break;
case 'url-brief':
$replacements[$original] = preg_replace(array('!^https?://!', '!/$!'), '', url('<front>', $url_options));
break;
case 'login-url':
$replacements[$original] = url('user', $url_options);
break;
}
}
}
elseif ($type == 'date') {
if (empty($data['date'])) {
$date = REQUEST_TIME;
}
else {
$date = $data['date'];
}
foreach ($tokens as $name => $original) {
switch ($name) {
case 'short':
$replacements[$original] = format_date($date, 'short', '', NULL, $language_code);
break;
case 'medium':
$replacements[$original] = format_date($date, 'medium', '', NULL, $language_code);
break;
case 'long':
$replacements[$original] = format_date($date, 'long', '', NULL, $language_code);
break;
case 'since':
$replacements[$original] = format_interval((REQUEST_TIME - $date), 2, $language_code);
break;
case 'raw':
$replacements[$original] = $sanitize ? check_plain($date) : $date;
break;
}
}
if ($created_tokens = token_find_with_prefix($tokens, 'custom')) {
foreach ($created_tokens as $name => $original) {
$replacements[$original] = format_date($date, 'custom', $name, NULL, $language_code);
}
}
}
elseif ($type == 'file' && !empty($data['file'])) {
$file = $data['file'];
foreach ($tokens as $name => $original) {
switch ($name) {
// Basic keys and values.
case 'fid':
$replacements[$original] = $file->fid;
break;
// Essential file data
case 'name':
$replacements[$original] = $sanitize ? check_plain($file->filename) : $file->filename;
break;
case 'path':
$replacements[$original] = $sanitize ? check_plain($file->uri) : $file->uri;
break;
case 'mime':
$replacements[$original] = $sanitize ? check_plain($file->filemime) : $file->filemime;
break;
case 'size':
$replacements[$original] = format_size($file->filesize);
break;
case 'url':
$replacements[$original] = $sanitize ? check_plain(file_create_url($file->uri)) : file_create_url($file->uri);
break;
// These tokens are default variations on the chained tokens handled below.
case 'timestamp':
$replacements[$original] = format_date($file->timestamp, 'medium', '', NULL, $language_code);
break;
case 'owner':
$account = user_load($file->uid);
$name = format_username($account);
$replacements[$original] = $sanitize ? check_plain($name) : $name;
break;
}
}
if ($date_tokens = token_find_with_prefix($tokens, 'timestamp')) {
$replacements += token_generate('date', $date_tokens, array('date' => $file->timestamp), $options);
}
if (($owner_tokens = token_find_with_prefix($tokens, 'owner')) && $account = user_load($file->uid)) {
$replacements += token_generate('user', $owner_tokens, array('user' => $account), $options);
}
}
return $replacements;
}

View file

@ -0,0 +1,150 @@
<?php
/**
* @file
* Subclasses of the Updater class to update Drupal core knows how to update.
* At this time, only modules and themes are supported.
*/
/**
* Class for updating modules using FileTransfer classes via authorize.php.
*/
class ModuleUpdater extends Updater implements DrupalUpdaterInterface {
/**
* Return the directory where a module should be installed.
*
* If the module is already installed, drupal_get_path() will return
* a valid path and we should install it there (although we need to use an
* absolute path, so we prepend DRUPAL_ROOT). If we're installing a new
* module, we always want it to go into sites/all/modules, since that's
* where all the documentation recommends users install their modules, and
* there's no way that can conflict on a multi-site installation, since
* the Update manager won't let you install a new module if it's already
* found on your system, and if there was a copy in sites/all, we'd see it.
*/
public function getInstallDirectory() {
if ($this->isInstalled() && ($relative_path = drupal_get_path('module', $this->name))) {
$relative_path = dirname($relative_path);
}
else {
$relative_path = 'sites/all/modules';
}
return DRUPAL_ROOT . '/' . $relative_path;
}
public function isInstalled() {
return (bool) drupal_get_filename('module', $this->name, NULL, FALSE);
}
public static function canUpdateDirectory($directory) {
if (file_scan_directory($directory, '/.*\.module$/')) {
return TRUE;
}
return FALSE;
}
public static function canUpdate($project_name) {
return (bool) drupal_get_path('module', $project_name);
}
/**
* Return available database schema updates one a new version is installed.
*/
public function getSchemaUpdates() {
require_once DRUPAL_ROOT . '/includes/install.inc';
require_once DRUPAL_ROOT . '/includes/update.inc';
if (_update_get_project_type($project) != 'module') {
return array();
}
module_load_include('install', $project);
if (!$updates = drupal_get_schema_versions($project)) {
return array();
}
$updates_to_run = array();
$modules_with_updates = update_get_update_list();
if ($updates = $modules_with_updates[$project]) {
if ($updates['start']) {
return $updates['pending'];
}
}
return array();
}
/**
* Returns a list of post install actions.
*/
public function postInstallTasks() {
return array(
l(t('Install another module'), 'admin/modules/install'),
l(t('Enable newly added modules'), 'admin/modules'),
l(t('Administration pages'), 'admin'),
);
}
public function postUpdateTasks() {
// We don't want to check for DB updates here, we do that once for all
// updated modules on the landing page.
}
}
/**
* Class for updating themes using FileTransfer classes via authorize.php.
*/
class ThemeUpdater extends Updater implements DrupalUpdaterInterface {
/**
* Return the directory where a theme should be installed.
*
* If the theme is already installed, drupal_get_path() will return
* a valid path and we should install it there (although we need to use an
* absolute path, so we prepend DRUPAL_ROOT). If we're installing a new
* theme, we always want it to go into sites/all/themes, since that's
* where all the documentation recommends users install their themes, and
* there's no way that can conflict on a multi-site installation, since
* the Update manager won't let you install a new theme if it's already
* found on your system, and if there was a copy in sites/all, we'd see it.
*/
public function getInstallDirectory() {
if ($this->isInstalled() && ($relative_path = drupal_get_path('theme', $this->name))) {
$relative_path = dirname($relative_path);
}
else {
$relative_path = 'sites/all/themes';
}
return DRUPAL_ROOT . '/' . $relative_path;
}
public function isInstalled() {
return (bool) drupal_get_filename('theme', $this->name, NULL, FALSE);
}
static function canUpdateDirectory($directory) {
// This is a lousy test, but don't know how else to confirm it is a theme.
if (file_scan_directory($directory, '/.*\.module$/')) {
return FALSE;
}
return TRUE;
}
public static function canUpdate($project_name) {
return (bool) drupal_get_path('theme', $project_name);
}
public function postInstall() {
// Update the system table.
clearstatcache();
system_rebuild_theme_data();
}
public function postInstallTasks() {
return array(
l(t('Enable newly added themes'), 'admin/appearance'),
l(t('Administration pages'), 'admin'),
);
}
}

View file

@ -0,0 +1,12 @@
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 2017-06-21
version = "7.56"
project = "drupal"
datestamp = "1498069849"

View file

@ -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.
}
}

View file

@ -0,0 +1,12 @@
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 2017-06-21
version = "7.56"
project = "drupal"
datestamp = "1498069849"

View file

@ -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();
}

View file

@ -0,0 +1,240 @@
<?php
/**
* @defgroup themeable Default theme implementations
* @{
* Functions and templates for the user interface to be implemented by themes.
*
* Drupal's presentation layer is a pluggable system known as the theme
* layer. Each theme can take control over most of Drupal's output, and
* has complete control over the CSS.
*
* Inside Drupal, the theme layer is utilized by the use of the theme()
* function, which is passed the name of a component (the theme hook)
* and an array of variables. For example,
* theme('table', array('header' => $header, 'rows' => $rows));
* Additionally, the theme() function can take an array of theme
* hooks, which can be used to provide 'fallback' implementations to
* allow for more specific control of output. For example, the function:
* theme(array('table__foo', 'table'), $variables) would look to see if
* 'table__foo' is registered anywhere; if it is not, it would 'fall back'
* to the generic 'table' implementation. This can be used to attach specific
* theme functions to named objects, allowing the themer more control over
* specific types of output.
*
* As of Drupal 6, every theme hook is required to be registered by the
* module that owns it, so that Drupal can tell what to do with it and
* to make it simple for themes to identify and override the behavior
* for these calls.
*
* The theme hooks are registered via hook_theme(), which returns an
* array of arrays with information about the hook. It describes the
* arguments the function or template will need, and provides
* defaults for the template in case they are not filled in. If the default
* implementation is a function, by convention it is named theme_HOOK().
*
* Each module should provide a default implementation for theme_hooks that
* it registers. This implementation may be either a function or a template;
* if it is a function it must be specified via hook_theme(). By convention,
* default implementations of theme hooks are named theme_HOOK. Default
* template implementations are stored in the module directory.
*
* Drupal's default template renderer is a simple PHP parsing engine that
* includes the template and stores the output. Drupal's theme engines
* can provide alternate template engines, such as XTemplate, Smarty and
* PHPTal. The most common template engine is PHPTemplate (included with
* Drupal and implemented in phptemplate.engine, which uses Drupal's default
* template renderer.
*
* In order to create theme-specific implementations of these hooks, themes can
* implement their own version of theme hooks, either as functions or templates.
* These implementations will be used instead of the default implementation. If
* using a pure .theme without an engine, the .theme is required to implement
* its own version of hook_theme() to tell Drupal what it is implementing;
* themes utilizing an engine will have their well-named theming functions
* automatically registered for them. While this can vary based upon the theme
* engine, the standard set by phptemplate is that theme functions should be
* named THEMENAME_HOOK. For example, for Drupal's default theme (Bartik) to
* implement the 'table' hook, the phptemplate.engine would find
* bartik_table().
*
* The theme system is described and defined in theme.inc.
*
* @see theme()
* @see hook_theme()
* @see hooks
* @see callbacks
*
* @} End of "defgroup themeable".
*/
/**
* Allow themes to alter the theme-specific settings form.
*
* With this hook, themes can alter the theme-specific settings form in any way
* allowable by Drupal's Form API, such as adding form elements, changing
* default values and removing form elements. See the Form API documentation on
* api.drupal.org for detailed information.
*
* Note that the base theme's form alterations will be run before any sub-theme
* alterations.
*
* @param $form
* Nested array of form elements that comprise the form.
* @param $form_state
* A keyed array containing the current state of the form.
*/
function hook_form_system_theme_settings_alter(&$form, &$form_state) {
// Add a checkbox to toggle the breadcrumb trail.
$form['toggle_breadcrumb'] = array(
'#type' => 'checkbox',
'#title' => t('Display the breadcrumb'),
'#default_value' => theme_get_setting('toggle_breadcrumb'),
'#description' => t('Show a trail of links from the homepage to the current page.'),
);
}
/**
* Preprocess theme variables for templates.
*
* This hook allows modules to preprocess theme variables for theme templates.
* It is called for all theme hooks implemented as templates, but not for theme
* hooks implemented as functions. hook_preprocess_HOOK() can be used to
* preprocess variables for a specific theme hook, whether implemented as a
* template or function.
*
* For more detailed information, see theme().
*
* @param $variables
* The variables array (modify in place).
* @param $hook
* The name of the theme hook.
*/
function hook_preprocess(&$variables, $hook) {
static $hooks;
// Add contextual links to the variables, if the user has permission.
if (!user_access('access contextual links')) {
return;
}
if (!isset($hooks)) {
$hooks = theme_get_registry();
}
// Determine the primary theme function argument.
if (isset($hooks[$hook]['variables'])) {
$keys = array_keys($hooks[$hook]['variables']);
$key = $keys[0];
}
else {
$key = $hooks[$hook]['render element'];
}
if (isset($variables[$key])) {
$element = $variables[$key];
}
if (isset($element) && is_array($element) && !empty($element['#contextual_links'])) {
$variables['title_suffix']['contextual_links'] = contextual_links_view($element);
if (!empty($variables['title_suffix']['contextual_links'])) {
$variables['classes_array'][] = 'contextual-links-region';
}
}
}
/**
* Preprocess theme variables for a specific theme hook.
*
* This hook allows modules to preprocess theme variables for a specific theme
* hook. It should only be used if a module needs to override or add to the
* theme preprocessing for a theme hook it didn't define.
*
* For more detailed information, see theme().
*
* @param $variables
* The variables array (modify in place).
*/
function hook_preprocess_HOOK(&$variables) {
// This example is from rdf_preprocess_image(). It adds an RDF attribute
// to the image hook's variables.
$variables['attributes']['typeof'] = array('foaf:Image');
}
/**
* Process theme variables for templates.
*
* This hook allows modules to process theme variables for theme templates. It
* is called for all theme hooks implemented as templates, but not for theme
* hooks implemented as functions. hook_process_HOOK() can be used to process
* variables for a specific theme hook, whether implemented as a template or
* function.
*
* For more detailed information, see theme().
*
* @param $variables
* The variables array (modify in place).
* @param $hook
* The name of the theme hook.
*/
function hook_process(&$variables, $hook) {
// Wraps variables in RDF wrappers.
if (!empty($variables['rdf_template_variable_attributes_array'])) {
foreach ($variables['rdf_template_variable_attributes_array'] as $variable_name => $attributes) {
$context = array(
'hook' => $hook,
'variable_name' => $variable_name,
'variables' => $variables,
);
$variables[$variable_name] = theme('rdf_template_variable_wrapper', array('content' => $variables[$variable_name], 'attributes' => $attributes, 'context' => $context));
}
}
}
/**
* Process theme variables for a specific theme hook.
*
* This hook allows modules to process theme variables for a specific theme
* hook. It should only be used if a module needs to override or add to the
* theme processing for a theme hook it didn't define.
*
* For more detailed information, see theme().
*
* @param $variables
* The variables array (modify in place).
*/
function hook_process_HOOK(&$variables) {
// @todo There are no use-cases in Drupal core for this hook. Find one from a
// contributed module, or come up with a good example. Coming up with a good
// example might be tough, since the intent is for nearly everything to be
// achievable via preprocess functions, and for process functions to only be
// used when requiring the later execution time.
}
/**
* Respond to themes being enabled.
*
* @param array $theme_list
* Array containing the names of the themes being enabled.
*
* @see theme_enable()
*/
function hook_themes_enabled($theme_list) {
foreach ($theme_list as $theme) {
block_theme_initialize($theme);
}
}
/**
* Respond to themes being disabled.
*
* @param array $theme_list
* Array containing the names of the themes being disabled.
*
* @see theme_disable()
*/
function hook_themes_disabled($theme_list) {
// Clear all update module caches.
_update_cache_clear();
}