From 92b7dd3335a6572debeacfb5faa82c63a5e67888 Mon Sep 17 00:00:00 2001 From: Marvin Borner Date: Fri, 8 Jun 2018 20:03:25 +0200 Subject: Some minor fixes --- .../core/src/Util/BadClassNameException.php | 38 +- main/app/sprinkles/core/src/Util/Captcha.php | 308 +++++----- .../sprinkles/core/src/Util/CheckEnvironment.php | 662 ++++++++++----------- main/app/sprinkles/core/src/Util/ClassMapper.php | 180 +++--- .../sprinkles/core/src/Util/EnvironmentInfo.php | 134 ++--- .../sprinkles/core/src/Util/ShutdownHandler.php | 324 +++++----- main/app/sprinkles/core/src/Util/Util.php | 348 +++++------ 7 files changed, 997 insertions(+), 997 deletions(-) (limited to 'main/app/sprinkles/core/src/Util') diff --git a/main/app/sprinkles/core/src/Util/BadClassNameException.php b/main/app/sprinkles/core/src/Util/BadClassNameException.php index 1cd6f4e..1271c44 100644 --- a/main/app/sprinkles/core/src/Util/BadClassNameException.php +++ b/main/app/sprinkles/core/src/Util/BadClassNameException.php @@ -1,19 +1,19 @@ -session = $session; - $this->key = $key; - - if (!$this->session->has($key)) { - $this->session[$key] = array(); - } - } - - /** - * Generates a new captcha for the user registration form. - * - * This generates a random 5-character captcha and stores it in the session with an md5 hash. - * Also, generates the corresponding captcha image. - */ - public function generateRandomCode() { - $md5_hash = md5(rand(0, 99999)); - $this->code = substr($md5_hash, 25, 5); - $enc = md5($this->code); - - // Store the generated captcha value to the session - $this->session[$this->key] = $enc; - - $this->generateImage(); - } - - /** - * Returns the captcha code. - */ - public function getCaptcha() { - return $this->code; - } - - /** - * Returns the captcha image. - */ - public function getImage() { - return $this->image; - } - - /** - * Check that the specified code, when hashed, matches the code in the session. - * - * Also, stores the specified code in the session with an md5 hash. - * @param string - * @return bool - */ - public function verifyCode($code) { - return (md5($code) == $this->session[$this->key]); - } - - /** - * Generate the image for the current captcha. - * - * This generates an image as a binary string. - */ - protected function generateImage() { - $width = 150; - $height = 30; - - $image = imagecreatetruecolor(150, 30); - - //color pallette - $white = imagecolorallocate($image, 255, 255, 255); - $black = imagecolorallocate($image, 0, 0, 0); - $red = imagecolorallocate($image, 255, 0, 0); - $yellow = imagecolorallocate($image, 255, 255, 0); - $dark_grey = imagecolorallocate($image, 64, 64, 64); - $blue = imagecolorallocate($image, 0, 0, 255); - - //create white rectangle - imagefilledrectangle($image, 0, 0, 150, 30, $white); - - //add some lines - for ($i = 0; $i < 2; $i++) { - imageline($image, 0, rand() % 10, 10, rand() % 30, $dark_grey); - imageline($image, 0, rand() % 30, 150, rand() % 30, $red); - imageline($image, 0, rand() % 30, 150, rand() % 30, $yellow); - } - - // RandTab color pallette - $randc[0] = imagecolorallocate($image, 0, 0, 0); - $randc[1] = imagecolorallocate($image, 255, 0, 0); - $randc[2] = imagecolorallocate($image, 255, 255, 0); - $randc[3] = imagecolorallocate($image, 64, 64, 64); - $randc[4] = imagecolorallocate($image, 0, 0, 255); - - //add some dots - for ($i = 0; $i < 1000; $i++) { - imagesetpixel($image, rand() % 200, rand() % 50, $randc[rand() % 5]); - } - - //calculate center of text - $x = (150 - 0 - imagefontwidth(5) * strlen($this->code)) / 2 + 0 + 5; - - //write string twice - imagestring($image, 5, $x, 7, $this->code, $black); - imagestring($image, 5, $x, 7, $this->code, $black); - //start ob - ob_start(); - imagepng($image); - - //get binary image data - $this->image = ob_get_clean(); - - return $this->image; - } -} +session = $session; + $this->key = $key; + + if (!$this->session->has($key)) { + $this->session[$key] = array(); + } + } + + /** + * Generates a new captcha for the user registration form. + * + * This generates a random 5-character captcha and stores it in the session with an md5 hash. + * Also, generates the corresponding captcha image. + */ + public function generateRandomCode() { + $md5_hash = md5(rand(0, 99999)); + $this->code = substr($md5_hash, 25, 5); + $enc = md5($this->code); + + // Store the generated captcha value to the session + $this->session[$this->key] = $enc; + + $this->generateImage(); + } + + /** + * Returns the captcha code. + */ + public function getCaptcha() { + return $this->code; + } + + /** + * Returns the captcha image. + */ + public function getImage() { + return $this->image; + } + + /** + * Check that the specified code, when hashed, matches the code in the session. + * + * Also, stores the specified code in the session with an md5 hash. + * @param string + * @return bool + */ + public function verifyCode($code) { + return (md5($code) == $this->session[$this->key]); + } + + /** + * Generate the image for the current captcha. + * + * This generates an image as a binary string. + */ + protected function generateImage() { + $width = 150; + $height = 30; + + $image = imagecreatetruecolor(150, 30); + + //color pallette + $white = imagecolorallocate($image, 255, 255, 255); + $black = imagecolorallocate($image, 0, 0, 0); + $red = imagecolorallocate($image, 255, 0, 0); + $yellow = imagecolorallocate($image, 255, 255, 0); + $dark_grey = imagecolorallocate($image, 64, 64, 64); + $blue = imagecolorallocate($image, 0, 0, 255); + + //create white rectangle + imagefilledrectangle($image, 0, 0, 150, 30, $white); + + //add some lines + for ($i = 0; $i < 2; $i++) { + imageline($image, 0, rand() % 10, 10, rand() % 30, $dark_grey); + imageline($image, 0, rand() % 30, 150, rand() % 30, $red); + imageline($image, 0, rand() % 30, 150, rand() % 30, $yellow); + } + + // RandTab color pallette + $randc[0] = imagecolorallocate($image, 0, 0, 0); + $randc[1] = imagecolorallocate($image, 255, 0, 0); + $randc[2] = imagecolorallocate($image, 255, 255, 0); + $randc[3] = imagecolorallocate($image, 64, 64, 64); + $randc[4] = imagecolorallocate($image, 0, 0, 255); + + //add some dots + for ($i = 0; $i < 1000; $i++) { + imagesetpixel($image, rand() % 200, rand() % 50, $randc[rand() % 5]); + } + + //calculate center of text + $x = (150 - 0 - imagefontwidth(5) * strlen($this->code)) / 2 + 0 + 5; + + //write string twice + imagestring($image, 5, $x, 7, $this->code, $black); + imagestring($image, 5, $x, 7, $this->code, $black); + //start ob + ob_start(); + imagepng($image); + + //get binary image data + $this->image = ob_get_clean(); + + return $this->image; + } +} diff --git a/main/app/sprinkles/core/src/Util/CheckEnvironment.php b/main/app/sprinkles/core/src/Util/CheckEnvironment.php index 05b555f..b8e5ec8 100644 --- a/main/app/sprinkles/core/src/Util/CheckEnvironment.php +++ b/main/app/sprinkles/core/src/Util/CheckEnvironment.php @@ -1,331 +1,331 @@ -view = $view; - $this->locator = $locator; - $this->cache = $cache; - } - - /** - * Invoke the CheckEnvironment middleware, performing all pre-flight checks and returning an error page if problems were found. - * - * @param \Psr\Http\Message\ServerRequestInterface $request PSR7 request - * @param \Psr\Http\Message\ResponseInterface $response PSR7 response - * @param callable $next Next middleware - * - * @return \Psr\Http\Message\ResponseInterface - */ - public function __invoke($request, $response, $next) { - $problemsFound = FALSE; - - // If production environment and no cached checks, perform environment checks - if ($this->isProduction() && $this->cache->get('checkEnvironment') != 'pass') { - $problemsFound = $this->checkAll(); - - // Cache if checks passed - if (!$problemsFound) { - $this->cache->forever('checkEnvironment', 'pass'); - } - } else if (!$this->isProduction()) { - $problemsFound = $this->checkAll(); - } - - if ($problemsFound) { - $results = array_merge($this->resultsFailed, $this->resultsSuccess); - - $response = $this->view->render($response, 'pages/error/config-errors.html.twig', [ - "messages" => $results - ]); - } else { - $response = $next($request, $response); - } - - return $response; - } - - /** - * Run through all pre-flight checks. - */ - public function checkAll() { - $problemsFound = FALSE; - - if ($this->checkApache()) $problemsFound = TRUE; - - if ($this->checkPhp()) $problemsFound = TRUE; - - if ($this->checkPdo()) $problemsFound = TRUE; - - if ($this->checkGd()) $problemsFound = TRUE; - - if ($this->checkImageFunctions()) $problemsFound = TRUE; - - if ($this->checkPermissions()) $problemsFound = TRUE; - - return $problemsFound; - } - - /** - * For Apache environments, check that required Apache modules are installed. - */ - public function checkApache() { - $problemsFound = FALSE; - - // Perform some Apache checks. We may also need to do this before any routing takes place. - if (strpos(php_sapi_name(), 'apache') !== FALSE) { - - $require_apache_modules = ['mod_rewrite']; - $apache_modules = apache_get_modules(); - - $apache_status = []; - - foreach ($require_apache_modules as $module) { - if (!in_array($module, $apache_modules)) { - $problemsFound = TRUE; - $this->resultsFailed['apache-' . $module] = [ - "title" => " Missing Apache module $module.", - "message" => "Please make sure that the $module Apache module is installed and enabled. If you use shared hosting, you will need to ask your web host to do this for you.", - "success" => FALSE - ]; - } else { - $this->resultsSuccess['apache-' . $module] = [ - "title" => " Apache module $module is installed and enabled.", - "message" => "Great, we found the $module Apache module!", - "success" => TRUE - ]; - } - } - } - - return $problemsFound; - } - - /** - * Check for GD library (required for Captcha). - */ - public function checkGd() { - $problemsFound = FALSE; - - if (!(extension_loaded('gd') && function_exists('gd_info'))) { - $problemsFound = TRUE; - $this->resultsFailed['gd'] = [ - "title" => " GD library not installed", - "message" => "We could not confirm that the GD library is installed and enabled. GD is an image processing library that UserFrosting uses to generate captcha codes for user account registration.", - "success" => FALSE - ]; - } else { - $this->resultsSuccess['gd'] = [ - "title" => " GD library installed!", - "message" => "Great, you have GD installed and enabled.", - "success" => TRUE - ]; - } - - return $problemsFound; - } - - /** - * Check that all image* functions used by Captcha exist. - * - * Some versions of GD are missing one or more of these functions, thus why we check for them explicitly. - */ - public function checkImageFunctions() { - $problemsFound = FALSE; - - $funcs = [ - 'imagepng', - 'imagecreatetruecolor', - 'imagecolorallocate', - 'imagefilledrectangle', - 'imageline', - 'imagesetpixel', - 'imagefontwidth', - 'imagestring' - ]; - - foreach ($funcs as $func) { - if (!function_exists($func)) { - $problemsFound = TRUE; - $this->resultsFailed['function-' . $func] = [ - "title" => " Missing image manipulation function.", - "message" => "It appears that function $func is not available. UserFrosting needs this to render captchas.", - "success" => FALSE - ]; - } else { - $this->resultsSuccess['function-' . $func] = [ - "title" => " Function $func is available!", - "message" => "Sweet!", - "success" => TRUE - ]; - } - } - - return $problemsFound; - } - - /** - * Check that PDO is installed and enabled. - */ - public function checkPdo() { - $problemsFound = FALSE; - - if (!class_exists('PDO')) { - $problemsFound = TRUE; - $this->resultsFailed['pdo'] = [ - "title" => " PDO is not installed.", - "message" => "I'm sorry, you must have PDO installed and enabled in order for UserFrosting to access the database. If you don't know what PDO is, please see http://php.net/manual/en/book.pdo.php.", - "success" => FALSE - ]; - } else { - $this->resultsSuccess['pdo'] = [ - "title" => " PDO is installed!", - "message" => "You've got PDO installed. Good job!", - "success" => TRUE - ]; - } - - return $problemsFound; - } - - /** - * Check that log, cache, and session directories are writable, and that other directories are set appropriately for the environment. - */ - function checkPermissions() { - $problemsFound = FALSE; - - $shouldBeWriteable = [ - $this->locator->findResource('log://') => TRUE, - $this->locator->findResource('cache://') => TRUE, - $this->locator->findResource('session://') => TRUE - ]; - - if ($this->isProduction()) { - // Should be write-protected in production! - $shouldBeWriteable = array_merge($shouldBeWriteable, [ - \UserFrosting\SPRINKLES_DIR => FALSE, - \UserFrosting\VENDOR_DIR => FALSE - ]); - } - - // Check for essential files & perms - foreach ($shouldBeWriteable as $file => $assertWriteable) { - $is_dir = FALSE; - if (!file_exists($file)) { - $problemsFound = TRUE; - $this->resultsFailed['file-' . $file] = [ - "title" => " File or directory does not exist.", - "message" => "We could not find the file or directory $file.", - "success" => FALSE - ]; - } else { - $writeable = is_writable($file); - if ($assertWriteable !== $writeable) { - $problemsFound = TRUE; - $this->resultsFailed['file-' . $file] = [ - "title" => " Incorrect permissions for file or directory.", - "message" => "$file is " - . ($writeable ? "writeable" : "not writeable") - . ", but it should " - . ($assertWriteable ? "be writeable" : "not be writeable") - . ". Please modify the OS user or group permissions so that user " - . exec('whoami') . " " - . ($assertWriteable ? "has" : "does not have") . " write permissions for this directory.", - "success" => FALSE - ]; - } else { - $this->resultsSuccess['file-' . $file] = [ - "title" => " File/directory check passed!", - "message" => "$file exists and is correctly set as " - . ($writeable ? "writeable" : "not writeable") - . ".", - "success" => TRUE - ]; - } - } - } - return $problemsFound; - } - - /** - * Check that PHP meets the minimum required version. - */ - public function checkPhp() { - $problemsFound = FALSE; - - // Check PHP version - if (version_compare(phpversion(), \UserFrosting\PHP_MIN_VERSION, '<')) { - $problemsFound = TRUE; - $this->resultsFailed['phpVersion'] = [ - "title" => " You need to upgrade your PHP installation.", - "message" => "I'm sorry, UserFrosting requires version " . \UserFrosting\PHP_MIN_VERSION . " or greater. Please upgrade your version of PHP, or contact your web hosting service and ask them to upgrade it for you.", - "success" => FALSE - ]; - } else { - $this->resultsSuccess['phpVersion'] = [ - "title" => " PHP version checks out!", - "message" => "You're using PHP " . \UserFrosting\PHP_MIN_VERSION . "or higher. Great!", - "success" => TRUE - ]; - } - - return $problemsFound; - } - - /** - * Determine whether or not we are running in production mode. - * - * @return bool - */ - public function isProduction() { - return (getenv('UF_MODE') == 'production'); - } -} +view = $view; + $this->locator = $locator; + $this->cache = $cache; + } + + /** + * Invoke the CheckEnvironment middleware, performing all pre-flight checks and returning an error page if problems were found. + * + * @param \Psr\Http\Message\ServerRequestInterface $request PSR7 request + * @param \Psr\Http\Message\ResponseInterface $response PSR7 response + * @param callable $next Next middleware + * + * @return \Psr\Http\Message\ResponseInterface + */ + public function __invoke($request, $response, $next) { + $problemsFound = FALSE; + + // If production environment and no cached checks, perform environment checks + if ($this->isProduction() && $this->cache->get('checkEnvironment') != 'pass') { + $problemsFound = $this->checkAll(); + + // Cache if checks passed + if (!$problemsFound) { + $this->cache->forever('checkEnvironment', 'pass'); + } + } else if (!$this->isProduction()) { + $problemsFound = $this->checkAll(); + } + + if ($problemsFound) { + $results = array_merge($this->resultsFailed, $this->resultsSuccess); + + $response = $this->view->render($response, 'pages/error/config-errors.html.twig', [ + "messages" => $results + ]); + } else { + $response = $next($request, $response); + } + + return $response; + } + + /** + * Run through all pre-flight checks. + */ + public function checkAll() { + $problemsFound = FALSE; + + if ($this->checkApache()) $problemsFound = TRUE; + + if ($this->checkPhp()) $problemsFound = TRUE; + + if ($this->checkPdo()) $problemsFound = TRUE; + + if ($this->checkGd()) $problemsFound = TRUE; + + if ($this->checkImageFunctions()) $problemsFound = TRUE; + + if ($this->checkPermissions()) $problemsFound = TRUE; + + return $problemsFound; + } + + /** + * For Apache environments, check that required Apache modules are installed. + */ + public function checkApache() { + $problemsFound = FALSE; + + // Perform some Apache checks. We may also need to do this before any routing takes place. + if (strpos(php_sapi_name(), 'apache') !== FALSE) { + + $require_apache_modules = ['mod_rewrite']; + $apache_modules = apache_get_modules(); + + $apache_status = []; + + foreach ($require_apache_modules as $module) { + if (!in_array($module, $apache_modules)) { + $problemsFound = TRUE; + $this->resultsFailed['apache-' . $module] = [ + "title" => " Missing Apache module $module.", + "message" => "Please make sure that the $module Apache module is installed and enabled. If you use shared hosting, you will need to ask your web host to do this for you.", + "success" => FALSE + ]; + } else { + $this->resultsSuccess['apache-' . $module] = [ + "title" => " Apache module $module is installed and enabled.", + "message" => "Great, we found the $module Apache module!", + "success" => TRUE + ]; + } + } + } + + return $problemsFound; + } + + /** + * Check for GD library (required for Captcha). + */ + public function checkGd() { + $problemsFound = FALSE; + + if (!(extension_loaded('gd') && function_exists('gd_info'))) { + $problemsFound = TRUE; + $this->resultsFailed['gd'] = [ + "title" => " GD library not installed", + "message" => "We could not confirm that the GD library is installed and enabled. GD is an image processing library that UserFrosting uses to generate captcha codes for user account registration.", + "success" => FALSE + ]; + } else { + $this->resultsSuccess['gd'] = [ + "title" => " GD library installed!", + "message" => "Great, you have GD installed and enabled.", + "success" => TRUE + ]; + } + + return $problemsFound; + } + + /** + * Check that all image* functions used by Captcha exist. + * + * Some versions of GD are missing one or more of these functions, thus why we check for them explicitly. + */ + public function checkImageFunctions() { + $problemsFound = FALSE; + + $funcs = [ + 'imagepng', + 'imagecreatetruecolor', + 'imagecolorallocate', + 'imagefilledrectangle', + 'imageline', + 'imagesetpixel', + 'imagefontwidth', + 'imagestring' + ]; + + foreach ($funcs as $func) { + if (!function_exists($func)) { + $problemsFound = TRUE; + $this->resultsFailed['function-' . $func] = [ + "title" => " Missing image manipulation function.", + "message" => "It appears that function $func is not available. UserFrosting needs this to render captchas.", + "success" => FALSE + ]; + } else { + $this->resultsSuccess['function-' . $func] = [ + "title" => " Function $func is available!", + "message" => "Sweet!", + "success" => TRUE + ]; + } + } + + return $problemsFound; + } + + /** + * Check that PDO is installed and enabled. + */ + public function checkPdo() { + $problemsFound = FALSE; + + if (!class_exists('PDO')) { + $problemsFound = TRUE; + $this->resultsFailed['pdo'] = [ + "title" => " PDO is not installed.", + "message" => "I'm sorry, you must have PDO installed and enabled in order for UserFrosting to access the database. If you don't know what PDO is, please see http://php.net/manual/en/book.pdo.php.", + "success" => FALSE + ]; + } else { + $this->resultsSuccess['pdo'] = [ + "title" => " PDO is installed!", + "message" => "You've got PDO installed. Good job!", + "success" => TRUE + ]; + } + + return $problemsFound; + } + + /** + * Check that log, cache, and session directories are writable, and that other directories are set appropriately for the environment. + */ + function checkPermissions() { + $problemsFound = FALSE; + + $shouldBeWriteable = [ + $this->locator->findResource('log://') => TRUE, + $this->locator->findResource('cache://') => TRUE, + $this->locator->findResource('session://') => TRUE + ]; + + if ($this->isProduction()) { + // Should be write-protected in production! + $shouldBeWriteable = array_merge($shouldBeWriteable, [ + \UserFrosting\SPRINKLES_DIR => FALSE, + \UserFrosting\VENDOR_DIR => FALSE + ]); + } + + // Check for essential files & perms + foreach ($shouldBeWriteable as $file => $assertWriteable) { + $is_dir = FALSE; + if (!file_exists($file)) { + $problemsFound = TRUE; + $this->resultsFailed['file-' . $file] = [ + "title" => " File or directory does not exist.", + "message" => "We could not find the file or directory $file.", + "success" => FALSE + ]; + } else { + $writeable = is_writable($file); + if ($assertWriteable !== $writeable) { + $problemsFound = TRUE; + $this->resultsFailed['file-' . $file] = [ + "title" => " Incorrect permissions for file or directory.", + "message" => "$file is " + . ($writeable ? "writeable" : "not writeable") + . ", but it should " + . ($assertWriteable ? "be writeable" : "not be writeable") + . ". Please modify the OS user or group permissions so that user " + . exec('whoami') . " " + . ($assertWriteable ? "has" : "does not have") . " write permissions for this directory.", + "success" => FALSE + ]; + } else { + $this->resultsSuccess['file-' . $file] = [ + "title" => " File/directory check passed!", + "message" => "$file exists and is correctly set as " + . ($writeable ? "writeable" : "not writeable") + . ".", + "success" => TRUE + ]; + } + } + } + return $problemsFound; + } + + /** + * Check that PHP meets the minimum required version. + */ + public function checkPhp() { + $problemsFound = FALSE; + + // Check PHP version + if (version_compare(phpversion(), \UserFrosting\PHP_MIN_VERSION, '<')) { + $problemsFound = TRUE; + $this->resultsFailed['phpVersion'] = [ + "title" => " You need to upgrade your PHP installation.", + "message" => "I'm sorry, UserFrosting requires version " . \UserFrosting\PHP_MIN_VERSION . " or greater. Please upgrade your version of PHP, or contact your web hosting service and ask them to upgrade it for you.", + "success" => FALSE + ]; + } else { + $this->resultsSuccess['phpVersion'] = [ + "title" => " PHP version checks out!", + "message" => "You're using PHP " . \UserFrosting\PHP_MIN_VERSION . "or higher. Great!", + "success" => TRUE + ]; + } + + return $problemsFound; + } + + /** + * Determine whether or not we are running in production mode. + * + * @return bool + */ + public function isProduction() { + return (getenv('UF_MODE') == 'production'); + } +} diff --git a/main/app/sprinkles/core/src/Util/ClassMapper.php b/main/app/sprinkles/core/src/Util/ClassMapper.php index 11720f6..e29c524 100644 --- a/main/app/sprinkles/core/src/Util/ClassMapper.php +++ b/main/app/sprinkles/core/src/Util/ClassMapper.php @@ -1,90 +1,90 @@ -getClassMapping($identifier); - - $params = array_slice(func_get_args(), 1); - - // We must use reflection in PHP < 5.6. See http://stackoverflow.com/questions/8734522/dynamically-call-class-with-variable-number-of-parameters-in-the-constructor - $reflection = new \ReflectionClass($className); - - return $reflection->newInstanceArgs($params); - } - - /** - * Gets the fully qualified class name for a specified class identifier. - * - * @param string $identifier - * @return string - */ - public function getClassMapping($identifier) { - if (isset($this->classMappings[$identifier])) { - return $this->classMappings[$identifier]; - } else { - throw new \OutOfBoundsException("There is no class mapped to the identifier '$identifier'."); - } - } - - /** - * Assigns a fully qualified class name to a specified class identifier. - * - * @param string $identifier - * @param string $className - * @return ClassMapper - */ - public function setClassMapping($identifier, $className) { - // Check that class exists - if (!class_exists($className)) { - throw new BadClassNameException("Unable to find the class '$className'."); - } - - $this->classMappings[$identifier] = $className; - - return $this; - } - - /** - * Call a static method for a specified class. - * - * @param string $identifier The identifier for the class, e.g. 'user' - * @param string $methodName The method to be invoked. - * @param mixed ...$arg Whatever needs to be passed to the method. - */ - public function staticMethod($identifier, $methodName) { - $className = $this->getClassMapping($identifier); - - $params = array_slice(func_get_args(), 2); - - return call_user_func_array("$className::$methodName", $params); - } -} +getClassMapping($identifier); + + $params = array_slice(func_get_args(), 1); + + // We must use reflection in PHP < 5.6. See http://stackoverflow.com/questions/8734522/dynamically-call-class-with-variable-number-of-parameters-in-the-constructor + $reflection = new \ReflectionClass($className); + + return $reflection->newInstanceArgs($params); + } + + /** + * Gets the fully qualified class name for a specified class identifier. + * + * @param string $identifier + * @return string + */ + public function getClassMapping($identifier) { + if (isset($this->classMappings[$identifier])) { + return $this->classMappings[$identifier]; + } else { + throw new \OutOfBoundsException("There is no class mapped to the identifier '$identifier'."); + } + } + + /** + * Assigns a fully qualified class name to a specified class identifier. + * + * @param string $identifier + * @param string $className + * @return ClassMapper + */ + public function setClassMapping($identifier, $className) { + // Check that class exists + if (!class_exists($className)) { + throw new BadClassNameException("Unable to find the class '$className'."); + } + + $this->classMappings[$identifier] = $className; + + return $this; + } + + /** + * Call a static method for a specified class. + * + * @param string $identifier The identifier for the class, e.g. 'user' + * @param string $methodName The method to be invoked. + * @param mixed ...$arg Whatever needs to be passed to the method. + */ + public function staticMethod($identifier, $methodName) { + $className = $this->getClassMapping($identifier); + + $params = array_slice(func_get_args(), 2); + + return call_user_func_array("$className::$methodName", $params); + } +} diff --git a/main/app/sprinkles/core/src/Util/EnvironmentInfo.php b/main/app/sprinkles/core/src/Util/EnvironmentInfo.php index 116a59e..e0e9d49 100644 --- a/main/app/sprinkles/core/src/Util/EnvironmentInfo.php +++ b/main/app/sprinkles/core/src/Util/EnvironmentInfo.php @@ -1,67 +1,67 @@ -getPdo(); - $results = []; - - try { - $results['type'] = $pdo->getAttribute(\PDO::ATTR_DRIVER_NAME); - } catch (Exception $e) { - $results['type'] = "Unknown"; - } - - try { - $results['version'] = $pdo->getAttribute(\PDO::ATTR_SERVER_VERSION); - } catch (Exception $e) { - $results['version'] = ""; - } - - return $results; - } - - /** - * Test whether a DB connection can be established. - * - * @return bool true if the connection can be established, false otherwise. - */ - public static function canConnectToDatabase() { - try { - Capsule::connection()->getPdo(); - } catch (\PDOException $e) { - return FALSE; - } - - return TRUE; - } -} +getPdo(); + $results = []; + + try { + $results['type'] = $pdo->getAttribute(\PDO::ATTR_DRIVER_NAME); + } catch (Exception $e) { + $results['type'] = "Unknown"; + } + + try { + $results['version'] = $pdo->getAttribute(\PDO::ATTR_SERVER_VERSION); + } catch (Exception $e) { + $results['version'] = ""; + } + + return $results; + } + + /** + * Test whether a DB connection can be established. + * + * @return bool true if the connection can be established, false otherwise. + */ + public static function canConnectToDatabase() { + try { + Capsule::connection()->getPdo(); + } catch (\PDOException $e) { + return FALSE; + } + + return TRUE; + } +} diff --git a/main/app/sprinkles/core/src/Util/ShutdownHandler.php b/main/app/sprinkles/core/src/Util/ShutdownHandler.php index 5447c8f..18e60ec 100644 --- a/main/app/sprinkles/core/src/Util/ShutdownHandler.php +++ b/main/app/sprinkles/core/src/Util/ShutdownHandler.php @@ -1,162 +1,162 @@ -ci = $ci; - $this->displayErrorInfo = $displayErrorInfo; - } - - /** - * Register this class with the shutdown handler. - * - * @return void - */ - public function register() { - register_shutdown_function([$this, 'fatalHandler']); - } - - /** - * Set up the fatal error handler, so that we get a clean error message and alert instead of a WSOD. - */ - public function fatalHandler() { - $error = error_get_last(); - $fatalErrorTypes = [ - E_ERROR, - E_PARSE, - E_CORE_ERROR, - E_COMPILE_ERROR, - E_RECOVERABLE_ERROR - ]; - - // Handle fatal errors and parse errors - if ($error !== NULL && in_array($error['type'], $fatalErrorTypes)) { - - // Build the appropriate error message (debug or client) - if ($this->displayErrorInfo) { - $errorMessage = $this->buildErrorInfoMessage($error); - } else { - $errorMessage = "Oops, looks like our server might have goofed. If you're an admin, please ensure that php.log_errors is enabled, and then check the PHP error log."; - } - - // For CLI, just print the message and exit. - if (php_sapi_name() === 'cli') { - exit($errorMessage . PHP_EOL); - } - - // For all other environments, print a debug response for the requested data type - echo $this->buildErrorPage($errorMessage); - - // If this is an AJAX request and AJAX debugging is turned off, write message to the alert stream - if ($this->ci->request->isXhr() && !$this->ci->config['site.debug.ajax']) { - if ($this->ci->alerts && is_object($this->ci->alerts)) { - $this->ci->alerts->addMessageTranslated('danger', $errorMessage); - } - } - - header('HTTP/1.1 500 Internal Server Error'); - exit(); - } - } - - /** - * Build the error message string. - * - * @param array $error - * @return string - */ - protected function buildErrorInfoMessage(array $error) { - $errfile = $error['file']; - $errline = (string)$error['line']; - $errstr = $error['message']; - - $errorTypes = [ - E_ERROR => 'Fatal error', - E_PARSE => 'Parse error', - E_CORE_ERROR => 'PHP core error', - E_COMPILE_ERROR => 'Zend compile error', - E_RECOVERABLE_ERROR => 'Catchable fatal error' - ]; - - return "" . $errorTypes[$error['type']] . ": $errstr in $errfile on line $errline"; - } - - /** - * Build an error response of the appropriate type as determined by the request's Accept header. - * - * @param string $message - * @return string - */ - protected function buildErrorPage($message) { - $contentType = $this->determineContentType($this->ci->request, $this->ci->config['site.debug.ajax']); - - switch ($contentType) { - case 'application/json': - $error = ['message' => $message]; - return json_encode($error, JSON_PRETTY_PRINT); - - case 'text/html': - return $this->buildHtmlErrorPage($message); - - default: - case 'text/plain': - return $message; - } - } - - /** - * Build an HTML error page from an error string. - * - * @param string $errorMessage - * @return string - */ - protected function buildHtmlErrorPage($message) { - $title = 'UserFrosting Application Error'; - $html = "

$message

"; - - return sprintf( - "" . - "%s

%s

%s", - $title, - $title, - $html - ); - } -} +ci = $ci; + $this->displayErrorInfo = $displayErrorInfo; + } + + /** + * Register this class with the shutdown handler. + * + * @return void + */ + public function register() { + register_shutdown_function([$this, 'fatalHandler']); + } + + /** + * Set up the fatal error handler, so that we get a clean error message and alert instead of a WSOD. + */ + public function fatalHandler() { + $error = error_get_last(); + $fatalErrorTypes = [ + E_ERROR, + E_PARSE, + E_CORE_ERROR, + E_COMPILE_ERROR, + E_RECOVERABLE_ERROR + ]; + + // Handle fatal errors and parse errors + if ($error !== NULL && in_array($error['type'], $fatalErrorTypes)) { + + // Build the appropriate error message (debug or client) + if ($this->displayErrorInfo) { + $errorMessage = $this->buildErrorInfoMessage($error); + } else { + $errorMessage = "Oops, looks like our server might have goofed. If you're an admin, please ensure that php.log_errors is enabled, and then check the PHP error log."; + } + + // For CLI, just print the message and exit. + if (php_sapi_name() === 'cli') { + exit($errorMessage . PHP_EOL); + } + + // For all other environments, print a debug response for the requested data type + echo $this->buildErrorPage($errorMessage); + + // If this is an AJAX request and AJAX debugging is turned off, write message to the alert stream + if ($this->ci->request->isXhr() && !$this->ci->config['site.debug.ajax']) { + if ($this->ci->alerts && is_object($this->ci->alerts)) { + $this->ci->alerts->addMessageTranslated('danger', $errorMessage); + } + } + + header('HTTP/1.1 500 Internal Server Error'); + exit(); + } + } + + /** + * Build the error message string. + * + * @param array $error + * @return string + */ + protected function buildErrorInfoMessage(array $error) { + $errfile = $error['file']; + $errline = (string)$error['line']; + $errstr = $error['message']; + + $errorTypes = [ + E_ERROR => 'Fatal error', + E_PARSE => 'Parse error', + E_CORE_ERROR => 'PHP core error', + E_COMPILE_ERROR => 'Zend compile error', + E_RECOVERABLE_ERROR => 'Catchable fatal error' + ]; + + return "" . $errorTypes[$error['type']] . ": $errstr in $errfile on line $errline"; + } + + /** + * Build an error response of the appropriate type as determined by the request's Accept header. + * + * @param string $message + * @return string + */ + protected function buildErrorPage($message) { + $contentType = $this->determineContentType($this->ci->request, $this->ci->config['site.debug.ajax']); + + switch ($contentType) { + case 'application/json': + $error = ['message' => $message]; + return json_encode($error, JSON_PRETTY_PRINT); + + case 'text/html': + return $this->buildHtmlErrorPage($message); + + default: + case 'text/plain': + return $message; + } + } + + /** + * Build an HTML error page from an error string. + * + * @param string $errorMessage + * @return string + */ + protected function buildHtmlErrorPage($message) { + $title = 'UserFrosting Application Error'; + $html = "

$message

"; + + return sprintf( + "" . + "%s

%s

%s", + $title, + $title, + $html + ); + } +} diff --git a/main/app/sprinkles/core/src/Util/Util.php b/main/app/sprinkles/core/src/Util/Util.php index 0db3b72..0cf3a56 100644 --- a/main/app/sprinkles/core/src/Util/Util.php +++ b/main/app/sprinkles/core/src/Util/Util.php @@ -1,174 +1,174 @@ -' . str_repeat('  ', $newLineLevel); - } - - $result .= $char . $post; - } - - return $result; - } - - /** - * Generate a random phrase, consisting of a specified number of adjectives, followed by a noun. - * - * @param int $numAdjectives - * @param int $maxLength - * @param int $maxTries - * @param string $separator - * @return string - */ - static public function randomPhrase($numAdjectives, $maxLength = 9999999, $maxTries = 10, $separator = '-') { - $adjectives = include('extra://adjectives.php'); - $nouns = include('extra://nouns.php'); - - for ($n = 0; $n < $maxTries; $n++) { - $keys = array_rand($adjectives, $numAdjectives); - $matches = array_only($adjectives, $keys); - - $result = implode($separator, $matches); - $result .= $separator . $nouns[array_rand($nouns)]; - $result = str_slug($result, $separator); - if (strlen($result) < $maxLength) { - return $result; - } - } - - return ''; - } -} +' . str_repeat('  ', $newLineLevel); + } + + $result .= $char . $post; + } + + return $result; + } + + /** + * Generate a random phrase, consisting of a specified number of adjectives, followed by a noun. + * + * @param int $numAdjectives + * @param int $maxLength + * @param int $maxTries + * @param string $separator + * @return string + */ + static public function randomPhrase($numAdjectives, $maxLength = 9999999, $maxTries = 10, $separator = '-') { + $adjectives = include('extra://adjectives.php'); + $nouns = include('extra://nouns.php'); + + for ($n = 0; $n < $maxTries; $n++) { + $keys = array_rand($adjectives, $numAdjectives); + $matches = array_only($adjectives, $keys); + + $result = implode($separator, $matches); + $result .= $separator . $nouns[array_rand($nouns)]; + $result = str_slug($result, $separator); + if (strlen($result) < $maxLength) { + return $result; + } + } + + return ''; + } +} -- cgit v1.2.3