diff --git a/sites/all/modules/contrib/dev/prod_check/README.txt b/sites/all/modules/contrib/dev/prod_check/README.txt index dad3e8d4..c572136f 100644 --- a/sites/all/modules/contrib/dev/prod_check/README.txt +++ b/sites/all/modules/contrib/dev/prod_check/README.txt @@ -232,11 +232,14 @@ Cron is NOT used to do this, since we want to keep the transfer to a minimum. Hidden link =========== -Production check adds a 'hidden link' to the site where you can check the APC -status of your site. This page can be found on /admin/reports/status/apc. -This is in analogy with the system module that adds these 'hidden pages': +Production check adds some 'hidden links' to the site where you can check the +APC, Memcache and DB status of your site. These pages can be found on: + /admin/reports/status/apc + /admin/reports/status/memcache + /admin/reports/status/database + +This is in analogy with the system module that adds this 'hidden page': /admin/reports/status/php - /admin/reports/status/sql Truely unmissable when setting up your site on a production server to check if all is well! diff --git a/sites/all/modules/contrib/dev/prod_check/css/prod-check.css b/sites/all/modules/contrib/dev/prod_check/css/prod-check.css index 057c692f..b3dccbc3 100644 --- a/sites/all/modules/contrib/dev/prod_check/css/prod-check.css +++ b/sites/all/modules/contrib/dev/prod_check/css/prod-check.css @@ -1,5 +1,5 @@ -/* Prod monitor settings page styling */ +/* Prod check settings page styling */ .prod-check-settings{float:left;padding:0 5px;} .prod-check-settings.odd{background-color:#f8f8f8;} diff --git a/sites/all/modules/contrib/dev/prod_check/includes/prod_check.admin.inc b/sites/all/modules/contrib/dev/prod_check/includes/prod_check.admin.inc index 7586ca28..b82b0b41 100644 --- a/sites/all/modules/contrib/dev/prod_check/includes/prod_check.admin.inc +++ b/sites/all/modules/contrib/dev/prod_check/includes/prod_check.admin.inc @@ -395,9 +395,9 @@ function prod_check_settings_form_validate($form, &$form_state) { // seem logical... $base = drupal_get_path('module', 'prod_check'); drupal_add_css($base . '/css/prod-check.css'); - drupal_add_js($base . '/js/jquery.equalheights.js', 'module', 'header'); - drupal_add_js($base . '/js/jquery.maskedinput.min.js', 'module', 'header'); - drupal_add_js($base . '/js/prod-check.js', 'module', 'header'); + drupal_add_js($base . '/js/jquery.equalheights.js'); + drupal_add_js($base . '/js/jquery.maskedinput.min.js'); + drupal_add_js($base . '/js/prod-check.js'); if (module_exists('dblog')) { if (!is_numeric($form_state['values']['prod_check_dblog_php_threshold'])) { @@ -737,6 +737,297 @@ function prod_check_prod_mode_modules($options) { return $modules; } +/** + * Generate default key if none is present. + */ +function prod_check_generate_key($length = 25) { + $chars = 'abcdefghijklmnopqrstuxyvwzABCDEFGHIJKLMNOPQRSTUXYVWZ+-*#&@!?'; + $size = strlen($chars); + $key = ''; + for ($i = 0; $i < $length; $i++) { + $key .= $chars[rand(0, $size - 1)]; + } + + return $key; +} + +/** + * Database status page. + */ +function prod_check_dbstatus() { + // Get active connection. + $pdo = Database::getConnection(); + // Get database driver. + $db_type = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME); + + $details = array( + 'status' => array(), + 'tables' => array(), + 'databases' => array(), + ); + + $add_js = FALSE; + + $title = ''; + $db = $db_type; + switch($db_type) { + case 'pgsql': + // Set title & version. + $server = db_query('SELECT version()')->fetchField(); + $title = t('Running @version', array('@version' => $server)); + // Get detailed status. + $details = _prod_check_dbstatus_pgsql($details); + break; + case 'mysql': + $db = 'MySQL'; + // Get detailed status. + $details = _prod_check_dbstatus_mysql($details); + // NO break here! + default: + // Set title & version. + $server = $pdo->getAttribute(PDO::ATTR_SERVER_VERSION); + $title = t('Running @db @version', array('@db' => $db, '@version' => $server)); + break; + } + + // Get basic status. + $status = ''; + try { + $status = $pdo->getAttribute(PDO::ATTR_SERVER_INFO); + if (is_array($status)) { + $status = implode("
\n", $status); + } + else { + $status = str_replace(' ', "
\n", $status); + } + } catch(Exception $e) {} + + // Get additional status. + $additional = ''; + $attributes = array( + 'AUTOCOMMIT' => 'Auto commit', + 'PREFETCH' => 'Prefetch', + 'TIMEOUT' => 'Timeout', + 'ERRMODE' => 'Error mode', + 'CLIENT_VERSION' => 'Client version', + 'CONNECTION_STATUS' => 'Connection status', + 'CASE' => 'Case', + 'CURSOR_NAME' => 'Cursor name', + 'CURSOR' => 'Cursor', + 'ORACLE_NULLS' => 'Oracle nulls', + 'PERSISTENT' => 'Persistent', + 'STATEMENT_CLASS' => 'Statement class', + 'FETCH_CATALOG_NAMES' => 'Fatch catalog names', + 'FETCH_TABLE_NAMES' => 'Fetch table names', + 'STRINGIFY_FETCHES' => 'Stringify fetches', + 'MAX_COLUMN_LEN' => 'Max column length', + 'DEFAULT_FETCH_MODE' => 'Default fetch mode', + 'EMULATE_PREPARES' => 'Emulate prepares', + ); + foreach ($attributes as $constant => $name) { + try { + $result = $pdo->getAttribute(constant("PDO::ATTR_$constant")); + if (is_bool($result)) { + $result = $result ? 'TRUE' : 'FALSE'; + } + elseif (is_array($result) || is_object($result)) { + $add_js = TRUE; + include_once DRUPAL_ROOT . '/includes/utility.inc'; + + $class = strtolower(str_replace('_', '-', $constant)); + + $link = l( + t('Show details'), + 'admin/reports/status/database', + array( + 'attributes' => array( + 'class' => array('show-more'), + 'data-details' => $class + ) + ) + ); + + // Seemed a bit overkill to create a css file only for this display:none + // thingy. + $result = $link . ''; + } + $additional .= $name . ': ' . $result . "
\n"; + } catch (Exception $e) {} + } + $status = "$additional
\n$status"; + + if ($add_js) { + $base = drupal_get_path('module', 'prod_check'); + drupal_add_js($base . '/js/prod-check-database.js'); + } + + return theme('prod_check_dbstatus', array('title' => $title, 'status' => $status, 'details' => $details)); +} + +/** + * Helper function to return MySQL detailed status info. + */ +function _prod_check_dbstatus_mysql($details) { + $db_name = ''; + // Feels like there should be a better way of getting the current database + // name. + $db_setting = Database::getConnectionInfo(); + foreach($db_setting as $params) { + if(isset($params['database'])) { + // We get the first name we find. + $db_name = $params['database']; + break; + } + } + + // Get detailed status. + $rows = array(); + try { + $result = db_query('SHOW STATUS'); + foreach ($result as $row) { + $rows[] = array($row->Variable_name, $row->Value); + } + } catch (Exception $e) {} + if ($rows) { + $details['status'] = array( + 'title' => t('Detailed status'), + 'header' => array( + t('Variable'), + t('Value'), + ), + 'rows' => $rows, + ); + } + + // Get all tables. + $rows = array(); + try { + // We cannot use the standard db_query with arguments here as the argument + // should NOT be enclosed in quotes. + $result = db_query(sprintf('SHOW TABLES FROM %s', $db_name)); + $property = 'Tables_in_' . $db_name; + foreach ($result as $row) { + $rows[] = array($row->$property); + } + } catch (Exception $e) {} + if ($rows) { + $details['tables'] = array( + 'title' => t('Tables for active database %name', array('%name' => $db_name)), + 'header' => array( + t('Table'), + ), + 'rows' => $rows, + ); + } + + // Get all databases. + $rows = array(); + try { + $result = db_query('SHOW DATABASES'); + foreach ($result as $row) { + $rows[] = array($row->Database); + } + } catch (Exception $e) {} + if ($rows) { + $details['databases'] = array( + 'title' => t('Available databases'), + 'header' => array( + t('Database'), + ), + 'rows' => $rows, + ); + } + + return $details; +} + +/** + * Helper function to return PostgreSQL status info. + * + * Useful links for possible expansion: + * http://www.php.net/manual/en/book.pgsql.php + * http://www.alberton.info/postgresql_meta_info.html#.UbXmAFQW3eU + * http://www.postgresql.org/docs/devel/static/catalog-pg-statistic.html + * http://www.postgresql.org/docs/9.0/static/functions-info.html + * http://www.postgresql.org/docs/9.0/static/functions-admin.html + */ +function _prod_check_dbstatus_pgsql($db_name, $details) { + // Get detailed status. + $rows = array(); + try { + // See http://www.postgresql.org/docs/9.0/static/view-pg-settings.html + $result = db_query('SELECT * FROM pg_settings'); + foreach ($result as $row) { + /* TODO: add some more detail here? This is available: + + Column | Type | Modifiers | Storage | Description + ------------+------+-----------+----------+------------- + name | text | | extended | + setting | text | | extended | + unit | text | | extended | + category | text | | extended | + short_desc | text | | extended | + extra_desc | text | | extended | + context | text | | extended | + vartype | text | | extended | + source | text | | extended | + min_val | text | | extended | + max_val | text | | extended | */ + $rows[] = array($row->name, $row->setting); + } + } catch (Exception $e) {} + if ($rows) { + $details['status'] = array( + 'title' => t('Detailed status'), + 'header' => array( + t('Name'), + t('Setting'), + ), + 'rows' => $rows, + ); + } + + // Get all tables. + $rows = array(); + try { + // See http://www.postgresql.org/docs/9.0/static/catalog-pg-class.html + // relclass: r = ordinary table, i = index, S = sequence, v = view, c = composite type, t = TOAST table + $result = db_query("SELECT relname FROM pg_class WHERE relname !~ '^(pg_|sql_)' AND relkind = 'r'"); + foreach ($result as $row) { + $rows[] = array($row->relname); + } + } catch (Exception $e) {} + if ($rows) { + $details['tables'] = array( + 'title' => t('Tables for active database %name', array('%name' => $db_name)), + 'header' => array( + t('Table'), + ), + 'rows' => $rows, + ); + } + + // Get all databases. + $rows = array(); + try { + $result = db_query('SELECT datname FROM pg_database'); + foreach ($result as $row) { + $rows[] = array($row->datname); + } + } catch (Exception $e) {} + if ($rows) { + $details['databases'] = array( + 'title' => t('Available databases'), + 'header' => array( + t('Database'), + ), + 'rows' => $rows, + ); + } + + return $details; +} + /** * Integration of the APC status page. */ @@ -751,29 +1042,12 @@ function prod_check_apc() { * Integration of the Memcache status page. */ function prod_check_memcache() { - global $conf; + // Memcache module defaults to 127.0.0.1:11211 + $memcache_servers = variable_get('memcache_servers', array('127.0.0.1:11211' => 'default')); + + global $MEMCACHE_SERVERS; + $MEMCACHE_SERVERS = array_keys($memcache_servers); + include(drupal_get_path('module', 'prod_check') . '/includes/prod_check.memcache.inc'); - if (isset($conf['memcache_servers'])) { - global $MEMCACHE_SERVERS; - $MEMCACHE_SERVERS = array_keys($conf['memcache_servers']); - include(drupal_get_path('module', 'prod_check') . '/includes/prod_check.memcache.inc'); - } - else { - print 'No memcache servers found in settings.php.'; - } exit; } - -/** - * Generate default key if none is present. - */ -function prod_check_generate_key($length = 25) { - $chars = 'abcdefghijklmnopqrstuxyvwzABCDEFGHIJKLMNOPQRSTUXYVWZ+-*#&@!?'; - $size = strlen($chars); - $key = ''; - for ($i = 0; $i < $length; $i++) { - $key .= $chars[rand(0, $size - 1)]; - } - - return $key; -} diff --git a/sites/all/modules/contrib/dev/prod_check/includes/prod_check.apc.inc b/sites/all/modules/contrib/dev/prod_check/includes/prod_check.apc.inc index 5fa79de8..9f2d9aa7 100644 --- a/sites/all/modules/contrib/dev/prod_check/includes/prod_check.apc.inc +++ b/sites/all/modules/contrib/dev/prod_check/includes/prod_check.apc.inc @@ -1,10 +1,9 @@ '/^[AHSMCDTZ]$/', // first sort key 'SORT2' => '/^[DA]$/', // second sort key 'AGGR' => '/^\d+$/', // aggregation by dir level - 'SEARCH' => '~^[a-zA-Z0-1/_.-]*$~' // aggregation by dir level + 'SEARCH' => '~^[a-zA-Z0-9/_.-]*$~' // aggregation by dir level ); // default cache mode @@ -132,6 +137,7 @@ if (empty($MYREQUEST['SORT2'])) $MYREQUEST['SORT2']="D"; if (empty($MYREQUEST['OB'])) $MYREQUEST['OB']=OB_HOST_STATS; if (!isset($MYREQUEST['COUNT'])) $MYREQUEST['COUNT']=20; if (!isset($scope_list[$MYREQUEST['SCOPE']])) $MYREQUEST['SCOPE']='A'; + // added for prod_check support global $MY_SELF; // end prod_check @@ -172,13 +178,13 @@ if (!USE_AUTHENTICATION) { EOB; exit; - + } else { $AUTHENTICATED=1; } } } - + // select cache mode if ($AUTHENTICATED && $MYREQUEST['OB'] == OB_USER_CACHE) { $cache_mode='user'; @@ -197,7 +203,7 @@ if(!function_exists('apc_cache_info') || !($cache=@apc_cache_info($cache_mode))) exit; } -$cache_user = apc_cache_info('user', 1); +$cache_user = apc_cache_info('user', 1); $mem=apc_sma_info(); if(!$cache['num_hits']) { $cache['num_hits']=1; $time++; } // Avoid division by 0 errors on a cache clear @@ -244,7 +250,7 @@ if (isset($MYREQUEST['IMG'])) $r=$diameter/2; $w=deg2rad((360+$start+($end-$start)/2)%360); - + if (function_exists("imagefilledarc")) { // exists only if GD 2.0.1 is avaliable imagefilledarc($im, $centerX+1, $centerY+1, $diameter, $diameter, $start, $end, $color1, IMG_ARC_PIE); @@ -261,13 +267,13 @@ if (isset($MYREQUEST['IMG'])) if ($text) { if ($placeindex>0) { imageline($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$diameter, $placeindex*12,$color1); - imagestring($im,4,$diameter, $placeindex*12,$text,$color1); - + imagestring($im,4,$diameter, $placeindex*12,$text,$color1); + } else { imagestring($im,4,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$text,$color1); } } - } + } function text_arc($im, $centerX, $centerY, $diameter, $start, $end, $color1,$text,$placeindex=0) { $r=$diameter/2; @@ -275,13 +281,13 @@ if (isset($MYREQUEST['IMG'])) if ($placeindex>0) { imageline($im,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$diameter, $placeindex*12,$color1); - imagestring($im,4,$diameter, $placeindex*12,$text,$color1); - + imagestring($im,4,$diameter, $placeindex*12,$text,$color1); + } else { imagestring($im,4,$centerX + $r*cos($w)/2, $centerY + $r*sin($w)/2,$text,$color1); } - } - + } + function fill_box($im, $x, $y, $w, $h, $color1, $color2,$text='',$placeindex='') { global $col_black; $x1=$x+$w-1; @@ -293,15 +299,15 @@ if (isset($MYREQUEST['IMG'])) imagerectangle($im, $x, $y1, $x1, $y, $color1); if ($text) { if ($placeindex>0) { - + if ($placeindex<16) { $px=5; $py=$placeindex*12+6; imagefilledrectangle($im, $px+90, $py+3, $px+90-4, $py-3, $color2); imageline($im,$x,$y+$h/2,$px+90,$py,$color2); - imagestring($im,2,$px,$py-6,$text,$color1); - + imagestring($im,2,$px,$py-6,$text,$color1); + } else { if ($placeindex<31) { $px=$x+40*2; @@ -312,7 +318,7 @@ if (isset($MYREQUEST['IMG'])) } imagefilledrectangle($im, $px, $py+3, $px-4, $py-3, $color2); imageline($im,$x+$w,$y+$h/2,$px,$py,$color2); - imagestring($im,2,$px+2,$py-6,$text,$color1); + imagestring($im,2,$px+2,$py-6,$text,$color1); } } else { imagestring($im,4,$x+5,$y1-16,$text,$color1); @@ -334,7 +340,7 @@ if (isset($MYREQUEST['IMG'])) imagecolortransparent($image,$col_white); switch ($MYREQUEST['IMG']) { - + case 1: $s=$mem['num_seg']*$mem['seg_size']; $a=$mem['avail_mem']; @@ -345,9 +351,10 @@ if (isset($MYREQUEST['IMG'])) // would expect because we try to visualize any memory fragmentation as well. $angle_from = 0; $string_placement=array(); - for($i=0; $i<$mem['num_seg']; $i++) { + for($i=0; $i<$mem['num_seg']; $i++) { $ptr = 0; $free = $mem['block_lists'][$i]; + uasort($free, 'block_sort'); foreach($free as $block) { if($block['offset']!=$ptr) { // Used block $angle_to = $angle_from+($block['offset']-$ptr)/$s; @@ -371,7 +378,7 @@ if (isset($MYREQUEST['IMG'])) $angle_from = $angle_to; $ptr = $block['offset']+$block['size']; } - if ($ptr < $mem['seg_size']) { // memory at the end + if ($ptr < $mem['seg_size']) { // memory at the end $angle_to = $angle_from + ($mem['seg_size'] - $ptr)/$s; if(($angle_to+$fuzz)>1) $angle_to = 1; fill_arc($image,$x,$y,$size,$angle_from*360,$angle_to*360,$col_black,$col_red); @@ -384,15 +391,15 @@ if (isset($MYREQUEST['IMG'])) text_arc($image,$x,$y,$size,$angle[0]*360,$angle[1]*360,$col_black,bsize($s*($angle[1]-$angle[0]))); } break; - - case 2: + + case 2: $s=$cache['num_hits']+$cache['num_misses']; $a=$cache['num_hits']; - + fill_box($image, 30,$size,50,-$a*($size-21)/$s,$col_black,$col_green,sprintf("%.1f%%",$cache['num_hits']*100/$s)); fill_box($image,130,$size,50,-max(4,($s-$a)*($size-21)/$s),$col_black,$col_red,sprintf("%.1f%%",$cache['num_misses']*100/$s)); break; - + case 3: $s=$mem['num_seg']*$mem['seg_size']; $a=$mem['avail_mem']; @@ -402,9 +409,10 @@ if (isset($MYREQUEST['IMG'])) // This block of code creates the bar chart. It is a lot more complex than you // would expect because we try to visualize any memory fragmentation as well. - for($i=0; $i<$mem['num_seg']; $i++) { + for($i=0; $i<$mem['num_seg']; $i++) { $ptr = 0; $free = $mem['block_lists'][$i]; + uasort($free, 'block_sort'); foreach($free as $block) { if($block['offset']!=$ptr) { // Used block $h=(GRAPH_SIZE-5)*($block['offset']-$ptr)/$s; @@ -424,7 +432,7 @@ if (isset($MYREQUEST['IMG'])) $y+=$h; $ptr = $block['offset']+$block['size']; } - if ($ptr < $mem['seg_size']) { // memory at the end + if ($ptr < $mem['seg_size']) { // memory at the end $h = (GRAPH_SIZE-5) * ($mem['seg_size'] - $ptr) / $s; if ($h > 0) { fill_box($image,$x,$y,50,$h,$col_black,$col_red,bsize($mem['seg_size']-$ptr),$j++); @@ -432,14 +440,14 @@ if (isset($MYREQUEST['IMG'])) } } break; - case 4: + case 4: $s=$cache['num_hits']+$cache['num_misses']; $a=$cache['num_hits']; - + fill_box($image, 30,$size,50,-$a*($size-21)/$s,$col_black,$col_green,sprintf("%.1f%%",$cache['num_hits']*100/$s)); fill_box($image,130,$size,50,-max(4,($s-$a)*($size-21)/$s),$col_black,$col_red,sprintf("%.1f%%",$cache['num_misses']*100/$s)); break; - + } header("Content-type: image/png"); imagepng($image); @@ -459,7 +467,7 @@ function bsize($s) { // sortable table header in "scripts for this host" view function sortheader($key,$name,$extra='') { global $MYREQUEST, $MY_SELF_WO_SORT; - + if ($MYREQUEST['SORT1']==$key) { $MYREQUEST['SORT2'] = $MYREQUEST['SORT2']=='A' ? 'D' : 'A'; } @@ -467,7 +475,7 @@ function sortheader($key,$name,$extra='') { } -// create menu entry +// create menu entry function menu_entry($ob,$title) { global $MYREQUEST,$MY_SELF; if ($MYREQUEST['OB']!=$ob) { @@ -475,7 +483,7 @@ function menu_entry($ob,$title) { } else if (empty($MYREQUEST['SH'])) { return "
  • $title
  • "; } else { - return "
  • $title
  • "; + return "
  • $title
  • "; } } @@ -488,8 +496,11 @@ function put_login_link($s="Login") return; } else if (ADMIN_PASSWORD=='password') { + // Message below changed to avoid prod_check integration confusion. It used + // to be: + // You need to set a password at the top of apc.php before this will work! print <<$s + $s EOB; } else if ($AUTHENTICATED) { print << $array2['offset']) { + return 1; + } else { + return -1; + } +} + ?> @@ -618,8 +638,8 @@ ol.menu a:hover { background:rgb(193,193,244); text-decoration:none; } - - + + div.info { background:rgb(204,204,204); border:solid rgb(204,204,204) 1px; @@ -692,7 +712,7 @@ div.authneeded { padding:2em; text-align:center; } - + input { background:rgb(153,153,204); border:solid rgb(102,102,153) 2px; @@ -732,10 +752,10 @@ if ($AUTHENTICATED) { echo menu_entry(3,'User Cache Entries'), menu_entry(9,'Version Check'); - + if ($AUTHENTICATED) { echo <<Clear $cache_mode Cache +
  • Clear $cache_mode Cache
  • EOB; } echo << EOB; -// MAIN SWITCH STATEMENT +// MAIN SWITCH STATEMENT switch ($MYREQUEST['OB']) { @@ -774,7 +794,7 @@ case OB_HOST_STATS: $insert_rate_user = sprintf("%.2f",($cache_user['num_inserts'])/($time-$cache_user['start_time'])); $apcversion = phpversion('apc'); $phpversion = phpversion(); - $number_files = $cache['num_entries']; + $number_files = $cache['num_entries']; $size_files = bsize($cache['mem_size']); $number_vars = $cache_user['num_entries']; $size_vars = bsize($cache_user['mem_size']); @@ -792,7 +812,7 @@ EOB; echo "Server Software{$_SERVER['SERVER_SOFTWARE']}\n"; echo <<Shared Memory{$mem['num_seg']} Segment(s) with $seg_size + Shared Memory{$mem['num_seg']} Segment(s) with $seg_size
    ({$cache['memory_type']} memory, {$cache['locking_type']} locking) EOB; @@ -860,7 +880,7 @@ EOB; EOB; echo - graphics_avail() ? + graphics_avail() ? ''. "\"\"". "\"\"\n" @@ -898,7 +918,7 @@ EOB; } $freeseg += count($mem['block_lists'][$i]); } - + if ($freeseg > 1) { $frag = sprintf("%.2f%% (%s out of %s in %d fragments)", ($fragsize/$freetotal)*100,bsize($fragsize),bsize($freetotal),$freeseg); } else { @@ -928,7 +948,7 @@ EOB; EOB; - + break; @@ -947,15 +967,15 @@ case OB_USER_CACHE: $fieldkey='info'; // ----------------------------------------------- -// System Cache Entries +// System Cache Entries // ----------------------------------------------- -case OB_SYS_CACHE: +case OB_SYS_CACHE: if (!isset($fieldname)) { $fieldname='filename'; $fieldheading='Script Filename'; if(ini_get("apc.stat")) $fieldkey='inode'; - else $fieldkey='filename'; + else $fieldkey='filename'; } if (!empty($MYREQUEST['SH'])) { @@ -983,14 +1003,14 @@ EOB; echo "", "",ucwords(preg_replace("/_/"," ",$k)),"", - "",(preg_match("/time/",$k) && $value!='None') ? date(DATE_FORMAT,$value) : $value,"", + "",(preg_match("/time/",$k) && $value!='None') ? date(DATE_FORMAT,$value) : htmlspecialchars($value, ENT_QUOTES, 'UTF-8'),"", ""; $m=1-$m; } if($fieldkey=='info') { echo "Stored Value
    ";
     					$output = var_export(apc_fetch($entry[$fieldkey]),true);
    -					echo htmlspecialchars($output);
    +					echo htmlspecialchars($output, ENT_QUOTES, 'UTF-8');
     					echo "
    \n"; } break; @@ -1010,7 +1030,7 @@ EOB; ", @@ -1024,7 +1044,7 @@ EOB; ""; if($fieldname=='info') echo ""; - echo + echo '', ' ", @@ -1241,14 +1262,14 @@ EOB; } if ($list) { - + // sort list // switch ($MYREQUEST['SORT2']) { case "A": krsort($list); break; case "D": ksort($list); break; } - + // output list $i = 0; foreach($list as $entry) { @@ -1264,7 +1285,7 @@ EOB; if (++$i == $MYREQUEST['COUNT']) break; } - + } else { echo 'No data'; } @@ -1292,8 +1313,12 @@ case OB_VERSION_CHECK: EOB; - - $rss = @file_get_contents("http://pecl.php.net/feeds/pkg_apc.rss"); + if (defined('PROXY')) { + $ctxt = stream_context_create( array( 'http' => array( 'proxy' => PROXY, 'request_fulluri' => True ) ) ); + $rss = @file_get_contents("http://pecl.php.net/feeds/pkg_apc.rss", False, $ctxt); + } else { + $rss = @file_get_contents("http://pecl.php.net/feeds/pkg_apc.rss"); + } if (!$rss) { echo 'Unable to fetch version information.'; } else { @@ -1305,7 +1330,7 @@ EOB; echo '
    You are running the latest version of APC ('.$apcversion.')
    '; $i = 3; } else { - echo '
    You are running an older version of APC ('.$apcversion.'), + echo '
    You are running an older version of APC ('.$apcversion.'), newer version '.$match[1].' is available at http://pecl.php.net/package/APC/'.$match[1].'
    '; @@ -1324,8 +1349,8 @@ EOB; } else if (!$i--) { break; } - echo "".htmlspecialchars($v)."
    "; - echo nl2br(htmlspecialchars(current($match[2])))."
    "; + echo "".htmlspecialchars($v, ENT_QUOTES, 'UTF-8')."
    "; + echo nl2br(htmlspecialchars(current($match[2]), ENT_QUOTES, 'UTF-8'))."
    "; next($match[2]); } echo ''; diff --git a/sites/all/modules/contrib/dev/prod_check/includes/prod_check.theme.inc b/sites/all/modules/contrib/dev/prod_check/includes/prod_check.theme.inc index 494f7e66..94fd8e2d 100644 --- a/sites/all/modules/contrib/dev/prod_check/includes/prod_check.theme.inc +++ b/sites/all/modules/contrib/dev/prod_check/includes/prod_check.theme.inc @@ -51,3 +51,38 @@ function theme_prod_check_status_report($variables) { $output .= ''; return $output; } + +/** + * Theme database status page. + * + * @param $variables + * An associative array containing: + * - title: title string to display. + * - status: string with status summary. + * - details: associative array of associative arrays containing detailed + * status info. + * + * @ingroup themeable + */ +function theme_prod_check_dbstatus($variables) { + $title = $variables['title']; + $status = $variables['status']; + $details = $variables['details']; + + $output = ''; + + // DB system and version. + $output .= '

    ' . $title . '

    '; + // Basic status info. + $output .= '
    ' . $status . '

     

    '; + + // Add detailed statuses. + foreach ($details as $type) { + if ($type) { + $caption = '

    ' . $type['title'] . '

    '; + $output .= theme('table', array('header' => $type['header'], 'rows' => $type['rows'], 'caption' => $caption)); + } + } + + return $output; +} diff --git a/sites/all/modules/contrib/dev/prod_check/prod_check.info b/sites/all/modules/contrib/dev/prod_check/prod_check.info index ef37a8c3..b913dcb4 100644 --- a/sites/all/modules/contrib/dev/prod_check/prod_check.info +++ b/sites/all/modules/contrib/dev/prod_check/prod_check.info @@ -4,9 +4,9 @@ package = Monitoring core = 7.x configure = admin/config/system/prod-check -; Information added by drupal.org packaging script on 2013-10-01 -version = "7.x-1.7+0-dev" +; Information added by packaging script on 2013-11-25 +version = "7.x-1.8" core = "7.x" project = "prod_check" -datestamp = "1380623918" +datestamp = "1385405033" diff --git a/sites/all/modules/contrib/dev/prod_check/prod_check.module b/sites/all/modules/contrib/dev/prod_check/prod_check.module index 0f94078b..40afdfdd 100644 --- a/sites/all/modules/contrib/dev/prod_check/prod_check.module +++ b/sites/all/modules/contrib/dev/prod_check/prod_check.module @@ -67,7 +67,6 @@ function prod_check_help($path, $arg) { * Implementation of hook_permission() */ function prod_check_permission() { - return array( 'administer production check' => array( 'title' => t('Administer Production Check'), @@ -90,6 +89,12 @@ function prod_check_permission() { function prod_check_menu() { $items = array(); + $admin_defaults = array( + 'access arguments' => array('access production check'), + 'type' => MENU_CALLBACK, + 'file' => 'includes/prod_check.admin.inc', + ); + $items['admin/reports/prod-check'] = array( 'title' => 'Production check', 'description' => 'View the Production check report page.', @@ -130,23 +135,22 @@ function prod_check_menu() { 'file' => 'includes/prod_check.admin.inc', ); + $items['admin/reports/status/database'] = array( + 'title' => 'Database', + 'page callback' => 'prod_check_dbstatus', + ) + $admin_defaults; + $items['admin/reports/status/apc'] = array( 'title' => 'APC', 'page callback' => 'prod_check_apc', 'access callback' => 'user_access', - 'access arguments' => array('access production check'), - 'type' => MENU_CALLBACK, - 'file' => 'includes/prod_check.admin.inc', - ); + ) + $admin_defaults; $items['admin/reports/status/memcache'] = array( 'title' => 'Memcache', 'page callback' => 'prod_check_memcache', 'access callback' => 'user_access', - 'access arguments' => array('access production check'), - 'type' => MENU_CALLBACK, - 'file' => 'includes/prod_check.admin.inc', - ); + ) + $admin_defaults; return $items; } @@ -173,6 +177,10 @@ function prod_check_theme($existing, $type, $theme, $path) { 'variables' => array('requirements' => NULL), 'file' => 'includes/prod_check.theme.inc', ), + 'prod_check_dbstatus' => array( + 'variables' => array('title' => NULL, 'status' => NULL, 'details' => NULL), + 'file' => 'includes/prod_check.theme.inc', + ), ); } @@ -565,6 +573,7 @@ function _prod_check_functions() { '_prod_check_error_reporting' => 'Error reporting', '_prod_check_user_register' => 'User registration', '_prod_check_site_mail' => 'Site e-mail', + '_prod_check_poormanscron' => 'Cron', ), ); @@ -753,6 +762,52 @@ function _prod_check_site_mail($caller = 'internal') { return prod_check_execute_check($check, $caller); } +// Cron check +function _prod_check_poormanscron($caller = 'internal') { + $check = array(); + + $title = 'Cron'; + $path = 'admin/config/system/cron'; + if ($caller != 'internal') { + $path = PRODCHECK_BASEURL . $path; + } + + $cron_interval = variable_get('cron_safe_threshold', DRUPAL_CRON_DEFAULT_THRESHOLD); + + // TODO: add some form of cron interval checking here so we can check if the + // cron is running regularly AND the poormanscron is disabled? + // We could use the data from dblog, but this might not always be enabled so + // it will be similar to _prod_check_dblog_php... + + /*$cron_interval_regularity = FALSE; + if (module_exists('dblog')) { + $result = db_query("SELECT timestamp FROM {watchdog} where type = 'cron' ORDER BY timestamp DESC LIMIT 10"); + $prev = -1; + $diff = array(); + foreach ($result as $row) { + if($prev == -1) { + $prev = $row->timestamp; + continue; + } + $diff[] = $prev - $row->timestamp; + } + }*/ + + $check['prod_check_poormanscron'] = array( + '#title' => t($title), + '#state' => $cron_interval == 0 /*&& $cron_interval_regularity*/, + '#severity' => ($caller == 'nagios') ? NAGIOS_STATUS_WARNING : PROD_CHECK_REQUIREMENT_WARNING, + '#value_ok' => t("Drupal's built in cron mechanism is disabled."), + '#value_nok' => t("Drupal's built in cron mechanism is set to run every %interval.", array('%interval' => format_interval($cron_interval))), + '#description_ok' => prod_check_ok_title($title, $path), + '#description_nok' => t('The !link interval should be disabled if you have also setup a crontab or scheduled task for this to avoid running the cron more often than you have planned to!', prod_check_link_array($title, $path)), + '#nagios_key' => 'CRON', + '#nagios_type' => 'state', + ); + + return prod_check_execute_check($check, $caller); +} + // --- SERVER --- // APC check @@ -999,16 +1054,19 @@ function _prod_check_boost($caller = 'internal') { if (module_exists('boost')) { $check = array(); - $path = 'admin/config/development/performance/boost'; + $path = 'admin/config/system/boost'; if ($caller != 'internal') { $path = PRODCHECK_BASEURL . $path; } + $path_htaccess = $path . '/htaccess'; + $path_crawler = $path . '/crawler'; + $path_expire = $path . '/expiration'; $title = 'Boost: '; // Cache lifetime check - $subtitle = 'HTML max. cache lifetime '; - $var = variable_get('boost_cache_lifetime', 3600); + $subtitle = 'text/html - Maximum Cache Lifetime'; + $var = variable_get('boost_lifetime_max_text/html', 3600); $check['prod_check_boost_cache_lifetime'] = array( '#title' => t($title.$subtitle), '#state' => $var <= 3600, @@ -1022,53 +1080,78 @@ function _prod_check_boost($caller = 'internal') { ); // Clear pages check - $subtitle = 'Clear expired pages on cron runs'; - $var = variable_get('boost_expire_cron', TRUE); + $subtitle = 'Remove old cache files on cron'; + $var = variable_get('boost_expire_cron', BOOST_EXPIRE_CRON); $check['prod_check_boost_expire_cron'] = array( '#title' => t($title.$subtitle), '#state' => $var, '#severity' => ($caller == 'nagios') ? NAGIOS_STATUS_WARNING : PROD_CHECK_REQUIREMENT_WARNING, '#value_ok' => t('Enabled'), '#value_nok' => t('Disabled'), - '#description_ok' => prod_check_ok_title($subtitle, $path), - '#description_nok' => t('!link is disabled! You should enable this to ensure that expired pages get flushed when the cron runs. This is imperative if you wish to keep view blocks up to date!', prod_check_link_array($subtitle, $path)), + '#description_ok' => prod_check_ok_title($subtitle, $path_expire), + '#description_nok' => t('!link is disabled! You should enable this to ensure that expired pages get flushed when the cron runs. This is imperative if you wish to keep view blocks up to date!', prod_check_link_array($subtitle, $path_expire)), '#nagios_key' => 'BCLPG', '#nagios_type' => 'state', ); - /* // Crawl on cron check + $subtitle = 'Crawl on cron'; + $var = module_exists('boost_crawler') && variable_get('boost_crawl_on_cron', FALSE); + $check['prod_check_boost_crawl_on_cron'] = array( + '#title' => t($title.$subtitle), + '#state' => $var, + '#severity' => ($caller == 'nagios') ? NAGIOS_STATUS_WARNING : PROD_CHECK_REQUIREMENT_WARNING, + '#value_ok' => t('Enabled'), + '#value_nok' => t('Disabled'), + '#description_ok' => prod_check_ok_title($subtitle, $path_crawler), + '#description_nok' => t('!link is disabled! You should enable this to ensure that the users are served cached pages all the time. The crawler caches pages before anyone can access them.', prod_check_link_array($subtitle, $path_crawler)), + '#nagios_key' => 'BCRCR', + '#nagios_type' => 'state', + ); - // The Boost module is in development atm, as soon as it is released we'll fix this. + // Boost nagios page check + if (module_exists('nagios')) { + $subtitle = 'Nagios page'; - $subtitle = 'Crawl on cron'; - $var = variable_get('boost_crawl_on_cron', FALSE); - $check['prod_check_boost_crawl_on_cron'] = array( - '#title' => t($title.$subtitle), - '#state' => $var, - '#severity' => ($caller == 'nagios') ? NAGIOS_STATUS_WARNING : PROD_CHECK_REQUIREMENT_WARNING, - '#value_ok' => t('Enabled'), - '#value_nok' => t('Disabled'), - '#description_ok' => prod_check_ok_title($subtitle, $path), - '#description_nok' => t('!link is disabled! You should enable this to ensure that the users are served cached pages all the time. The crawler caches pages before anyone can access them.', prod_check_link_array($subtitle, $path)), - '#nagios_key' => 'BCRCR', - '#nagios_type' => 'state', - ); - */ + $visibility = variable_get('boost_cacheability_option', BOOST_VISIBILITY_NOTLISTED); + $pages_setting = variable_get('boost_cacheability_pages', BOOST_CACHEABILITY_PAGES); + + $pages_array = explode("\n", str_replace(array("\n", "\r\n"), "\n", strtolower($pages_setting))); + + $var = ($visibility && in_array('nagios', $pages_array)) || (!$visibility && !in_array('nagios', $pages_array)); + if($visibility) { + $advise = "You should remove 'nagios' from the listed pages."; + } + else { + $advise = "You should add 'nagios' to the listed pages."; + } + + $check['prod_check_boost_apache_nagios_page'] = array( + '#title' => t($title.$subtitle), + '#state' => !$var, + '#severity' => ($caller == 'nagios') ? NAGIOS_STATUS_WARNING : PROD_CHECK_REQUIREMENT_WARNING, + '#value_ok' => t('Enabled'), + '#value_nok' => t('Not properly configured.'), + '#description_ok' => prod_check_ok_title($subtitle, $path), + '#description_nok' => t('The !link is being cached by Boost. '.$advise, prod_check_link_array($subtitle, $path)), + '#nagios_key' => 'BNAPA', + '#nagios_type' => 'state', + ); + } // Apache etag check $subtitle = 'ETag'; - $var = variable_get('boost_apache_etag', 0); + $var = variable_get('boost_apache_etag', BOOST_APACHE_ETAG); $check['prod_check_boost_apache_etag'] = array( '#title' => t($title.$subtitle), '#state' => $var >= 2, '#severity' => ($caller == 'nagios') ? NAGIOS_STATUS_WARNING : PROD_CHECK_REQUIREMENT_WARNING, '#value_ok' => t('Enabled'), '#value_nok' => t('Not properly configured.'), - '#description_ok' => prod_check_ok_title($subtitle, $path), + '#description_ok' => prod_check_ok_title($subtitle, $path_htaccess), '#description_nok' => t('Your !link settings are not ok! You should enable entity tags (!etag) in Boost so that user side caching and bandwith usage will be optimal! You do need to enable !mod for this to work.', array( - '!link' => ''.l(t($subtitle), $path, array('attributes' => array('title' => t($subtitle)), 'query' => drupal_get_destination())).'', + '!link' => ''.l(t($subtitle), $path_htaccess, array('attributes' => array('title' => t($subtitle)), 'query' => drupal_get_destination())).'', '!etag' => ''.l(t('ETags'), 'http://en.wikipedia.org/wiki/HTTP_ETag', array('attributes' => array('title' => t('Etags')))).'', '!mod' => ''.l(t('mod_headers'), 'http://httpd.apache.org/docs/2.0/mod/mod_headers.html', array('attributes' => array('title' => t('mod_headers')))).'', ) @@ -1076,6 +1159,7 @@ function _prod_check_boost($caller = 'internal') { '#nagios_key' => 'BETAG', '#nagios_type' => 'state', ); + $result = prod_check_execute_check($check, $caller); } return $result; @@ -1769,6 +1853,10 @@ function _prod_check_redirect($caller = 'internal') { // XML sitemap function _prod_check_xmlsitemap($caller = 'internal') { $check = array(); + $error = FALSE; + $xml_base_url = variable_get('xmlsitemap_base_url', $GLOBALS['base_url']); + $value_nok = $msg_nok = ''; + $title_ok = 'settings'; $text_ok = 'Check the !link to verify if they are as you expect.'; @@ -1778,14 +1866,25 @@ function _prod_check_xmlsitemap($caller = 'internal') { $path = PRODCHECK_BASEURL . $path; } - $check['prod_check_sitemap'] = array( + if(!module_exists('xmlsitemap')) { + $error = TRUE; + $value_nok = t('Disabled'); + $msg_nok = t('You have not enabled the !link module. This module generates an XML sitemap which can be submitted to search engines, guaranteeing optimal indexation of all urls within the site.', prod_check_link_array($title, 'http://drupal.org/project/xmlsitemap')); + } + elseif (strtolower($xml_base_url) != strtolower($GLOBALS['base_url'])) { + $error = TRUE; + $value_nok = t('Not properly configured.'); + $msg_nok = t('Your sitemap.xml !link is not the same as the current base URL you are viewing the site from.', prod_check_link_array('default base URL', $path)); + } + + $check['prod_check_xmlsitemap'] = array( '#title' => t($title), - '#state' => module_exists('xmlsitemap'), + '#state' => !$error, '#severity' => ($caller == 'nagios') ? NAGIOS_STATUS_WARNING : PROD_CHECK_REQUIREMENT_WARNING, '#value_ok' => t('Enabled'), - '#value_nok' => t('Disabled'), + '#value_nok' => $value_nok, '#description_ok' => prod_check_ok_title($title_ok, $path, $text_ok), - '#description_nok' => t('You have not enabled the !link module. This module generates an XML sitemap which can be submitted to search engines, guaranteeing optimal indexation of all urls within the site.', prod_check_link_array($title, 'http://drupal.org/project/xmlsitemap')), + '#description_nok' => $msg_nok, '#nagios_key' => 'XMLS', '#nagios_type' => 'state', ); diff --git a/sites/all/modules/contrib/dev/prod_check/prod_monitor/js/prod-monitor.performance.js b/sites/all/modules/contrib/dev/prod_check/prod_monitor/js/prod-monitor.performance.js index 21a25868..17e0617b 100644 --- a/sites/all/modules/contrib/dev/prod_check/prod_monitor/js/prod-monitor.performance.js +++ b/sites/all/modules/contrib/dev/prod_check/prod_monitor/js/prod-monitor.performance.js @@ -4,7 +4,7 @@ Drupal.behaviors.prod_monitor_init = { attach: function(context, settings) { var script = document.createElement('script'); - script.src = 'http://www.google.com/jsapi?callback=Drupal.behaviors.prod_monitor_performance.initGoogleDependencies'; + script.src = document.location.protocol + '//www.google.com/jsapi?callback=Drupal.behaviors.prod_monitor_performance.initGoogleDependencies'; script.type = 'text/javascript'; $('head').append(script); } @@ -14,12 +14,12 @@ Drupal.behaviors.prod_monitor_performance = { initGoogleDependencies: function() { google.load('visualization', '1', { - 'callback':Drupal.behaviors.prod_monitor_performance.initGraphs, + 'callback':Drupal.behaviors.prod_monitor_performance.initGraphs, 'packages':['annotatedtimeline'] }) }, - initGraphs: function() { + initGraphs: function() { $('.performance-data').each(function() { var callback = $(this).attr('id').replace('-', '_'); //console.log(Drupal.behaviors.prod_monitor_performance[callback]); diff --git a/sites/all/modules/contrib/dev/prod_check/prod_monitor/prod_monitor.info b/sites/all/modules/contrib/dev/prod_check/prod_monitor/prod_monitor.info index c6764925..fd22ae54 100644 --- a/sites/all/modules/contrib/dev/prod_check/prod_monitor/prod_monitor.info +++ b/sites/all/modules/contrib/dev/prod_check/prod_monitor/prod_monitor.info @@ -4,9 +4,9 @@ package = Monitoring core = 7.x configure = admin/reports/prod-monitor -; Information added by drupal.org packaging script on 2013-10-01 -version = "7.x-1.7+0-dev" +; Information added by packaging script on 2013-11-25 +version = "7.x-1.8" core = "7.x" project = "prod_check" -datestamp = "1380623918" +datestamp = "1385405033" diff --git a/sites/all/modules/contrib/dev/prod_check/prod_monitor/prod_monitor.module b/sites/all/modules/contrib/dev/prod_check/prod_monitor/prod_monitor.module index 8b1bedfb..e80cb92a 100644 --- a/sites/all/modules/contrib/dev/prod_check/prod_monitor/prod_monitor.module +++ b/sites/all/modules/contrib/dev/prod_check/prod_monitor/prod_monitor.module @@ -328,7 +328,7 @@ function prod_monitor_cron() { $elapsed = $process = 0; foreach ($sites as $id => $site_info) { - $elapsed = REQUEST_TIME - $cron_start; + $elapsed = time() - $cron_start; if ($elapsed < $time_limit) { //TODO: add module status update check here. _prod_monitor_retrieve_data($id, $site_info); diff --git a/sites/all/modules/contrib/mail/smtp/smtp-base64-1741082-16.patch b/sites/all/modules/contrib/mail/smtp/smtp-base64-1741082-16.patch deleted file mode 100644 index fdc9fe24..00000000 --- a/sites/all/modules/contrib/mail/smtp/smtp-base64-1741082-16.patch +++ /dev/null @@ -1,28 +0,0 @@ -diff --git a/smtp.mail.inc b/smtp.mail.inc -index 2cf0841..b228e45 100644 ---- a/smtp.mail.inc -+++ b/smtp.mail.inc -@@ -367,10 +367,21 @@ class SmtpMailSystem implements MailSystemInterface { - } - // If plain/html within the body part, add it to $mailer->Body. - elseif (strpos($body_part2, 'text/html')) { -+ // Get the encoding. -+ $body_part2_encoding = $this->_get_substring($body_part2, 'Content-Transfer-Encoding', ' ', "\n"); - // Clean up the text. - $body_part2 = trim($this->_remove_headers(trim($body_part2))); -- // Include it as part of the mail object. -- $mailer->Body = $body_part2; -+ // Check whether the encoding is base64, and if so, decode it. -+ if (drupal_strtolower($body_part2_encoding) == 'base64') { -+ // Include it as part of the mail object. -+ $mailer->Body = base64_decode($body_part2); -+ // Ensure the whole message is recoded in the base64 format. -+ $mailer->Encoding = 'base64'; -+ } -+ else { -+ // Include it as part of the mail object. -+ $mailer->Body = $body_part2; -+ } - $mailer->ContentType = 'multipart/mixed'; - } - } diff --git a/sites/all/modules/contrib/mail/smtp/smtp.admin.inc b/sites/all/modules/contrib/mail/smtp/smtp.admin.inc index 3a90f0f9..cee7c8cb 100644 --- a/sites/all/modules/contrib/mail/smtp/smtp.admin.inc +++ b/sites/all/modules/contrib/mail/smtp/smtp.admin.inc @@ -49,6 +49,12 @@ function smtp_admin_settings() { '#options' => array(1 => t('On'), 0 => t('Off')), '#description' => t('To uninstall this module you must turn it off here first.'), ); + $form['onoff']['smtp_queue'] = array( + '#type' => 'checkbox', + '#title' => t('Send mail by queue'), + '#default_value' => variable_get('smtp_queue', FALSE), + '#description' => t('Mails will be sent by drupal queue api.'), + ); $form['server'] = array( '#type' => 'fieldset', @@ -167,6 +173,8 @@ function smtp_admin_settings() { '#description' => t('Checking this box will print SMTP messages from the server for every e-mail that is sent.'), ); + $form['#submit'][] = 'smtp_admin_settings_form_submit'; + return system_settings_form($form); } // End of smtp_admin_settings(). @@ -205,3 +213,27 @@ function smtp_admin_settings_validate($form, &$form_state) { } } // End of smtp_admin_settings_validate(). +/** + * Submit handler(). + */ +function smtp_admin_settings_form_submit($form, &$form_state) { + // Check if SMTP status has been changed. + if ( + (!variable_get('smtp_on', FALSE) && $form_state['values']['smtp_on']) || + (variable_get('smtp_on', FALSE) && !$form_state['values']['smtp_on']) + ) { + $mail_modes = variable_get('mail_system', array('default-system' => 'DefaultMailSystem')); + + // Turning on. + if ($form_state['values']['smtp_on']) { + variable_set('smtp_previous_mail_system', $mail_modes['default-system']); + $mail_modes['default-system'] = 'SmtpMailSystem'; + } + // Turning off. + else { + $mail_modes['default-system'] = variable_get('smtp_previous_mail_system', 'DefaultMailSystem'); + } + + variable_set('mail_system', $mail_modes); + } +} diff --git a/sites/all/modules/contrib/mail/smtp/smtp.info b/sites/all/modules/contrib/mail/smtp/smtp.info index 77858b56..7986f1b9 100644 --- a/sites/all/modules/contrib/mail/smtp/smtp.info +++ b/sites/all/modules/contrib/mail/smtp/smtp.info @@ -7,9 +7,9 @@ files[] = smtp.mail.inc files[] = smtp.phpmailer.inc files[] = smtp.transport.inc -; Information added by drupal.org packaging script on 2013-02-17 -version = "7.x-1.0" +; Information added by Drupal.org packaging script on 2015-01-07 +version = "7.x-1.2" core = "7.x" project = "smtp" -datestamp = "1361062292" +datestamp = "1420662781" diff --git a/sites/all/modules/contrib/mail/smtp/smtp.install b/sites/all/modules/contrib/mail/smtp/smtp.install index da7b5f3a..61ab1356 100644 --- a/sites/all/modules/contrib/mail/smtp/smtp.install +++ b/sites/all/modules/contrib/mail/smtp/smtp.install @@ -32,15 +32,6 @@ function smtp_uninstall() { } } -/** - * Implements hook_enable(). - */ -function smtp_enable() { - $mail_modes = variable_get('mail_system', array('default-system' => 'DefaultMailSystem')); - $mail_modes['default-system'] = 'SmtpMailSystem'; - variable_set('mail_system', $mail_modes); -} - /** * Implements hook_disable(). */ @@ -59,3 +50,16 @@ function smtp_update_7000() { variable_set('mail_system', array('default-system' => 'SmtpMailSystem')); } } + +/** + * Implements hook_update_N(). + * + * Back to default mail system if the status flag is off. + */ +function smtp_update_7100() { + $mail_modes = variable_get('mail_system', array('default-system' => 'DefaultMailSystem')); + if ($mail_modes['default-system'] == 'SmtpMailSystem' && !variable_get('smtp_on', FALSE)) { + $mail_modes['default-system'] = 'DefaultMailSystem'; + variable_set('mail_system', $mail_modes); + } +} diff --git a/sites/all/modules/contrib/mail/smtp/smtp.mail.inc b/sites/all/modules/contrib/mail/smtp/smtp.mail.inc index b228e457..b220eeb1 100644 --- a/sites/all/modules/contrib/mail/smtp/smtp.mail.inc +++ b/sites/all/modules/contrib/mail/smtp/smtp.mail.inc @@ -230,6 +230,16 @@ class SmtpMailSystem implements MailSystemInterface { break; case 'return-path': + if (strpos($value, '<') !== FALSE) { + $returnPathParts = explode('<', $value); + $returnPathAddr = rtrim($returnPathParts[1], '>'); + $mailer->Sender = $returnPathAddr; + } + else { + $mailer->Sender = $value; + } + break; + case 'mime-version': case 'x-mailer': // Let PHPMailer specify these. @@ -271,27 +281,31 @@ class SmtpMailSystem implements MailSystemInterface { } break; + case 'message-id': + $mailer->MessageID = $value; + break; + default: // The header key is not special - add it as is. $mailer->AddCustomHeader($key . ': ' . $value); } } -/** - * TODO - * Need to figure out the following. - * - * Add one last header item, but not if it has already been added. - * $errors_to = FALSE; - * foreach ($mailer->CustomHeader as $custom_header) { - * if ($custom_header[0] = '') { - * $errors_to = TRUE; - * } - * } - * if ($errors_to) { - * $mailer->AddCustomHeader('Errors-To: '. $from); - * } - */ + /** + * TODO + * Need to figure out the following. + * + * Add one last header item, but not if it has already been added. + * $errors_to = FALSE; + * foreach ($mailer->CustomHeader as $custom_header) { + * if ($custom_header[0] = '') { + * $errors_to = TRUE; + * } + * } + * if ($errors_to) { + * $mailer->AddCustomHeader('Errors-To: '. $from); + * } + */ // Add the message's subject. $mailer->Subject = $subject; @@ -299,12 +313,7 @@ class SmtpMailSystem implements MailSystemInterface { switch ($content_type) { case 'multipart/related': $mailer->Body = $body; - - /** - * TODO - * Firgure out if there is anything more to handling this type. - */ - + // TODO: Figure out if there is anything more to handling this type. break; case 'multipart/alternative': @@ -368,7 +377,7 @@ class SmtpMailSystem implements MailSystemInterface { // If plain/html within the body part, add it to $mailer->Body. elseif (strpos($body_part2, 'text/html')) { // Get the encoding. - $body_part2_encoding = $this->_get_substring($body_part2, 'Content-Transfer-Encoding', ' ', "\n"); + $body_part2_encoding = $this->_get_substring($body_part2, 'Content-Transfer-Encoding', ':', "\n"); // Clean up the text. $body_part2 = trim($this->_remove_headers(trim($body_part2))); // Check whether the encoding is base64, and if so, decode it. @@ -412,7 +421,7 @@ class SmtpMailSystem implements MailSystemInterface { $mailer->ContentType = 'multipart/mixed'; } // Add the attachment. - elseif (strpos($body_part, 'Content-Disposition: attachment;')) { + elseif (strpos($body_part, 'Content-Disposition: attachment;') && !isset($message['params']['attachments'])) { $file_path = $this->_get_substring($body_part, 'filename=', '"', '"'); $file_name = $this->_get_substring($body_part, ' name=', '"', '"'); $file_encoding = $this->_get_substring($body_part, 'Content-Transfer-Encoding', ' ', "\n"); @@ -454,14 +463,16 @@ class SmtpMailSystem implements MailSystemInterface { break; } - // Process mimemail attachments + // Process mimemail attachments, which are prepared in mimemail_mail(). if (isset($message['params']['attachments'])) { foreach ($message['params']['attachments'] as $attachment) { if (isset($attachment['filecontent'])) { $mailer->AddStringAttachment($attachment['filecontent'], $attachment['filename'], 'base64', $attachment['filemime']); } if (isset($attachment['filepath'])) { - $mailer->AddAttachment($attachment['filepath'], $attachment['filename'], 'base64', $attachment['filemime']); + $filename = isset($attachment['filename']) ? $attachment['filename'] : basename($attachment['filepath']); + $filemime = isset($attachment['filemime']) ? $attachment['filemime'] : file_get_mimetype($attachment['filepath']); + $mailer->AddAttachment($attachment['filepath'], $filename, 'base64', $filemime); } } } @@ -498,16 +509,19 @@ class SmtpMailSystem implements MailSystemInterface { $mailer->Port = variable_get('smtp_port', '25'); $mailer->Mailer = 'smtp'; - // Let the people know what is going on. - watchdog('smtp', 'Sending mail to: @to', array('@to' => $to)); - - // Try to send e-mail. If it fails, set watchdog entry. - if (!$mailer->Send()) { - watchdog('smtp', 'Error sending e-mail from @from to @to : !error_message', array('@from' => $from, '@to' => $to, '!error_message' => $mailer->ErrorInfo), WATCHDOG_ERROR); - return FALSE; + $mailerArr = array( + 'mailer' => $mailer, + 'to' => $to, + 'from' => $from, + ); + if (variable_get('smtp_queue', FALSE)) { + watchdog('smtp', 'Queue sending mail to: @to', array('@to' => $to)); + smtp_send_queue($mailerArr); + } + else { + return _smtp_mailer_send($mailerArr); } - $mailer->SmtpClose(); return TRUE; } diff --git a/sites/all/modules/contrib/mail/smtp/smtp.module b/sites/all/modules/contrib/mail/smtp/smtp.module index 85938cb5..9c15c530 100644 --- a/sites/all/modules/contrib/mail/smtp/smtp.module +++ b/sites/all/modules/contrib/mail/smtp/smtp.module @@ -61,3 +61,44 @@ function smtp_mail($key, &$message, $params) { $message['body'] = $params['body']; } } + +/** + * Implementation of hook_cron_queue_info(). + */ +function smtp_cron_queue_info() { + $queues['smtp_send_queue'] = array( + 'worker callback' => 'smtp_send_queue_runner', + 'time' => 60, // This is the max run time per cron run in seconds. + ); + return $queues; +} + +/** + * smtp_send_queue queuer. + */ +function smtp_send_queue($mailerObj) { + $queue = DrupalQueue::get('smtp_send_queue'); + $queue->createItem($mailerObj); +} + +function smtp_send_queue_runner($variables) { + _smtp_mailer_send($variables); +} + +function _smtp_mailer_send($variables) { + $mailer = $variables['mailer']; + $to = $variables['to']; + $from = $variables['from']; + + // Let the people know what is going on. + watchdog('smtp', 'Sending mail to: @to', array('@to' => $to)); + + // Try to send e-mail. If it fails, set watchdog entry. + if (!$mailer->Send()) { + watchdog('smtp', 'Error sending e-mail from @from to @to : !error_message', array('@from' => $from, '@to' => $to, '!error_message' => $mailer->ErrorInfo), WATCHDOG_ERROR); + return FALSE; + } + + $mailer->SmtpClose(); + return TRUE; +} \ No newline at end of file diff --git a/sites/all/modules/contrib/mail/smtp/smtp.phpmailer.inc b/sites/all/modules/contrib/mail/smtp/smtp.phpmailer.inc index 27d41328..e0c0747c 100644 --- a/sites/all/modules/contrib/mail/smtp/smtp.phpmailer.inc +++ b/sites/all/modules/contrib/mail/smtp/smtp.phpmailer.inc @@ -1741,27 +1741,41 @@ class PHPMailer { */ public function EncodeQ($str, $position = 'text') { // There should not be any EOL in the string - $encoded = preg_replace('/[\r\n]*/', '', $str); - + $pattern = ''; + $encoded = str_replace(array("\r", "\n"), '', $str); switch (strtolower($position)) { case 'phrase': - $encoded = preg_replace("/([^A-Za-z0-9!*+\/ -])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded); + // RFC 2047 section 5.3 + $pattern = '^A-Za-z0-9!*+\/ -'; break; + /** @noinspection PhpMissingBreakStatementInspection */ case 'comment': - $encoded = preg_replace("/([\(\)\"])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded); + // RFC 2047 section 5.2 + $pattern = '\(\)"'; + // intentional fall-through + // for this reason we build the $pattern without including delimiters and [] case 'text': default: - // Replace every high ascii, control =, ? and _ characters - //TODO using /e (equivalent to eval()) is probably not a good idea - $encoded = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e', - "'='.sprintf('%02X', ord('\\1'))", $encoded); + // RFC 2047 section 5.1 + // Replace every high ascii, control, =, ? and _ characters + $pattern = '\000-\011\013\014\016-\037\075\077\137\177-\377' . $pattern; break; } - + $matches = array(); + if (preg_match_all("/[{$pattern}]/", $encoded, $matches)) { + // If the string contains an '=', make sure it's the first thing we replace + // so as to avoid double-encoding + $s = array_search('=', $matches[0]); + if ($s !== false) { + unset($matches[0][$s]); + array_unshift($matches[0], '='); + } + foreach (array_unique($matches[0]) as $char) { + $encoded = str_replace($char, '=' . sprintf('%02X', ord($char)), $encoded); + } + } // Replace every spaces to _ (more readable than =20) - $encoded = str_replace(' ', '_', $encoded); - - return $encoded; + return str_replace(' ', '_', $encoded); } /** diff --git a/sites/all/modules/contrib/messages/better_messages/better_messages.inc b/sites/all/modules/contrib/messages/better_messages/better_messages.inc index fb5b8cda..ebc6e195 100644 --- a/sites/all/modules/contrib/messages/better_messages/better_messages.inc +++ b/sites/all/modules/contrib/messages/better_messages/better_messages.inc @@ -171,7 +171,13 @@ function better_messages_admin() { '#default_value' => $settings['extra']['pages'], '#description' => $description, ); - + + $form['vis_settings']['admin'] = array( + '#type' => 'checkbox', + '#title' => t('Use Better Messages popup for the admin user (UID 1)'), + '#default_value' => $settings['extra']['admin'], + ); + $form['jquery_ui'] = array( '#type' => 'fieldset', '#title' => t('jQuery UI enhancements'), @@ -218,7 +224,7 @@ function better_messages_admin_submit($form, &$form_state) { 'popin' => array('effect' => $form_state['values']['popin_effect'], 'duration' => $form_state['values']['popin_duration']), 'popout' => array('effect' => $form_state['values']['popout_effect'], 'duration' => $form_state['values']['popout_duration']), 'jquery_ui' => array('draggable' => $form_state['values']['draggable'], 'resizable' => $form_state['values']['resizable']), - 'extra' => array('pages' => $form_state['values']['pages'], 'visibility' => $form_state['values']['visibility'], + 'extra' => array('pages' => $form_state['values']['pages'], 'visibility' => $form_state['values']['visibility'], 'admin' => $form_state['values']['admin'] ) ); variable_set('better_messages', $settings); diff --git a/sites/all/modules/contrib/messages/better_messages/better_messages.info b/sites/all/modules/contrib/messages/better_messages/better_messages.info index 7d35cd0d..61f7f70d 100644 --- a/sites/all/modules/contrib/messages/better_messages/better_messages.info +++ b/sites/all/modules/contrib/messages/better_messages/better_messages.info @@ -2,10 +2,11 @@ name = Better Messages description = This module adds simple functions to make Drupal messages look and act better. core = 7.x package = User interface +configure = admin/config/user-interface/better-messages -; Information added by drupal.org packaging script on 2012-03-25 -version = "7.x-1.x-dev" +; Information added by Drupal.org packaging script on 2014-12-11 +version = "7.x-1.0-alpha1" core = "7.x" project = "better_messages" -datestamp = "1332677109" +datestamp = "1418319316" diff --git a/sites/all/modules/contrib/messages/better_messages/better_messages.install b/sites/all/modules/contrib/messages/better_messages/better_messages.install index 3725d700..68ea9065 100644 --- a/sites/all/modules/contrib/messages/better_messages/better_messages.install +++ b/sites/all/modules/contrib/messages/better_messages/better_messages.install @@ -4,7 +4,7 @@ * Implementaton of hook_install */ function better_messages_install() { - drupal_set_message(t("Better Messages is installed successfully.
    Click here to visit the settings page!", array('@href' => base_path() . 'admin/settings/better-messages'))); + drupal_set_message(t("Better Messages is installed successfully.
    Click here to visit the settings page!", array('@href' => base_path() . 'admin/config/user-interface/better-messages'))); } /** @@ -12,6 +12,7 @@ function better_messages_install() { */ function better_messages_uninstall() { db_query("DELETE FROM {variable} WHERE name LIKE 'better_messages_%'"); + db_query("DELETE FROM {variable} WHERE name = 'better_messages'"); db_query("DELETE FROM {system} WHERE name = 'better_messages'"); } @@ -32,4 +33,4 @@ function better_messages_update_6000() { db_query("DELETE FROM {variable} WHERE name LIKE 'better_messages_%'"); variable_set('better_messages', $settings_new); return array(); -} \ No newline at end of file +} diff --git a/sites/all/modules/contrib/messages/better_messages/better_messages.js b/sites/all/modules/contrib/messages/better_messages/better_messages.js index 8390dfb0..1f9da017 100644 --- a/sites/all/modules/contrib/messages/better_messages/better_messages.js +++ b/sites/all/modules/contrib/messages/better_messages/better_messages.js @@ -39,7 +39,7 @@ if(seconds > 0) { seconds--; if (betterMessages.show_countdown == '1') { - $('.message-timer').text(Drupal.t('Closing in' + ' ' + seconds + ' ' + Drupal.t('seconds'))); + $('.message-timer').text(Drupal.t('Closing in !seconds seconds', {'!seconds': seconds})); } if(seconds > 0) { betterMessages.countDown = setTimeout( function() {betterMessages.countDownClose(seconds);}, 1000 ); diff --git a/sites/all/modules/contrib/messages/better_messages/better_messages.module b/sites/all/modules/contrib/messages/better_messages/better_messages.module index 1a64981d..85013f95 100644 --- a/sites/all/modules/contrib/messages/better_messages/better_messages.module +++ b/sites/all/modules/contrib/messages/better_messages/better_messages.module @@ -5,6 +5,7 @@ Implementation of hook_init */ function better_messages_init() { drupal_add_css(drupal_get_path('module', 'better_messages') . '/better_messages_admin.css'); + drupal_add_css(drupal_get_path('module', 'better_messages') . '/skins/default/better_messages.css'); } /* @@ -29,11 +30,11 @@ function better_messages_menu() { function better_messages_permission() { return array( 'access better messages' => array( - 'title' => t('access better messages'), + 'title' => t('access better messages'), 'description' => t('access better messages.'), ), 'administer better messages' => array( - 'title' => t('administer better messages'), + 'title' => t('administer better messages'), 'description' => t('administer better messages.'), ), ); @@ -45,11 +46,11 @@ Implementation of hook_theme function better_messages_theme($existing, $type, $theme, $path) { return array( 'better_messages_content' => array( - 'arguments' => array('display' => NULL), + 'variables' => array('messages_drupal' => array()), ), 'better_messages' => array( 'template' => 'better_messages', - 'arguments' => array('content' => NULL), + 'variables' => array('content' => NULL), ), ); } @@ -65,26 +66,29 @@ function theme_better_messages($display = NULL) { $output = ''; $better_messages = better_messages_process_visibility(); $access = user_access('access better messages'); - $message = drupal_get_messages($display['display'], FALSE); + $message = drupal_get_messages($display['display']); if ($better_messages && $access && !empty($message)) { - $disable_autoclose = array_key_exists('error', $message); + $disable_autoclose = better_messages_process_autoclose($message); better_messages_add_files($disable_autoclose); - $message = theme('better_messages_content', $display['display']); - // We save the intial output to SESSION so we can put it in