--- C:\Users\Edward\Webs\drupal\includes\common.inc 2008-01-15 23:26:00.086000000 -0500 +++ C:\Users\Edward\Webs\drupal\includes\common.inc.formatted 2008-01-16 00:08:58.707000000 -0500 @@ -1,6 +1,7 @@ 'alternate', - 'type' => 'application/rss+xml', - 'title' => $title, - 'href' => $url)); + 'type' => 'application/rss+xml', + 'title' => $title, + 'href' => $url)); } return $stored_feed_links; } @@ -200,22 +201,23 @@ * nested items. * @param $parent * Should not be passed, only used in recursive calls. + * * @return * An urlencoded string which can be appended to/as the URL query string. */ function drupal_query_string_encode($query, $exclude = array(), $parent = '') { $params = array(); - + foreach ($query as $key => $value) { $key = drupal_urlencode($key); if ($parent) { $key = $parent .'['. $key .']'; } - + if (in_array($key, $exclude)) { continue; } - + if (is_array($value)) { $params[] = drupal_query_string_encode($value, $exclude, $key); } @@ -223,7 +225,7 @@ $params[] = $key .'='. drupal_urlencode($value); } } - + return implode('&', $params); } @@ -294,30 +296,30 @@ * @see drupal_get_destination() */ function drupal_goto($path = '', $query = NULL, $fragment = NULL, $http_response_code = 302) { - + if (isset($_REQUEST['destination'])) { extract(parse_url(urldecode($_REQUEST['destination']))); } else if (isset($_REQUEST['edit']['destination'])) { extract(parse_url(urldecode($_REQUEST['edit']['destination']))); } - + $url = url($path, array('query' => $query, 'fragment' => $fragment, 'absolute' => TRUE)); // Remove newlines from the URL to avoid header injection attacks. $url = str_replace(array("\n", "\r"), '', $url); - + // Allow modules to react to the end of the page request before redirecting. // We do not want this while running update.php. if (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update') { module_invoke_all('exit', $url); } - + // Even though session_write_close() is registered as a shutdown function, we // need all session data written to the database before redirecting. session_write_close(); - + header('Location: '. $url, TRUE, $http_response_code); - + // The "Location" header sends a redirect status code to the HTTP daemon. In // some cases this can be wrong, so we make sure none of the code below the // drupal_goto() call gets executed upon redirection. @@ -332,7 +334,7 @@ drupal_set_header('HTTP/1.1 503 Service unavailable'); drupal_set_title(t('Site off-line')); print theme('maintenance_page', filter_xss_admin(variable_get('site_offline_message', - t('@site is currently under maintenance. We should be back shortly. Thank you for your patience.', array('@site' => variable_get('site_name', 'Drupal')))))); + t('@site is currently under maintenance. We should be back shortly. Thank you for your patience.', array('@site' => variable_get('site_name', 'Drupal')))))); } /** @@ -340,14 +342,14 @@ */ function drupal_not_found() { drupal_set_header('HTTP/1.1 404 Not Found'); - + watchdog('page not found', check_plain($_GET['q']), NULL, WATCHDOG_WARNING); - + // Keep old path for reference. if (!isset($_REQUEST['destination'])) { $_REQUEST['destination'] = $_GET['q']; } - + $path = drupal_get_normal_path(variable_get('site_404', '')); if ($path && $path != $_GET['q']) { // Set the active item in case there are tabs to display, or other @@ -355,12 +357,12 @@ menu_set_active_item($path); $return = menu_execute_active_handler($path); } - + if (empty($return) || $return == MENU_NOT_FOUND || $return == MENU_ACCESS_DENIED) { drupal_set_title(t('Page not found')); $return = t('The requested page could not be found.'); } - + // To conserve CPU and bandwidth, omit the blocks. print theme('page', $return, FALSE); } @@ -371,12 +373,12 @@ function drupal_access_denied() { drupal_set_header('HTTP/1.1 403 Forbidden'); watchdog('access denied', check_plain($_GET['q']), NULL, WATCHDOG_WARNING); - + // Keep old path for reference. if (!isset($_REQUEST['destination'])) { $_REQUEST['destination'] = $_GET['q']; } - + $path = drupal_get_normal_path(variable_get('site_403', '')); if ($path && $path != $_GET['q']) { // Set the active item in case there are tabs to display or other @@ -384,7 +386,7 @@ menu_set_active_item($path); $return = menu_execute_active_handler($path); } - + if (empty($return) || $return == MENU_NOT_FOUND || $return == MENU_ACCESS_DENIED) { drupal_set_title(t('Access denied')); $return = t('You are not authorized to access this page.'); @@ -409,6 +411,7 @@ * @param $retry * An integer representing how many times to retry the request in case of a * redirect. + * * @return * An object containing the HTTP request headers, response code, headers, * data and redirect status. @@ -422,7 +425,7 @@ // some parsing has failed. if (!$self_test && variable_get('drupal_http_request_fails', FALSE)) { $self_test = TRUE; - $works = module_invoke('system', 'check_http_request'); + $works = module_invoke('system', 'check_http_request'); $self_test = FALSE; if (!$works) { // Do not bother with further operations if we already know that we @@ -431,27 +434,29 @@ return $result; } } - + // Parse the URL and make sure we can handle the schema. $uri = parse_url($url); - + switch ($uri['scheme']) { case 'http': $port = isset($uri['port']) ? $uri['port'] : 80; $host = $uri['host'] . ($port != 80 ? ':'. $port : ''); - $fp = @fsockopen($uri['host'], $port, $errno, $errstr, 15); + $fp = @fsockopen($uri['host'], $port, $errno, $errstr, 15); break; + case 'https': // Note: Only works for PHP 4.3 compiled with OpenSSL. $port = isset($uri['port']) ? $uri['port'] : 443; $host = $uri['host'] . ($port != 443 ? ':'. $port : ''); - $fp = @fsockopen('ssl://'. $uri['host'], $port, $errno, $errstr, 20); + $fp = @fsockopen('ssl://'. $uri['host'], $port, $errno, $errstr, 20); break; + default: $result->error = 'invalid schema '. $uri['scheme']; return $result; } - + // Make sure the socket opened properly. if (!$fp) { // When a network error occurs, we use a negative number so it does not @@ -460,13 +465,13 @@ $result->error = trim($errstr); return $result; } - + // Construct the path to act on. $path = isset($uri['path']) ? $uri['path'] : '/'; if (isset($uri['query'])) { $path .= '?'. $uri['query']; } - + // Create HTTP request. $defaults = array( // RFC 2616: "non-standard ports MUST, default ports MAY be included". @@ -474,18 +479,18 @@ // host that do not take into account the port number. 'Host' => "Host: $host", 'User-Agent' => 'User-Agent: Drupal (+http://drupal.org/)', - 'Content-Length' => 'Content-Length: '. strlen($data) + 'Content-Length' => 'Content-Length: '. strlen($data), ); - + // If the server url has a user then attempt to use basic authentication if (isset($uri['user'])) { $defaults['Authorization'] = 'Authorization: Basic '. base64_encode($uri['user'] . (!empty($uri['pass']) ? ":". $uri['pass'] : '')); } - + foreach ($headers as $header => $value) { $defaults[$header] = $header .': '. $value; } - + $request = $method .' '. $path ." HTTP/1.0\r\n"; $request .= implode("\r\n", $defaults); $request .= "\r\n\r\n"; @@ -493,23 +498,23 @@ $request .= $data ."\r\n"; } $result->request = $request; - + fwrite($fp, $request); - + // Fetch response. $response = ''; while (!feof($fp) && $chunk = fread($fp, 1024)) { $response .= $chunk; } fclose($fp); - + // Parse response. list($split, $result->data) = explode("\r\n\r\n", $response, 2); $split = preg_split("/\r\n|\n|\r/", $split); - + list($protocol, $code, $text) = explode(' ', trim(array_shift($split)), 3); $result->headers = array(); - + // Parse headers. while ($line = trim(array_shift($split))) { list($header, $value) = explode(':', $line, 2); @@ -522,43 +527,50 @@ $result->headers[$header] = trim($value); } } - + $responses = array( 100 => 'Continue', 101 => 'Switching Protocols', 200 => 'OK', 201 => 'Created', 202 => 'Accepted', 203 => 'Non-Authoritative Information', 204 => 'No Content', 205 => 'Reset Content', 206 => 'Partial Content', 300 => 'Multiple Choices', 301 => 'Moved Permanently', 302 => 'Found', 303 => 'See Other', 304 => 'Not Modified', 305 => 'Use Proxy', 307 => 'Temporary Redirect', 400 => 'Bad Request', 401 => 'Unauthorized', 402 => 'Payment Required', 403 => 'Forbidden', 404 => 'Not Found', 405 => 'Method Not Allowed', 406 => 'Not Acceptable', 407 => 'Proxy Authentication Required', 408 => 'Request Time-out', 409 => 'Conflict', 410 => 'Gone', 411 => 'Length Required', 412 => 'Precondition Failed', 413 => 'Request Entity Too Large', 414 => 'Request-URI Too Large', 415 => 'Unsupported Media Type', 416 => 'Requested range not satisfiable', 417 => 'Expectation Failed', - 500 => 'Internal Server Error', 501 => 'Not Implemented', 502 => 'Bad Gateway', 503 => 'Service Unavailable', 504 => 'Gateway Time-out', 505 => 'HTTP Version not supported' + 500 => 'Internal Server Error', 501 => 'Not Implemented', 502 => 'Bad Gateway', 503 => 'Service Unavailable', 504 => 'Gateway Time-out', 505 => 'HTTP Version not supported', ); // RFC 2616 states that all unknown HTTP codes must be treated the same as the // base code in their class. if (!isset($responses[$code])) { $code = floor($code / 100) * 100; } - + switch ($code) { - case 200: // OK - case 304: // Not modified + case 200: + // OK + case 304: + // Not modified break; - case 301: // Moved permanently - case 302: // Moved temporarily - case 307: // Moved temporarily + + case 301: + // Moved permanently + case 302: + // Moved temporarily + case 307: + // Moved temporarily $location = $result->headers['Location']; - + if ($retry) { $result = drupal_http_request($result->headers['Location'], $headers, $method, $data, --$retry); $result->redirect_code = $result->code; } $result->redirect_url = $location; - break; + default: $result->error = $text; } - + $result->code = $code; return $result; } + /** * @} End of "HTTP handling". */ @@ -576,18 +588,18 @@ if (error_reporting() == 0) { return; } - + if ($errno & (E_ALL)) { $types = array(1 => 'error', 2 => 'warning', 4 => 'parse error', 8 => 'notice', 16 => 'core error', 32 => 'core warning', 64 => 'compile error', 128 => 'compile warning', 256 => 'user error', 512 => 'user warning', 1024 => 'user notice', 2048 => 'strict warning', 4096 => 'recoverable fatal error'); - + // For database errors, we want the line number/file name of the place that // the query was originally called, not _db_query(). if (isset($context[DB_ERROR])) { $backtrace = array_reverse(debug_backtrace()); - + // List of functions where SQL queries can originate. $query_functions = array('db_query', 'pager_query', 'db_query_range', 'db_query_temporary', 'update_sql'); - + // Determine where query function was called, and adjust line/file // accordingly. foreach ($backtrace as $index => $function) { @@ -598,14 +610,14 @@ } } } - + $entry = $types[$errno] .': '. $message .' in '. $filename .' on line '. $line .'.'; - + // Force display of error messages in update.php. if (variable_get('error_level', 1) == 1 || strstr($_SERVER['SCRIPT_NAME'], 'update.php')) { drupal_set_message($entry, 'error'); } - + watchdog('php', '%message in %file on line %line.', array('%error' => $types[$errno], '%message' => $message, '%file' => $filename, '%line' => $line), WATCHDOG_ERROR); } } @@ -747,15 +759,16 @@ * @param $langcode * Optional language code to translate to a language other than what is used * to display the page. + * * @return * The translated string. */ function t($string, $args = array(), $langcode = NULL) { global $language; static $custom_strings; - + $langcode = isset($langcode) ? $langcode : $language->language; - + // First, check for an array of customized strings. If present, use the array // *instead of* database lookups. This is a high performance way to provide a // handful of string replacements. See settings.php for examples. @@ -782,13 +795,13 @@ // Escaped only. $args[$key] = check_plain($value); break; - + case '%': default: // Escaped and placeholder. $args[$key] = theme('placeholder', $value); break; - + case '!': // Pass-through. } @@ -810,15 +823,16 @@ * * @param $mail * A string containing an e-mail address. + * * @return * TRUE if the address is in a valid format. */ function valid_email_address($mail) { - $user = '[a-zA-Z0-9_\-\.\+\^!#\$%&*+\/\=\?\`\|\{\}~\']+'; + $user = '[a-zA-Z0-9_\-\.\+\^!#\$%&*+\/\=\?\`\|\{\}~\']+'; $domain = '(?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.?)+'; - $ipv4 = '[0-9]{1,3}(\.[0-9]{1,3}){3}'; - $ipv6 = '[0-9a-fA-F]{1,4}(\:[0-9a-fA-F]{1,4}){7}'; - + $ipv4 = '[0-9]{1,3}(\.[0-9]{1,3}){3}'; + $ipv6 = '[0-9a-fA-F]{1,4}(\:[0-9a-fA-F]{1,4}){7}'; + return preg_match("/^$user@($domain|(\[($ipv4|$ipv6)\]))$/", $mail); } @@ -832,6 +846,7 @@ * The URL to verify. * @param $absolute * Whether the URL is absolute (beginning with a scheme such as "http:"). + * * @return * TRUE if the URL is in a valid format. */ @@ -865,6 +880,7 @@ * The name of the event. * @param $number * The maximum number of the specified event per hour (per visitor). + * * @return * True if the user did not exceed the hourly threshold. False otherwise. */ @@ -898,11 +914,11 @@ function format_rss_channel($title, $link, $description, $items, $langcode = NULL, $args = array()) { global $language; $langcode = $langcode ? $langcode : $language->language; - + $output = "\n"; $output .= ' '. check_plain($title) ."\n"; $output .= ' '. check_url($link) ."\n"; - + // The RSS 2.0 "spec" doesn't indicate HTML can be used in the description. // We strip all HTML tags, but need to prevent double encoding from properly // escaped source data (such as & becoming &amp;). @@ -911,7 +927,7 @@ $output .= format_xml_elements($args); $output .= $items; $output .= "\n"; - + return $output; } @@ -927,7 +943,7 @@ $output .= ' '. check_plain($description) ."\n"; $output .= format_xml_elements($args); $output .= "\n"; - + return $output; } @@ -954,7 +970,7 @@ if (isset($value['attributes']) && is_array($value['attributes'])) { $output .= drupal_attributes($value['attributes']); } - + if ($value['value'] != '') { $output .= '>'. (is_array($value['value']) ? format_xml_elements($value['value']) : check_plain($value['value'])) .'\n"; } @@ -1013,6 +1029,7 @@ * @param $langcode * Optional language code to translate to a language other than * what is used to display the page. + * * @return * A translated string. */ @@ -1021,7 +1038,7 @@ if ($count == 1) { return t($singular, $args, $langcode); } - + // Get the plural index through the gettext formula. $index = (function_exists('locale_get_plural')) ? locale_get_plural($count, $langcode) : -1; // Backwards compatibility. @@ -1032,8 +1049,10 @@ switch ($index) { case "0": return t($singular, $args, $langcode); + case "1": return t($plural, $args, $langcode); + default: unset($args['@count']); $args['@count['. $index .']'] = $count; @@ -1048,6 +1067,7 @@ * @param $size * A size expressed as a number of bytes with optional SI size and unit * suffix (e.g. 2, 3K, 5MB, 10G). + * * @return * An integer representation of the size. */ @@ -1055,8 +1075,10 @@ $suffixes = array( '' => 1, 'k' => 1024, - 'm' => 1048576, // 1024 * 1024 - 'g' => 1073741824, // 1024 * 1024 * 1024 + // 1024 * 1024 + 'm' => 1048576, + // 1024 * 1024 * 1024 + 'g' => 1073741824, ); if (preg_match('/([0-9]+)\s*(k|m|g)?(b?(ytes?)?)/i', $size, $match)) { return $match[1] * $suffixes[drupal_strtolower($match[2])]; @@ -1071,6 +1093,7 @@ * @param $langcode * Optional language code to translate to a language other than what is used * to display the page. + * * @return * A translated string representation of the size. */ @@ -1099,6 +1122,7 @@ * @param $langcode * Optional language code to translate to a language other than * what is used to display the page. + * * @return * A translated string representation of the interval. */ @@ -1112,7 +1136,7 @@ $timestamp %= $value; $granularity--; } - + if ($granularity == 0) { break; } @@ -1141,6 +1165,7 @@ * @param $langcode * Optional language code to translate to a language other than what is used * to display the page. + * * @return * A translated date string in the requested format. */ @@ -1154,24 +1179,27 @@ $timezone = variable_get('date_default_timezone', 0); } } - + $timestamp += $timezone; - + switch ($type) { case 'small': $format = variable_get('date_format_short', 'm/d/Y - H:i'); break; + case 'large': $format = variable_get('date_format_long', 'l, F j, Y - H:i'); break; + case 'custom': // No change to format. break; + case 'medium': default: $format = variable_get('date_format_medium', 'D, m/d/Y - H:i'); } - + $max = strlen($format); $date = ''; for ($i = 0; $i < $max; $i++) { @@ -1204,7 +1232,7 @@ $date .= $c; } } - + return $date; } @@ -1244,6 +1272,7 @@ * 'prefix' * Only used internally, to modify the path when a language dependent URL * requires so. + * * @return * A string containing a URL to the given path. * @@ -1257,7 +1286,7 @@ 'query' => '', 'absolute' => FALSE, 'alias' => FALSE, - 'prefix' => '' + 'prefix' => '', ); if (!isset($options['external'])) { // Return an external link if $path contains an allowed absolute URL. @@ -1266,7 +1295,7 @@ $colonpos = strpos($path, ':'); $options['external'] = ($colonpos !== FALSE && !preg_match('![/?#]!', substr($path, 0, $colonpos)) && filter_xss_bad_protocol($path, FALSE) == check_plain($path)); } - + // May need language dependent rewriting if language.inc is present. if (function_exists('language_url_rewrite')) { language_url_rewrite($path, $options); @@ -1277,7 +1306,7 @@ if (is_array($options['query'])) { $options['query'] = drupal_query_string_encode($options['query']); } - + if ($options['external']) { // Split off the fragment. if (strpos($path, '#') !== FALSE) { @@ -1293,32 +1322,32 @@ // Reassemble. return $path . $options['fragment']; } - + global $base_url; static $script; static $clean_url; - + if (!isset($script)) { // On some web servers, such as IIS, we can't omit "index.php". So, we // generate "index.php?q=foo" instead of "?q=foo" on anything that is not // Apache. $script = (strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') === FALSE) ? 'index.php' : ''; } - + // Cache the clean_url variable to improve performance. if (!isset($clean_url)) { $clean_url = (bool)variable_get('clean_url', '0'); } - + if (!isset($options['base_url'])) { // The base_url might be rewritten from the language rewrite in domain mode. $options['base_url'] = $base_url; } $base = $options['absolute'] ? $options['base_url'] .'/' : base_path(); - + // Preserve the original path before aliasing. $original_path = $path; - + // The special path '' links to the default front page. if (!empty($path) && $path != '') { if (!$options['alias']) { @@ -1334,7 +1363,7 @@ // Will be empty if there is no language prefix. $path = trim($options['prefix'], '/'); } - + if ($clean_url) { // With Clean URLs. if ($options['query']) { @@ -1367,6 +1396,7 @@ * * @param $attributes * An associative array of HTML attributes. + * * @return * An HTML string ready for insertion in a tag. */ @@ -1420,16 +1450,17 @@ * escaped HTML. * 'alias' (default FALSE) * Whether the given path is an alias already. + * * @return * an HTML string containing a link to the given path. */ function l($text, $path, $options = array()) { // Merge in defaults. $options += array( - 'attributes' => array(), - 'html' => FALSE, - ); - + 'attributes' => array(), + 'html' => FALSE, + ); + // Append active class. if ($path == $_GET['q'] || ($path == '' && drupal_is_front_page())) { if (isset($options['attributes']['class'])) { @@ -1439,13 +1470,13 @@ $options['attributes']['class'] = 'active'; } } - + // Remove all HTML and PHP tags from a tooltip. For best performance, we act only // if a quick strpos() pre-check gave a suspicion (because strip_tags() is expensive). if (isset($options['attributes']['title']) && strpos($options['attributes']['title'], '<') !== FALSE) { $options['attributes']['title'] = strip_tags($options['attributes']['title']); } - + return ''. ($options['html'] ? $text : check_plain($text)) .''; } @@ -1459,7 +1490,7 @@ if (variable_get('cache', CACHE_DISABLED) != CACHE_DISABLED) { page_set_cache(); } - + module_invoke_all('exit'); } @@ -1509,16 +1540,17 @@ * * @param $code * The code to evaluate. + * * @return * A string containing the printed output of the code, followed by the returned * output of the code. */ function drupal_eval($code) { global $theme_path, $theme_info, $conf; - + // Store current theme path. $old_theme_path = $theme_path; - + // Restore theme_path to the theme, as long as drupal_eval() executes, // so code evaluted will not see the caller module as the current theme. // If theme info is not initialized get the path from theme_default. @@ -1528,15 +1560,15 @@ else { $theme_path = dirname($theme_info->filename); } - + ob_start(); print eval('?>'. $code); $output = ob_get_contents(); ob_end_clean(); - + // Recover original theme path. $theme_path = $old_theme_path; - + return $output; } @@ -1633,13 +1665,14 @@ * * Typical candidates for caching are for example styles for nodes across * the site, or used in the theme. + * * @return * An array of CSS files. */ function drupal_add_css($path = NULL, $type = 'module', $media = 'all', $preprocess = TRUE) { static $css = array(); global $language; - + // Create an array of CSS files for each media type first, since each type needs to be served // to the browser differently. if (isset($path)) { @@ -1647,7 +1680,7 @@ if (!isset($css[$media])) { $css[$media] = array('module' => array(), 'theme' => array()); } - + // If a theme is adding the current stylesheet, check for any existing CSS files // with the same name. If they exist, remove them and allow the theme's own CSS // file to replace it. @@ -1656,7 +1689,7 @@ // Match by style sheet name. if (basename($path) == basename($old_path)) { unset($css[$media]['module'][$old_path]); - + // If the current language is RTL and the CSS file had an RTL variant, // pull out the original. The theme must provide its own RTL style. if (defined('LANGUAGE_RTL') && $language->direction == LANGUAGE_RTL) { @@ -1672,7 +1705,7 @@ } } $css[$media][$type][$path] = $preprocess; - + // If the current language is RTL, add the CSS file with RTL overrides. if (defined('LANGUAGE_RTL') && $language->direction == LANGUAGE_RTL) { $rtl_path = str_replace('.css', '-rtl.css', $path); @@ -1681,7 +1714,7 @@ } } } - + return $css; } @@ -1695,6 +1728,7 @@ * @param $css * (optional) An array of CSS files. If no array is provided, the default * stylesheets array is used instead. + * * @return * A string of XHTML CSS tags. */ @@ -1705,17 +1739,17 @@ } $no_module_preprocess = ''; $no_theme_preprocess = ''; - + $preprocess_css = (variable_get('preprocess_css', FALSE) && (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update')); $directory = file_directory_path(); $is_writable = is_dir($directory) && is_writable($directory) && (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) == FILE_DOWNLOADS_PUBLIC); - + // A dummy query-string is added to filenames, to gain control over // browser-caching. The string changes on every update or full cache // flush, forcing browsers to load a new copy of the files, as the // URL changed. $query_string = '?'. substr(variable_get('css_js_query_string', '0'), 0, 1); - + foreach ($css as $media => $types) { // If CSS preprocessing is off, we still need to output the styles. // Additionally, go through any remaining styles if CSS preprocessing is on and output the non-cached ones. @@ -1738,14 +1772,14 @@ } } } - + if ($is_writable && $preprocess_css) { $filename = md5(serialize($types) . $query_string) .'.css'; $preprocess_file = drupal_build_css_cache($types, $filename); $output .= ''."\n"; } } - + return $no_module_preprocess . $output . $no_theme_preprocess; } @@ -1757,16 +1791,17 @@ * compress into one file. * @param $filename * The name of the aggregate CSS file. + * * @return * The name of the CSS file. */ function drupal_build_css_cache($types, $filename) { $data = ''; - + // Create the css/ within the files folder. $csspath = file_create_path('css'); file_check_directory($csspath, FILE_CREATE_DIRECTORY); - + if (!file_exists($csspath .'/'. $filename)) { // Build aggregate CSS file. foreach ($types as $type) { @@ -1781,14 +1816,14 @@ } } } - + // Per the W3C specification at http://www.w3.org/TR/REC-CSS2/cascade.html#at-import, // @import rules must proceed any other style, so we move those to the top. $regexp = '/@import[^;]+;/i'; preg_match_all($regexp, $data, $matches); $data = preg_replace($regexp, '', $data); $data = implode('', $matches[0]) . $data; - + // Create the CSS file. file_save_data($data, $csspath .'/'. $filename, FILE_EXISTS_REPLACE); } @@ -1806,7 +1841,7 @@ if (isset($base)) { $_base = $base; } - + // Prefix with base and remove '../' segments where possible. $path = $_base . $matches[1]; $last = ''; @@ -1832,6 +1867,7 @@ * Name of the stylesheet to be processed. * @param $optimize * Defines if CSS contents should be compressed or not. + * * @return * Contents of the stylesheet including the imported stylesheets. */ @@ -1841,22 +1877,22 @@ if (isset($optimize)) { $_optimize = $optimize; } - + $contents = ''; if (file_exists($file)) { // Load the local CSS stylesheet. $contents = file_get_contents($file); - + // Change to the current stylesheet's directory. $cwd = getcwd(); chdir(dirname($file)); - + // Replaces @import commands with the actual stylesheet content. // This happens recursively but omits external files. $contents = preg_replace_callback('/@import\s*(?:url\()?[\'"]?(?![a-z]+:)([^\'"\()]+)[\'"]?\)?;/', '_drupal_load_stylesheet', $contents); // Remove multiple charset declarations for standards compliance (and fixing Safari problems). $contents = preg_replace('/^@charset\s+[\'"](\S*)\b[\'"];/i', '', $contents); - + if ($_optimize) { // Perform some safe CSS optimizations. $contents = preg_replace('< @@ -1865,11 +1901,11 @@ [\n\r] # Remove line breaks. >x', '\1', $contents); } - + // Change back directory. chdir($cwd); } - + return $contents; } @@ -1945,6 +1981,7 @@ * @param $preprocess * (optional) Should this JS file be aggregated if this * feature has been turned on under the performance section? + * * @return * If the first parameter is NULL, the JavaScript array that has been built so * far for $scope is returned. If the first three parameters are NULL, @@ -1952,9 +1989,9 @@ */ function drupal_add_js($data = NULL, $type = 'module', $scope = 'header', $defer = FALSE, $cache = TRUE, $preprocess = TRUE) { static $javascript = array(); - + if (isset($data)) { - + // Add jquery.js and drupal.js, as well as the basePath setting, the // first time a Javascript file is added. if (empty($javascript)) { @@ -1971,30 +2008,32 @@ 'inline' => array(), ); } - + if (isset($scope) && !isset($javascript[$scope])) { $javascript[$scope] = array('core' => array(), 'module' => array(), 'theme' => array(), 'setting' => array(), 'inline' => array()); } - + if (isset($type) && isset($scope) && !isset($javascript[$scope][$type])) { $javascript[$scope][$type] = array(); } - + switch ($type) { case 'setting': $javascript[$scope][$type][] = $data; break; + case 'inline': $javascript[$scope][$type][] = array('code' => $data, 'defer' => $defer); break; + default: // If cache is FALSE, don't preprocess the JS file. $javascript[$scope][$type][$data] = array('cache' => $cache, 'defer' => $defer, 'preprocess' => (!$cache ? FALSE : $preprocess)); } } - + if (isset($scope)) { - + if (isset($javascript[$scope])) { return $javascript[$scope]; } @@ -2021,6 +2060,7 @@ * @parameter $javascript * (optional) An array with all JavaScript code. Defaults to the default * JavaScript array for the given scope. + * * @return * All JavaScript code segments and includes for the scope as HTML tags. */ @@ -2028,23 +2068,23 @@ if ((!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update') && function_exists('locale_update_js_files')) { locale_update_js_files(); } - + if (!isset($javascript)) { $javascript = drupal_add_js(NULL, NULL, $scope); } - + if (empty($javascript)) { return ''; } - - $output = ''; - $preprocessed = ''; + + $output = ''; + $preprocessed = ''; $no_preprocess = array('core' => '', 'module' => '', 'theme' => ''); - $files = array(); + $files = array(); $preprocess_js = (variable_get('preprocess_js', FALSE) && (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update')); - $directory = file_directory_path(); - $is_writable = is_dir($directory) && is_writable($directory) && (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) == FILE_DOWNLOADS_PUBLIC); - + $directory = file_directory_path(); + $is_writable = is_dir($directory) && is_writable($directory) && (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) == FILE_DOWNLOADS_PUBLIC); + // A dummy query-string is added to filenames, to gain control over // browser-caching. The string changes on every update or full cache // flush, forcing browsers to load a new copy of the files, as the @@ -2052,20 +2092,22 @@ // get time() as query-string instead, to enforce reload on every // page request. $query_string = '?'. substr(variable_get('css_js_query_string', '0'), 0, 1); - + foreach ($javascript as $type => $data) { - + if (!$data) continue; - + switch ($type) { case 'setting': $output .= '\n"; break; + case 'inline': foreach ($data as $info) { $output .= '\n"; } break; + default: // If JS preprocessing is off, we still need to output the scripts. // Additionally, go through any remaining scripts if JS preprocessing is on and output the non-cached ones. @@ -2079,18 +2121,18 @@ } } } - + // Aggregate any remaining JS files that haven't already been output. if ($is_writable && $preprocess_js && count($files) > 0) { $filename = md5(serialize($files) . $query_string) .'.js'; $preprocess_file = drupal_build_js_cache($files, $filename); $preprocessed .= ''."\n"; } - + // Keep the order of JS files consistent as some are preprocessed and others are not. // Make sure any inline or JS setting variables appear last after libraries have loaded. $output = $preprocessed . implode('', $no_preprocess) . $output; - + return $output; } @@ -2207,7 +2249,7 @@ drupal_add_js('misc/tabledrag.js', 'core'); $js_added = TRUE; } - + // If a subgroup or source isn't set, assume it is the same as the group. $target = isset($subgroup) ? $subgroup : $group; $source = isset($source) ? $source : $target; @@ -2229,16 +2271,17 @@ * An array of JS files to aggregate and compress into one file. * @param $filename * The name of the aggregate JS file. + * * @return * The name of the JS file. */ function drupal_build_js_cache($files, $filename) { $contents = ''; - + // Create the js/ within the files folder. $jspath = file_create_path('js'); file_check_directory($jspath, FILE_CREATE_DIRECTORY); - + if (!file_exists($jspath .'/'. $filename)) { // Build aggregate JS file. foreach ($files as $path => $info) { @@ -2247,11 +2290,11 @@ $contents .= file_get_contents($path) .';'; } } - + // Create the JS file. file_save_data($contents, $jspath .'/'. $filename, FILE_EXISTS_REPLACE); } - + return $jspath .'/'. $filename; } @@ -2271,20 +2314,24 @@ function drupal_to_js($var) { switch (gettype($var)) { case 'boolean': - return $var ? 'true' : 'false'; // Lowercase necessary! + // Lowercase necessary! + return $var ? 'true' : 'false'; + case 'integer': case 'double': return $var; + case 'resource': case 'string': return '"'. str_replace(array("\r", "\n", "<", ">", "&"), - array('\r', '\n', '\x3c', '\x3e', '\x26'), - addslashes($var)) .'"'; + array('\r', '\n', '\x3c', '\x3e', '\x26'), + addslashes($var)) .'"'; + case 'array': // Arrays in JSON can't be associative. If the array is empty or if it // has sequential whole number keys starting with 0, it's not associative // so we can go ahead and convert it as an array. - if (empty ($var) || array_keys($var) === range(0, sizeof($var) - 1)) { + if (empty($var) || array_keys($var) === range(0, sizeof($var) - 1)) { $output = array(); foreach ($var as $v) { $output[] = drupal_to_js($v); @@ -2298,6 +2345,7 @@ $output[] = drupal_to_js(strval($k)) .': '. drupal_to_js($v); } return '{ '. implode(', ', $output) .' }'; + default: return 'null'; } @@ -2315,7 +2363,7 @@ function drupal_json($var = NULL) { // We are returning JavaScript, so tell the browser. drupal_set_header('Content-Type: text/javascript; charset=utf-8'); - + if (isset($var)) { echo drupal_to_js($var); } @@ -2334,7 +2382,8 @@ * - mod_rewrite unescapes %-encoded ampersands, hashes, and slashes when clean * URLs are used, which are interpreted as delimiters by PHP. These * characters are double escaped so PHP will still see the encoded version. - * - With clean URLs, Apache changes '//' to '/', so every second slash is + // ' to '/', so every second slash is + * - With clean URLs, Apache changes * double escaped. * * @param $text @@ -2342,12 +2391,13 @@ */ function drupal_urlencode($text) { if (variable_get('clean_url', '0')) { - return str_replace(array('%2F', '%26', '%23', '//'), - array('/', '%2526', '%2523', '/%252F'), - rawurlencode($text)); + // '), + return str_replace(array('%2F', '%26', '%23', + array('/', '%2526', '%2523', '/%252F'), + rawurlencode($text)); } else { - return str_replace('%2F', '/', rawurlencode($text)); + return str_replace('%2F', '/', rawurlencode($text)); } } @@ -2358,11 +2408,11 @@ * The private key. */ function drupal_get_private_key() { - if (!($key = variable_get('drupal_private_key', 0))) { - $key = md5(uniqid(mt_rand(), true)) . md5(uniqid(mt_rand(), true)); - variable_set('drupal_private_key', $key); + if (!($key = variable_get('drupal_private_key', 0))) { + $key = md5(uniqid(mt_rand(), true)) . md5(uniqid(mt_rand(), true)); + variable_set('drupal_private_key', $key); } - return $key; + return $key; } /** @@ -2372,8 +2422,8 @@ * An additional value to base the token on. */ function drupal_get_token($value = '') { - $private_key = drupal_get_private_key(); - return md5(session_id() . $value . $private_key); + $private_key = drupal_get_private_key(); + return md5(session_id() . $value . $private_key); } /** @@ -2385,13 +2435,14 @@ * An additional value to base the token on. * @param $skip_anonymous * Set to true to skip token validation for anonymous users. + * * @return * True for a valid token, false for an invalid token. When $skip_anonymous * is true, the return value will always be true for anonymous users. */ function drupal_valid_token($token, $value = '', $skip_anonymous = FALSE) { - global $user; - return (($skip_anonymous && $user->uid == 0) || ($token == md5(session_id() . $value . variable_get('drupal_private_key', '')))); + global $user; + return (($skip_anonymous && $user->uid == 0) || ($token == md5(session_id() . $value . variable_get('drupal_private_key', '')))); } /** @@ -2407,6 +2458,7 @@ * For multiple requests (system.multicall): * An array of call arrays. Each call array follows the pattern of the single * request: method name followed by the arguments to the method. + * * @return * For one request: * Either the return value of the method on success, or FALSE. @@ -2417,42 +2469,41 @@ * failed. See xmlrpc_error(). */ function xmlrpc($url) { - require_once './includes/xmlrpc.inc'; - $args = func_get_args(); - return call_user_func_array('_xmlrpc', $args); + require_once './includes/xmlrpc.inc'; + $args = func_get_args(); + return call_user_func_array('_xmlrpc', $args); } function _drupal_bootstrap_full() { - static $called; - - if ($called) { - return; - } - $called = 1; - require_once './includes/theme.inc'; - require_once './includes/pager.inc'; - require_once './includes/menu.inc'; - require_once './includes/tablesort.inc'; - require_once './includes/file.inc'; - require_once './includes/unicode.inc'; - require_once './includes/image.inc'; - require_once './includes/form.inc'; - require_once './includes/mail.inc'; - require_once './includes/actions.inc'; - // Set the Drupal custom error handler. - set_error_handler('drupal_error_handler'); - // Emit the correct charset HTTP header. - drupal_set_header('Content-Type: text/html; charset=utf-8'); - // Detect string handling method - unicode_check(); - // Undo magic quotes - fix_gpc_magic(); - // Load all enabled modules - module_load_all(); - // Let all modules take action before menu system handles the request - // We do not want this while running update.php. - if (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update') { - module_invoke_all('init'); + static $called; + if ($called) { + return; + } + $called = 1; + require_once './includes/theme.inc'; + require_once './includes/pager.inc'; + require_once './includes/menu.inc'; + require_once './includes/tablesort.inc'; + require_once './includes/file.inc'; + require_once './includes/unicode.inc'; + require_once './includes/image.inc'; + require_once './includes/form.inc'; + require_once './includes/mail.inc'; + require_once './includes/actions.inc'; + // Set the Drupal custom error handler. + set_error_handler('drupal_error_handler'); + // Emit the correct charset HTTP header. + drupal_set_header('Content-Type: text/html; charset=utf-8'); + // Detect string handling method + unicode_check(); + // Undo magic quotes + fix_gpc_magic(); + // Load all enabled modules + module_load_all(); + // Let all modules take action before menu system handles the request + // We do not want this while running update.php. + if (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update') { + module_invoke_all('init'); } } @@ -2470,27 +2521,26 @@ * @see drupal_page_header */ function page_set_cache() { - global $user, $base_root; - - if (!$user->uid && $_SERVER['REQUEST_METHOD'] == 'GET' && count(drupal_get_messages(NULL, FALSE)) == 0) { - // This will fail in some cases, see page_get_cache() for the explanation. - if ($data = ob_get_contents()) { - $cache = TRUE; - if (variable_get('page_compression', TRUE) && function_exists('gzencode')) { - // We do not store the data in case the zlib mode is deflate. - // This should be rarely happening. - if (zlib_get_coding_type() == 'deflate') { - $cache = FALSE; + global $user, $base_root; + if (!$user->uid && $_SERVER['REQUEST_METHOD'] == 'GET' && count(drupal_get_messages(NULL, FALSE)) == 0) { + // This will fail in some cases, see page_get_cache() for the explanation. + if ($data = ob_get_contents()) { + $cache = TRUE; + if (variable_get('page_compression', TRUE) && function_exists('gzencode')) { + // We do not store the data in case the zlib mode is deflate. + // This should be rarely happening. + if (zlib_get_coding_type() == 'deflate') { + $cache = FALSE; } else if (zlib_get_coding_type() == FALSE) { - $data = gzencode($data, 9, FORCE_GZIP); + $data = gzencode($data, 9, FORCE_GZIP); } - // The remaining case is 'gzip' which means the data is - // already compressed and nothing left to do but to store it. + // The remaining case is 'gzip' which means the data is + // already compressed and nothing left to do but to store it. } - ob_end_flush(); - if ($cache && $data) { - cache_set($base_root . request_uri(), $data, 'cache_page', CACHE_TEMPORARY, drupal_get_headers()); + ob_end_flush(); + if ($cache && $data) { + cache_set($base_root . request_uri(), $data, 'cache_page', CACHE_TEMPORARY, drupal_get_headers()); } } } @@ -2498,51 +2548,44 @@ /** * Executes a cron run when called + * * @return * Returns TRUE if ran successfully */ function drupal_cron_run() { - // If not in 'safe mode', increase the maximum execution time: - if (!ini_get('safe_mode')) { - set_time_limit(240); - } - - // Fetch the cron semaphore - $semaphore = variable_get('cron_semaphore', FALSE); - - if ($semaphore) { - if (time() - $semaphore > 3600) { - // Either cron has been running for more than an hour or the semaphore - // was not reset due to a database error. - watchdog('cron', 'Cron has been running for more than an hour and is most likely stuck.', array(), WATCHDOG_ERROR); - - // Release cron semaphore - variable_del('cron_semaphore'); + // If not in 'safe mode', increase the maximum execution time: + if (!ini_get('safe_mode')) { + set_time_limit(240); + } + // Fetch the cron semaphore + $semaphore = variable_get('cron_semaphore', FALSE); + if ($semaphore) { + if (time() - $semaphore > 3600) { + // Either cron has been running for more than an hour or the semaphore + // was not reset due to a database error. + watchdog('cron', 'Cron has been running for more than an hour and is most likely stuck.', array(), WATCHDOG_ERROR); + // Release cron semaphore + variable_del('cron_semaphore'); } else { - // Cron is still running normally. - watchdog('cron', 'Attempting to re-run cron while it is already running.', array(), WATCHDOG_WARNING); + // Cron is still running normally. + watchdog('cron', 'Attempting to re-run cron while it is already running.', array(), WATCHDOG_WARNING); } } else { - // Register shutdown callback - register_shutdown_function('drupal_cron_cleanup'); - - // Lock cron semaphore - variable_set('cron_semaphore', time()); - - // Iterate through the modules calling their cron handlers (if any): - module_invoke_all('cron'); - - // Record cron time - variable_set('cron_last', time()); - watchdog('cron', 'Cron run completed.', array(), WATCHDOG_NOTICE); - - // Release cron semaphore - variable_del('cron_semaphore'); - - // Return TRUE so other functions can check if it did run successfully - return TRUE; + // Register shutdown callback + register_shutdown_function('drupal_cron_cleanup'); + // Lock cron semaphore + variable_set('cron_semaphore', time()); + // Iterate through the modules calling their cron handlers (if any): + module_invoke_all('cron'); + // Record cron time + variable_set('cron_last', time()); + watchdog('cron', 'Cron run completed.', array(), WATCHDOG_NOTICE); + // Release cron semaphore + variable_del('cron_semaphore'); + // Return TRUE so other functions can check if it did run successfully + return TRUE; } } @@ -2550,12 +2593,11 @@ * Shutdown function for cron cleanup. */ function drupal_cron_cleanup() { - // See if the semaphore is still locked. - if (variable_get('cron_semaphore', FALSE)) { - watchdog('cron', 'Cron run exceeded the time limit and was aborted.', array(), WATCHDOG_WARNING); - - // Release cron semaphore - variable_del('cron_semaphore'); + // See if the semaphore is still locked. + if (variable_get('cron_semaphore', FALSE)) { + watchdog('cron', 'Cron run exceeded the time limit and was aborted.', array(), WATCHDOG_WARNING); + // Release cron semaphore + variable_del('cron_semaphore'); } } @@ -2587,44 +2629,37 @@ * An array of file objects of the specified type. */ function drupal_system_listing($mask, $directory, $key = 'name', $min_depth = 1) { - global $profile; - $config = conf_path(); - - // When this function is called during Drupal's initial installation process, - // the name of the profile that's about to be installed is stored in the global - // $profile variable. At all other times, the standard Drupal systems variable - // table contains the name of the current profile, and we can call variable_get() - // to determine what one is active. - if (!isset($profile)) { - $profile = variable_get('install_profile', 'default'); + global $profile; + $config = conf_path(); + // When this function is called during Drupal's initial installation process, + // the name of the profile that's about to be installed is stored in the global + // $profile variable. At all other times, the standard Drupal systems variable + // table contains the name of the current profile, and we can call variable_get() + // to determine what one is active. + if (!isset($profile)) { + $profile = variable_get('install_profile', 'default'); + } + $searchdir = array($directory); + $files = array(); + // Always search sites/all/* as well as the global directories + $searchdir[] = 'sites/all/'. $directory; + // The 'profiles' directory contains pristine collections of modules and + // themes as organized by a distribution. It is pristine in the same way + // that /modules is pristine for core; users should avoid changing anything + // there in favor of sites/all or sites/ directories. + if (file_exists("profiles/$profile/$directory")) { + $searchdir[] = "profiles/$profile/$directory"; + } + if (file_exists("$config/$directory")) { + $searchdir[] = "$config/$directory"; + } + // Get current list of items + foreach ($searchdir as $dir) { + $files = array_merge($files, file_scan_directory($dir, $mask, array('.', '..', 'CVS'), 0, TRUE, $key, $min_depth)); } - $searchdir = array($directory); - $files = array(); - - // Always search sites/all/* as well as the global directories - $searchdir[] = 'sites/all/'. $directory; - - // The 'profiles' directory contains pristine collections of modules and - // themes as organized by a distribution. It is pristine in the same way - // that /modules is pristine for core; users should avoid changing anything - // there in favor of sites/all or sites/ directories. - if (file_exists("profiles/$profile/$directory")) { - $searchdir[] = "profiles/$profile/$directory"; - } - - if (file_exists("$config/$directory")) { - $searchdir[] = "$config/$directory"; - } - - // Get current list of items - foreach ($searchdir as $dir) { - $files = array_merge($files, file_scan_directory($dir, $mask, array('.', '..', 'CVS'), 0, TRUE, $key, $min_depth)); - } - - return $files; + return $files; } - /** * This dispatch function hands off structured Drupal arrays to type-specific * *_alter implementations. It ensures a consistent interface for all altering @@ -2640,40 +2675,36 @@ * hook_$type_alter functions. */ function drupal_alter($type, &$data) { - // PHP's func_get_args() always returns copies of params, not references, so - // drupal_alter() can only manipulate data that comes in via the required first - // param. For the edge case functions that must pass in an arbitrary number of - // alterable parameters (hook_form_alter() being the best example), an array of - // those params can be placed in the __drupal_alter_by_ref key of the $data - // array. This is somewhat ugly, but is an unavoidable consequence of a flexible - // drupal_alter() function, and the limitations of func_get_args(). - // @todo: Remove this in Drupal 7. - if (is_array($data) && isset($data['__drupal_alter_by_ref'])) { - $by_ref_parameters = $data['__drupal_alter_by_ref']; - unset($data['__drupal_alter_by_ref']); - } - - // Hang onto a reference to the data array so that it isn't blown away later. - // Also, merge in any parameters that need to be passed by reference. - $args = array(&$data); - if (isset($by_ref_parameters)) { - $args = array_merge($args, $by_ref_parameters); - } - - // Now, use func_get_args() to pull in any additional parameters passed into - // the drupal_alter() call. - $additional_args = func_get_args(); - array_shift($additional_args); - array_shift($additional_args); - $args = array_merge($args, $additional_args); - - foreach (module_implements($type .'_alter') as $module) { - $function = $module .'_'. $type .'_alter'; - call_user_func_array($function, $args); + // PHP's func_get_args() always returns copies of params, not references, so + // drupal_alter() can only manipulate data that comes in via the required first + // param. For the edge case functions that must pass in an arbitrary number of + // alterable parameters (hook_form_alter() being the best example), an array of + // those params can be placed in the __drupal_alter_by_ref key of the $data + // array. This is somewhat ugly, but is an unavoidable consequence of a flexible + // drupal_alter() function, and the limitations of func_get_args(). + // @todo: Remove this in Drupal 7. + if (is_array($data) && isset($data['__drupal_alter_by_ref'])) { + $by_ref_parameters = $data['__drupal_alter_by_ref']; + unset($data['__drupal_alter_by_ref']); + } + // Hang onto a reference to the data array so that it isn't blown away later. + // Also, merge in any parameters that need to be passed by reference. + $args = array(&$data); + if (isset($by_ref_parameters)) { + $args = array_merge($args, $by_ref_parameters); + } + // Now, use func_get_args() to pull in any additional parameters passed into + // the drupal_alter() call. + $additional_args = func_get_args(); + array_shift($additional_args); + array_shift($additional_args); + $args = array_merge($args, $additional_args); + foreach (module_implements($type .'_alter') as $module) { + $function = $module .'_'. $type .'_alter'; + call_user_func_array($function, $args); } } - /** * Renders HTML given a structured array tree. * @@ -2683,97 +2714,90 @@ * * @param $elements * The structured array describing the data to be rendered. + * * @return * The rendered HTML. */ function drupal_render(&$elements) { - if (!isset($elements) || (isset($elements['#access']) && !$elements['#access'])) { - return NULL; + if (!isset($elements) || (isset($elements['#access']) && !$elements['#access'])) { + return NULL; } - - // If the default values for this element haven't been loaded yet, populate - // them. - if (!isset($elements['#defaults_loaded']) || !$elements['#defaults_loaded']) { - if ((!empty($elements['#type'])) && ($info = _element_info($elements['#type']))) { - $elements += $info; + // If the default values for this element haven't been loaded yet, populate + // them. + if (!isset($elements['#defaults_loaded']) || !$elements['#defaults_loaded']) { + if ((!empty($elements['#type'])) && ($info = _element_info($elements['#type']))) { + $elements += $info; } } - - // Make any final changes to the element before it is rendered. This means - // that the $element or the children can be altered or corrected before the - // element is rendered into the final text. - if (isset($elements['#pre_render'])) { - foreach ($elements['#pre_render'] as $function) { - if (function_exists($function)) { - $elements = $function($elements); + // Make any final changes to the element before it is rendered. This means + // that the $element or the children can be altered or corrected before the + // element is rendered into the final text. + if (isset($elements['#pre_render'])) { + foreach ($elements['#pre_render'] as $function) { + if (function_exists($function)) { + $elements = $function($elements); } } } - - $content = ''; - // Either the elements did not go through form_builder or one of the children - // has a #weight. - if (!isset($elements['#sorted'])) { - uasort($elements, "element_sort"); - } - $elements += array('#title' => NULL, '#description' => NULL); - if (!isset($elements['#children'])) { - $children = element_children($elements); - /* Render all the children that use a theme function */ - if (isset($elements['#theme']) && empty($elements['#theme_used'])) { - $elements['#theme_used'] = TRUE; - - $previous = array(); - foreach (array('#value', '#type', '#prefix', '#suffix') as $key) { - $previous[$key] = isset($elements[$key]) ? $elements[$key] : NULL; - } - // If we rendered a single element, then we will skip the renderer. - if (empty($children)) { - $elements['#printed'] = TRUE; + $content = ''; + // Either the elements did not go through form_builder or one of the children + // has a #weight. + if (!isset($elements['#sorted'])) { + uasort($elements, "element_sort"); + } + $elements += array('#title' => NULL, '#description' => NULL); + if (!isset($elements['#children'])) { + $children = element_children($elements); + /* Render all the children that use a theme function */ + if (isset($elements['#theme']) && empty($elements['#theme_used'])) { + $elements['#theme_used'] = TRUE; + $previous = array(); + foreach (array('#value', '#type', '#prefix', '#suffix') as $key) { + $previous[$key] = isset($elements[$key]) ? $elements[$key] : NULL; + } + // If we rendered a single element, then we will skip the renderer. + if (empty($children)) { + $elements['#printed'] = TRUE; } else { - $elements['#value'] = ''; + $elements['#value'] = ''; } - $elements['#type'] = 'markup'; - - unset($elements['#prefix'], $elements['#suffix']); - $content = theme($elements['#theme'], $elements); - - foreach (array('#value', '#type', '#prefix', '#suffix') as $key) { - $elements[$key] = isset($previous[$key]) ? $previous[$key] : NULL; - } - } - /* render each of the children using drupal_render and concatenate them */ - if (!isset($content) || $content === '') { - foreach ($children as $key) { - $content .= drupal_render($elements[$key]); + $elements['#type'] = 'markup'; + unset($elements['#prefix'], $elements['#suffix']); + $content = theme($elements['#theme'], $elements); + foreach (array('#value', '#type', '#prefix', '#suffix') as $key) { + $elements[$key] = isset($previous[$key]) ? $previous[$key] : NULL; + } + } + /* render each of the children using drupal_render and concatenate them */ + if (!isset($content) || $content === '') { + foreach ($children as $key) { + $content .= drupal_render($elements[$key]); } } } - if (isset($content) && $content !== '') { - $elements['#children'] = $content; - } - - // Until now, we rendered the children, here we render the element itself - if (!isset($elements['#printed'])) { - $content = theme(!empty($elements['#type']) ? $elements['#type'] : 'markup', $elements); - $elements['#printed'] = TRUE; - } - - if (isset($content) && $content !== '') { - // Filter the outputted content and make any last changes before the - // content is sent to the browser. The changes are made on $content - // which allows the output'ed text to be filtered. - if (isset($elements['#post_render'])) { - foreach ($elements['#post_render'] as $function) { - if (function_exists($function)) { - $content = $function($content, $elements); + if (isset($content) && $content !== '') { + $elements['#children'] = $content; + } + // Until now, we rendered the children, here we render the element itself + if (!isset($elements['#printed'])) { + $content = theme(!empty($elements['#type']) ? $elements['#type'] : 'markup', $elements); + $elements['#printed'] = TRUE; + } + if (isset($content) && $content !== '') { + // Filter the outputted content and make any last changes before the + // content is sent to the browser. The changes are made on $content + // which allows the output'ed text to be filtered. + if (isset($elements['#post_render'])) { + foreach ($elements['#post_render'] as $function) { + if (function_exists($function)) { + $content = $function($content, $elements); } } } - $prefix = isset($elements['#prefix']) ? $elements['#prefix'] : ''; - $suffix = isset($elements['#suffix']) ? $elements['#suffix'] : ''; - return $prefix . $content . $suffix; + $prefix = isset($elements['#prefix']) ? $elements['#prefix'] : ''; + $suffix = isset($elements['#suffix']) ? $elements['#suffix'] : ''; + return $prefix . $content . $suffix; } } @@ -2781,240 +2805,240 @@ * Function used by uasort to sort structured arrays by weight. */ function element_sort($a, $b) { - $a_weight = (is_array($a) && isset($a['#weight'])) ? $a['#weight'] : 0; - $b_weight = (is_array($b) && isset($b['#weight'])) ? $b['#weight'] : 0; - if ($a_weight == $b_weight) { - return 0; + $a_weight = (is_array($a) && isset($a['#weight'])) ? $a['#weight'] : 0; + $b_weight = (is_array($b) && isset($b['#weight'])) ? $b['#weight'] : 0; + if ($a_weight == $b_weight) { + return 0; } - return ($a_weight < $b_weight) ? -1 : 1; + return ($a_weight < $b_weight) ? - 1 : 1; } /** * Check if the key is a property. */ function element_property($key) { - return $key[0] == '#'; + return $key[0] == '#'; } /** * Get properties of a structured array element. Properties begin with '#'. */ function element_properties($element) { - return array_filter(array_keys((array) $element), 'element_property'); + return array_filter(array_keys((array) $element), 'element_property'); } /** * Check if the key is a child. */ function element_child($key) { - return !isset($key[0]) || $key[0] != '#'; + return !isset($key[0]) || $key[0] != '#'; } /** * Get keys of a structured array tree element that are not properties (i.e., do not begin with '#'). */ function element_children($element) { - return array_filter(array_keys((array) $element), 'element_child'); + return array_filter(array_keys((array) $element), 'element_child'); } /** * Provide theme registration for themes across .inc files. */ function drupal_common_theme() { - return array( - // theme.inc - 'placeholder' => array( - 'arguments' => array('text' => NULL) - ), - 'page' => array( - 'arguments' => array('content' => NULL, 'show_blocks' => TRUE, 'show_messages' => TRUE), - 'template' => 'page', - ), - 'maintenance_page' => array( - 'arguments' => array('content' => NULL, 'show_blocks' => TRUE, 'show_messages' => TRUE), - 'template' => 'maintenance-page', - ), - 'update_page' => array( - 'arguments' => array('content' => NULL, 'show_messages' => TRUE), - ), - 'install_page' => array( - 'arguments' => array('content' => NULL), - ), - 'task_list' => array( - 'arguments' => array('items' => NULL, 'active' => NULL), - ), - 'status_messages' => array( - 'arguments' => array('display' => NULL), - ), - 'links' => array( - 'arguments' => array('links' => NULL, 'attributes' => array('class' => 'links')), - ), - 'image' => array( - 'arguments' => array('path' => NULL, 'alt' => '', 'title' => '', 'attributes' => NULL, 'getsize' => TRUE), - ), - 'breadcrumb' => array( - 'arguments' => array('breadcrumb' => NULL), - ), - 'help' => array( - 'arguments' => array(), - ), - 'submenu' => array( - 'arguments' => array('links' => NULL), - ), - 'table' => array( - 'arguments' => array('header' => NULL, 'rows' => NULL, 'attributes' => array(), 'caption' => NULL), - ), - 'table_select_header_cell' => array( - 'arguments' => array(), - ), - 'tablesort_indicator' => array( - 'arguments' => array('style' => NULL), - ), - 'box' => array( - 'arguments' => array('title' => NULL, 'content' => NULL, 'region' => 'main'), - 'template' => 'box', - ), - 'block' => array( - 'arguments' => array('block' => NULL), - 'template' => 'block', - ), - 'mark' => array( - 'arguments' => array('type' => MARK_NEW), - ), - 'item_list' => array( - 'arguments' => array('items' => array(), 'title' => NULL, 'type' => 'ul', 'attributes' => NULL), - ), - 'more_help_link' => array( - 'arguments' => array('url' => NULL), - ), - 'xml_icon' => array( - 'arguments' => array('url' => NULL), - ), - 'feed_icon' => array( - 'arguments' => array('url' => NULL, 'title' => NULL), - ), - 'more_link' => array( - 'arguments' => array('url' => NULL, 'title' => NULL) - ), - 'closure' => array( - 'arguments' => array('main' => 0), - ), - 'blocks' => array( - 'arguments' => array('region' => NULL), - ), - 'username' => array( - 'arguments' => array('object' => NULL), - ), - 'progress_bar' => array( - 'arguments' => array('percent' => NULL, 'message' => NULL), - ), - 'indentation' => array( - 'arguments' => array('size' => 1), - ), - // from pager.inc - 'pager' => array( - 'arguments' => array('tags' => array(), 'limit' => 10, 'element' => 0, 'parameters' => array()), - ), - 'pager_first' => array( - 'arguments' => array('text' => NULL, 'limit' => NULL, 'element' => 0, 'parameters' => array()), - ), - 'pager_previous' => array( - 'arguments' => array('text' => NULL, 'limit' => NULL, 'element' => 0, 'interval' => 1, 'parameters' => array()), - ), - 'pager_next' => array( - 'arguments' => array('text' => NULL, 'limit' => NULL, 'element' => 0, 'interval' => 1, 'parameters' => array()), - ), - 'pager_last' => array( - 'arguments' => array('text' => NULL, 'limit' => NULL, 'element' => 0, 'parameters' => array()), - ), - 'pager_link' => array( - 'arguments' => array('text' => NULL, 'page_new' => NULL, 'element' => NULL, 'parameters' => array(), 'attributes' => array()), - ), - // from locale.inc - 'locale_admin_manage_screen' => array( - 'arguments' => array('form' => NULL), - ), - // from menu.inc - 'menu_item_link' => array( - 'arguments' => array('item' => NULL), - ), - 'menu_tree' => array( - 'arguments' => array('tree' => NULL), - ), - 'menu_item' => array( - 'arguments' => array('link' => NULL, 'has_children' => NULL, 'menu' => ''), - ), - 'menu_local_task' => array( - 'arguments' => array('link' => NULL, 'active' => FALSE), - ), - 'menu_local_tasks' => array( - 'arguments' => array(), - ), - // from form.inc - 'select' => array( - 'arguments' => array('element' => NULL), - ), - 'fieldset' => array( - 'arguments' => array('element' => NULL), - ), - 'radio' => array( - 'arguments' => array('element' => NULL), - ), - 'radios' => array( - 'arguments' => array('element' => NULL), - ), - 'password_confirm' => array( - 'arguments' => array('element' => NULL), - ), - 'date' => array( - 'arguments' => array('element' => NULL), - ), - 'item' => array( - 'arguments' => array('element' => NULL), - ), - 'checkbox' => array( - 'arguments' => array('element' => NULL), - ), - 'checkboxes' => array( - 'arguments' => array('element' => NULL), - ), - 'submit' => array( - 'arguments' => array('element' => NULL), - ), - 'button' => array( - 'arguments' => array('element' => NULL), - ), - 'image_button' => array( - 'arguments' => array('element' => NULL), - ), - 'hidden' => array( - 'arguments' => array('element' => NULL), - ), - 'token' => array( - 'arguments' => array('element' => NULL), - ), - 'textfield' => array( - 'arguments' => array('element' => NULL), - ), - 'form' => array( - 'arguments' => array('element' => NULL), - ), - 'textarea' => array( - 'arguments' => array('element' => NULL), - ), - 'markup' => array( - 'arguments' => array('element' => NULL), - ), - 'password' => array( - 'arguments' => array('element' => NULL), - ), - 'file' => array( - 'arguments' => array('element' => NULL), - ), - 'form_element' => array( - 'arguments' => array('element' => NULL, 'value' => NULL), - ), - ); + return array( + // theme.inc + 'placeholder' => array( + 'arguments' => array('text' => NULL) + ), + 'page' => array( + 'arguments' => array('content' => NULL, 'show_blocks' => TRUE, 'show_messages' => TRUE), + 'template' => 'page', + ), + 'maintenance_page' => array( + 'arguments' => array('content' => NULL, 'show_blocks' => TRUE, 'show_messages' => TRUE), + 'template' => 'maintenance-page', + ), + 'update_page' => array( + 'arguments' => array('content' => NULL, 'show_messages' => TRUE), + ), + 'install_page' => array( + 'arguments' => array('content' => NULL), + ), + 'task_list' => array( + 'arguments' => array('items' => NULL, 'active' => NULL), + ), + 'status_messages' => array( + 'arguments' => array('display' => NULL), + ), + 'links' => array( + 'arguments' => array('links' => NULL, 'attributes' => array('class' => 'links')), + ), + 'image' => array( + 'arguments' => array('path' => NULL, 'alt' => '', 'title' => '', 'attributes' => NULL, 'getsize' => TRUE), + ), + 'breadcrumb' => array( + 'arguments' => array('breadcrumb' => NULL), + ), + 'help' => array( + 'arguments' => array(), + ), + 'submenu' => array( + 'arguments' => array('links' => NULL), + ), + 'table' => array( + 'arguments' => array('header' => NULL, 'rows' => NULL, 'attributes' => array(), 'caption' => NULL), + ), + 'table_select_header_cell' => array( + 'arguments' => array(), + ), + 'tablesort_indicator' => array( + 'arguments' => array('style' => NULL), + ), + 'box' => array( + 'arguments' => array('title' => NULL, 'content' => NULL, 'region' => 'main'), + 'template' => 'box', + ), + 'block' => array( + 'arguments' => array('block' => NULL), + 'template' => 'block', + ), + 'mark' => array( + 'arguments' => array('type' => MARK_NEW), + ), + 'item_list' => array( + 'arguments' => array('items' => array(), 'title' => NULL, 'type' => 'ul', 'attributes' => NULL), + ), + 'more_help_link' => array( + 'arguments' => array('url' => NULL), + ), + 'xml_icon' => array( + 'arguments' => array('url' => NULL), + ), + 'feed_icon' => array( + 'arguments' => array('url' => NULL, 'title' => NULL), + ), + 'more_link' => array( + 'arguments' => array('url' => NULL, 'title' => NULL) + ), + 'closure' => array( + 'arguments' => array('main' => 0), + ), + 'blocks' => array( + 'arguments' => array('region' => NULL), + ), + 'username' => array( + 'arguments' => array('object' => NULL), + ), + 'progress_bar' => array( + 'arguments' => array('percent' => NULL, 'message' => NULL), + ), + 'indentation' => array( + 'arguments' => array('size' => 1), + ), + // from pager.inc + 'pager' => array( + 'arguments' => array('tags' => array(), 'limit' => 10, 'element' => 0, 'parameters' => array()), + ), + 'pager_first' => array( + 'arguments' => array('text' => NULL, 'limit' => NULL, 'element' => 0, 'parameters' => array()), + ), + 'pager_previous' => array( + 'arguments' => array('text' => NULL, 'limit' => NULL, 'element' => 0, 'interval' => 1, 'parameters' => array()), + ), + 'pager_next' => array( + 'arguments' => array('text' => NULL, 'limit' => NULL, 'element' => 0, 'interval' => 1, 'parameters' => array()), + ), + 'pager_last' => array( + 'arguments' => array('text' => NULL, 'limit' => NULL, 'element' => 0, 'parameters' => array()), + ), + 'pager_link' => array( + 'arguments' => array('text' => NULL, 'page_new' => NULL, 'element' => NULL, 'parameters' => array(), 'attributes' => array()), + ), + // from locale.inc + 'locale_admin_manage_screen' => array( + 'arguments' => array('form' => NULL), + ), + // from menu.inc + 'menu_item_link' => array( + 'arguments' => array('item' => NULL), + ), + 'menu_tree' => array( + 'arguments' => array('tree' => NULL), + ), + 'menu_item' => array( + 'arguments' => array('link' => NULL, 'has_children' => NULL, 'menu' => ''), + ), + 'menu_local_task' => array( + 'arguments' => array('link' => NULL, 'active' => FALSE), + ), + 'menu_local_tasks' => array( + 'arguments' => array(), + ), + // from form.inc + 'select' => array( + 'arguments' => array('element' => NULL), + ), + 'fieldset' => array( + 'arguments' => array('element' => NULL), + ), + 'radio' => array( + 'arguments' => array('element' => NULL), + ), + 'radios' => array( + 'arguments' => array('element' => NULL), + ), + 'password_confirm' => array( + 'arguments' => array('element' => NULL), + ), + 'date' => array( + 'arguments' => array('element' => NULL), + ), + 'item' => array( + 'arguments' => array('element' => NULL), + ), + 'checkbox' => array( + 'arguments' => array('element' => NULL), + ), + 'checkboxes' => array( + 'arguments' => array('element' => NULL), + ), + 'submit' => array( + 'arguments' => array('element' => NULL), + ), + 'button' => array( + 'arguments' => array('element' => NULL), + ), + 'image_button' => array( + 'arguments' => array('element' => NULL), + ), + 'hidden' => array( + 'arguments' => array('element' => NULL), + ), + 'token' => array( + 'arguments' => array('element' => NULL), + ), + 'textfield' => array( + 'arguments' => array('element' => NULL), + ), + 'form' => array( + 'arguments' => array('element' => NULL), + ), + 'textarea' => array( + 'arguments' => array('element' => NULL), + ), + 'markup' => array( + 'arguments' => array('element' => NULL), + ), + 'password' => array( + 'arguments' => array('element' => NULL), + ), + 'file' => array( + 'arguments' => array('element' => NULL), + ), + 'form_element' => array( + 'arguments' => array('element' => NULL, 'value' => NULL), + ), + ); } /** @@ -3034,39 +3058,35 @@ * If true, the schema will be rebuilt instead of retrieved from the cache. */ function drupal_get_schema($table = NULL, $rebuild = FALSE) { - static $schema = array(); - - if (empty($schema) || $rebuild) { - // Try to load the schema from cache. - if (!$rebuild && $cached = cache_get('schema')) { - $schema = $cached->data; + static $schema = array(); + if (empty($schema) || $rebuild) { + // Try to load the schema from cache. + if (!$rebuild && $cached = cache_get('schema')) { + $schema = $cached->data; } - // Otherwise, rebuild the schema cache. + // Otherwise, rebuild the schema cache. else { - $schema = array(); - // Load the .install files to get hook_schema. - module_load_all_includes('install'); - - // Invoke hook_schema for all modules. - foreach (module_implements('schema') as $module) { - $current = module_invoke($module, 'schema'); - _drupal_initialize_schema($module, $current); - $schema = array_merge($schema, $current); + $schema = array(); + // Load the .install files to get hook_schema. + module_load_all_includes('install'); + // Invoke hook_schema for all modules. + foreach (module_implements('schema') as $module) { + $current = module_invoke($module, 'schema'); + _drupal_initialize_schema($module, $current); + $schema = array_merge($schema, $current); } - - drupal_alter('schema', $schema); - cache_set('schema', $schema); + drupal_alter('schema', $schema); + cache_set('schema', $schema); } } - - if (!isset($table)) { - return $schema; + if (!isset($table)) { + return $schema; } elseif (isset($schema[$table])) { - return $schema[$table]; + return $schema[$table]; } else { - return FALSE; + return FALSE; } } @@ -3079,20 +3099,20 @@ * * @param $module * The module for which the tables will be created. + * * @return * An array of arrays with the following key/value pairs: * success: a boolean indicating whether the query succeeded * query: the SQL query(s) executed, passed through check_plain() */ function drupal_install_schema($module) { - $schema = drupal_get_schema_unprocessed($module); - _drupal_initialize_schema($module, $schema); - - $ret = array(); - foreach ($schema as $name => $table) { - db_create_table($ret, $name, $table); + $schema = drupal_get_schema_unprocessed($module); + _drupal_initialize_schema($module, $schema); + $ret = array(); + foreach ($schema as $name => $table) { + db_create_table($ret, $name, $table); } - return $ret; + return $ret; } /** @@ -3104,20 +3124,20 @@ * * @param $module * The module for which the tables will be removed. + * * @return * An array of arrays with the following key/value pairs: * success: a boolean indicating whether the query succeeded * query: the SQL query(s) executed, passed through check_plain() */ function drupal_uninstall_schema($module) { - $schema = drupal_get_schema_unprocessed($module); - _drupal_initialize_schema($module, $schema); - - $ret = array(); - foreach ($schema as $table) { - db_drop_table($ret, $table['name']); + $schema = drupal_get_schema_unprocessed($module); + _drupal_initialize_schema($module, $schema); + $ret = array(); + foreach ($schema as $table) { + db_drop_table($ret, $table['name']); } - return $ret; + return $ret; } /** @@ -3145,15 +3165,14 @@ * is returned. */ function drupal_get_schema_unprocessed($module, $table = NULL) { - // Load the .install file to get hook_schema. - module_load_include('install', $module); - $schema = module_invoke($module, 'schema'); - - if (!is_null($table) && isset($schema[$table])) { - return $schema[$table]; + // Load the .install file to get hook_schema. + module_load_include('install', $module); + $schema = module_invoke($module, 'schema'); + if (!is_null($table) && isset($schema[$table])) { + return $schema[$table]; } else { - return $schema; + return $schema; } } @@ -3167,13 +3186,13 @@ * hook_schema(). */ function _drupal_initialize_schema($module, &$schema) { - // Set the name and module key for all tables. - foreach ($schema as $name => $table) { - if (empty($table['module'])) { - $schema[$name]['module'] = $module; + // Set the name and module key for all tables. + foreach ($schema as $name => $table) { + if (empty($table['module'])) { + $schema[$name]['module'] = $module; } - if (!isset($table['name'])) { - $schema[$name]['name'] = $name; + if (!isset($table['name'])) { + $schema[$name]['name'] = $name; } } } @@ -3189,17 +3208,17 @@ * @return An array of fields. **/ function drupal_schema_fields_sql($table, $prefix = NULL) { - $schema = drupal_get_schema($table); - $fields = array_keys($schema['fields']); - if ($prefix) { - $columns = array(); - foreach ($fields as $field) { - $columns[] = "$prefix.$field"; + $schema = drupal_get_schema($table); + $fields = array_keys($schema['fields']); + if ($prefix) { + $columns = array(); + foreach ($fields as $field) { + $columns[] = "$prefix.$field"; } - return $columns; + return $columns; } else { - return $fields; + return $fields; } } @@ -3219,6 +3238,7 @@ * If this is an update, specify the primary keys' field names. It is the * caller's responsibility to know if a record for this object already * exists in the database. If there is only 1 key, you may pass a simple string. + * * @return * Failure to write a record will return FALSE. Otherwise SAVED_NEW or * SAVED_UPDATED is returned depending on the operation performed. The @@ -3227,103 +3247,88 @@ * a new node. */ function drupal_write_record($table, &$object, $update = array()) { - // Standardize $update to an array. - if (is_string($update)) { - $update = array($update); - } - - // Convert to an object if needed. - if (is_array($object)) { - $object = (object) $object; - $array = TRUE; + // Standardize $update to an array. + if (is_string($update)) { + $update = array($update); + } + // Convert to an object if needed. + if (is_array($object)) { + $object = (object) $object; + $array = TRUE; } else { - $array = FALSE; - } - - $schema = drupal_get_schema($table); - if (empty($schema)) { - return FALSE; + $array = FALSE; } - - $fields = $defs = $values = $serials = array(); - - // Go through our schema, build SQL, and when inserting, fill in defaults for - // fields that are not set. - foreach ($schema['fields'] as $field => $info) { - // Special case -- skip serial types if we are updating. - if ($info['type'] == 'serial' && count($update)) { - continue; - } - - // For inserts, populate defaults from Schema if not already provided - if (!isset($object->$field) && !count($update) && isset($info['default'])) { - $object->$field = $info['default']; - } - - // Track serial fields so we can helpfully populate them after the query. - if ($info['type'] == 'serial') { - $serials[] = $field; - // Ignore values for serials when inserting data. Unsupported. - unset($object->$field); - } - - // Build arrays for the fields, placeholders, and values in our query. - if (isset($object->$field)) { - $fields[] = $field; - $placeholders[] = db_type_placeholder($info['type']); - - if (empty($info['serialize'])) { - $values[] = $object->$field; + $schema = drupal_get_schema($table); + if (empty($schema)) { + return FALSE; + } + $fields = $defs = $values = $serials = array(); + // Go through our schema, build SQL, and when inserting, fill in defaults for + // fields that are not set. + foreach ($schema['fields'] as $field => $info) { + // Special case -- skip serial types if we are updating. + if ($info['type'] == 'serial' && count($update)) { + continue; + } + // For inserts, populate defaults from Schema if not already provided + if (!isset($object->$field) && !count($update) && isset($info['default'])) { + $object->$field = $info['default']; + } + // Track serial fields so we can helpfully populate them after the query. + if ($info['type'] == 'serial') { + $serials[] = $field; + // Ignore values for serials when inserting data. Unsupported. + unset($object->$field); + } + // Build arrays for the fields, placeholders, and values in our query. + if (isset($object->$field)) { + $fields[] = $field; + $placeholders[] = db_type_placeholder($info['type']); + if (empty($info['serialize'])) { + $values[] = $object->$field; } else { - $values[] = serialize($object->$field); + $values[] = serialize($object->$field); } } } - - // Build the SQL. - $query = ''; - if (!count($update)) { - $query = "INSERT INTO {". $table ."} (". implode(', ', $fields) .') VALUES ('. implode(', ', $placeholders) .')'; - $return = SAVED_NEW; + // Build the SQL. + $query = ''; + if (!count($update)) { + $query = "INSERT INTO {". $table ."} (". implode(', ', $fields) .') VALUES ('. implode(', ', $placeholders) .')'; + $return = SAVED_NEW; } else { - $query = ''; - foreach ($fields as $id => $field) { - if ($query) { - $query .= ', '; + $query = ''; + foreach ($fields as $id => $field) { + if ($query) { + $query .= ', '; } - $query .= $field .' = '. $placeholders[$id]; + $query .= $field .' = '. $placeholders[$id]; } - - foreach ($update as $key){ - $conditions[] = "$key = ". db_type_placeholder($schema['fields'][$key]['type']); - $values[] = $object->$key; + foreach ($update as $key) { + $conditions[] = "$key = ". db_type_placeholder($schema['fields'][$key]['type']); + $values[] = $object->$key; } - - $query = "UPDATE {". $table ."} SET $query WHERE ". implode(' AND ', $conditions); - $return = SAVED_UPDATED; + $query = "UPDATE {". $table ."} SET $query WHERE ". implode(' AND ', $conditions); + $return = SAVED_UPDATED; } - - // Execute the SQL. - if (db_query($query, $values)) { - if ($serials) { - // Get last insert ids and fill them in. - foreach ($serials as $field) { - $object->$field = db_last_insert_id($table, $field); + // Execute the SQL. + if (db_query($query, $values)) { + if ($serials) { + // Get last insert ids and fill them in. + foreach ($serials as $field) { + $object->$field = db_last_insert_id($table, $field); } } - - // If we began with an array, convert back so we don't surprise the caller. - if ($array) { - $object = (array) $object; + // If we began with an array, convert back so we don't surprise the caller. + if ($array) { + $object = (array) $object; } - - return $return; + return $return; } - - return FALSE; + return FALSE; } /** @@ -3386,18 +3391,17 @@ * * @param $filename * The file we are parsing. Accepts file with relative or absolute path. + * * @return * The info array. */ function drupal_parse_info_file($filename) { - $info = array(); - - if (!file_exists($filename)) { - return $info; + $info = array(); + if (!file_exists($filename)) { + return $info; } - - $data = file_get_contents($filename); - if (preg_match_all(' + $data = file_get_contents($filename); + if (preg_match_all(' @^\s* # Start at the beginning of a line, ignoring leading whitespace ((?: [^=;\[\]]| # Key names cannot contain equal signs, semi-colons or square brackets, @@ -3410,104 +3414,96 @@ ([^\r\n]*?) # Non-quoted string )\s*$ # Stop at the next end of a line, ignoring trailing whitespace @msx', $data, $matches, PREG_SET_ORDER)) { - foreach ($matches as $match) { - // Fetch the key and value string - $i = 0; - foreach (array('key', 'value1', 'value2', 'value3') as $var) { - $$var = isset($match[++$i]) ? $match[$i] : ''; - } - $value = stripslashes(substr($value1, 1, -1)) . stripslashes(substr($value2, 1, -1)) . $value3; - - // Parse array syntax - $keys = preg_split('/\]?\[/', rtrim($key, ']')); - $last = array_pop($keys); - $parent = &$info; - - // Create nested arrays - foreach ($keys as $key) { - if ($key == '') { - $key = count($parent); + foreach ($matches as $match) { + // Fetch the key and value string + $i = 0; + foreach (array('key', 'value1', 'value2', 'value3') as $var) { + $$var = isset($match[++$i]) ? $match[$i] : ''; + } + $value = stripslashes(substr($value1, 1, -1)) . stripslashes(substr($value2, 1, -1)) . $value3; + // Parse array syntax + $keys = preg_split('/\]?\[/', rtrim($key, ']')); + $last = array_pop($keys); + $parent = &$info; + // Create nested arrays + foreach ($keys as $key) { + if ($key == '') { + $key = count($parent); } - if (!isset($parent[$key]) || !is_array($parent[$key])) { - $parent[$key] = array(); + if (!isset($parent[$key]) || !is_array($parent[$key])) { + $parent[$key] = array(); } - $parent = &$parent[$key]; + $parent = &$parent[$key]; } - - // Handle PHP constants - if (defined($value)) { - $value = constant($value); + // Handle PHP constants + if (defined($value)) { + $value = constant($value); } - - // Insert actual value - if ($last == '') { - $last = count($parent); + // Insert actual value + if ($last == '') { + $last = count($parent); } - $parent[$last] = $value; + $parent[$last] = $value; } } - - return $info; + return $info; } /** + * * @return * Array of the possible severity levels for log messages. * * @see watchdog */ function watchdog_severity_levels() { - return array( - WATCHDOG_EMERG => t('emergency'), - WATCHDOG_ALERT => t('alert'), - WATCHDOG_CRITICAL => t('critical'), - WATCHDOG_ERROR => t('error'), - WATCHDOG_WARNING => t('warning'), - WATCHDOG_NOTICE => t('notice'), - WATCHDOG_INFO => t('info'), - WATCHDOG_DEBUG => t('debug'), - ); + return array( + WATCHDOG_EMERG => t('emergency'), + WATCHDOG_ALERT => t('alert'), + WATCHDOG_CRITICAL => t('critical'), + WATCHDOG_ERROR => t('error'), + WATCHDOG_WARNING => t('warning'), + WATCHDOG_NOTICE => t('notice'), + WATCHDOG_INFO => t('info'), + WATCHDOG_DEBUG => t('debug'), + ); } - /** * Explode a string of given tags into an array. */ function drupal_explode_tags($tags) { - // This regexp allows the following types of user input: - // this, "somecompany, llc", "and ""this"" w,o.rks", foo bar - $regexp = '%(?:^|,\ *)("(?>[^"]*)(?>""[^"]* )*"|(?: [^",]*))%x'; - preg_match_all($regexp, $tags, $matches); - $typed_tags = array_unique($matches[1]); - - $tags = array(); - foreach ($typed_tags as $tag) { - // If a user has escaped a term (to demonstrate that it is a group, - // or includes a comma or quote character), we remove the escape - // formatting so to save the term into the database as the user intends. - $tag = trim(str_replace('""', '"', preg_replace('/^"(.*)"$/', '\1', $tag))); - if ($tag != "") { - $tags[] = $tag; + // This regexp allows the following types of user input: + // this, "somecompany, llc", "and ""this"" w,o.rks", foo bar + $regexp = '%(?:^|,\ *)("(?>[^"]*)(?>""[^"]* )*"|(?: [^",]*))%x'; + preg_match_all($regexp, $tags, $matches); + $typed_tags = array_unique($matches[1]); + $tags = array(); + foreach ($typed_tags as $tag) { + // If a user has escaped a term (to demonstrate that it is a group, + // or includes a comma or quote character), we remove the escape + // formatting so to save the term into the database as the user intends. + $tag = trim(str_replace('""', '"', preg_replace('/^"(.*)"$/', '\1', $tag))); + if ($tag != "") { + $tags[] = $tag; } } - - return $tags; + return $tags; } /** * Implode an array of tags into a string. */ function drupal_implode_tags($tags) { - $encoded_tags = array(); - foreach ($tags as $tag) { - // Commas and quotes in tag names are special cases, so encode them. - if (strpos($tag, ',') !== FALSE || strpos($tag, '"') !== FALSE) { - $tag = '"'. str_replace('"', '""', $tag) .'"'; + $encoded_tags = array(); + foreach ($tags as $tag) { + // Commas and quotes in tag names are special cases, so encode them. + if (strpos($tag, ',') !== FALSE || strpos($tag, '"') !== FALSE) { + $tag = '"'. str_replace('"', '""', $tag) .'"'; } - - $encoded_tags[] = $tag; + $encoded_tags[] = $tag; } - return implode(', ', $encoded_tags); + return implode(', ', $encoded_tags); } /** @@ -3517,20 +3513,19 @@ * exposes a hook for other modules to clear their own cache data as well. */ function drupal_flush_all_caches() { - // Change query-strings on css/js files to enforce reload for all users. - _drupal_flush_css_js(); - - drupal_clear_css_cache(); - drupal_clear_js_cache(); - drupal_rebuild_theme_registry(); - menu_rebuild(); - node_types_rebuild(); - // Don't clear cache_form - in-progress form submissions may break. - // Ordered so clearing the page cache will always be the last action. - $core = array('cache', 'cache_block', 'cache_filter', 'cache_page'); - $cache_tables = array_merge(module_invoke_all('flush_caches'), $core); - foreach ($cache_tables as $table) { - cache_clear_all('*', $table, TRUE); + // Change query-strings on css/js files to enforce reload for all users. + _drupal_flush_css_js(); + drupal_clear_css_cache(); + drupal_clear_js_cache(); + drupal_rebuild_theme_registry(); + menu_rebuild(); + node_types_rebuild(); + // Don't clear cache_form - in-progress form submissions may break. + // Ordered so clearing the page cache will always be the last action. + $core = array('cache', 'cache_block', 'cache_filter', 'cache_page'); + $cache_tables = array_merge(module_invoke_all('flush_caches'), $core); + foreach ($cache_tables as $table) { + cache_clear_all('*', $table, TRUE); } } @@ -3544,11 +3539,12 @@ * This is also called from update.php. */ function _drupal_flush_css_js() { - $string_history = variable_get('css_js_query_string', '00000000000000000000'); - $new_character = $string_history[0]; - $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; - while (strpos($string_history, $new_character) !== FALSE) { - $new_character = $characters[mt_rand(0, strlen($characters) - 1)]; + $string_history = variable_get('css_js_query_string', '00000000000000000000'); + $new_character = $string_history[0]; + $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; + while (strpos($string_history, $new_character) !== FALSE) { + $new_character = $characters[mt_rand(0, strlen($characters) - 1)]; } - variable_set('css_js_query_string', $new_character . substr($string_history, 0, 19)); + variable_set('css_js_query_string', $new_character . substr($string_history, 0, 19)); } +