timer('check_' . __CLASS__, self::CHECK_TIMER)) {
// Best attempt at re-securing folders
$config = CRM_Core_Config::singleton();
$config->cleanup(0, FALSE);
if ($messages === NULL) {
$messages = $this->checkAll();
}
$statusMessages = array();
$statusType = 'alert';
foreach ($messages as $message) {
if ($filter === TRUE || call_user_func($filter, $message->getSeverity()) >= 3) {
$statusType = (call_user_func($filter, $message->getSeverity()) >= 4) ? 'error' : $statusType;
$statusMessage = $message->getMessage();
$statusMessages[] = $statusTitle = $message->getTitle();
}
}
if (count($statusMessages)) {
if (count($statusMessages) > 1) {
$statusTitle = ts('Multiple Alerts');
$statusMessage = '
- ' . implode('
- ', $statusMessages) . '
';
}
// TODO: add link to status page
CRM_Core_Session::setStatus($statusMessage, $statusTitle, $statusType);
}
}
}
}
/**
* Sort messages based upon severity
*
* @param CRM_Utils_Check_Message $a
* @param CRM_Utils_Check_Message $b
* @return int
*/
public function severitySort($a, $b) {
$aSeverity = $a->getSeverity();
$bSeverity = $b->getSeverity();
if ($aSeverity == $bSeverity) {
return strcmp($a->getName(), $b->getName());
}
return (self::severityMap($aSeverity) > self::severityMap($bSeverity));
}
/**
* Get the integer value (useful for thresholds) of the severity.
*
* @param int|const $severity
* the value to look up
* @param bool $reverse
* whether to find the constant from the integer
* @return bool
*/
public static function severityMap($severity, $reverse = FALSE) {
// Lowercase string-based severities
if (!$reverse) {
$severity = strtolower($severity);
}
// See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
$levels = array(
\Psr\Log\LogLevel::EMERGENCY => 7,
\Psr\Log\LogLevel::ALERT => 6,
\Psr\Log\LogLevel::CRITICAL => 5,
\Psr\Log\LogLevel::ERROR => 4,
\Psr\Log\LogLevel::WARNING => 3,
\Psr\Log\LogLevel::NOTICE => 2,
\Psr\Log\LogLevel::INFO => 1,
\Psr\Log\LogLevel::DEBUG => 0,
);
return ($reverse) ? array_search($severity, $levels) : $levels[$severity];
}
/**
* Throw an exception if any of the checks fail.
*
* @param array|NULL $messages list of CRM_Utils_Check_Message; or NULL if the default list should be fetched
*
* @throws Exception
*/
public function assertValid($messages = NULL) {
if ($messages === NULL) {
$messages = $this->checkAll();
}
if (!empty($messages)) {
$messagesAsArray = array();
foreach ($messages as $message) {
$messagesAsArray[] = $message->toArray();
}
throw new Exception('There are configuration problems with this installation: ' . print_r($messagesAsArray, TRUE));
}
}
/**
* Run some sanity checks.
*
* This could become a hook so that CiviCRM can run both built-in
* configuration & sanity checks, and modules/extensions can add
* their own checks.
*
* We might even expose the results of these checks on the Wordpress
* plugin status page or the Drupal admin/reports/status path.
*
* @return array
* Array of messages
* @link https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_requirements
*/
public function checkAll($showHushed = FALSE) {
$checks = array();
$checks[] = new CRM_Utils_Check_Security();
$checks[] = new CRM_Utils_Check_Env();
$compInfo = CRM_Core_Component::getEnabledComponents();
foreach ($compInfo as $compObj) {
switch ($compObj->info['name']) {
case 'CiviCase':
$checks[] = new CRM_Utils_Check_Case(CRM_Case_XMLRepository::singleton(), CRM_Case_PseudoConstant::caseType('name'));
break;
default:
}
}
$messages = array();
foreach ($checks as $check) {
$messages = array_merge($messages, $check->checkAll());
}
CRM_Utils_Hook::check($messages);
if (!$showHushed) {
foreach ($messages as $key => $message) {
$hush = self::checkHushSnooze($message);
if ($hush) {
unset($messages[$key]);
}
}
}
uasort($messages, array(__CLASS__, 'severitySort'));
return $messages;
}
/**
* Evaluate if a system check should be hushed/snoozed.
*
* @return bool
* TRUE means hush/snooze, FALSE means display.
*/
public function checkHushSnooze($message) {
$statusPreferenceParams = array(
'name' => $message->getName(),
'domain_id' => CRM_Core_Config::domainID(),
);
// Check if there's a StatusPreference matching this name/domain.
$statusPreference = civicrm_api3('StatusPreference', 'get', $statusPreferenceParams);
if ($statusPreference['id']) {
// If so, compare severity to StatusPreference->severity.
$spid = $statusPreference['id'];
$severity = self::severityMap($message->getSeverity());
if ($severity <= $statusPreference['values'][$spid]['ignore_severity']) {
// A hush or a snooze has been set. Find out which.
if ($statusPreference['values'][$spid]['hush_until']) {
// Snooze is set.
$today = new DateTime();
$snoozeDate = new DateTime($statusPreference['values'][$spid]['hush_until']);
if ($today > $snoozeDate) {
// Snooze is expired.
return FALSE;
}
else {
// Snooze is active.
return TRUE;
}
}
else {
// Hush.
return TRUE;
}
}
}
return FALSE;
}
}