mirror of
https://github.com/silverstripe/silverstripe-environmentcheck
synced 2024-10-22 17:05:40 +02:00
Merge pull request #2 from chillu/new-checks
New checks, some restructuring
This commit is contained in:
commit
b20867aa77
23
README.md
23
README.md
@ -14,6 +14,29 @@ Almost, but not really. Environment checks differ from unit tests in two importa
|
|||||||
* **They test environment specific settings.** Unit tests are designed to use dummy data and mock interfaces to external system. Environment checks check the real systems and data that the given environment is actually connected to.
|
* **They test environment specific settings.** Unit tests are designed to use dummy data and mock interfaces to external system. Environment checks check the real systems and data that the given environment is actually connected to.
|
||||||
* **They can't modify data.** Because these checks will run using production databases, they can't go modifying the data in there. This is the biggest reason why we haven't used the same base class as a unit test for writing environment checks - we wanted to make it impossible to accidentally plug a unit test into the environment checker!
|
* **They can't modify data.** Because these checks will run using production databases, they can't go modifying the data in there. This is the biggest reason why we haven't used the same base class as a unit test for writing environment checks - we wanted to make it impossible to accidentally plug a unit test into the environment checker!
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Register checks in your own `_config.php` - see the `_config.php` in this module for some defaults.
|
||||||
|
|
||||||
|
:::php
|
||||||
|
EnvironmentCheckSuite::register('health', 'DatabaseCheck', "Can we connect to the database?");
|
||||||
|
EnvironmentCheckSuite::register('check', 'URLCheck("")', "Is the homepage accessible?");
|
||||||
|
|
||||||
|
## Available checks
|
||||||
|
|
||||||
|
* `DatabaseCheck`: Check that the connection to the database is working, by looking for records in some table. By default, Member will be checked.
|
||||||
|
* `URLCheck`: Check that a given URL is functioning, by default, the homepage.
|
||||||
|
* `HasFunctionCheck`: Check that the given function exists.
|
||||||
|
This can be used to check that PHP modules or features are installed.
|
||||||
|
* `HasClassCheck`: Check that the given class exists.
|
||||||
|
This can be used to check that PHP modules or features are installed.
|
||||||
|
* `FileWriteableCheck`: Check that the given file is writeable.
|
||||||
|
* `FileAgeCheck`: Checks for the maximum age of one or more files or folders.
|
||||||
|
Useful for files which should be frequently auto-generated,
|
||||||
|
like static caches, as well as for backup files and folders.
|
||||||
|
* `ExternalURLCheck`: Checks that one or more URLs are reachable via HTTP.
|
||||||
|
* `SMTPConnectCheck`: Checks if the SMTP connection configured through PHP.ini works as expected.
|
||||||
|
|
||||||
## Adding more checks
|
## Adding more checks
|
||||||
|
|
||||||
To add more checks, you should put additional `EnvironmentCheckSuite::register` calls into your `_config.php`. See the `_config.php` file of this module for examples.
|
To add more checks, you should put additional `EnvironmentCheckSuite::register` calls into your `_config.php`. See the `_config.php` file of this module for examples.
|
||||||
|
34
_config.php
34
_config.php
@ -1,25 +1,25 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
// These power dev/health, which can be used by load balancers and other such systems
|
// // These power dev/health, which can be used by load balancers and other such systems
|
||||||
EnvironmentCheckSuite::register('health', 'DatabaseCheck');
|
// EnvironmentCheckSuite::register('health', 'DatabaseCheck');
|
||||||
|
|
||||||
// These power dev/check, which is used for diagnostics and for deployment
|
// // These power dev/check, which is used for diagnostics and for deployment
|
||||||
EnvironmentCheckSuite::register('check', 'DatabaseCheck("Member")', "Is the database accessible?");
|
// EnvironmentCheckSuite::register('check', 'DatabaseCheck("Member")', "Is the database accessible?");
|
||||||
EnvironmentCheckSuite::register('check', 'URLCheck("")', "Is the homepage accessible?");
|
// EnvironmentCheckSuite::register('check', 'URLCheck("")', "Is the homepage accessible?");
|
||||||
|
|
||||||
EnvironmentCheckSuite::register('check', 'HasFunctionCheck("curl_init")', "Does PHP have CURL support?");
|
// EnvironmentCheckSuite::register('check', 'HasFunctionCheck("curl_init")', "Does PHP have CURL support?");
|
||||||
EnvironmentCheckSuite::register('check', 'HasFunctionCheck("imagecreatetruecolor")', "Does PHP have GD2 support?");
|
// EnvironmentCheckSuite::register('check', 'HasFunctionCheck("imagecreatetruecolor")', "Does PHP have GD2 support?");
|
||||||
EnvironmentCheckSuite::register('check', 'HasFunctionCheck("xml_set_object")', "Does PHP have XML support?");
|
// EnvironmentCheckSuite::register('check', 'HasFunctionCheck("xml_set_object")', "Does PHP have XML support?");
|
||||||
EnvironmentCheckSuite::register('check', 'HasFunctionCheck("token_get_all")', "Does PHP have tokenizer support?");
|
// EnvironmentCheckSuite::register('check', 'HasFunctionCheck("token_get_all")', "Does PHP have tokenizer support?");
|
||||||
EnvironmentCheckSuite::register('check', 'HasFunctionCheck("iconv")', "Does PHP have iconv support?");
|
// EnvironmentCheckSuite::register('check', 'HasFunctionCheck("iconv")', "Does PHP have iconv support?");
|
||||||
EnvironmentCheckSuite::register('check', 'HasFunctionCheck("hash")', "Does PHP have hash support?");
|
// EnvironmentCheckSuite::register('check', 'HasFunctionCheck("hash")', "Does PHP have hash support?");
|
||||||
EnvironmentCheckSuite::register('check', 'HasFunctionCheck("session_start")', "Does PHP have session support?");
|
// EnvironmentCheckSuite::register('check', 'HasFunctionCheck("session_start")', "Does PHP have session support?");
|
||||||
EnvironmentCheckSuite::register('check', 'HasClassCheck("DOMDocument")', "Does PHP have DOMDocument support?");
|
// EnvironmentCheckSuite::register('check', 'HasClassCheck("DOMDocument")', "Does PHP have DOMDocument support?");
|
||||||
|
|
||||||
EnvironmentCheckSuite::register('check', 'FileWriteableCheck("assets")', "Is assets/ writeable?");
|
// EnvironmentCheckSuite::register('check', 'FileWriteableCheck("assets")', "Is assets/ writeable?");
|
||||||
EnvironmentCheckSuite::register('check', 'FileWriteableCheck("' . TEMP_FOLDER . '")', "Is the temp folder writeable?");
|
// EnvironmentCheckSuite::register('check', 'FileWriteableCheck("' . TEMP_FOLDER . '")', "Is the temp folder writeable?");
|
||||||
|
|
||||||
Director::addRules(100, array(
|
Director::addRules(100, array(
|
||||||
'dev/health' => 'DevHealth',
|
'dev/health' => 'DevHealthController',
|
||||||
'dev/check' => 'DevCheck',
|
'dev/check' => 'DevCheckController',
|
||||||
));
|
));
|
@ -1,157 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This file contains a number of default environment checks that you can use.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check that the connection to the database is working, by looking for records in some table.
|
|
||||||
* By default, Member will be checked.
|
|
||||||
*
|
|
||||||
* @param $checkTable The table that will be checked.
|
|
||||||
*/
|
|
||||||
class DatabaseCheck implements EnvironmentCheck {
|
|
||||||
protected $checkTable;
|
|
||||||
|
|
||||||
function __construct($checkTable = "Member") {
|
|
||||||
$this->checkTable = $checkTable;
|
|
||||||
}
|
|
||||||
|
|
||||||
function check() {
|
|
||||||
$count = DB::query("SELECT COUNT(*) FROM \"$this->checkTable\"")->value();
|
|
||||||
|
|
||||||
if($count > 0) {
|
|
||||||
return array(EnvironmentCheck::OK, "");
|
|
||||||
} else {
|
|
||||||
return array(EnvironmentCheck::WARNING, "$this->checkTable queried ok but has no records");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check that a given URL is functioning, by default, the homepage.
|
|
||||||
*
|
|
||||||
* Note that Director::test() will be used rather than a CURL check.
|
|
||||||
*/
|
|
||||||
class URLCheck implements EnvironmentCheck {
|
|
||||||
protected $url;
|
|
||||||
protected $testString;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @param $url The URL to check, relative to the site. "" is the homepage.
|
|
||||||
* @param $testString A piece of text to optionally search for in the homepage HTML. If omitted, no such check is made.
|
|
||||||
*/
|
|
||||||
function __construct($url = "", $testString = "") {
|
|
||||||
$this->url = $url;
|
|
||||||
$this->testString = $testString;
|
|
||||||
}
|
|
||||||
|
|
||||||
function check() {
|
|
||||||
$response = Director::test($this->url);
|
|
||||||
|
|
||||||
if($response->getStatusCode() != 200) {
|
|
||||||
return array(EnvironmentCheck::ERROR, "Homepage requested and returned HTTP " . $response->getStatusCode() . " response");
|
|
||||||
|
|
||||||
} else if($this->testString && (strpos($response->getBody(), $this->testString) === false)) {
|
|
||||||
return array(EnvironmentCheck::WARNING, "Homepage requested ok but '$testString' not found.");
|
|
||||||
|
|
||||||
} else {
|
|
||||||
return array(EnvironmentCheck::OK, "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check that the given function exists.
|
|
||||||
* This can be used to check that PHP modules or features are installed.
|
|
||||||
* @param $functionName The name of the function to look for.
|
|
||||||
*/
|
|
||||||
class HasFunctionCheck implements EnvironmentCheck {
|
|
||||||
protected $functionName;
|
|
||||||
|
|
||||||
function __construct($functionName) {
|
|
||||||
$this->functionName = $functionName;
|
|
||||||
}
|
|
||||||
|
|
||||||
function check() {
|
|
||||||
if(function_exists($this->functionName)) return array(EnvironmentCheck::OK, $this->functionName.'() exists');
|
|
||||||
else return array(EnvironmentCheck::ERROR, $this->functionName.'() doesn\'t exist');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check that the given class exists.
|
|
||||||
* This can be used to check that PHP modules or features are installed.
|
|
||||||
* @param $className The name of the class to look for.
|
|
||||||
*/
|
|
||||||
class HasClassCheck implements EnvironmentCheck {
|
|
||||||
protected $className;
|
|
||||||
|
|
||||||
function __construct($className) {
|
|
||||||
$this->className = $className;
|
|
||||||
}
|
|
||||||
|
|
||||||
function check() {
|
|
||||||
if(class_exists($this->className)) return array(EnvironmentCheck::OK, 'Class ' . $this->className.' exists');
|
|
||||||
else return array(EnvironmentCheck::ERROR, 'Class ' . $this->className.' doesn\'t exist');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check that the given file is writeable.
|
|
||||||
* This can be used to check that the environment doesn't have permission set-up errors.
|
|
||||||
* @param $path The full path. If a relative path, it will relative to the BASE_PATH
|
|
||||||
*/
|
|
||||||
class FileWriteableCheck implements EnvironmentCheck {
|
|
||||||
protected $path;
|
|
||||||
|
|
||||||
function __construct($path) {
|
|
||||||
$this->path = $path;
|
|
||||||
}
|
|
||||||
|
|
||||||
function check() {
|
|
||||||
if($this->path[0] == '/') $filename = $this->path;
|
|
||||||
else $filename = BASE_PATH . DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $this->path);
|
|
||||||
|
|
||||||
if(file_exists($filename)) $isWriteable = is_writeable($filename);
|
|
||||||
else $isWriteable = is_writeable(dirname($filename));
|
|
||||||
|
|
||||||
if(!$isWriteable) {
|
|
||||||
if(function_exists('posix_getgroups')) {
|
|
||||||
$userID = posix_geteuid();
|
|
||||||
$user = posix_getpwuid($userID);
|
|
||||||
|
|
||||||
$currentOwnerID = fileowner(file_exists($filename) ? $filename : dirname($filename) );
|
|
||||||
$currentOwner = posix_getpwuid($currentOwnerID);
|
|
||||||
|
|
||||||
$message = "User '$user[name]' needs to be able to write to this file:\n$filename\n\nThe file is currently owned by '$currentOwner[name]'. ";
|
|
||||||
|
|
||||||
if($user['name'] == $currentOwner['name']) {
|
|
||||||
$message .= "We recommend that you make the file writeable.";
|
|
||||||
} else {
|
|
||||||
|
|
||||||
$groups = posix_getgroups();
|
|
||||||
$groupList = array();
|
|
||||||
foreach($groups as $group) {
|
|
||||||
$groupInfo = posix_getgrgid($group);
|
|
||||||
if(in_array($currentOwner['name'], $groupInfo['members'])) $groupList[] = $groupInfo['name'];
|
|
||||||
}
|
|
||||||
if($groupList) {
|
|
||||||
$message .= " We recommend that you make the file group-writeable and change the group to one of these groups:\n - ". implode("\n - ", $groupList)
|
|
||||||
. "\n\nFor example:\nchmod g+w $filename\nchgrp " . $groupList[0] . " $filename";
|
|
||||||
} else {
|
|
||||||
$message .= " There is no user-group that contains both the web-server user and the owner of this file. Change the ownership of the file, create a new group, or temporarily make the file writeable by everyone during the install process.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
$message .= "The webserver user needs to be able to write to this file:\n$filename";
|
|
||||||
}
|
|
||||||
|
|
||||||
return array(EnvironmentCheck::ERROR, $message);
|
|
||||||
}
|
|
||||||
|
|
||||||
return array(EnvironmentCheck::OK,'');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
class DevCheck extends Controller {
|
class DevCheckController extends Controller {
|
||||||
function index() {
|
function index() {
|
||||||
if(!Permission::check("ADMIN")) return Security::permissionFailure();
|
if(!Permission::check("ADMIN")) return Security::permissionFailure();
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
class DevHealth extends Controller {
|
class DevHealthController extends Controller {
|
||||||
function index() {
|
function index() {
|
||||||
$e = new EnvironmentChecker('health', 'Site health');
|
$e = new EnvironmentChecker('health', 'Site health');
|
||||||
$e->setErrorCode(404);
|
$e->setErrorCode(404);
|
@ -28,148 +28,3 @@ interface EnvironmentCheck {
|
|||||||
function check();
|
function check();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a suite of environment checks.
|
|
||||||
* Also has a register for assigning environment checks to named instances of EnvironmentCheckSuite
|
|
||||||
*
|
|
||||||
* Usage:
|
|
||||||
* EnvironmentCheckSuite::register('health', 'MyHealthCheck');
|
|
||||||
*
|
|
||||||
* $result = EnvironmentCheckSuite::inst('health')->run();
|
|
||||||
*/
|
|
||||||
class EnvironmentCheckSuite {
|
|
||||||
protected $checks = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run this test suite
|
|
||||||
* @return The result code of the worst result.
|
|
||||||
*/
|
|
||||||
public function run() {
|
|
||||||
$worstResult = 0;
|
|
||||||
|
|
||||||
$result = new EnvironmentCheckSuiteResult;
|
|
||||||
foreach($this->checkInstances() as $check) {
|
|
||||||
list($checkClass, $checkTitle) = $check;
|
|
||||||
try {
|
|
||||||
list($status, $message) = $checkClass->check();
|
|
||||||
// If the check fails, register that as an error
|
|
||||||
} catch(Exception $e) {
|
|
||||||
$status = EnvironmentCheck::ERROR;
|
|
||||||
$message = $e->getMessage();
|
|
||||||
}
|
|
||||||
$result->addResult($status, $message, $checkTitle);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get instances of all the environment checks
|
|
||||||
*/
|
|
||||||
protected function checkInstances() {
|
|
||||||
$output = array();
|
|
||||||
foreach($this->checks as $check) {
|
|
||||||
list($checkClass, $checkTitle) = $check;
|
|
||||||
if(is_string($checkClass)) {
|
|
||||||
$checkInst = Object::create_from_string($checkClass);
|
|
||||||
if($checkInst instanceof EnvironmentCheck) {
|
|
||||||
$output[] = array($checkInst, $checkTitle);
|
|
||||||
} else {
|
|
||||||
throw new InvalidArgumentException("Bad EnvironmentCheck: '$checkClass' - the named class doesn't implement EnvironmentCheck");
|
|
||||||
}
|
|
||||||
} else if($checkClass instanceof EnvironmentCheck) {
|
|
||||||
$output[] = array($checkClass, $checkTitle);
|
|
||||||
} else {
|
|
||||||
throw new InvalidArgumentException("Bad EnvironmentCheck: " . var_export($check, true));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $output;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a check to this suite.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public function push($check, $title = null) {
|
|
||||||
if(!$title) {
|
|
||||||
$title = is_string($check) ? $check : get_class($check);
|
|
||||||
}
|
|
||||||
$this->checks[] = array($check, $title);
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
protected static $instances = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a named instance of EnvironmentCheckSuite.
|
|
||||||
*/
|
|
||||||
static function inst($name) {
|
|
||||||
if(!isset(self::$instances[$name])) self::$instances[$name] = new EnvironmentCheckSuite();
|
|
||||||
return self::$instances[$name];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a check against the named check suite
|
|
||||||
*/
|
|
||||||
static function register($name, $check, $title = null) {
|
|
||||||
self::inst($name)->push($check, $title);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A single set of results from running an EnvironmentCheckSuite
|
|
||||||
*/
|
|
||||||
class EnvironmentCheckSuiteResult extends ViewableData {
|
|
||||||
protected $details, $worst = 0;
|
|
||||||
|
|
||||||
function __construct() {
|
|
||||||
parent::__construct();
|
|
||||||
$this->details = new DataObjectSet();
|
|
||||||
}
|
|
||||||
|
|
||||||
function addResult($status, $message, $checkIdentifier) {
|
|
||||||
$this->details->push(new ArrayData(array(
|
|
||||||
'Check' => $checkIdentifier,
|
|
||||||
'Status' => $this->statusText($status),
|
|
||||||
'Message' => $message,
|
|
||||||
)));
|
|
||||||
|
|
||||||
$this->worst = max($this->worst, $status);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if there are no ERRORs, only WARNINGs or OK
|
|
||||||
*/
|
|
||||||
function ShouldPass() {
|
|
||||||
return $this->worst <= EnvironmentCheck::WARNING;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns overall (i.e. worst) status as a string.
|
|
||||||
*/
|
|
||||||
function Status() {
|
|
||||||
return $this->statusText($this->worst);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns detailed status information about each check
|
|
||||||
*/
|
|
||||||
function Details() {
|
|
||||||
return $this->details;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a text version of a status code
|
|
||||||
*/
|
|
||||||
protected function statusText($status) {
|
|
||||||
switch($status) {
|
|
||||||
case EnvironmentCheck::ERROR: return "ERROR";
|
|
||||||
case EnvironmentCheck::WARNING: return "WARNING";
|
|
||||||
case EnvironmentCheck::OK: return "OK";
|
|
||||||
case 0: return "NO CHECKS";
|
|
||||||
default: throw new InvalidArgumentException("Bad environment check status '$status'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
148
code/EnvironmentCheckSuite.php
Normal file
148
code/EnvironmentCheckSuite.php
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Represents a suite of environment checks.
|
||||||
|
* Also has a register for assigning environment checks to named instances of EnvironmentCheckSuite
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* EnvironmentCheckSuite::register('health', 'MyHealthCheck');
|
||||||
|
*
|
||||||
|
* $result = EnvironmentCheckSuite::inst('health')->run();
|
||||||
|
*/
|
||||||
|
class EnvironmentCheckSuite {
|
||||||
|
protected $checks = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run this test suite
|
||||||
|
* @return The result code of the worst result.
|
||||||
|
*/
|
||||||
|
public function run() {
|
||||||
|
$worstResult = 0;
|
||||||
|
|
||||||
|
$result = new EnvironmentCheckSuiteResult;
|
||||||
|
foreach($this->checkInstances() as $check) {
|
||||||
|
list($checkClass, $checkTitle) = $check;
|
||||||
|
try {
|
||||||
|
list($status, $message) = $checkClass->check();
|
||||||
|
// If the check fails, register that as an error
|
||||||
|
} catch(Exception $e) {
|
||||||
|
$status = EnvironmentCheck::ERROR;
|
||||||
|
$message = $e->getMessage();
|
||||||
|
}
|
||||||
|
$result->addResult($status, $message, $checkTitle);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get instances of all the environment checks
|
||||||
|
*/
|
||||||
|
protected function checkInstances() {
|
||||||
|
$output = array();
|
||||||
|
foreach($this->checks as $check) {
|
||||||
|
list($checkClass, $checkTitle) = $check;
|
||||||
|
if(is_string($checkClass)) {
|
||||||
|
$checkInst = Object::create_from_string($checkClass);
|
||||||
|
if($checkInst instanceof EnvironmentCheck) {
|
||||||
|
$output[] = array($checkInst, $checkTitle);
|
||||||
|
} else {
|
||||||
|
throw new InvalidArgumentException("Bad EnvironmentCheck: '$checkClass' - the named class doesn't implement EnvironmentCheck");
|
||||||
|
}
|
||||||
|
} else if($checkClass instanceof EnvironmentCheck) {
|
||||||
|
$output[] = array($checkClass, $checkTitle);
|
||||||
|
} else {
|
||||||
|
throw new InvalidArgumentException("Bad EnvironmentCheck: " . var_export($check, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a check to this suite.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function push($check, $title = null) {
|
||||||
|
if(!$title) {
|
||||||
|
$title = is_string($check) ? $check : get_class($check);
|
||||||
|
}
|
||||||
|
$this->checks[] = array($check, $title);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
protected static $instances = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a named instance of EnvironmentCheckSuite.
|
||||||
|
*/
|
||||||
|
static function inst($name) {
|
||||||
|
if(!isset(self::$instances[$name])) self::$instances[$name] = new EnvironmentCheckSuite();
|
||||||
|
return self::$instances[$name];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a check against the named check suite.
|
||||||
|
*
|
||||||
|
* @param String|Array
|
||||||
|
*/
|
||||||
|
static function register($names, $check, $title = null) {
|
||||||
|
if(!is_array($names)) $names = array($names);
|
||||||
|
foreach($names as $name) self::inst($name)->push($check, $title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A single set of results from running an EnvironmentCheckSuite
|
||||||
|
*/
|
||||||
|
class EnvironmentCheckSuiteResult extends ViewableData {
|
||||||
|
protected $details, $worst = 0;
|
||||||
|
|
||||||
|
function __construct() {
|
||||||
|
parent::__construct();
|
||||||
|
$this->details = new DataObjectSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
function addResult($status, $message, $checkIdentifier) {
|
||||||
|
$this->details->push(new ArrayData(array(
|
||||||
|
'Check' => $checkIdentifier,
|
||||||
|
'Status' => $this->statusText($status),
|
||||||
|
'Message' => $message,
|
||||||
|
)));
|
||||||
|
|
||||||
|
$this->worst = max($this->worst, $status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if there are no ERRORs, only WARNINGs or OK
|
||||||
|
*/
|
||||||
|
function ShouldPass() {
|
||||||
|
return $this->worst <= EnvironmentCheck::WARNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns overall (i.e. worst) status as a string.
|
||||||
|
*/
|
||||||
|
function Status() {
|
||||||
|
return $this->statusText($this->worst);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns detailed status information about each check
|
||||||
|
*/
|
||||||
|
function Details() {
|
||||||
|
return $this->details;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a text version of a status code
|
||||||
|
*/
|
||||||
|
protected function statusText($status) {
|
||||||
|
switch($status) {
|
||||||
|
case EnvironmentCheck::ERROR: return "ERROR";
|
||||||
|
case EnvironmentCheck::WARNING: return "WARNING";
|
||||||
|
case EnvironmentCheck::OK: return "OK";
|
||||||
|
case 0: return "NO CHECKS";
|
||||||
|
default: throw new InvalidArgumentException("Bad environment check status '$status'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
29
code/checks/DatabaseCheck.php
Normal file
29
code/checks/DatabaseCheck.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file contains a number of default environment checks that you can use.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check that the connection to the database is working, by looking for records in some table.
|
||||||
|
* By default, Member will be checked.
|
||||||
|
*
|
||||||
|
* @param $checkTable The table that will be checked.
|
||||||
|
*/
|
||||||
|
class DatabaseCheck implements EnvironmentCheck {
|
||||||
|
protected $checkTable;
|
||||||
|
|
||||||
|
function __construct($checkTable = "Member") {
|
||||||
|
$this->checkTable = $checkTable;
|
||||||
|
}
|
||||||
|
|
||||||
|
function check() {
|
||||||
|
$count = DB::query("SELECT COUNT(*) FROM \"$this->checkTable\"")->value();
|
||||||
|
|
||||||
|
if($count > 0) {
|
||||||
|
return array(EnvironmentCheck::OK, "");
|
||||||
|
} else {
|
||||||
|
return array(EnvironmentCheck::WARNING, "$this->checkTable queried ok but has no records");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
110
code/checks/ExternalURLCheck.php
Normal file
110
code/checks/ExternalURLCheck.php
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Checks that one or more URLs are reachable via HTTP.
|
||||||
|
* Note that the HTTP connectivity can just be verified from the server to the remote URL,
|
||||||
|
* it can still fail if the URL in question is requested by the client, e.g. through an iframe.
|
||||||
|
*
|
||||||
|
* Requires curl to present, so ensure to check it before with the following:
|
||||||
|
* <code>EnvironmentCheckSuite::register('check', 'HasFunctionCheck("curl_init")', "Does PHP have CURL support?");</code>
|
||||||
|
*/
|
||||||
|
class ExternalURLCheck implements EnvironmentCheck {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $urls = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Int Timeout in seconds.
|
||||||
|
*/
|
||||||
|
protected $timeout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param String Space separated list of absolute URLs
|
||||||
|
* (can't be an array as we're using Object::create() with strings for the constructor signature)
|
||||||
|
*/
|
||||||
|
function __construct($urls, $timeout = 15) {
|
||||||
|
if($urls) $this->urls = explode(' ', $urls);
|
||||||
|
$this->timeout = $timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
function check() {
|
||||||
|
$urls = $this->getURLs();
|
||||||
|
|
||||||
|
$chs = array();
|
||||||
|
foreach($urls as $url) {
|
||||||
|
$ch = curl_init();
|
||||||
|
$chs[] = $ch;
|
||||||
|
curl_setopt_array($ch, $this->getCurlOpts($url));
|
||||||
|
}
|
||||||
|
// Parallel execution for faster performance
|
||||||
|
$mh = curl_multi_init();
|
||||||
|
foreach($chs as $ch) curl_multi_add_handle($mh,$ch);
|
||||||
|
|
||||||
|
$active = null;
|
||||||
|
// Execute the handles
|
||||||
|
do {
|
||||||
|
$mrc = curl_multi_exec($mh, $active);
|
||||||
|
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
|
||||||
|
|
||||||
|
while ($active && $mrc == CURLM_OK) {
|
||||||
|
if (curl_multi_select($mh) != -1) {
|
||||||
|
do {
|
||||||
|
$mrc = curl_multi_exec($mh, $active);
|
||||||
|
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$hasError = false;
|
||||||
|
$msgs = array();
|
||||||
|
foreach($chs as $ch) {
|
||||||
|
$url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
|
||||||
|
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||||
|
if(curl_errno($ch) || $code >= 400) {
|
||||||
|
$hasError = true;
|
||||||
|
$msgs[] = sprintf(
|
||||||
|
'Error retrieving "%s": %s (Code: %s)',
|
||||||
|
$url,
|
||||||
|
curl_error($ch),
|
||||||
|
$code
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$msgs[] = sprintf(
|
||||||
|
'Success retrieving "%s" (Code: %s)',
|
||||||
|
$url,
|
||||||
|
$code
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close the handles
|
||||||
|
foreach($chs as $ch) curl_multi_remove_handle($mh, $ch);
|
||||||
|
curl_multi_close($mh);
|
||||||
|
|
||||||
|
if($hasError) {
|
||||||
|
return array(EnvironmentCheck::ERROR, implode(', ', $msgs));
|
||||||
|
} else {
|
||||||
|
return array(EnvironmentCheck::OK, implode(', ', $msgs));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Array
|
||||||
|
*/
|
||||||
|
protected function getCurlOpts($url) {
|
||||||
|
return array(
|
||||||
|
CURLOPT_URL => $url,
|
||||||
|
CURLOPT_HEADER => 0,
|
||||||
|
CURLOPT_RETURNTRANSFER => 1,
|
||||||
|
CURLOPT_FAILONERROR => 1,
|
||||||
|
CURLOPT_TIMEOUT => $this->timeout,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Array
|
||||||
|
*/
|
||||||
|
protected function getURLs() {
|
||||||
|
return $this->urls;
|
||||||
|
}
|
||||||
|
}
|
106
code/checks/FileAgeCheck.php
Normal file
106
code/checks/FileAgeCheck.php
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Checks for the maximum age of one or more files or folders.
|
||||||
|
* Useful for files which should be frequently auto-generated,
|
||||||
|
* like static caches, as well as for backup files and folders.
|
||||||
|
* Does NOT check for existence of a file (will silently fail).
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
* // Checks that Requirements::combine_files() has regenerated files in the last 24h
|
||||||
|
* EnvironmentCheckSuite::register(
|
||||||
|
* 'check',
|
||||||
|
* 'FileAgeCheck("' . ASSETS_PATH . '/_combined_files/*.js' . '", "-1 day", '>', " . FileAgeCheck::CHECK_ALL) . "'
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* // Checks that at least one backup folder has been created in the last 24h
|
||||||
|
* EnvironmentCheckSuite::register(
|
||||||
|
* 'check',
|
||||||
|
* 'FileAgeCheck("' . BASE_PATH . '/../backups/*' . '", "-1 day", '>', " . FileAgeCheck::CHECK_SINGLE) . "'
|
||||||
|
* );
|
||||||
|
*/
|
||||||
|
class FileAgeCheck implements EnvironmentCheck {
|
||||||
|
|
||||||
|
const CHECK_SINGLE = 1;
|
||||||
|
|
||||||
|
const CHECK_ALL = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var String Absolute path to a file or folder, compatible with glob().
|
||||||
|
*/
|
||||||
|
protected $path;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var String strtotime() compatible relative date specification.
|
||||||
|
*/
|
||||||
|
protected $relativeAge;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var String The function to use for checking file age,
|
||||||
|
* so filemtime(), filectime() or fileatime().
|
||||||
|
*/
|
||||||
|
protected $checkFn;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Int Constant, check for a single file to match age criteria, or all of them.
|
||||||
|
*/
|
||||||
|
protected $checkType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var String Either '>' or '<'.
|
||||||
|
*/
|
||||||
|
protected $compareOperand;
|
||||||
|
|
||||||
|
function __construct($path, $relativeAge, $compareOperand = '>', $checkType = null, $checkFn = 'filemtime') {
|
||||||
|
$this->path = $path;
|
||||||
|
$this->relativeAge = $relativeAge;
|
||||||
|
$this->checkFn = $checkFn;
|
||||||
|
$this->checkType = ($checkType) ? $checkType : self::CHECK_SINGLE;
|
||||||
|
$this->compareOperand = $compareOperand;
|
||||||
|
}
|
||||||
|
|
||||||
|
function check() {
|
||||||
|
$cutoffTime = strtotime($this->relativeAge, SS_Datetime::now()->Format('U'));
|
||||||
|
$files = $this->getFiles();
|
||||||
|
$invalidFiles = array();
|
||||||
|
$validFiles = array();
|
||||||
|
$checkFn = $this->checkFn;
|
||||||
|
$allValid = true;
|
||||||
|
if($files) foreach($files as $file) {
|
||||||
|
$fileTime = $checkFn($file);
|
||||||
|
$valid = ($this->compareOperand == '>') ? ($fileTime >= $cutoffTime) : ($fileTime <= $cutoffTime);
|
||||||
|
if($valid) {
|
||||||
|
$validFiles[] = $file;
|
||||||
|
} else {
|
||||||
|
$invalidFiles[] = $file;
|
||||||
|
if($this->checkType == self::CHECK_ALL) {
|
||||||
|
return array(
|
||||||
|
EnvironmentCheck::ERROR,
|
||||||
|
sprintf(
|
||||||
|
'File "%s" doesn\'t match age check (compare %s: %s, actual: %s)',
|
||||||
|
$file, $this->compareOperand, date('c', $cutoffTime), date('c', $fileTime)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If at least one file was valid, count as passed
|
||||||
|
if($this->checkType == self::CHECK_SINGLE && count($invalidFiles) < count($files)) {
|
||||||
|
return array(EnvironmentCheck::OK, '');
|
||||||
|
} else {
|
||||||
|
return array(
|
||||||
|
EnvironmentCheck::ERROR,
|
||||||
|
sprintf('No files matched criteria (%s %s)', $this->compareOperand, date('c', $cutoffTime))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Array Of absolute file paths
|
||||||
|
*/
|
||||||
|
protected function getFiles() {
|
||||||
|
return glob($this->path);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
58
code/checks/FileWriteableCheck.php
Normal file
58
code/checks/FileWriteableCheck.php
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Check that the given file is writeable.
|
||||||
|
* This can be used to check that the environment doesn't have permission set-up errors.
|
||||||
|
* @param $path The full path. If a relative path, it will relative to the BASE_PATH
|
||||||
|
*/
|
||||||
|
class FileWriteableCheck implements EnvironmentCheck {
|
||||||
|
protected $path;
|
||||||
|
|
||||||
|
function __construct($path) {
|
||||||
|
$this->path = $path;
|
||||||
|
}
|
||||||
|
|
||||||
|
function check() {
|
||||||
|
if($this->path[0] == '/') $filename = $this->path;
|
||||||
|
else $filename = BASE_PATH . DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $this->path);
|
||||||
|
|
||||||
|
if(file_exists($filename)) $isWriteable = is_writeable($filename);
|
||||||
|
else $isWriteable = is_writeable(dirname($filename));
|
||||||
|
|
||||||
|
if(!$isWriteable) {
|
||||||
|
if(function_exists('posix_getgroups')) {
|
||||||
|
$userID = posix_geteuid();
|
||||||
|
$user = posix_getpwuid($userID);
|
||||||
|
|
||||||
|
$currentOwnerID = fileowner(file_exists($filename) ? $filename : dirname($filename) );
|
||||||
|
$currentOwner = posix_getpwuid($currentOwnerID);
|
||||||
|
|
||||||
|
$message = "User '$user[name]' needs to be able to write to this file:\n$filename\n\nThe file is currently owned by '$currentOwner[name]'. ";
|
||||||
|
|
||||||
|
if($user['name'] == $currentOwner['name']) {
|
||||||
|
$message .= "We recommend that you make the file writeable.";
|
||||||
|
} else {
|
||||||
|
|
||||||
|
$groups = posix_getgroups();
|
||||||
|
$groupList = array();
|
||||||
|
foreach($groups as $group) {
|
||||||
|
$groupInfo = posix_getgrgid($group);
|
||||||
|
if(in_array($currentOwner['name'], $groupInfo['members'])) $groupList[] = $groupInfo['name'];
|
||||||
|
}
|
||||||
|
if($groupList) {
|
||||||
|
$message .= " We recommend that you make the file group-writeable and change the group to one of these groups:\n - ". implode("\n - ", $groupList)
|
||||||
|
. "\n\nFor example:\nchmod g+w $filename\nchgrp " . $groupList[0] . " $filename";
|
||||||
|
} else {
|
||||||
|
$message .= " There is no user-group that contains both the web-server user and the owner of this file. Change the ownership of the file, create a new group, or temporarily make the file writeable by everyone during the install process.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$message .= "The webserver user needs to be able to write to this file:\n$filename";
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(EnvironmentCheck::ERROR, $message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(EnvironmentCheck::OK,'');
|
||||||
|
}
|
||||||
|
}
|
18
code/checks/HasClassCheck.php
Normal file
18
code/checks/HasClassCheck.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Check that the given class exists.
|
||||||
|
* This can be used to check that PHP modules or features are installed.
|
||||||
|
* @param $className The name of the class to look for.
|
||||||
|
*/
|
||||||
|
class HasClassCheck implements EnvironmentCheck {
|
||||||
|
protected $className;
|
||||||
|
|
||||||
|
function __construct($className) {
|
||||||
|
$this->className = $className;
|
||||||
|
}
|
||||||
|
|
||||||
|
function check() {
|
||||||
|
if(class_exists($this->className)) return array(EnvironmentCheck::OK, 'Class ' . $this->className.' exists');
|
||||||
|
else return array(EnvironmentCheck::ERROR, 'Class ' . $this->className.' doesn\'t exist');
|
||||||
|
}
|
||||||
|
}
|
18
code/checks/HasFunctionCheck.php
Normal file
18
code/checks/HasFunctionCheck.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Check that the given function exists.
|
||||||
|
* This can be used to check that PHP modules or features are installed.
|
||||||
|
* @param $functionName The name of the function to look for.
|
||||||
|
*/
|
||||||
|
class HasFunctionCheck implements EnvironmentCheck {
|
||||||
|
protected $functionName;
|
||||||
|
|
||||||
|
function __construct($functionName) {
|
||||||
|
$this->functionName = $functionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
function check() {
|
||||||
|
if(function_exists($this->functionName)) return array(EnvironmentCheck::OK, $this->functionName.'() exists');
|
||||||
|
else return array(EnvironmentCheck::ERROR, $this->functionName.'() doesn\'t exist');
|
||||||
|
}
|
||||||
|
}
|
58
code/checks/SMTPConnectCheck.php
Normal file
58
code/checks/SMTPConnectCheck.php
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Checks if the SMTP connection configured through PHP.ini works as expected.
|
||||||
|
* Only checks socket connection with HELO command, not actually sending the email.
|
||||||
|
*/
|
||||||
|
class SMTPConnectCheck implements EnvironmentCheck {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var String
|
||||||
|
*/
|
||||||
|
protected $host;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Int
|
||||||
|
*/
|
||||||
|
protected $port;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Int In seconds
|
||||||
|
*/
|
||||||
|
protected $timeout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param String
|
||||||
|
* @param Int
|
||||||
|
*/
|
||||||
|
function __construct($host = null, $port = null, $timeout = 15) {
|
||||||
|
$this->host = ($host) ? $host : ini_get('SMTP');
|
||||||
|
if(!$this->host) $this->host = 'localhost';
|
||||||
|
|
||||||
|
$this->port = ($port) ? $port : ini_get('smtp_port');
|
||||||
|
if(!$this->port) $this->port = 25;
|
||||||
|
|
||||||
|
$this->timeout = $timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
function check() {
|
||||||
|
$f = @fsockopen($this->host, $this->port, $errno, $errstr, $this->timeout);
|
||||||
|
if(!$f) {
|
||||||
|
return array(
|
||||||
|
EnvironmentCheck::ERROR,
|
||||||
|
sprintf("Couldn't connect to SMTP on %s:%s (Error: %s %s)", $this->host, $this->port, $errno, $errstr)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fwrite($f, "HELO its_me\r\n");
|
||||||
|
$response = fread($f, 26);
|
||||||
|
if(substr($response, 0, 3) != '220') {
|
||||||
|
return array(
|
||||||
|
EnvironmentCheck::ERROR,
|
||||||
|
sprintf("Invalid mail server response: %s", $response)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(EnvironmentCheck::OK, '');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
42
code/checks/URLCheck.php
Normal file
42
code/checks/URLCheck.php
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Check that a given URL is functioning, by default, the homepage.
|
||||||
|
*
|
||||||
|
* Note that Director::test() will be used rather than a CURL check.
|
||||||
|
*/
|
||||||
|
class URLCheck implements EnvironmentCheck {
|
||||||
|
protected $url;
|
||||||
|
protected $testString;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @param $url The URL to check, relative to the site. "" is the homepage.
|
||||||
|
* @param $testString A piece of text to optionally search for in the homepage HTML. If omitted, no such check is made.
|
||||||
|
*/
|
||||||
|
function __construct($url = "", $testString = "") {
|
||||||
|
$this->url = $url;
|
||||||
|
$this->testString = $testString;
|
||||||
|
}
|
||||||
|
|
||||||
|
function check() {
|
||||||
|
$response = Director::test($this->url);
|
||||||
|
|
||||||
|
if($response->getStatusCode() != 200) {
|
||||||
|
return array(
|
||||||
|
EnvironmentCheck::ERROR,
|
||||||
|
sprintf('Error retrieving "%s" (Code: %d)', $this->url, $response->getStatusCode())
|
||||||
|
);
|
||||||
|
|
||||||
|
} else if($this->testString && (strpos($response->getBody(), $this->testString) === false)) {
|
||||||
|
return array(
|
||||||
|
EnvironmentCheck::WARNING,
|
||||||
|
sprintf('Success retrieving "%s", but string "%s" not found', $this->url, $testString)
|
||||||
|
);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return array(
|
||||||
|
EnvironmentCheck::OK,
|
||||||
|
sprintf('Success retrieving "%s"', $this->url)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user