diff --git a/core/Pimf/Application.php b/core/Pimf/Application.php index 99fb3fc..18e3ea6 100644 --- a/core/Pimf/Application.php +++ b/core/Pimf/Application.php @@ -53,25 +53,45 @@ final class Application * * @return boolean|null */ - public function __construct(Config $conf, array $server = []) + public function __construct(Config $conf, Environment $server) { - $problems = []; + $this->env = $server; + $problems = []; + // nothing exceptionable should be happening in __construct() try { - $environment = $conf['environment']; - $appname = $conf['app.name']; + // this belongs in run() somehow, but $conf isn't there + \date_default_timezone_set($conf['timezone']); - date_default_timezone_set($conf['timezone']); + // this one is a mess + $this->setupUtils($conf['bootstrap.local_temp_directory'], $conf->get('logging.storage', 'file')); + + // this needs to be done before much user app code is run + $this->setupErrorHandling($conf['environment']); + + $appPath = BASE_PATH . 'app/' . $conf['app.name']; + + // $this->loadListeners(); + if (file_exists($appPath . '/events.php')) { + include_once $appPath . '/events.php'; + } + + // $this->loadPdoDriver(); + $dbConf = $conf[$conf['environment'] . '.db']; + if (is_array($dbConf) && $conf['environment'] != 'testing') { + $this->em = new EntityManager(Pdo\Factory::get($dbConf), $conf['app.name']); + } + + // $this->loadRoutes(); + if ($conf['app.routeable'] === true && file_exists($appPath . '/routes.php')) { + $this->router = new Router(); + + foreach ((array)(include $routes) as $route) { + $this->router->map($route); + } + } - $this->setupUtils($server, $conf['bootstrap.local_temp_directory'], $conf->get('logging.storage', 'file')); - $this->loadListeners(BASE_PATH . 'app/' . $appname . '/events.php'); - $this->setupErrorHandling($environment); - $this->loadPdoDriver($environment, $conf[$environment . '.db'], $appname); - $this->loadRoutes( - $conf['app.routeable'], - BASE_PATH . 'app/' . $appname . '/routes.php' - ); } catch (\Throwable $throwable) { $problems[] = $throwable->getMessage(); @@ -79,7 +99,14 @@ public function __construct(Config $conf, array $server = []) $problems[] = $exception->getMessage(); } - $this->reportIf($problems, PHP_VERSION); + // $this->reportIf(); + if (version_compare($version, 5.3) == -1) { + $problems[] = 'You have PHP ' . PHP_VERSION . ' and you need 5.3 or higher!'; + } + + if (!empty($problems)) { + die(implode(PHP_EOL . PHP_EOL, $problems)); + } } /** @@ -171,15 +198,9 @@ function () use ($logger) { * @param $tmpPath * @param string $logging */ - private function setupUtils(array $server, $tmpPath, $logging = 'file') + private function setupUtils($tmpPath, $logging = 'file') { - self::$env = new Environment($server); - $envData = self::$env->data(); - - Logger::setup( - self::$env->getIp(), - $envData->get('PHP_SELF', $envData->get('SCRIPT_NAME')) - ); + $envData = $this->env->data(); ResponseStatus::setup($envData->get('SERVER_PROTOCOL', 'HTTP/1.0')); @@ -191,79 +212,28 @@ private function setupUtils(array $server, $tmpPath, $logging = 'file') Uri::setup(self::$env->PATH_INFO, self::$env->REQUEST_URI); Uuid::setup(self::$env->getIp(), self::$env->getHost()); + $remoteIp = $this->env->getIp(); + $script = $envData->get('PHP_SELF', $envData->get('SCRIPT_NAME')); + if ($logging === 'file') { - self::$logger = new Logger( + $this->logger = new Logger( + $remoteIp, + $script, new Adapter\File($tmpPath, "pimf-logs.txt"), new Adapter\File($tmpPath, "pimf-warnings.txt"), new Adapter\File($tmpPath, "pimf-errors.txt") ); } else { - self::$logger = new Logger( + $this->logger = new Logger( + $remoteIp, + $script, new Adapter\Std(Adapter\Std::OUT), new Adapter\Std(Adapter\Std::OUT), new Adapter\Std(Adapter\Std::ERR) ); } - self::$logger->init(); - } - - /** - * @param string $environment - * @param array $dbConf - * @param string $appName - */ - private function loadPdoDriver($environment, $dbConf, $appName) - { - if (is_array($dbConf) && $environment != 'testing') { - self::$em = new EntityManager(Pdo\Factory::get($dbConf), $appName); - } - } - - /** - * @param boolean $routeable - * @param string $routes Path to routes definition file. - */ - private function loadRoutes($routeable, $routes) - { - if ($routeable === true && file_exists($routes)) { - - self::$router = new Router(); - - foreach ((array)(include $routes) as $route) { - - self::$router->map($route); - - } - } - } - - /** - * @param string $events Path to event listeners - */ - private function loadListeners($events) - { - if (file_exists($events)) { - include_once $events; - } - } - - /** - * @param array $problems - * @param float $version - * @param bool $die - * - * @return array|void - */ - private function reportIf(array $problems, $version, $die = true) - { - if (version_compare($version, 5.3) == -1) { - $problems[] = 'You have PHP ' . $version . ' and you need 5.3 or higher!'; - } - - if (!empty($problems)) { - return ($die === true) ? die(implode(PHP_EOL . PHP_EOL, $problems)) : $problems; - } + $this->logger->init(); } /** diff --git a/core/Pimf/Config.php b/core/Pimf/Config.php index a890390..82aff03 100644 --- a/core/Pimf/Config.php +++ b/core/Pimf/Config.php @@ -71,11 +71,7 @@ public function get($index, $default = null) */ public function offsetExists($offset) { - if ($this->get($offset, null) !== null) { - return true; - } - - return false; + return ($this->get($offset, null) !== null); } /** diff --git a/core/Pimf/Environment.php b/core/Pimf/Environment.php index 3495bc6..ecb89dd 100644 --- a/core/Pimf/Environment.php +++ b/core/Pimf/Environment.php @@ -51,9 +51,9 @@ class Environment /** * @param array $server */ - public function __construct(array $server) + public function __construct(Param $server) { - $this->data = new Param($server); + $this->data = $server; } /** @@ -81,7 +81,7 @@ public function __get($key) */ public function isAjax() { - return $this->X_REQUESTED_WITH === 'XMLHttpRequest'; + return ($this->X_REQUESTED_WITH === 'XMLHttpRequest'); } /** @@ -101,7 +101,7 @@ public function isHttp() */ public function isHttps() { - return $this->HTTPS === 'on'; + return ($this->HTTPS === 'on'); } /** @@ -111,18 +111,17 @@ public function isHttps() */ public function getHost() { - if ($this->HOST) { - - if (strpos($this->HOST, ':') !== false) { - $hostParts = explode(':', $this->HOST); + if (!$this->HOST) { + return $this->SERVER_NAME; + } - return $hostParts[0]; - } + if (strpos($this->HOST, ':') !== false) { + $hostParts = explode(':', $this->HOST); - return $this->HOST; + return $hostParts[0]; } - return $this->SERVER_NAME; + return $this->HOST; } /** diff --git a/core/Pimf/Logger.php b/core/Pimf/Logger.php index 0b9d0a8..5d9a266 100644 --- a/core/Pimf/Logger.php +++ b/core/Pimf/Logger.php @@ -34,34 +34,31 @@ class Logger /** * @var string */ - private static $remoteIp; + private $remoteIp; /** * @var string */ - private static $script; + private $script; /** + * Logger constructor. + * * @param string $remoteIp * @param string $script - */ - public static function setup($remoteIp, $script) - { - self::$remoteIp = $remoteIp; - self::$script = $script; - } - - /** - * Logger constructor. * @param Contracts\Streamable $infoHandle * @param Contracts\Streamable $warnHandle * @param Contracts\Streamable $errorHandle */ public function __construct( + $remoteIp, + $script, Contracts\Streamable $infoHandle, Contracts\Streamable $warnHandle, - Contracts\Streamable $errorHandle) - { + Contracts\Streamable $errorHandle + ) { + $this->remoteIp = $remoteIp; + $this->script = $script; $this->infoHandle = $infoHandle->open(); $this->warnHandle = $warnHandle->open(); $this->errorHandle = $errorHandle->open(); diff --git a/core/Pimf/Param.php b/core/Pimf/Param.php index 96c36e0..59d2c6f 100644 --- a/core/Pimf/Param.php +++ b/core/Pimf/Param.php @@ -12,7 +12,7 @@ * @package Pimf * @author Gjero Krsteski */ -class Param +class Param implements \ArrayAccess { /** * @var \ArrayObject|null @@ -22,9 +22,12 @@ class Param /** * @param array $data */ - public function __construct(array $data = array()) + public function __construct(array $data = []) { - $this->data = new \ArrayObject($data, \ArrayObject::STD_PROP_LIST + \ArrayObject::ARRAY_AS_PROPS); + $this->data = new \ArrayObject( + $data, + \ArrayObject::STD_PROP_LIST & \ArrayObject::ARRAY_AS_PROPS + ); } /** @@ -44,36 +47,74 @@ public function getAll() */ public function get($index, $defaultValue = null, $filtered = true) { - if ($this->data->offsetExists($index)) { + if (!$this->offsetExists($index)) { + return $defaultValue; + } + + $rawData = $this->offsetGet($index); - if ($filtered === true) { - // pretty high-level filtering here... - return self::filter($this->data->offsetGet($index)); - } + if ($filtered !== true) { + return $rawData; + } - return $this->data->offsetGet($index); + // pretty high-level filtering here... + if (!\is_array($rawData)) { + return \Pimf\Util\Character\Clean::xss($rawData); } - return $defaultValue; + return \array_map( + function ($value) { + return \Pimf\Util\Character\Clean::xss($value); + }, $rawData + ); } /** - * Never ever (ever) trust foreign input introduced to your PHP code! + * Responds to: isset($param['index']) * - * @param mixed $rawData + * @param string|integer $offset The index or identifier * - * @return mixed + * @return bool */ - public static function filter($rawData) + public function offsetExists($offset) { - return is_array($rawData) + return $this->data->offsetExists($offset); + } - ? array_map( - function ($value) { - return \Pimf\Util\Character\Clean::xss($value); - }, $rawData - ) + /** + * Responds to: $param['index'] + * + * @param string|integer $offset The index or identifier + * + * @return mixed The value at the specified array index + */ + public function offsetGet($offset) + { + return $this->data->offsetGet($offset); + } - : \Pimf\Util\Character\Clean::xss($rawData); + /** + * Responds to: $param['index'] = 'something'; + * + * @param string|integer $offset The index or identifier + * @param mixed $value The value at the specified array index + * + * @throws \LogicException Object is immutable + */ + public function offsetSet($offset, $value) + { + throw new \LogicException('Param objects are immutable'); + } + + /** + * Responds to: unset($param['index']); + * + * @param string|integer $offset The index or identifier + * + * @throws \LogicException Object is immutable + */ + public function offsetUnset($offset) + { + throw new \LogicException('Param objects are immutable'); } } diff --git a/core/Pimf/Util/Character/Clean.php b/core/Pimf/Util/Character/Clean.php index 25d809f..4ce04b0 100644 --- a/core/Pimf/Util/Character/Clean.php +++ b/core/Pimf/Util/Character/Clean.php @@ -37,21 +37,19 @@ public static function aggressive($string) */ public static function xss($string, $charset = 'ISO-8859-1') { - $sanitize = new Sanitize(); - - $string = $sanitize::removeNullCharacters($string); - $string = $sanitize::validateStandardCharacterEntities($string); - $string = $sanitize::validateUTF16TwoByteEncoding($string); - $string = $sanitize::strangeThingsAreSubmitted($string); - $string = $sanitize::convertCharacterEntitiesToASCII($string, $charset); - $string = $sanitize::convertAllTabsToSpaces($string); - $string = $sanitize::makesPhpTagsSafe($string); - $string = $sanitize::compactAnyExplodedWords($string); - $string = $sanitize::removeDisallowedJavaScriptInLinksOrImgTags($string); - $string = $sanitize::removeJavaScriptEventHandlers($string); - $string = $sanitize::healNaughtyHTMLElements($string); - $string = $sanitize::healNaughtyScriptingElements($string); - $string = $sanitize::removeJavaScriptHardRedirects($string); + $string = Sanitize::removeNullCharacters($string); + $string = Sanitize::validateStandardCharacterEntities($string); + $string = Sanitize::validateUTF16TwoByteEncoding($string); + $string = Sanitize::strangeThingsAreSubmitted($string); + $string = Sanitize::convertCharacterEntitiesToASCII($string, $charset); + $string = Sanitize::convertAllTabsToSpaces($string); + $string = Sanitize::makesPhpTagsSafe($string); + $string = Sanitize::compactAnyExplodedWords($string); + $string = Sanitize::removeDisallowedJavaScriptInLinksOrImgTags($string); + $string = Sanitize::removeJavaScriptEventHandlers($string); + $string = Sanitize::healNaughtyHTMLElements($string); + $string = Sanitize::healNaughtyScriptingElements($string); + $string = Sanitize::removeJavaScriptHardRedirects($string); return $string; } diff --git a/core/Pimf/Util/Header.php b/core/Pimf/Util/Header.php index 5f90b7e..7c62919 100644 --- a/core/Pimf/Util/Header.php +++ b/core/Pimf/Util/Header.php @@ -9,7 +9,6 @@ namespace Pimf\Util; use Pimf\Config; -use Pimf\Sapi; /** * Manages a raw HTTP header sending. @@ -17,7 +16,7 @@ * @package Util * @author Gjero Krsteski */ -class Header extends Header\ContentType +class Header extends Header\ResponseStatus { /** * @var string @@ -77,7 +76,7 @@ public static function toLocation($url, $exit = true) */ protected static function view($code, $status, $exit = true) { - if (Sapi::isCli()) { + if (\Pimf\Sapi::isCli()) { echo $status . PHP_EOL; if ($exit) { exit; diff --git a/core/Pimf/Util/Header/ContentType.php b/core/Pimf/Util/Header/ContentType.php index af23037..319ce87 100644 --- a/core/Pimf/Util/Header/ContentType.php +++ b/core/Pimf/Util/Header/ContentType.php @@ -13,7 +13,7 @@ * @package Util_Header * @author Gjero Krsteski */ -abstract class ContentType extends ResponseStatus +class ContentType { public static function asJSON() { diff --git a/core/Pimf/Util/Header/ResponseStatus.php b/core/Pimf/Util/Header/ResponseStatus.php index 5a01795..cb1e4b2 100644 --- a/core/Pimf/Util/Header/ResponseStatus.php +++ b/core/Pimf/Util/Header/ResponseStatus.php @@ -13,7 +13,7 @@ * @package Util_Header * @author Gjero Krsteski */ -abstract class ResponseStatus +class ResponseStatus { /** * Name and revision of the information protocol