ee89958f5a4ab3d0a4ad2b90ca518ac251da58ce
[civicrm-core.git] / CRM / Utils / Check / Component / Env.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.7 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2016 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
26 */
27
28 /**
29 *
30 * @package CRM
31 * @copyright CiviCRM LLC (c) 2004-2016
32 */
33 class CRM_Utils_Check_Component_Env extends CRM_Utils_Check_Component {
34
35 /**
36 * @return array
37 */
38 public function checkPhpVersion() {
39 $messages = array();
40
41 if (version_compare(phpversion(), CRM_Upgrade_Incremental_General::MIN_RECOMMENDED_PHP_VER) >= 0) {
42 $messages[] = new CRM_Utils_Check_Message(
43 __FUNCTION__,
44 ts('This system uses PHP version %1 which meets or exceeds the minimum recommendation of %2.',
45 array(
46 1 => phpversion(),
47 2 => CRM_Upgrade_Incremental_General::MIN_RECOMMENDED_PHP_VER,
48 )),
49 ts('PHP Up-to-Date'),
50 \Psr\Log\LogLevel::INFO,
51 'fa-server'
52 );
53 }
54 elseif (version_compare(phpversion(), CRM_Upgrade_Incremental_General::MIN_DEFECT_PHP_VER) >= 0) {
55 $messages[] = new CRM_Utils_Check_Message(
56 __FUNCTION__,
57 ts('This system uses PHP version %1. While this meets the minimum requirements for CiviCRM to function, upgrading to PHP version %2 or newer is recommended for maximum compatibility.',
58 array(
59 1 => phpversion(),
60 2 => CRM_Upgrade_Incremental_General::MIN_RECOMMENDED_PHP_VER,
61 3 => CRM_Upgrade_Incremental_General::MIN_DEFECT_PHP_VER,
62 )),
63 ts('PHP Out-of-Date'),
64 \Psr\Log\LogLevel::NOTICE,
65 'fa-server'
66 );
67 }
68 else {
69 $messages[] = new CRM_Utils_Check_Message(
70 __FUNCTION__,
71 ts('This system uses PHP version %1. CiviCRM can be installed on this version, but some specific features are known to fail or degrade. Version %3 is the bare minimum to avoid known issues, and version %2 is recommended.',
72 array(
73 1 => phpversion(),
74 2 => CRM_Upgrade_Incremental_General::MIN_RECOMMENDED_PHP_VER,
75 3 => CRM_Upgrade_Incremental_General::MIN_DEFECT_PHP_VER,
76 )),
77 ts('PHP Out-of-Date'),
78 \Psr\Log\LogLevel::WARNING,
79 'fa-server'
80 );
81 }
82
83 return $messages;
84 }
85
86 /**
87 * @return array
88 */
89 public function checkPhpMysqli() {
90 $messages = array();
91
92 if (!extension_loaded('mysqli')) {
93 $messages[] = new CRM_Utils_Check_Message(
94 __FUNCTION__,
95 ts('Future versions of CiviCRM may require the PHP extension "%2". To ensure that your system will be compatible, please install it in advance. For more explanation, see <a href="%1">the announcement</a>.',
96 array(
97 1 => 'https://civicrm.org/blog/totten/psa-please-verify-php-extension-mysqli',
98 2 => 'mysqli',
99 )),
100 ts('Forward Compatibility: Enable "mysqli"'),
101 \Psr\Log\LogLevel::WARNING,
102 'fa-server'
103 );
104 }
105
106 return $messages;
107 }
108
109 /**
110 * Check that the MySQL time settings match the PHP time settings.
111 *
112 * @return array<CRM_Utils_Check_Message> an empty array, or a list of warnings
113 */
114 public function checkMysqlTime() {
115 //CRM-19115 - Always set MySQL time before checking it.
116 CRM_Core_Config::singleton()->userSystem->setMySQLTimeZone();
117 $messages = array();
118
119 $phpNow = date('Y-m-d H:i');
120 $sqlNow = CRM_Core_DAO::singleValueQuery("SELECT date_format(now(), '%Y-%m-%d %H:%i')");
121 if (!CRM_Utils_Time::isEqual($phpNow, $sqlNow, 2.5 * 60)) {
122 $messages[] = new CRM_Utils_Check_Message(
123 __FUNCTION__,
124 ts('Timestamps reported by MySQL (eg "%2") and PHP (eg "%3" ) are mismatched.<br /><a href="%1">Read more about this warning</a>', array(
125 1 => CRM_Utils_System::getWikiBaseURL() . 'checkMysqlTime',
126 2 => $sqlNow,
127 3 => $phpNow,
128 )),
129 ts('Timestamp Mismatch'),
130 \Psr\Log\LogLevel::ERROR,
131 'fa-server'
132 );
133 }
134
135 return $messages;
136 }
137
138 /**
139 * @return array
140 */
141 public function checkDebug() {
142 $messages = array();
143
144 $config = CRM_Core_Config::singleton();
145 if ($config->debug) {
146 $messages[] = new CRM_Utils_Check_Message(
147 __FUNCTION__,
148 ts('Warning: Debug is enabled in <a href="%1">system settings</a>. This should not be enabled on production servers.',
149 array(1 => CRM_Utils_System::url('civicrm/admin/setting/debug', 'reset=1'))),
150 ts('Debug Mode Enabled'),
151 \Psr\Log\LogLevel::WARNING,
152 'fa-bug'
153 );
154 }
155
156 return $messages;
157 }
158
159 /**
160 * @return array
161 */
162 public function checkOutboundMail() {
163 $messages = array();
164
165 $mailingInfo = Civi::settings()->get('mailing_backend');
166 if (($mailingInfo['outBound_option'] == CRM_Mailing_Config::OUTBOUND_OPTION_REDIRECT_TO_DB
167 || (defined('CIVICRM_MAIL_LOG') && CIVICRM_MAIL_LOG)
168 || $mailingInfo['outBound_option'] == CRM_Mailing_Config::OUTBOUND_OPTION_DISABLED
169 || $mailingInfo['outBound_option'] == CRM_Mailing_Config::OUTBOUND_OPTION_MOCK)
170 ) {
171 $messages[] = new CRM_Utils_Check_Message(
172 __FUNCTION__,
173 ts('Warning: Outbound email is disabled in <a href="%1">system settings</a>. Proper settings should be enabled on production servers.',
174 array(1 => CRM_Utils_System::url('civicrm/admin/setting/smtp', 'reset=1'))),
175 ts('Outbound Email Disabled'),
176 \Psr\Log\LogLevel::WARNING,
177 'fa-envelope'
178 );
179 }
180
181 return $messages;
182 }
183
184 /**
185 * Check that domain email and org name are set
186 * @return array
187 */
188 public function checkDomainNameEmail() {
189 $messages = array();
190
191 list($domainEmailName, $domainEmailAddress) = CRM_Core_BAO_Domain::getNameAndEmail(TRUE);
192 $domain = CRM_Core_BAO_Domain::getDomain();
193 $domainName = $domain->name;
194 $fixEmailUrl = CRM_Utils_System::url("civicrm/admin/domain", "action=update&reset=1");
195
196 if (!$domainEmailAddress || $domainEmailAddress == 'info@EXAMPLE.ORG') {
197 if (!$domainName || $domainName == 'Default Domain Name') {
198 $msg = ts("Please enter your organization's <a href=\"%1\">name, primary address, and default FROM Email Address</a> (for system-generated emails).",
199 array(1 => $fixEmailUrl));
200 }
201 else {
202 $msg = ts('Please enter a <a href="%1">default FROM Email Address</a> (for system-generated emails).',
203 array(1 => $fixEmailUrl));
204 }
205 }
206 elseif (!$domainName || $domainName == 'Default Domain Name') {
207 $msg = ts("Please enter your organization's <a href=\"%1\">name and primary address</a>.",
208 array(1 => $fixEmailUrl));
209 }
210
211 if (!empty($msg)) {
212 $messages[] = new CRM_Utils_Check_Message(
213 __FUNCTION__,
214 $msg,
215 ts('Complete Setup'),
216 \Psr\Log\LogLevel::WARNING,
217 'fa-check-square-o'
218 );
219 }
220
221 return $messages;
222 }
223
224 /**
225 * Checks if a default bounce handling mailbox is set up
226 * @return array
227 */
228 public function checkDefaultMailbox() {
229 $messages = array();
230 $config = CRM_Core_Config::singleton();
231
232 if (in_array('CiviMail', $config->enableComponents) &&
233 CRM_Core_BAO_MailSettings::defaultDomain() == "EXAMPLE.ORG"
234 ) {
235 $message = new CRM_Utils_Check_Message(
236 __FUNCTION__,
237 ts('Please configure a <a href="%1">default mailbox</a> for CiviMail.',
238 array(1 => CRM_Utils_System::url('civicrm/admin/mailSettings', "reset=1"))),
239 ts('Configure Default Mailbox'),
240 \Psr\Log\LogLevel::WARNING,
241 'fa-envelope'
242 );
243 $docUrl = 'target="_blank" href="' . CRM_Utils_System::docURL(array('page' => 'user/advanced-configuration/email-system-configuration/', 'URLonly' => TRUE)) . '""';
244 $message->addHelp(
245 ts('A default mailbox must be configured for email bounce processing.') . '<br />' .
246 ts("Learn more in the <a %1>online documentation</a>.", array(1 => $docUrl))
247 );
248 $messages[] = $message;
249 }
250
251 return $messages;
252 }
253
254 /**
255 * Checks if cron has run in a reasonable amount of time
256 * @return array
257 */
258 public function checkLastCron() {
259 $messages = array();
260
261 $statusPreference = new CRM_Core_DAO_StatusPreference();
262 $statusPreference->domain_id = CRM_Core_Config::domainID();
263 $statusPreference->name = 'checkLastCron';
264
265 if ($statusPreference->find(TRUE) && !empty($statusPreference->check_info)) {
266 $lastCron = $statusPreference->check_info;
267 $msg = ts('Last cron run at %1.', array(1 => CRM_Utils_Date::customFormat(date('c', $lastCron))));
268 }
269 else {
270 $lastCron = 0;
271 $msg = ts('No cron runs have been recorded.');
272 }
273
274 if ($lastCron > gmdate('U') - 3600) {
275 $messages[] = new CRM_Utils_Check_Message(
276 __FUNCTION__,
277 $msg,
278 ts('Cron Running OK'),
279 \Psr\Log\LogLevel::INFO,
280 'fa-clock-o'
281 );
282 }
283 else {
284 $message = new CRM_Utils_Check_Message(
285 __FUNCTION__,
286 $msg,
287 ts('Cron Not Running'),
288 ($lastCron > gmdate('U') - 86400) ? \Psr\Log\LogLevel::WARNING : \Psr\Log\LogLevel::ERROR,
289 'fa-clock-o'
290 );
291 $docUrl = 'target="_blank" href="' . CRM_Utils_System::docURL(array('resource' => 'wiki', 'page' => 'Managing Scheduled Jobs', 'URLonly' => TRUE)) . '""';
292 $message->addHelp(
293 ts('Configuring cron on your server is necessary for running scheduled jobs such as sending mail and scheduled reminders.') . '<br />' .
294 ts("Learn more in the <a %1>online documentation</a>.", array(1 => $docUrl))
295 );
296 $messages[] = $message;
297 }
298
299 return $messages;
300 }
301
302 /**
303 * Recommend that sites use path-variables for their directories and URLs.
304 * @return array
305 */
306 public function checkUrlVariables() {
307 $messages = array();
308 $hasOldStyle = FALSE;
309 $settingNames = array(
310 'userFrameworkResourceURL',
311 'imageUploadURL',
312 'customCSSURL',
313 'extensionsURL',
314 );
315
316 foreach ($settingNames as $settingName) {
317 $settingValue = Civi::settings()->get($settingName);
318 if (!empty($settingValue) && $settingValue{0} != '[') {
319 $hasOldStyle = TRUE;
320 break;
321 }
322 }
323
324 if ($hasOldStyle) {
325 $message = new CRM_Utils_Check_Message(
326 __FUNCTION__,
327 ts('<a href="%1">Resource URLs</a> may use absolute paths, relative paths, or variables. Absolute paths are more difficult to maintain. To maximize portability, consider using a variable in each URL (eg "<tt>[cms.root]</tt>" or "<tt>[civicrm.files]</tt>").',
328 array(1 => CRM_Utils_System::url('civicrm/admin/setting/url', "reset=1"))),
329 ts('Resource URLs: Make them portable'),
330 \Psr\Log\LogLevel::NOTICE,
331 'fa-server'
332 );
333 $messages[] = $message;
334 }
335
336 return $messages;
337 }
338
339 /**
340 * Recommend that sites use path-variables for their directories and URLs.
341 * @return array
342 */
343 public function checkDirVariables() {
344 $messages = array();
345 $hasOldStyle = FALSE;
346 $settingNames = array(
347 'uploadDir',
348 'imageUploadDir',
349 'customFileUploadDir',
350 'customTemplateDir',
351 'customPHPPathDir',
352 'extensionsDir',
353 );
354
355 foreach ($settingNames as $settingName) {
356 $settingValue = Civi::settings()->get($settingName);
357 if (!empty($settingValue) && $settingValue{0} != '[') {
358 $hasOldStyle = TRUE;
359 break;
360 }
361 }
362
363 if ($hasOldStyle) {
364 $message = new CRM_Utils_Check_Message(
365 __FUNCTION__,
366 ts('<a href="%1">Directories</a> may use absolute paths, relative paths, or variables. Absolute paths are more difficult to maintain. To maximize portability, consider using a variable in each directory (eg "<tt>[cms.root]</tt>" or "<tt>[civicrm.files]</tt>").',
367 array(1 => CRM_Utils_System::url('civicrm/admin/setting/path', "reset=1"))),
368 ts('Directory Paths: Make them portable'),
369 \Psr\Log\LogLevel::NOTICE,
370 'fa-server'
371 );
372 $messages[] = $message;
373 }
374
375 return $messages;
376 }
377
378
379 /**
380 * Checks if new versions are available
381 * @return array
382 */
383 public function checkVersion() {
384 $messages = array();
385 try {
386 $vc = new CRM_Utils_VersionCheck();
387 $vc->initialize();
388 }
389 catch (Exception $e) {
390 $messages[] = new CRM_Utils_Check_Message(
391 'checkVersionError',
392 ts('Directory %1 is not writable. Please change your file permissions.',
393 array(1 => dirname($vc->cacheFile))),
394 ts('Directory not writable'),
395 \Psr\Log\LogLevel::ERROR,
396 'fa-times-circle-o'
397 );
398 return $messages;
399 }
400
401 // Show a notice if the version_check job is disabled
402 if (empty($vc->cronJob['is_active'])) {
403 $args = empty($vc->cronJob['id']) ? array('reset' => 1) : array('reset' => 1, 'action' => 'update', 'id' => $vc->cronJob['id']);
404 $messages[] = new CRM_Utils_Check_Message(
405 'checkVersionDisabled',
406 ts('The check for new versions of CiviCRM has been disabled. <a %1>Re-enable the scheduled job</a> to receive important security update notifications.', array(1 => 'href="' . CRM_Utils_System::url('civicrm/admin/job', $args) . '"')),
407 ts('Update Check Disabled'),
408 \Psr\Log\LogLevel::NOTICE,
409 'fa-times-circle-o'
410 );
411 }
412
413 if ($vc->isInfoAvailable) {
414 $newerVersion = $vc->isNewerVersionAvailable();
415 if ($newerVersion['version']) {
416 $vInfo = array(
417 1 => $newerVersion['version'],
418 2 => $vc->localVersion,
419 );
420 // LTS = long-term support version
421 if ($newerVersion['status'] == 'lts') {
422 $vInfo[1] .= ' ' . ts('(long-term support)');
423 }
424
425 if ($newerVersion['upgrade'] == 'security') {
426 // Security
427 $severity = \Psr\Log\LogLevel::CRITICAL;
428 $title = ts('CiviCRM Security Update Required');
429 $message = ts('New security release %1 is available. The site is currently running %2.', $vInfo);
430 }
431 elseif ($newerVersion['status'] == 'eol') {
432 // Warn about EOL
433 $severity = \Psr\Log\LogLevel::WARNING;
434 $title = ts('CiviCRM Update Needed');
435 $message = ts('New version %1 is available. The site is currently running %2, which has reached its end of life.', $vInfo);
436 }
437 else {
438 // For most new versions, just make them notice
439 $severity = \Psr\Log\LogLevel::NOTICE;
440 $title = ts('CiviCRM Update Available');
441 $message = ts('New version %1 is available. The site is currently running %2.', $vInfo);
442 }
443 }
444 elseif (!empty($vc->cronJob['is_active'])) {
445 $vNum = $vc->localVersion;
446 // LTS = long-term support version
447 if ($newerVersion['status'] == 'lts') {
448 $vNum .= ' ' . ts('(long-term support)');
449 }
450
451 $severity = \Psr\Log\LogLevel::INFO;
452 $title = ts('CiviCRM Up-to-Date');
453 $message = ts('CiviCRM version %1 is up-to-date.', array(1 => $vNum));
454 }
455
456 if (!empty($message)) {
457 $messages[] = new CRM_Utils_Check_Message(
458 __FUNCTION__,
459 $message,
460 $title,
461 $severity,
462 'fa-cloud-upload'
463 );
464 }
465 }
466
467 return $messages;
468 }
469
470 /**
471 * Checks if extensions are set up properly
472 * @return array
473 */
474 public function checkExtensions() {
475 $messages = array();
476 $extensionSystem = CRM_Extension_System::singleton();
477 $mapper = $extensionSystem->getMapper();
478 $manager = $extensionSystem->getManager();
479
480 if ($extensionSystem->getDefaultContainer()) {
481 $basedir = $extensionSystem->getDefaultContainer()->baseDir;
482 }
483
484 if (empty($basedir)) {
485 // no extension directory
486 $messages[] = new CRM_Utils_Check_Message(
487 __FUNCTION__,
488 ts('Your extensions directory is not set. Click <a href="%1">here</a> to set the extensions directory.',
489 array(1 => CRM_Utils_System::url('civicrm/admin/setting/path', 'reset=1'))),
490 ts('Directory not writable'),
491 \Psr\Log\LogLevel::NOTICE,
492 'fa-plug'
493 );
494 return $messages;
495 }
496
497 if (!is_dir($basedir)) {
498 $messages[] = new CRM_Utils_Check_Message(
499 __FUNCTION__,
500 ts('Your extensions directory path points to %1, which is not a directory. Please check your file system.',
501 array(1 => $basedir)),
502 ts('Extensions directory incorrect'),
503 \Psr\Log\LogLevel::ERROR,
504 'fa-plug'
505 );
506 return $messages;
507 }
508 elseif (!is_writable($basedir)) {
509 $messages[] = new CRM_Utils_Check_Message(
510 __FUNCTION__,
511 ts('Directory %1 is not writable. Please change your file permissions.',
512 array(1 => $basedir)),
513 ts('Directory not writable'),
514 \Psr\Log\LogLevel::ERROR,
515 'fa-plug'
516 );
517 return $messages;
518 }
519
520 if (empty($extensionSystem->getDefaultContainer()->baseUrl)) {
521 $messages[] = new CRM_Utils_Check_Message(
522 __FUNCTION__,
523 ts('The extensions URL is not properly set. Please go to the <a href="%1">URL setting page</a> and correct it.',
524 array(1 => CRM_Utils_System::url('civicrm/admin/setting/url', 'reset=1'))),
525 ts('Extensions url missing'),
526 \Psr\Log\LogLevel::ERROR,
527 'fa-plug'
528 );
529 return $messages;
530 }
531
532 if (!$extensionSystem->getBrowser()->isEnabled()) {
533 $messages[] = new CRM_Utils_Check_Message(
534 __FUNCTION__,
535 ts('Not checking remote URL for extensions since ext_repo_url is set to false.'),
536 ts('Extensions check disabled'),
537 \Psr\Log\LogLevel::NOTICE,
538 'fa-plug'
539 );
540 return $messages;
541 }
542
543 try {
544 $remotes = $extensionSystem->getBrowser()->getExtensions();
545 }
546 catch (CRM_Extension_Exception $e) {
547 $messages[] = new CRM_Utils_Check_Message(
548 __FUNCTION__,
549 $e->getMessage(),
550 ts('Extension download error'),
551 \Psr\Log\LogLevel::ERROR,
552 'fa-plug'
553 );
554 return $messages;
555 }
556
557 if (!$remotes) {
558 // CRM-13141 There may not be any compatible extensions available for the requested CiviCRM version + CMS. If so, $extdir is empty so just return a notice.
559 $messages[] = new CRM_Utils_Check_Message(
560 __FUNCTION__,
561 ts('There are currently no extensions on the CiviCRM public extension directory which are compatible with version %1. If you want to install an extension which is not marked as compatible, you may be able to <a %2>download and install extensions manually</a> (depending on access to your web server).', array(
562 1 => CRM_Utils_System::majorVersion(),
563 2 => 'href="http://wiki.civicrm.org/confluence/display/CRMDOC/Extensions"',
564 )),
565 ts('No Extensions Available for this Version'),
566 \Psr\Log\LogLevel::NOTICE,
567 'fa-plug'
568 );
569 return $messages;
570 }
571
572 $keys = array_keys($manager->getStatuses());
573 sort($keys);
574 $updates = $errors = $okextensions = array();
575
576 foreach ($keys as $key) {
577 try {
578 $obj = $mapper->keyToInfo($key);
579 }
580 catch (CRM_Extension_Exception $ex) {
581 $errors[] = ts('Failed to read extension (%1). Please refresh the extension list.', array(1 => $key));
582 continue;
583 }
584 $row = CRM_Admin_Page_Extensions::createExtendedInfo($obj);
585 switch ($row['status']) {
586 case CRM_Extension_Manager::STATUS_INSTALLED_MISSING:
587 $errors[] = ts('%1 extension (%2) is installed but missing files.', array(1 => CRM_Utils_Array::value('label', $row), 2 => $key));
588 break;
589
590 case CRM_Extension_Manager::STATUS_INSTALLED:
591 if (!empty($remotes[$key]) && version_compare($row['version'], $remotes[$key]->version, '<')) {
592 $updates[] = ts('%1 (%2) version %3 is installed. <a %4>Upgrade to version %5</a>.', array(
593 1 => CRM_Utils_Array::value('label', $row),
594 2 => $key,
595 3 => $row['version'],
596 4 => 'href="' . CRM_Utils_System::url('civicrm/admin/extensions', "action=update&id=$key&key=$key") . '"',
597 5 => $remotes[$key]->version,
598 ));
599 }
600 else {
601 if (empty($row['label'])) {
602 $okextensions[] = $key;
603 }
604 else {
605 $okextensions[] = ts('%1 (%2) version %3', array(
606 1 => $row['label'],
607 2 => $key,
608 3 => $row['version'],
609 ));
610 }
611 }
612 break;
613 }
614 }
615
616 if (!$okextensions && !$updates && !$errors) {
617 $messages[] = new CRM_Utils_Check_Message(
618 'extensionsOk',
619 ts('No extensions installed. <a %1>Browse available extensions</a>.', array(
620 1 => 'href="' . CRM_Utils_System::url('civicrm/admin/extensions', 'reset=1') . '"',
621 )),
622 ts('Extensions'),
623 \Psr\Log\LogLevel::INFO,
624 'fa-plug'
625 );
626 }
627
628 if ($errors) {
629 $messages[] = new CRM_Utils_Check_Message(
630 __FUNCTION__,
631 '<ul><li>' . implode('</li><li>', $errors) . '</li></ul>',
632 ts('Extension Error'),
633 \Psr\Log\LogLevel::ERROR,
634 'fa-plug'
635 );
636 }
637
638 if ($updates) {
639 $messages[] = new CRM_Utils_Check_Message(
640 'extensionUpdates',
641 '<ul><li>' . implode('</li><li>', $updates) . '</li></ul>',
642 ts('Extension Update Available', array('plural' => '%count Extension Updates Available', 'count' => count($updates))),
643 \Psr\Log\LogLevel::WARNING,
644 'fa-plug'
645 );
646 }
647
648 if ($okextensions) {
649 if ($updates || $errors) {
650 $message = ts('1 extension is up-to-date:', array('plural' => '%count extensions are up-to-date:', 'count' => count($okextensions)));
651 }
652 else {
653 $message = ts('All extensions are up-to-date:');
654 }
655 $messages[] = new CRM_Utils_Check_Message(
656 'extensionsOk',
657 $message . '<ul><li>' . implode('</li><li>', $okextensions) . '</li></ul>',
658 ts('Extensions'),
659 \Psr\Log\LogLevel::INFO,
660 'fa-plug'
661 );
662 }
663
664 return $messages;
665 }
666
667
668 /**
669 * Checks if extensions are set up properly
670 * @return array
671 */
672 public function checkExtensionUpgrades() {
673 $messages = array();
674
675 if (CRM_Extension_Upgrades::hasPending()) {
676 $messages[] = new CRM_Utils_Check_Message(
677 __FUNCTION__,
678 ts('Extension upgrades are pending. Please visit <a href="%1">the upgrade page</a> to run them.',
679 array(1 => CRM_Utils_System::url('civicrm/admin/extensions/upgrade', 'reset=1'))),
680 ts('Run Extension Upgrades'),
681 \Psr\Log\LogLevel::ERROR,
682 'fa-plug'
683 );
684 }
685 return $messages;
686 }
687
688 /**
689 * Checks if CiviCRM database version is up-to-date
690 * @return array
691 */
692 public function checkDbVersion() {
693 $messages = array();
694 $dbVersion = CRM_Core_BAO_Domain::version();
695 $upgradeUrl = CRM_Utils_System::url("civicrm/upgrade", "reset=1");
696
697 if (!$dbVersion) {
698 // if db.ver missing
699 $messages[] = new CRM_Utils_Check_Message(
700 __FUNCTION__,
701 ts('Version information found to be missing in database. You will need to determine the correct version corresponding to your current database state.'),
702 ts('Database Version Missing'),
703 \Psr\Log\LogLevel::ERROR,
704 'fa-database'
705 );
706 }
707 elseif (!CRM_Utils_System::isVersionFormatValid($dbVersion)) {
708 $messages[] = new CRM_Utils_Check_Message(
709 __FUNCTION__,
710 ts('Database is marked with invalid version format. You may want to investigate this before you proceed further.'),
711 ts('Database Version Invalid'),
712 \Psr\Log\LogLevel::ERROR,
713 'fa-database'
714 );
715 }
716 elseif (stripos($dbVersion, 'upgrade')) {
717 // if db.ver indicates a partially upgraded db
718 $messages[] = new CRM_Utils_Check_Message(
719 __FUNCTION__,
720 ts('Database check failed - the database looks to have been partially upgraded. You must reload the database with the backup and try the <a href=\'%1\'>upgrade process</a> again.', array(1 => $upgradeUrl)),
721 ts('Database Partially Upgraded'),
722 \Psr\Log\LogLevel::ALERT,
723 'fa-database'
724 );
725 }
726 else {
727 $codeVersion = CRM_Utils_System::version();
728
729 // if db.ver < code.ver, time to upgrade
730 if (version_compare($dbVersion, $codeVersion) < 0) {
731 $messages[] = new CRM_Utils_Check_Message(
732 __FUNCTION__,
733 ts('New codebase version detected. You must visit <a href=\'%1\'>upgrade screen</a> to upgrade the database.', array(1 => $upgradeUrl)),
734 ts('Database Upgrade Required'),
735 \Psr\Log\LogLevel::ALERT,
736 'fa-database'
737 );
738 }
739
740 // if db.ver > code.ver, sth really wrong
741 if (version_compare($dbVersion, $codeVersion) > 0) {
742 $messages[] = new CRM_Utils_Check_Message(
743 __FUNCTION__,
744 ts('Your database is marked with an unexpected version number: %1. The v%2 codebase may not be compatible with your database state.
745 You will need to determine the correct version corresponding to your current database state. You may want to revert to the codebase
746 you were using until you resolve this problem.<br/>OR if this is a manual install from git, you might want to fix civicrm-version.php file.',
747 array(1 => $dbVersion, 2 => $codeVersion)
748 ),
749 ts('Database In Unexpected Version'),
750 \Psr\Log\LogLevel::ERROR,
751 'fa-database'
752 );
753 }
754 }
755
756 return $messages;
757 }
758
759 /**
760 * ensure that all CiviCRM tables are InnoDB
761 * @return array
762 */
763 public function checkDbEngine() {
764 $messages = array();
765
766 if (CRM_Core_DAO::isDBMyISAM(150)) {
767 $messages[] = new CRM_Utils_Check_Message(
768 __FUNCTION__,
769 ts('Your database is configured to use the MyISAM database engine. CiviCRM requires InnoDB. You will need to convert any MyISAM tables in your database to InnoDB. Using MyISAM tables will result in data integrity issues.'),
770 ts('MyISAM Database Engine'),
771 \Psr\Log\LogLevel::ERROR,
772 'fa-database'
773 );
774 }
775 return $messages;
776 }
777
778 }