return $messages;
}
- $config = CRM_Core_Config::singleton();
-
- if (in_array('CiviMail', $config->enableComponents) &&
+ if (CRM_Core_Component::isEnabled('CiviMail') &&
CRM_Core_BAO_MailSettings::defaultDomain() == "EXAMPLE.ORG"
) {
$message = new CRM_Utils_Check_Message(
return $messages;
}
- $keys = array_keys($manager->getStatuses());
+ $stauses = $manager->getStatuses();
+ $keys = array_keys($stauses);
+ $enabled = array_keys(array_filter($stauses, function($status) {
+ return $status === CRM_Extension_Manager::STATUS_INSTALLED;
+ }));
sort($keys);
$updates = $errors = $okextensions = [];
+ $extPrettyLabel = function($key) use ($mapper) {
+ // We definitely know a $key, but we may not have a $label.
+ // Which is too bad - because it would be nicer if $label could be the reliable start of the string.
+ $keyFmt = '<code>' . htmlentities($key) . '</code>';
+ try {
+ $info = $mapper->keyToInfo($key);
+ if ($info->label) {
+ return sprintf('"<em>%s</em>" (%s)', htmlentities($info->label), $keyFmt);
+ }
+ }
+ catch (CRM_Extension_Exception $ex) {
+ return "($keyFmt)";
+ }
+ };
+
foreach ($keys as $key) {
try {
$obj = $mapper->keyToInfo($key);
$row = CRM_Admin_Page_Extensions::createExtendedInfo($obj);
switch ($row['status']) {
case CRM_Extension_Manager::STATUS_INSTALLED_MISSING:
- $errors[] = ts('%1 extension (%2) is installed but missing files.', [1 => $row['label'] ?? NULL, 2 => $key]);
+ $errors[] = ts('%1 is installed but missing files.', [1 => $extPrettyLabel($key)]);
break;
case CRM_Extension_Manager::STATUS_INSTALLED:
- if (!empty($remotes[$key]) && version_compare($row['version'], $remotes[$key]->version, '<')) {
+ $missingRequirements = array_diff($row['requires'], $enabled);
+ if (!empty($row['requires']) && $missingRequirements) {
+ $errors[] = ts('%1 has a missing dependency on %2', [
+ 1 => $extPrettyLabel($key),
+ 2 => implode(', ', array_map($extPrettyLabel, $missingRequirements)),
+ 'plural' => '%1 has missing dependencies: %2',
+ 'count' => count($missingRequirements),
+ ]);
+ }
+ elseif (!empty($remotes[$key]) && version_compare($row['version'], $remotes[$key]->version, '<')) {
$updates[] = $row['label'] . ': ' . $mapper->getUpgradeLink($remotes[$key], $row);
}
else {
if ($errors) {
$messages[] = new CRM_Utils_Check_Message(
__FUNCTION__ . 'Error',
- '<ul><li>' . implode('</li><li>', $errors) . '</li></ul>',
- ts('Extension Error'),
+ ts('There is one extension error:', [
+ 'count' => count($errors),
+ 'plural' => 'There are %count extension errors:',
+ ])
+ . '<ul><li>' . implode('</li><li>', $errors) . '</li></ul>'
+ . ts('To resolve any errors, go to <a %1>Manage Extensions</a>.', [
+ 1 => 'href="' . CRM_Utils_System::url('civicrm/admin/extensions', 'reset=1') . '"',
+ ]),
+ ts('Extension Error', ['count' => count($errors), 'plural' => 'Extension Errors']),
\Psr\Log\LogLevel::ERROR,
'fa-plug'
);
else {
$message = ts('All extensions are up-to-date:');
}
+ natcasesort($okextensions);
$messages[] = new CRM_Utils_Check_Message(
__FUNCTION__ . 'Ok',
$message . '<ul><li>' . implode('</li><li>', $okextensions) . '</li></ul>',
return $messages;
}
+ /**
+ * @return CRM_Utils_Check_Message[]
+ */
+ public function checkScheduledJobLogErrors() {
+ $jobs = civicrm_api3('Job', 'get', [
+ 'sequential' => 1,
+ 'return' => ["id", "name", "last_run"],
+ 'is_active' => 1,
+ 'options' => ['limit' => 0],
+ ]);
+ $html = '';
+ foreach ($jobs['values'] as $job) {
+ $lastExecutionMessage = civicrm_api3('JobLog', 'get', [
+ 'sequential' => 1,
+ 'return' => ["description"],
+ 'job_id' => $job['id'],
+ 'options' => ['sort' => "id desc", 'limit' => 1],
+ ])['values'][0]['description'] ?? NULL;
+ if (!empty($lastExecutionMessage) && strpos($lastExecutionMessage, 'Failure') !== FALSE) {
+ $viewLogURL = CRM_Utils_System::url('civicrm/admin/joblog', "jid={$job['id']}&reset=1");
+ $html .= '<tr>
+ <td>' . $job['name'] . ' </td>
+ <td>' . $lastExecutionMessage . '</td>
+ <td>' . $job['last_run'] . '</td>
+ <td><a href="' . $viewLogURL . '">' . ts('View Job Log') . '</a></td>
+ </tr>';
+ }
+ }
+ if (empty($html)) {
+ return [];
+ }
+
+ $message = '<p>' . ts('The following scheduled jobs failed on the last run:') . '</p>
+ <p><table><thead><tr><th>' . ts('Job') . '</th><th>' . ts('Message') . '</th><th>' . ts('Last Run') . '</th><th></th>
+ </tr></thead><tbody>' . $html . '
+ </tbody></table></p>';
+
+ $msg = new CRM_Utils_Check_Message(
+ __FUNCTION__,
+ $message,
+ ts('Scheduled Job Failures'),
+ \Psr\Log\LogLevel::WARNING,
+ 'fa-server'
+ );
+ $messages[] = $msg;
+ return $messages;
+ }
+
/**
* Checks if there are pending extension upgrades.
*
return $messages;
}
+ /**
+ * Ensure that the CMS is providing a supported timezone.
+ *
+ * @return CRM_Utils_Check_Message[]
+ */
+ public function checkUFTimezoneValid() {
+ $messages = [];
+ $check_tz = CRM_Core_Config::singleton()->userSystem->getTimeZoneString();
+
+ if (!array_key_exists($check_tz, CRM_Core_SelectValues::timezone())) {
+ $messages[] = new CRM_Utils_Check_Message(
+ __FUNCTION__,
+ ts('This system has an invalid timezone set. Please verify that your CMS has a timezone configured that is listed under the <a href="%1">PHP List of Supported Timezones</a>.', [1 => 'https://www.php.net/manual/en/timezones.php']),
+ ts('Missing or Invalid Timezone'),
+ \Psr\Log\LogLevel::ERROR,
+ 'fa-clock-o'
+ );
+ }
+
+ return $messages;
+ }
+
}