MINOR Consistent class naming and file<->class relationships (no functional changes)

This commit is contained in:
Ingo Schommer 2012-01-20 18:10:48 +01:00
parent 908a66b4ef
commit 616f0d98c1
11 changed files with 317 additions and 318 deletions

View File

@ -20,6 +20,6 @@
// EnvironmentCheckSuite::register('check', 'FileWriteableCheck("' . TEMP_FOLDER . '")', "Is the temp folder writeable?");
Director::addRules(100, array(
'dev/health' => 'DevHealth',
'dev/check' => 'DevCheck',
'dev/health' => 'DevHealthController',
'dev/check' => 'DevCheckController',
));

View File

@ -1,166 +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,
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)
);
}
}
}
/**
* 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,'');
}
}

View File

@ -1,6 +1,6 @@
<?php
class DevCheck extends Controller {
class DevCheckController extends Controller {
function index() {
if(!Permission::check("ADMIN")) return Security::permissionFailure();

View File

@ -1,6 +1,6 @@
<?php
class DevHealth extends Controller {
class DevHealthController extends Controller {
function index() {
$e = new EnvironmentChecker('health', 'Site health');
$e->setErrorCode(404);

View File

@ -27,152 +27,4 @@ interface EnvironmentCheck {
*/
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.
*
* @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'");
}
}
}

View 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'");
}
}
}

View 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");
}
}
}

View 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,'');
}
}

View 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');
}
}

View 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');
}
}

42
code/checks/URLCheck.php Normal file
View 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)
);
}
}
}