diff --git a/bootstrap.php b/bootstrap.php new file mode 100644 index 0000000..db287a4 --- /dev/null +++ b/bootstrap.php @@ -0,0 +1,44 @@ + + * require_once('/app/core/sleepy.php'); + * + * + * ### Changelog + * + * ### Version 2.0a + * * Converted to PSR-4 + * + * ## Version 1.1 + * * Added documentation + * + * php version 7.0.0 + * + * @category Core + * @package Sleepy + * @author Jaime A. Rodriguez + * @license http://opensource.org/licenses/MIT; MIT + * @link https://sleepymustache.com + */ + +// Get the loader that all other Classes will rely on +require_once $_SERVER['DOCUMENT_ROOT'] . '/app/sleepy/core/Loader.php'; + +use Sleepy\Core\Loader; +use Sleepy\Core\SM; + +Loader::register(); +Loader::addNamespace('Sleepy', $_SERVER['DOCUMENT_ROOT'] . '/app/sleepy'); +Loader::addNamespace('Sleepy\Core', $_SERVER['DOCUMENT_ROOT'] . '/app/sleepy/core'); +Loader::addNamespace('Sleepy\MVC', $_SERVER['DOCUMENT_ROOT'] . '/app/sleepy/mvc'); + +Loader::addNamespace('Module', $_SERVER['DOCUMENT_ROOT'] . '/app/sleepy/modules'); +Loader::addNamespace('Model', $_SERVER['DOCUMENT_ROOT'] . '/app/models'); + + +SM::initialize(); \ No newline at end of file diff --git a/class.controller.php b/class.controller.php deleted file mode 100644 index 587aeae..0000000 --- a/class.controller.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @version 1.1 - * @license http://opensource.org/licenses/MIT - */ -abstract class Controller { - public function __construct() { - if (class_exists('Hook')) { - Hook::addFilter('controller_preprocess', $string); - } - } - - public function __destruct() { - if (class_exists('Hook')) { - Hook::addFilter('controller_postprocess', $string); - } - } -} \ No newline at end of file diff --git a/class.crud.php b/class.crud.php deleted file mode 100644 index 6afc476..0000000 --- a/class.crud.php +++ /dev/null @@ -1,112 +0,0 @@ - - * @version 1.0.1 - * @license http://opensource.org/licenses/MIT - */ -abstract class CRUD extends Controller { - - /** - * Default action routes based on method - * - * @param \Sleepy\Route $route - * @return \Sleepy\View - */ - public function index(Route $route) : View { - switch ($route->method) { - case 'OPTIONS': - http_response_code(200); - return new View(new Model(), 'default'); - case 'POST': - http_response_code(201); - return $this->create($route); - break; - case 'GET': - if (is_numeric($route->params['id'])) { - http_response_code(200); - return $this->read($route); - } else { - http_response_code(200); - return $this->list($route); - } - break; - case 'DELETE': - http_response_code(204); - return $this->delete($route); - break; - case 'PUT': - http_response_code(204); - return $this->update($route); - } - } - - /** - * Gets a list of items - * - * @param \Sleepy\Route $route - * @return \Sleepy\View - */ - abstract function list(Route $route) : View; - - /** - * Create a new item - * - * @param \Sleepy\Route $route - * @return \Sleepy\View - */ - abstract function create(Route $route) : View; - - /** - * Gets a single item - * - * @param \Sleepy\Route $route - * @return \Sleepy\View - */ - abstract function read(Route $route) : View; - - /** - * Updates a single item - * - * @param \Sleepy\Route $route - * @return \Sleepy\View - */ - abstract public function update(Route $route) : View; - - /** - * Deletes a single item - * - * @param \Sleepy\Route $route - * @return \Sleepy\View - */ - abstract function delete(Route $route) : View; -} \ No newline at end of file diff --git a/class.hooks.php b/class.hooks.php deleted file mode 100644 index 420bdc8..0000000 --- a/class.hooks.php +++ /dev/null @@ -1,288 +0,0 @@ - - * @version 1.2 - * @license http://opensource.org/licenses/MIT - * - * @todo devise a better way of passing multiple parameters to hooks, perhaps use objects instead of - * arrays - */ -class Hook { - - /** - * Has this been initialized? - * - * @var bool - * @private - */ - private static $_initialized = false; - - /** - * An array of filters - * - * @var _Filter[] - * @private - */ - private static $_filters = array(); - - /** - * The directories where the modules are stored - * - * @var string - */ - public static $directories = array(); - - /** - * Prevent class from being cloned - * - * @private - */ - private function __clone() {} - - /** - * The constructor is private to ensure we only have one instance - * - * @private - */ - private function __construct() {} - - /** - * Return instance or create initial instance - * - * @private - * @static - * @return object - */ - private static function _initialize() { - if (!self::$_initialized) { - self::$directories[] = DIRBASE . '/modules/'; - self::$_initialized = true; - self::_load(); - } - } - - /** - * Loads all the modules - * - * @private - * @static - * @return void - */ - private static function _load() { - $directories = self::$directories; - - // get all subdirectories - foreach (self::$directories as $directory) { - $subdirectories = glob($directory . '/*' , GLOB_ONLYDIR); - - if (is_array($subdirectories)) { - $directories = array_merge($directories, $subdirectories); - } - } - - // include all php files - foreach ($directories as $directory) { - $files = glob($directory . '/*.php'); - - if (!is_array($files)) { - continue; - } - - foreach($files as $file) { - if (strpos($file, '_test.php') !== false) { - continue; - } - - require_once($file); - } - } - } - - /** - * Adds a new filter to a filter-type hook point - * - * @param string $name [description] - * @param string $function [description] - * @param int $args [description] - * @static - * @return void - */ - public static function applyFilter($name, $function) { - self::_initialize(); - - $name = strtolower($name); - $args = func_get_args(); - - array_shift($args); - array_shift($args); - - if (!isset(self::$_filters[$name])) { - self::$_filters[$name] = new _Filter ($name); - } - - // add the function to the filter - self::$_filters[$name]->add($function, $args); - } - - /** - * Adds a new filter-type hook point - * - * @param mixed $name [description] - * @param string $value [description] - * @static - * @return void - */ - public static function addFilter($name, $value) { - self::_initialize(); - $name = strtolower($name); - - // If there are no functions to run - if (!isset(self::$_filters[$name])) { - if (is_array($value)) { - return $value[0]; - } else { - return $value; - } - } - - foreach (self::$_filters[$name]->functions as $function => $args) { - if (is_array($value)) { - $returned = call_user_func_array($function, $value); - } else { - $returned = call_user_func($function, $value); - } - } - - return $returned; - } - - /** - * Adds a new function to a action-type hook point - * - * @param string $name Name of filter - * @param string $function Function to call - * @static - * @return void - */ - public static function doAction($name, $function) { - call_user_func_array('self::applyFilter', func_get_args()); - } - - /** - * Adds a new action-type hook point - * - * @param string $name [description] - * @static - * @return void - */ - public static function addAction($name) { - self::addFilter($name, ''); - } -} - -/** - * Private class used by the Hooks class - * - * The class stores the filters. It has properties to store the name of the - * filter as well the functions that should run when the filters are stored. - * The filters property is an array. The key is the name of the - * function and value is the arguments. Currently we do not make any use of the - * arguments. - * - * ### Usage - * - * This class is private and should not be used outside of the Hooks class - * - * @param string $name name of the filter - * - * @date September 31, 2014 - * @author Jaime A. Rodriguez - * @version 0.4 - * @license http://opensource.org/licenses/MIT - * @internal - */ - -class _Filter { - /** - * The name of the filter - * - * @var string - */ - public $name; - - /** - * A list of functions to execute - * - * @var string[] - */ - public $functions; - - /** - * Constructor - * - * @param string $name The name of the filter - */ - public function __construct($name) { - $this->name = $name; - } - - /** - * Adds a function to this filter - * - * @param string $function The function to call - * @param array $args An array of parameters - */ - public function add($function, $args) { - $this->functions[$function] = $args; - } -} \ No newline at end of file diff --git a/class.model.php b/class.model.php deleted file mode 100644 index 0f8dbc2..0000000 --- a/class.model.php +++ /dev/null @@ -1,166 +0,0 @@ -name = "John Doe"; - * ~~~ - * - * ## Changelog - * - * ### Version 1.1 - * * Add filters to the getter and setters - * * filters change if Model is extended - * - * ### Version 1.0 - * * Initial release - * - * @date May 17, 2019 - * @author Jaime A. Rodriguez - * @version 1.1 - * @license http://opensource.org/licenses/MIT - */ -class Model implements \Iterator { - private $position = 0; - private $data = array(); - - public function rewind() { - $this->position = 0; - } - - public function current() { - $keys = array_keys($this->data); - return $this->data[$keys[$this->position]]; - } - - public function key() { - $keys = array_keys($this->data); - return $keys[$this->position]; - } - - public function next() { - ++$this->position; - } - - public function valid() { - $keys = array_keys($this->data); - return isset($keys[$this->position]); - } - - /** - * Return the name of the Class - * - * @return void - */ - private function clean_class() { - $className = get_class($this); - - if ($pos = strrpos($className, '\\')) { - return substr($className, $pos + 1); - } - - return $className; - } - - /** - * Contructor - * - * @param array $props an array of properties to streamline adding them - */ - public function __construct($props = []) { - $this->position = 0; - - if (class_exists('\Sleepy\Hook')) { - Hook::addAction($this->clean_class() . '_preprocess'); - } - - foreach($props as $property => $value) { - if (class_exists('\Sleepy\Hook')) { - $this->data[$property] = Hook::addFilter($this->clean_class() . '_set_' . $property, $value); - $this->data[$property] = Hook::addFilter($this->clean_class() . '_set_property', $value); - } else { - $this->data[$property] = $value; - } - } - } - - /** - * When the Model is destructed - */ - public function __destruct() { - if (class_exists('\Sleepy\Hook')) { - Hook::addAction($this->clean_class() . '_postprocess'); - } - } - - /** - * Getter for all properties - */ - public function __get($property) { - if (isset($this->data[$property])) { - if (class_exists('\Sleepy\Hook')) { - $output = Hook::addFilter($this->clean_class() . '_get_' . $property, $this->data[$property]); - $output = Hook::addFilter($this->clean_class() . '_get_property', $output); - return $output; - - } else { - return $this->data[$property]; - } - } - } - - /** - * Setter for all properties - */ - public function __set($property, $value) { - if (class_exists('\Sleepy\Hook')) { - $this->data[$property] = Hook::addFilter($this->clean_class() . '_set_' . $property, $value); - $this->data[$property] = Hook::addFilter($this->clean_class() . '_set_property', $value); - } else { - $this->data[$property] = $value; - } - } - - /** - * Output for var_dump should be from $this->data - * - * @return array - */ - public function __debugInfo() { - return $this->data; - } - - /** - * When used as a string, output JSON of $this->data - * - * @return string - */ - public function __toString() { - return $this->toJson($this->data); - } - - /** - * When we invoke the object as a function - * - * @return void - */ - public function __invoke() { - return (object) $this->data; - } - - /** - * Return the data as JSON - * - * @return void - */ - public function toJson() { - return json_encode($this->data); - } -} \ No newline at end of file diff --git a/class.router.php b/class.router.php deleted file mode 100644 index fb59ed1..0000000 --- a/class.router.php +++ /dev/null @@ -1,497 +0,0 @@ -pattern; - * echo "Route was matched using method: ", $route->method; - * echo "The wildcard matched: ", $route->splat; - * echo "Showing user ", $route->params['id'], "
"; - * }); - * ~~~ - * - * ## Changelog - * - * ### Version 1.2.1 - * * Updated documentation - * - * ### Version 1.2 - * * Renamed _Route to Route to help with Typehinting - * - * ### Version 1.1 - * * updated private prefix (_) for consistency - * * updated documentation - * - * ### Version 1.0 - * * With unit tests in place, we're ready to call this 1.0 - * - * ### Version 0.4 - * * Simplified interface, thanks @cameff - * - * @date February 13, 2020 - * @author Jaime A. Rodriguez - * @version 1.2.1 - * @license http://opensource.org/licenses/MIT - */ -class Router { - /** - * An array of routes - * - * @var array - * @private - */ - private static $_routes = array(); - - /** - * Has a route been matched? - * - * @var boolean True, if we matched a route - */ - public static $routeFound = false; - - /** - * The delimiter for the route pattern - * - * @var string - */ - public static $delimiter = '/'; - - /** - * If true, parse the querystring instead of the path - * - * @var boolean - */ - public static $querystring = false; - - /** - * An array of parameters, either from the path or querystring - * - * @var array - */ - public static $parameters = array(); - - /** - * Gets an array from a string based on Router::$delimeter - * - * @param string $string a string to explode() - * @return array an exploded string - */ - public static function getArray($string) { - if (substr($string, strlen($string) - 1, 1) == self::$delimiter) { - $string = substr($string, 0, strlen($string) - 1); - } - - if (substr($string, 0, 1) != self::$delimiter) { - $string = self::$delimiter . $string; - } - - return explode(self::$delimiter, $string);; - } - - /** - * Creates a new route - * - * @param string $pattern A pattern to match - * @param function $func A callback function - * @return object \Sleepy\Route() - */ - public static function route($pattern, $func) { - if (is_array($pattern)) { - $route = new Route(md5($pattern[0])); - } else { - $route = new Route(md5($pattern)); - } - - array_push(self::$_routes, $route); - $route->add($pattern, $func); - return $route; - } - - /** - * Creates a new route, uses a controller and view - * - * @param string $pattern A pattern to match - * @param function $func A callback function - * @return object \Sleepy\Route() - */ - public static function mvc($pattern, $defaults = array()) { - self::route($pattern, function ($route) use ($defaults) { - // set default for defaults... (-_-) - $defaults['controller'] = (array_key_exists('controller', $defaults)) ? $defaults['controller'] : 'home'; - $defaults['action'] = (array_key_exists('action', $defaults)) ? $defaults['action'] : 'index'; - $defaults['id'] = (array_key_exists('id', $defaults)) ? $defaults['id'] : ''; - - if (!is_array($route->params)) $route->params = array(); - - // Set default controller, action, and id - $controller = (array_key_exists('controller', $route->params)) ? $route->params['controller'] : $defaults['controller']; - $action = (array_key_exists('action', $route->params)) ? $route->params['action'] : $defaults['action']; - $id = (array_key_exists('id', $route->params)) ? $route->params['id'] : $defaults['id']; - - // Make all the defaults available in the routes parameters - $route->params = array_merge($defaults, $route->params); - - $controller_file = $_SERVER['DOCUMENT_ROOT'] . '/app/controllers/'; - $controller_file .= strtolower($controller) . '.php'; - - //Sterilize - $controller = strtolower($controller); - $controller = str_replace('-', '', $controller); - $action = str_replace('-', '_', $action); - - // Call Controller::action($route) - if (file_exists($controller_file)) { - require_once($controller_file); - if (class_exists($controller)) { - $c = new $controller; - if (method_exists($c, $action)) { - $c->$action($route); - } else { - throw new RouteNotFound("Router: Action ($action) does not exist in Controller ($controller)."); - } - } else { - throw new RouteNotFound("Router: Controller ($controller) does not exist."); - } - } else { - throw new RouteNotFound("Router: Controller File ($controller_file) does not exist."); - } - }); - } - - /** - * Redirects a user to another route - * - * @param Controller $controller - * @param string $action - * @param string $params - * @return void - */ - public static function redirect($controller, $action='index', $params='') { - $route = new Route(md5("{{ $controller }}/{{ $action }}/{{ id }}/*")); - $route->params = $params; - - $controller_file = $_SERVER['DOCUMENT_ROOT'] . '/app/controllers/'; - $controller_file .= strtolower($controller) . '.php'; - - //Sterilize - $controller = strtolower($controller); - $controller = str_replace('-', '', $controller); - $action = str_replace('-', '_', $action); - - // Call Controller::action($route) - if (file_exists($controller_file)) { - require_once($controller_file); - if (class_exists($controller)) { - $c = new $controller; - if (method_exists($c, $action)) { - $c->$action($route); - } else { - throw new \Exception("Router: Action ($action) does not exist."); - } - } else { - throw new \Exception("Router: Controller ($controller) does not exist."); - } - } else { - throw new \Exception("Router: Controller File ($controller_file) does not exist."); - } - } - - /** - * Starts parsing the Router::routes - * - * @return boolean true if a route was matched - */ - public static function start($currentPath='') { - self::$routeFound = false; - - if ($currentPath == '') { - $currentPath = $_SERVER['REQUEST_URI']; - } - - if (self::$querystring) { - $currentPath = str_replace('/?q=', '', $currentPath); - } else { - $currentPath = preg_replace('/\?.*/', '', $currentPath); - } - - // Get all parameters - self::$parameters = self::getArray($currentPath); - - foreach (self::$_routes as $route) { - $route->method = (isset($_SERVER['REQUEST_METHOD'])) ? $_SERVER['REQUEST_METHOD'] : 'GET'; - $route->execute(); - } - - if (!self::$routeFound) { - throw new RouteNotFound('Router: Route not found.'); - } - - return self::$routeFound; - } - - public static function reset() { - self::$_routes = array(); - } -} - -/** - * Private class used by the Router class - * - * ### Usage - * - * This class is private and should not be instatiated outside of the Router - * class - * - * ### Changelog - * - * ## Version 0.4 - * * Bug fixes - * - * @todo Write tests for the class - * - * @date September 31, 2014 - * @author Jaime A. Rodriguez - * @version 0.4 - * @license http://opensource.org/licenses/MIT - * @internal - */ -class Route { - /** - * A list of (pattern ,callbacks) - * - * @var array - */ - private $_functions = array(); - - /** - * The name of the route, MD5 hash of pattern by default - * - * @var string - */ - public $name; - - /** - * A hash of matched placeholder - * - * @var string[] - */ - public $params; - - /** - * The method that was matched - * - * @var string - */ - public $method; - - /** - * Returns the string matched with a wildcard - * - * @var string - */ - public $splat; - - /** - * Cleans the handlebars from placeholders - * - * @param string $placeholder The full placeholder - * @return string The stripped placeholder - */ - private function _cleanPlaceholder($placeholder) { - $key = str_replace('{{', '', $placeholder); - $key = str_replace('}}', '', $key); - - return trim($key); - } - - /** - * Is this $string a placeholder - * - * @param string $string The possible placeholder - * @return boolean True, if it is a placeholder - */ - private function _isPlaceholder($string) { - return substr($string, 0, 2) == '{{' && substr($string, strlen($string) - 2, 2) == '}}'; - } - - /** - * Run all the filters for a placeholder - * - * @param string $key The placeholder - * @param string $string The string to parse - * @return string The parsed string - */ - private function _runFilters($key, $string) { - if (class_exists('Hook')) { - $string = Hook::addFilter('route_parameters', $string); - $string = Hook::addFilter('route_parameter_' . $key, $string); - $string = Hook::addFilter('route_' . $this->name . '_parameters', $string); - $string = Hook::addFilter('route_' . $this->name . '_parameter_' . $key, $string); - } - - return $string; - } - - /** - * Does the pattern have a wildcard? - * - * @return boolean True, if there is a wildcard - */ - private function _hasWildcard($pattern) { - if (strlen($pattern) == 0) { - return false; - } else { - return strpos($pattern, '*') !== false; - } - } - - /** - * Store the variables found in the route - - * @param string $key The placeholder - * @param string $value The value - * @return boolean True, if we succeeded - */ - private function _storeVariable($key, $value) { - if ($value == '') { - return false; - } - - $key = $this->_cleanPlaceholder($key); - $value = $this->_runFilters($key, $value); - - // Check for multiple variables, they should match. - if (isset($this->params[$key])) { - if ($value != $this->params[$key]) { - return false; - } - } - - $this->params[$key] = $value; - return true; - } - - /** - * Creates a new route - * - * @param string $name Optional. - * @return void - */ - public function __construct($name='') { - $this->name = $name; - } - - /** - * if URL matches pattern do $func - * - * @param string $pattern a pattern with {{ placeholders }} - * @param function $func Executes if pattern matches; func($variables) - * @return void - */ - public function add($pattern, $func) { - // If we have an array of patterns match those individually - if (is_array($pattern)) { - foreach ($pattern as $p) { - $this->add($p, $func); - } - } else { - array_push($this->_functions, array($pattern, $func)); - } - - return $this; - } - - /** - * Executes the call back functions - * - * @return void - */ - public function execute() { - $noMatch = false; - - // Exit when there is nothing left to do - if (count($this->_functions) < 1) { - return; - } - - // Shift a function off the queue - $r = array_shift($this->_functions); - $rawPattern = $r[0]; - $func = $r[1]; - - if (Router::$routeFound) { - $noMatch = true; - } else { - // Get array from string - $pattern = Router::getArray($rawPattern); - - // If they are obviously different then stop the route - if (count(Router::$parameters) == count($pattern) || $this->_hasWildcard($rawPattern)) { - // Check for matches, stop if we have a problem - foreach ($pattern as $idx => $value) { - // Store the variable - if ($this->_isPlaceholder($value)) { - if (!$this->_storeVariable($value, @Router::$parameters[$idx])) { - $noMatch = true; - break; - } - - continue; - } - - // If we are at a wildcard, we have a match! - if ($value == '*') { - $this->splat = implode(Router::$delimiter, array_slice(Router::$parameters, $idx)); - break; - } - - // If something doesn't match then stop the route. - if (!isset(Router::$parameters[$idx]) || $value != Router::$parameters[$idx]) { - $noMatch = true; - break; - } - } - } else { - $noMatch = true; - } - } - - if ($noMatch) { - if (class_exists('Hook')) { - Hook::addAction('route_failed'); - Hook::addAction('route_failed_' . $this->name); - } - } else { - // Call route_start actions - if (class_exists('Hook')) { - $continue = Hook::addFilter('route_start', true); - $continue = Hook::addFilter('route_start_' . $this->name, true); - } - - if ($continue) { - $this->pattern = $rawPattern; - Router::$routeFound = true; - $func($this); - } - - // Call route_end actions - if (class_exists('Hook')) { - Hook::addAction('route_end'); - Hook::addAction('route_end_' . $this->name); - } - } - - // This wasn't it, let's try the next one - $this->execute(); - } -} - -/** - * Exception: Route not Found - */ -class RouteNotFound extends \Exception {} diff --git a/class.sm.php b/class.sm.php deleted file mode 100644 index 0b42a4e..0000000 --- a/class.sm.php +++ /dev/null @@ -1,160 +0,0 @@ - - * @version 1.3.1 - * @license http://opensource.org/licenses/MIT - */ -class SM { - /** - * Stores the instance of SM when initialized - * - * @var SM - */ - private static $_instance; - - /** - * Is sleepyMUSTACHE initialized? - * - * @var boolean - */ - public static $is_initialized = false; - - /** - * Prevent class from being cloned - * - * @return void - */ - private function __clone() {} - - /** - * The constructor is private to ensure we only have one sleepy_preprocess - * and sleepy_postprocess hooks. - * - * @return void - */ - private function __construct() { - require_once('class.debug.php'); - - // Enable sessions - session_start(); - - // Teamsite fixes - if (@include_once('Webkit/init.php')) { - define('TEAMSITE', true); - $_SERVER['DOCUMENT_ROOT'] = $docroot; - } else { - $WHG_DB_HOST = ""; - $WHG_DB_USER = ""; - $WHG_DB_PASSWD = ""; - $WHG_DB_REPLDB = ""; - } - - // Check for the settings overide in the root - if (@!include_once($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'settings.php')) { - include_once('settings.php'); - } - - require_once('class.hooks.php'); - require_once('class.template.php'); - require_once('class.router.php'); - - ob_start(); - Hook::addAction('sleepy_preprocess'); - - // Send the encoding ahead of time to speed up rendering - header('Content-Type: text/html; charset=utf-8'); - } - - /** - * Show the buffered pages with actions and filters - * - * @return void - */ - public function __destruct() { - echo Hook::addFilter('sleepy_render', ob_get_clean()); - Hook::addAction('sleepy_postprocess'); - } - - /** - * Initialized the SM class - * - * @return void - */ - public static function initialize() { - if (!self::$is_initialized) { - self::$is_initialized = true; - self::$_instance = new SM; - } - } - - /** - * Checks if we are in the live environment - * - * @return boolean Are we in the live environment? - */ - public static function isLive() { - return (ENV == 'LIVE'); - } - - /** - * Checks if we are in the staging environment - * - * @return boolean True Are we in the staging environment? - */ - public static function isStage() { - return (ENV == 'STAGE'); - } - - /** - * Checks if we are in the development environment - * - * @return boolean Are we in the development environment? - */ - public static function isDev() { - return (ENV != 'LIVE' && ENV != 'STAGE'); - } - - /** - * Checks if the current site matches a URL - * - * @param string $str The URL to match with current site - * @return boolean true if there was a match - */ - public static function isENV($str) { - foreach (explode(',' , $str) as $url) { - if (stripos($_SERVER['SERVER_NAME'], $url) !== false) - return true; - } - - return false; - } -} \ No newline at end of file diff --git a/class.template.php b/class.template.php deleted file mode 100644 index 65f6b7b..0000000 --- a/class.template.php +++ /dev/null @@ -1,545 +0,0 @@ - - * - * {{ page_title }} - * - * - *

{{ heading }}

- *

This page has been viewed {{ hits }} times.

- * - * - * ~~~ - * - * Templates are used by instantiating the Template class and passing the template URL to the - * constructor. The bind method is used to map the placeholders to content. - * - * ### PHP file: *index.php* - * - * ~~~ php - * require_once('include/sleepy.php'); - * $page = new \Sleepy\Template('templates/default.tpl'); - * $page->bind('page_title', 'Sleepy Mustache'); - * $page->bind('heading', 'Hello world!'); - * $page->show(); // Display the compiled template - * ~~~ - * - * #### Components - * - * Components are design to be reusable templates. They can be attached to other templates by using - * the *#include* directive. Good examples are *header.tpl* or *slideshow.tpl*. - * - * ### PHP file: *\app\templates\components\header.tpl* - * - * ~~~ php - * - * - * {{ page_title }} - * - * - * ~~~ - * - * ### PHP file: *\app\templates\components\footer.tpl* - * - * ~~~ php - * - * - * ~~~ - * - * ### Template file: *\app\templates\default.tpl* - * ~~~ php - * {{#include components/header.tpl }} - *

{{ heading }}

- *

This page has been viewed {{ hits }} times.

- * {{#include components/footer.tpl }} - * ~~~ - * - * ### Binding Arrays - * - * Many times you need to bind an array of data to a template. For example, a slideshow or list of - * users. In this case, we use the #each directives to loop thru the array. - * - * ### Template file: *\app\templates\users.tpl* - * - * ~~~ php - * {#each u in users} - *
- *

{{ u.name }}

- *

{{ u.description }}

- *
- * {\each} - * ~~~ - * - * ## Changelog - * - * ### Version 1.10.1 - * * Updated documentation - * - * ### Version 1.10 - * * Add rudimentary if statement blocks - * - * ### Version 1.9 - * * Add Action for individual Template Starts per $template name - * - * ### Version 1.8 - * * Allow Template::bind() to take an array to bind multiple values at once - * - * ### Version 1.7 - * * Updated private prefix (_) for consistency - * * Updated documentation - * - * ### Version 1.6 - * * No longer dependant on Hooks Module - * - * @date February 13, 2020 - * @author Jaime A. Rodriguez - * @version 1.10.1 - * @license http://opensource.org/licenses/MIT - */ - -class Template { - /** - * The extension for template files - * - * @var string - */ - public $extension = '.tpl'; - - /** - * The template directory - * - * @var string - */ - public $directory; - - /** - * The template file - * - * @var string - */ - protected $_file; - - /** - * The data bound to the template - * - * @var mixed[] - */ - protected $_data = array(); - - /** - * The constructor - * - * @param string $template The name of the template - * @param string $basedir The base directory for template files - * @return void - */ - public function __construct($template='', $basedir='') { - if (class_exists('\Sleepy\Hook')) { - Hook::addAction('template_start'); - Hook::addAction('template_start' . $template); - } - - // If they didn't pass a basedir then try the default - if ($basedir == '') { - if (!defined('DIRBASE')) { - define('DIRBASE', $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'app'); - } - - $this->directory = DIRBASE . DIRECTORY_SEPARATOR . 'templates' . DIRECTORY_SEPARATOR; - } else { - $this->directory = $basedir; - } - - if (!empty($template)) { - $this->setTemplate($template); - } - } - - /** - * Does the template exist? - * - * @param string $file Name of template - * @return bool True if template exists - */ - private function _checkTemplate($file) { - if (empty($file)) { - throw new \Exception('Template file has not been set.'); - } - - // Check that the directory is set correctly - if (!file_exists($this->directory)) { - throw new \Exception("Template directory '{$this->directory}' does not exists."); - } - - // Check if the template exists in the directory - if (!file_exists($this->directory . $file . $this->extension)) { - throw new \Exception("Template '{$this->directory}{$file}{$this->extension}' does not exist."); - } - - return true; - } - - /** - * Given a path, the function returns a piece of $arr. For example - * 'name.first' will return $arr['name']['first'] - * - * @param array $arr An array to search using the $path - * @param string $path A path representing the dimensions of the array - * @return mixed A sub-array or string - */ - private function _assignArrayByPath($arr, $path) { - - $keys = explode('.', $path); - - if (is_array($keys)) { - foreach ($keys as $key) { - if (array_key_exists($key, $arr)) { - $arr = $arr[$key]; - } else { - return false; - } - } - } - - return $arr; - } - - /** - * Renders the template - * - * @param string $template The template to render - * @param mixed[] $data The data bound to the template - * @return string The rendered template - */ - private function _render($template, $data) { - $template = $this->_renderInclude($template); - $template = $this->_renderEach($template, $data); - $template = $this->_renderIf($template, $data); - - if (class_exists('\Sleepy\Hook')) { - $template = Hook::addFilter('prerender_template', $template); - } - - $template = $this->_renderPlaceholder($template, $data); - - return $template; - } - - /** - * Render the if blocks - * - * @todo Not very robust, remove eval at a later date - * @todo Add Else blcok - * @todo Add tests - * - * @param string $template - * @param mixed[] $data - * @return void - */ - private function _renderIf($template, $data) { - // Process the #if blocks - if (preg_match_all('/{{\s?#if.+?}}(?:(?>[^{}]+)|(?R))*{{\s?\/if\s?}}/ism', $template, $ifs)) { - - // For every #if - foreach ($ifs[0] as $value) { - // Reset rendered data - $rendered = ''; - - // break statement into 3 pieces (val1) (operator) (val2) - preg_match('/{{\s?#if\s?(?.*?)\s(?.*?)\s(?.*?)\s?}}/', $value, $tokens); - - // Replace placeholders - if (isset($this->_data[$tokens[1]])) { - $tokens[1] = &$this->_data[$tokens[1]]; - } else { - $tokens[1] = trim(trim($tokens[1], '"'), "'"); - } - - // Replace placeholders - if (isset($this->_data[$tokens[3]])) { - $tokens[3] = &$this->_data[$tokens[3]]; - } else { - $tokens[3] = trim(trim($tokens[3], '"'), "'"); - } - - // Evaluate if Statement - $truthy = eval("return \$tokens[1] $tokens[2] \$tokens[3];"); - - if ($truthy) { - // replace with the if statements - $new_template = preg_replace('/{{\s?#if.*?}}/s', '', $value, 1); - $new_template = preg_replace('/{{\s?\/if\s?}}$/s', '', $new_template, 1); - } else { - $new_template = str_replace($value, '', $value); - } - - $rendered = $rendered . $this->_render($new_template, $data); - $template = str_replace($value, $rendered, $template); - } - } - - return $template; - } - - /** - * Render the includes - * - * @param string $template - * @return void - */ - private function _renderInclude($template) { - // Process the includes - if (preg_match('/{{\s*#include\s.*}}/', $template, $include)) { - $index = trim(str_replace('{{', '', str_replace('}}', '', $include[0]))); - - if (file_exists($this->directory . str_replace('#include ', '', $index) . $this->extension)) { - ob_start(); - include($this->directory . str_replace('#include ', '', $index) . $this->extension); - } else { - ob_clean(); // clear buffer in $this->show(); - throw new \Exception($this->directory . str_replace('#include ', '', $index) . $this->extension . ' doesn\'t exist. Cannot include file.'); - } - - $template = $this->_renderInclude(str_replace($include[0], ob_get_clean(), $template)); - } - - return $template; - } - - /** - * Render the each blocks - * - * @param string $template - * @param mixed[] $data - * @return void - */ - private function _renderEach($template, $data) { - // Process the #each blocks - if (preg_match_all('/{{\s?#each.+?}}(?:(?>[^{}]+)|(?R))*{{\s?\/each\s?}}/ism', $template, $loops)) { - // For every #each - foreach ($loops[0] as $value) { - // Reset rendered data - $rendered = ''; - - // Stores the values of and into $forin - preg_match('/{{\s?#each\s(?\w+) in (?.*?)\s?}}/', $value, $forin); - - $forin['in'] = strtolower($forin['in']); - - // Removes the each loop - $new_template = preg_replace('/{{\s?#each.*?}}/s', '', $value, 1); - $new_template = preg_replace('/{{\s?\/each\s?}}$/s', '', $new_template, 1); - - // get the array based on the - $in = $this->_assignArrayByPath($data, $forin['in']); - - // for each changelog - if (is_array($in[0])) { - - // Allow hooks to edit the data - if (class_exists('\Sleepy\Hook')) { - $in = Hook::addFilter('template_each_array', array($in)); - } - - $iterator = 0; - - foreach ($in as $new_data) { - $iterator++; - - if (class_exists('\Sleepy\Hook')) { - $new_data = Hook::addFilter('template_each', array($new_data)); - $new_data = Hook::addFilter('template_each_' . $forin['for'], array($new_data)); - } - - $new_data['iterator'] = $iterator; - $new_data['zebra'] = ($iterator % 2) ? 'odd' : 'even'; - - // Make the $new_data match the - $new_data[$forin['for']] = $new_data; - - // render the new template - $rendered = $rendered . $this->_render($new_template, $new_data); - } - } else { - // render the new template - $rendered = $rendered . $this->_render($new_template, $data); - } - - $template = str_replace($value, $rendered, $template); - } - } - - return $template; - } - - /** - * Render the placeholders - * - * @param string $template - * @param mixed[] $data - * @return void - */ - private function _renderPlaceholder($template, $data) { - // Find all the single placeholders - preg_match_all('/{{\s?(.*?)(\s.*?)?\s?}}/', $template, $matches); - - // For each replace with a value - foreach (array_unique($matches[0]) as $index => $placeholder) { - $key = strtolower($matches[1][$index]); - - $arguments = array( - $this->_assignArrayByPath($data, $key) - ); - - # We trim so that there are no extra blank arguments - $arguments = array_merge($arguments, explode(' ', trim($matches[2][$index]))); - - $boundData = $arguments; - - if (class_exists('\Sleepy\Hook')) { - $boundData = Hook::addFilter('render_placeholder_' . strtolower($key), $boundData); - } - - // Some filters might take arrays and return only a single value, if - // hooks are disabled, lets return only this single value - if (is_array($boundData)) { - $boundData = $boundData[0]; - } - - $template = str_replace($placeholder, $boundData, $template); - } - - return $template; - } - - /** - * Parses the template after it's been setup - * - * @return string The rendered template - */ - private function _parseTemplate() { - $this->_checkTemplate($this->_file); - - // Render template file - ob_start(); - include($this->directory . $this->_file . $this->extension); - $template = $this->_render(ob_get_clean(), $this->_data); - - if (class_exists('\Sleepy\Hook')) { - $template = Hook::addFilter('render_template_' . $this->_file, $template); - $template = Hook::addFilter('render_template', $template); - } - - return $template; - } - - /** - * Sets the template to use. - * - * @param string $file The Filename - * @return void - */ - public function setTemplate($file) { - if ($this->_checkTemplate($file)) { - $this->_file = $file; - } - } - - /** - * Binds data to the template placeholders - * - * @param mixed $placeholder The template placeholder - * @param mixed $value The value that replaced the placeholder - * @return void - */ - public function bind($placeholder, $value='') { - if (!is_array($placeholder)) { - $placeholder = array( - trim(strtolower($placeholder)) => $value - ); - } - - foreach($placeholder as $key => $value) { - $key = trim(strtolower($key)); - - if (!is_array($value)) { - if (class_exists('\Sleepy\Hook')) { - $value = Hook::addFilter('bind_placeholder_' . trim($key), $value); - } - } - - $this->_data[$key] = $value; - } - } - - /** - * Starts a buffer that will bind data to the template placeholders. The - * buffer will capture anything you output until $this->bindStop() - * - * @return void - */ - public function bindStart() { - ob_start(); - } - - /** - * Stops the buffer that binds data to the template placeholders - * - * @param string $placeholder The template placeholder - * @return void - */ - public function bindStop($placeholder) { - $content = ob_get_clean(); - - if (class_exists('\Sleepy\Hook')) { - $content = Hook::addFilter('bind_placeholder_' . $placeholder, $content); - } - - $this->_data[trim(strtolower($placeholder))] = $content; - } - - /** - * Gets the data for a placeholder - * - * @param string $placeholder The placeholder - * @return mixed The data stored in the placeholder - */ - public function get($key) { - $value = $this->_data[$key]; - - if (class_exists('\Sleepy\Hook')) { - Hook::addFilter('template_get_' . $key, $value); - } - - return $value; - } - - /** - * Shows the rendered template - * - * @return void - */ - public function show() { - echo $this->_parseTemplate(); - } - - /** - * Retrieves the rendered template - * - * @return void - */ - public function retrieve() { - return $this->_parseTemplate(); - } -} \ No newline at end of file diff --git a/class.view.php b/class.view.php deleted file mode 100644 index 6a9f96c..0000000 --- a/class.view.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @version 1.1.1 - * @license http://opensource.org/licenses/MIT - */ - class View { - public function __construct(Model $model, string $template="default") { - $this->model = $model; - - $this->page = new Template($template, DIRBASE . DIRECTORY_SEPARATOR . 'views' . DIRECTORY_SEPARATOR); - $this->page->model = &$this->model; - $this->modelToPlaceholder($model); - $this->render($model); - } - - /** - * Render function used to scope out variables - * - * @param Model $model - * @return void - */ - private function render($model) { - $this->page->show(); - } - - /** - * Creates placeholders for all Model properties - * - * @param Model $model - * @return void - */ - private function modelToPlaceholder($model) { - foreach($model as $key => $value) { - $this->page->bind($key, $value); - } - } - } \ No newline at end of file diff --git a/class.debug.php b/core/Debug.php similarity index 59% rename from class.debug.php rename to core/Debug.php index a0a2824..6948e56 100644 --- a/class.debug.php +++ b/core/Debug.php @@ -1,6 +1,4 @@ - * @version 1.10 - * @license http://opensource.org/licenses/MIT + * php version 7.0.0 + * + * @category Core + * @package Sleepy + * @author Jaime A. Rodriguez + * @license http://opensource.org/licenses/MIT; MIT + * @link https://sleepymustache.com */ -class Debug { +namespace Sleepy\Core; + +/** + * The Debug class + * + * @category Core + * @package Sleepy + * @author Jaime A. Rodriguez + * @license http://opensource.org/licenses/MIT; MIT + * @link https://sleepymustache.com + */ +class Debug +{ /** * The single instance is stored here. * * @var Debug */ - private static $_instance = NULL; + private static $_instance = null; /** * PDO Database object @@ -58,28 +76,28 @@ class Debug { * * @var bool */ - public static $enable_console = false; + public static $enableConsole = false; /** * Enable output to screen * * @var bool */ - public static $enable_show = false; + public static $enableShow = false; /** * Enabled logging to a database * * @var bool */ - public static $enable_log = false; + public static $enableLog = false; /** * Enabled logging via email * * @var bool */ - public static $enable_send = false; + public static $enableSend = false; /** * Email address to send email to. @@ -163,24 +181,36 @@ class Debug { * * @return void */ - private function __clone() {} + private function __clone() + { + } /** * The constructor is private to ensure we only have one instance * * @return void */ - private function __construct() { + private function __construct() + { // Setup email defaults - $server_ip = (isset($_SERVER['SERVER_ADDR'])) ? $_SERVER['SERVER_ADDR'] : ''; - $user_ip = (isset($_SERVER['REMOTE_ADDR'])) ? $_SERVER['REMOTE_ADDR'] : ''; - $filename = (isset($_SERVER['SCRIPT_FILENAME'])) ? $_SERVER['SCRIPT_FILENAME'] : ''; - $date = date(DATE_ATOM, mktime(date('G'), date('i'), 0, date('m'), date('d'), date('Y'))); + $serverIp = (isset($_SERVER['SERVER_ADDR'])) + ? $_SERVER['SERVER_ADDR'] + : ''; + $userIp = (isset($_SERVER['REMOTE_ADDR'])) + ? $_SERVER['REMOTE_ADDR'] + : ''; + $filename = (isset($_SERVER['SCRIPT_FILENAME'])) + ? $_SERVER['SCRIPT_FILENAME'] + : ''; + $date = date( + DATE_ATOM, + mktime(date('G'), date('i'), 0, date('m'), date('d'), date('Y')) + ); Debug::$emailBuffer = array(); Debug::$emailBuffer[] = "Date: {$date}"; - Debug::$emailBuffer[] = "Server IP: {$server_ip}"; - Debug::$emailBuffer[] = "Client IP: {$user_ip}"; + Debug::$emailBuffer[] = "Server IP: {$serverIp}"; + Debug::$emailBuffer[] = "Client IP: {$userIp}"; Debug::$emailBuffer[] = "Filename: {$filename}"; Debug::$emailBuffer[] = '---'; Debug::$emailTo = EMAIL_TO; @@ -202,18 +232,20 @@ private function __construct() { * * @return void */ - public function __destruct() { - if (self::$enable_send) { + public function __destruct() + { + if (self::$enableSend) { self::sendEmail(); } } /** - * Return instance or create initial instance - * - * @return Debug - */ - private static function _initialize() { + * Return instance or create initial instance + * + * @return Debug + */ + private static function _initialize() + { if (!self::$_instance) { self::$_instance = new Debug(); } @@ -225,14 +257,17 @@ private static function _initialize() { * Displays debug information in JS Console * * @param mixed $var Anything you want to log + * * @return bool - * @todo create a hook so the dev can create custom views when outputting - * debug data. + * + * @todo create a hook so the dev can create custom views when outputting + * debug data. */ - private static function console($var) { + private static function _console($var) + { $output = ''; - if (!self::$enable_console) { + if (!self::$enableConsole) { return false; } @@ -258,21 +293,32 @@ private static function console($var) { } /** - * sets the Exception Handler + * Sets the Exception Handler + * + * @return void */ - public function setHandler() { + public function setHandler() + { self::_initialize(); set_exception_handler(array('Debug', 'exceptionHandler')); } /** * Exception Handler + * + * @param Exception $e The exception + * + * @return void */ - public function exceptionHandler($e) { + public function exceptionHandler($e) + { if (headers_sent()) { echo 'Error: ' , $e->getMessage(), "\n"; } else { - $_SESSION['exception'] = $e->getMessage() . '
' . str_replace("\n", '
', $e->getTraceAsString()) . ''; + $_SESSION['exception'] + = $e->getMessage() + . '
' + . str_replace("\n", '
', $e->getTraceAsString()); header('Location: /error/'); } } @@ -281,12 +327,15 @@ public function exceptionHandler($e) { * Writes to a database log table. The table should be called log, or set * $this->dbTable. It should contain 2 columns: 'datetime, message' * - * @param mixed $var Anything you want to log + * @param mixed $var Anything you want to log + * * @return bool + * * @todo add a create for the log table */ - private function log($var) { - if (!self::$enable_log) { + private function _log($var) + { + if (!self::$enableLog) { return false; } @@ -299,16 +348,29 @@ private function log($var) { try { // MySQL with PDO_MYSQL if (!is_object(self::$_dbPDO)) { - self::$_dbPDO = new \PDO('mysql:host=' . self::$dbHost . ';dbname=' . self::$dbName, self::$dbUser, self::$dbPass); - self::$_dbPDO->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); + self::$_dbPDO = new \PDO( + 'mysql:host=' . self::$dbHost . ';dbname=' . self::$dbName, + self::$dbUser, self::$dbPass + ); + self::$_dbPDO->setAttribute( + \PDO::ATTR_ERRMODE, + \PDO::ERRMODE_EXCEPTION + ); } - $query = self::$_dbPDO->prepare('INSERT INTO ' . self::$dbTable . ' (datetime, message) values (:datetime, :message)'); - $datetime = date(DATE_ATOM, mktime(date('G'), date('i'), 0, date('m'), date('d'), date('Y'))); + $query = self::$_dbPDO->prepare( + 'INSERT INTO ' + . self::$dbTable + . ' (datetime, message) values (:datetime, :message)' + ); + $datetime = date( + DATE_ATOM, + mktime(date('G'), date('i'), 0, date('m'), date('d'), date('Y')) + ); $query->bindParam(':datetime', $datetime); $query->bindParam(':message', $buffer); $query->execute(); } catch(\PDOException $e) { - self::show($e->getMessage()); + self::_show($e->getMessage()); return false; } @@ -318,13 +380,16 @@ private function log($var) { /** * Displays debug information on screen * - * @param mixed $var Anything you want to log + * @param mixed $var Anything you want to log * + * * @return bool - * @todo create a hook so the dev can create custom views when outputting - * debug data. + * + * @todo create a hook so the dev can create custom views when outputting + * debug data. */ - private static function show($var) { - if (!self::$enable_show) { + private static function _show($var) + { + if (!self::$enableShow) { return false; } @@ -344,12 +409,13 @@ private static function show($var) { /** * Iterates a buffer that gets emailed on __destruct() * - * @param mixed $var - * Anything you want to log + * @param mixed $var Anything you want to log + * * @return bool */ - private static function send($var) { - if (!self::$enable_send) { + private static function _send($var) + { + if (!self::$enableSend) { return false; } @@ -365,34 +431,37 @@ private static function send($var) { /** * Determines what output methods are enabled and passes $var to it. * - * @param mixed $var Anything you want to log + * @param mixed $var Anything you want to log + * * @return void */ - public static function out($var) { + public static function out($var) + { $result = true; self::_initialize(); - if (self::$enable_console) { - $result = $result && self::$_instance->console($var); + if (self::$enableConsole) { + $result = $result && self::$_instance->_console($var); } - if (self::$enable_send) { - $result = $result && self::$_instance->send($var); + if (self::$enableSend) { + $result = $result && self::$_instance->_send($var); } - if (self::$enable_log) { - $result = $result && self::$_instance->log($var); + if (self::$enableLog) { + $result = $result && self::$_instance->_log($var); } - if (self::$enable_show) { - $result = $result && self::$_instance->show($var); + if (self::$enableShow) { + $result = $result && self::$_instance->_show($var); } - if (!self::$enable_console && - !self::$enable_show && - !self::$enable_send && - !self::$enable_log) { + if (!self::$enableConsole + && !self::$enableShow + && !self::$enableSend + && !self::$enableLog + ) { $result = false; } @@ -404,21 +473,23 @@ public static function out($var) { * * @return void */ - public static function disable() { - self::$enable_console = false; - self::$enable_log = false; - self::$enable_send = false; - self::$enable_show = false; + public static function disable() + { + self::$enableConsole = false; + self::$enableLog = false; + self::$enableSend = false; + self::$enableShow = false; } /** * Sends the email. * * @return bool true if sent successfully - * @todo make this private, I cannot remember why this is public... + * @todo make this private, I cannot remember why this is public... */ - public static function sendEmail() { - if (!self::$enable_send) { + public static function sendEmail() + { + if (!self::$enableSend) { return false; } @@ -432,6 +503,11 @@ public static function sendEmail() { if (self::$emailBCC != '') { $headers[] = 'Bcc: ' . self::$emailBCC; } - return mail(self::$emailTo, self::$emailSubject, implode("
\n", self::$emailBuffer), implode("\n", $headers)); + return mail( + self::$emailTo, + self::$emailSubject, + implode("
\n", self::$emailBuffer), + implode("\n", $headers) + ); } } diff --git a/core/Hook.php b/core/Hook.php new file mode 100644 index 0000000..559070a --- /dev/null +++ b/core/Hook.php @@ -0,0 +1,359 @@ + + * @license http://opensource.org/licenses/MIT; MIT + * @link https://sleepymustache.com + */ + +namespace Sleepy\Core; + +/** + * The Hook Class + * + * The static class that is used to define hook points and assign functionality to + * the actions and filters + * + * @category Core + * @package Sleepy + * @author Jaime A. Rodriguez + * @license http://opensource.org/licenses/MIT; MIT + * @link https://sleepymustache.com + */ +class Hook +{ + public static $hooks = []; + + /** + * Has this been initialized? + * + * @var bool + * @private + */ + private static $_initialized = false; + + /** + * An array of filters + * + * @var Filter[] + * @private + */ + private static $_filters = array(); + + /** + * The directories where the modules are stored + * + * @var string + */ + public static $directories = array(); + + /** + * Prevent class from being cloned + * + * @private + * @return void + */ + private function __clone() + { + } + + /** + * The constructor is private to ensure we only have one instance + * + * @private + * @return void + */ + private function __construct() + { + } + + /** + * Return instance or create initial instance + * + * @private + * @static + * @return object + */ + private static function _initialize() + { + if (!self::$_initialized) { + self::$directories[] + = DIRBASE . DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR; + self::$_initialized = true; + self::_load(); + } + } + + /** + * Loads all the modules + * + * @private + * @static + * @return void + */ + private static function _load() + { + $directories = self::$directories; + + // get all subdirectories + foreach (self::$directories as $directory) { + $subdirectories = glob($directory . '/*', GLOB_ONLYDIR); + + if (is_array($subdirectories)) { + $directories = array_merge($directories, $subdirectories); + } + } + + // include all php files + foreach ($directories as $directory) { + $files = glob($directory . '/*.php'); + + if (!is_array($files)) { + continue; + } + + foreach ($files as $file) { + if (strpos($file, '_test.php') !== false) { + continue; + } + + include_once $file; + } + } + } + + /** + * Adds a new filter to a filter-type hook point + * + * @param string $name [description] + * @param string $function [description] + * + * @static + * @return void + */ + public static function applyFilter($name, $function) + { + self::_initialize(); + + $name = strtolower($name); + $args = func_get_args(); + + array_shift($args); + array_shift($args); + + if (!isset(self::$_filters[$name])) { + self::$_filters[$name] = new Filter($name); + } + + // add the function to the filter + self::$_filters[$name]->add($function, $args); + } + + /** + * Adds a new filter-type hook point + * + * @param mixed $name [description] + * @param string $value [description] + * + * @static + * @return void + */ + public static function addFilter($name, $value) + { + self::_initialize(); + $name = strtolower($name); + array_push(self::$hooks, $name); + + // If there are no functions to run + if (!isset(self::$_filters[$name])) { + if (is_array($value)) { + return $value[0]; + } else { + return $value; + } + } + + foreach (self::$_filters[$name]->functions as $function) { + if (is_array($value)) { + $returned = call_user_func_array($function['call'], $value); + } else { + $returned = call_user_func($function['call'], $value); + } + } + + return $returned; + } + + /** + * Adds a new function to a action-type hook point + * + * @param string $name Name of filter + * @param string $function Function to call + * + * @static + * @return void + */ + public static function doAction($name, $function) + { + call_user_func_array('self::applyFilter', func_get_args()); + } + + /** + * Adds a new action-type hook point + * + * @param string $name [description] + * + * @static + * @return void + */ + public static function addAction($name) + { + self::addFilter($name, ''); + } + + /** + * Registers a module + * + * @param Module $className The Module to register + * + * @return void + */ + public static function register($className) + { + if ($className instanceof Module) { + //$x = new $className(); + } else { + throw new Exception('Modules must extend \Sleepy\Core\Module'); + } + } +} + +/** + * Private class used by the Hooks class + * + * The class stores the filters. It has properties to store the name of the + * filter as well the functions that should run when the filters are stored. + * The filters property is an array. The key is the name of the + * function and value is the arguments. Currently we do not make any use of the + * arguments. + * + * ### Usage + * + * This class is private and should not be used outside of the Hooks class + * + * @param string $name name of the filter + * + * @category Core + * @package Sleepy + * @author Jaime A. Rodriguez + * @license http://opensource.org/licenses/MIT; MIT + * @version Release: 2.0.0 + * @link https://sleepymustache.com + * @date March 02, 2020 + * @internal + */ +class Filter +{ + /** + * The name of the filter + * + * @var string + */ + public $name; + + /** + * A list of functions to execute + * + * @var string[] + */ + public $functions = []; + + /** + * Constructor + * + * @param string $name The name of the filter + */ + public function __construct($name) + { + $this->name = $name; + } + + /** + * Adds a function to this filter + * + * @param string $function The function to call + * @param array $args An array of parameters + * + * @return void + */ + public function add($function, $args) + { + array_push( + $this->functions, + [ + "call" => $function, + "arguments" => $args + ] + ); + } +} \ No newline at end of file diff --git a/core/Loader.php b/core/Loader.php new file mode 100644 index 0000000..1372b9c --- /dev/null +++ b/core/Loader.php @@ -0,0 +1,215 @@ + + * @license http://opensource.org/licenses/MIT; MIT + * @link https://sleepymustache.com + */ + +namespace Sleepy\Core; + +/** + * The Loader Class + * + * Used to load PSR-4 Modules. Taken and modified from the php-fig.com website + * + * @category Core + * @package Sleepy + * @author Jaime A. Rodriguez + * @license http://opensource.org/licenses/MIT; MIT + * @link https://sleepymustache.com + */ +class Loader +{ + /** + * An associative array where the key is a namespace prefix and the value + * is an array of base directories for classes in that namespace. + * + * @var array + */ + protected static $prefixes = array(); + + /** + * Register loader with SPL autoloader stack. + * + * @return void + */ + public static function register() + { + spl_autoload_register('self::loadClass'); + } + + /** + * Adds a base directory for a namespace prefix. + * + * @param string $prefix The namespace prefix. + * @param string $base_dir A base directory for class files in the namespace. + * @param bool $prepend If true, prepend the base directory to the stack + * instead of appending it; this causes it to be searched + * first rather than last. + * + * @return void + */ + public static function addNamespace($prefix, $base_dir, $prepend = false) + { + // normalize namespace prefix + $prefix = trim($prefix, '\\') . '\\'; + + // normalize the base directory with a trailing separator + $base_dir = rtrim($base_dir, DIRECTORY_SEPARATOR) . '/'; + + // initialize the namespace prefix array + if (isset(self::$prefixes[$prefix]) === false) { + self::$prefixes[$prefix] = array(); + } + + // retain the base directory for the namespace prefix + if ($prepend) { + array_unshift(self::$prefixes[$prefix], $base_dir); + } else { + array_push(self::$prefixes[$prefix], $base_dir); + } + } + + /** + * Loads the class file for a given class name. + * + * @param string $class The fully-qualified class name. + * + * @return mixed The mapped file name on success, or boolean false on + * failure. + */ + public static function loadClass($class) + { + // the current namespace prefix + $prefix = $class; + + // work backwards through the namespace names of the fully-qualified + // class name to find a mapped file name + while (false !== $pos = strrpos($prefix, '\\')) { + // retain the trailing namespace separator in the prefix + $prefix = substr($class, 0, $pos + 1); + + // the rest is the relative class name + $relative_class = substr($class, $pos + 1); + + // try to load a mapped file for the prefix and relative class + $mapped_file = self::loadMappedFile($prefix, $relative_class); + if ($mapped_file) { + return $mapped_file; + } + + // remove the trailing namespace separator for the next iteration + // of strrpos() + $prefix = rtrim($prefix, '\\'); + } + + // never found a mapped file + return false; + } + + /** + * Load the mapped file for a namespace prefix and relative class. + * + * @param string $prefix The namespace prefix + * @param string $relative_class The relative class name + * + * @return mixed Boolean false if no mapped file can be loaded, or the + * name of the mapped file that was loaded. + */ + protected static function loadMappedFile($prefix, $relative_class) + { + // are there any base directories for this namespace prefix? + if (isset(self::$prefixes[$prefix]) === false) { + return false; + } + + // look through base directories for this namespace prefix + foreach (self::$prefixes[$prefix] as $base_dir) { + + // replace the namespace prefix with the base directory, + // replace namespace separators with directory separators + // in the relative class name, append with .php + $file = $base_dir + . str_replace('\\', DIRECTORY_SEPARATOR, $relative_class) + . '.php'; + + // if the mapped file exists, require it + if (self::requireFile($file)) { + // yes, we're done + return $file; + } + } + + // never found it + return false; + } + + /** + * If a file exists, require it from the file system. + * + * @param string $file The file to require. + * + * @return bool True if the file exists, false if not. + */ + protected static function requireFile($file) + { + if (file_exists($file)) { + include $file; + return true; + } + + return false; + } +} \ No newline at end of file diff --git a/core/Module.php b/core/Module.php new file mode 100644 index 0000000..16c31ce --- /dev/null +++ b/core/Module.php @@ -0,0 +1,90 @@ + + * @license http://opensource.org/licenses/MIT; MIT + * @link https://sleepymustache.com + */ + +namespace Sleepy\Core; + +use Sleepy\Core\Hook; + +/** + * The Module class that all modules must extend + * + * @category Core + * @package Sleepy + * @author Jaime A. Rodriguez + * @license http://opensource.org/licenses/MIT; MIT + * @link https://sleepymustache.com + */ +abstract class Module +{ + // A list of hooks and methods. e.g. 'sleepy_preprocess' => 'startMethod', + public $hooks = []; + + // The module will only execute on environments that are set to true + public $environments = [ + 'dev' => true, + 'stage' => true, + 'live' => true + ]; + + /** + * The constructor + */ + public function __construct() + { + $this->_render(); + // Each module will automatically include a preprocess Action for extendibility + Hook::addAction((new \ReflectionClass($this))->getShortName() . "_preprocess"); + } + + /** + * The destructor + */ + public function __destruct() + { + // Each module will automatically include a postprocess Action for extendibility + Hook::addAction((new \ReflectionClass($this))->getShortName() . "_postprocess"); + } + + /** + * The main render function that always gets executed + * + * @return void + */ + private function _render() + { + if (!is_array($this->hooks)) { + throw new \Exception( + '$this->hooks need to be an associative array of hook -> method' + ); + } + + if (SM::isLive() && !$this->environments['live']) { + return false; + } + + if (SM::isStage() && !$this->environments['stage']) { + return false; + } + + if (SM::isDev() && !$this->environments['dev']) { + return false; + } + + foreach ($this->hooks as $key => $value) { + Hook::applyFilter($key, array($this, $value)); + } + } +} diff --git a/core/SM.php b/core/SM.php new file mode 100644 index 0000000..b353559 --- /dev/null +++ b/core/SM.php @@ -0,0 +1,199 @@ + + * @license http://opensource.org/licenses/MIT; MIT + * @link https://sleepymustache.com + */ + +namespace Sleepy\Core; + +use Sleepy\Core\Hook; + +/** + * The SM class is used to initialize/get/set information about the sleepyMUSTACHE + * install. + * + * @category Core + * @package Sleepy + * @author Jaime A. Rodriguez + * @license http://opensource.org/licenses/MIT; MIT + * @link https://sleepymustache.com + */ +class SM +{ + /** + * The Live URL + * + * @var string + */ + public static $live_urls = ''; + + /** + * The stage URL + * + * @var string + */ + public static $stage_urls = ''; + + /** + * Stores the instance of SM when initialized + * + * @var SM + */ + private static $_instance; + + /** + * Is sleepyMUSTACHE initialized? + * + * @var boolean + */ + public static $is_initialized = false; + + /** + * Prevent class from being cloned + * + * @return void + */ + private function __clone() + { + } + + /** + * The constructor is private to ensure we only have one sleepy_preprocess + * and sleepy_postprocess hooks. + * + * @return void + */ + private function __construct() + { + // Enable sessions + session_start(); + + $settingsFile = $_SERVER['DOCUMENT_ROOT'] + . DIRECTORY_SEPARATOR . 'settings.php'; + + // Check for the settings overide in the root + if (@!include_once $settingsFile) { + include_once 'settings.php'; + } + + Hook::addAction('sleepy_preprocess'); + register_shutdown_function('\Sleepy\Core\SM::shutdown'); + ob_start(); + + // Send the encoding ahead of time to speed up rendering + if (!headers_sent()) { + header('Content-Type: text/html; charset=utf-8'); + } + } + + /** + * Show the buffered pages with actions and filters + * + * @return void + */ + public static function shutdown() + { + echo Hook::addFilter('sleepy_render', ob_get_clean()); + Hook::addAction('sleepy_postprocess'); + } + + /** + * Initialized the SM class + * + * @return void + */ + public static function initialize() + { + if (!self::$is_initialized) { + self::$is_initialized = true; + self::$_instance = new SM; + } + } + + /** + * Checks if we are in the live environment + * + * @return boolean Are we in the live environment? + */ + public static function isLive() + { + return self::isENV(self::$live_urls); + } + + /** + * Checks if we are in the staging environment + * + * @return boolean True Are we in the staging environment? + */ + public static function isStage() + { + return self::isENV(self::$stage_urls); + } + + /** + * Checks if we are in the development environment + * + * @return boolean Are we in the development environment? + */ + public static function isDev() + { + return (!self::isEnv(self::$stage_urls) && !self::isEnv(self::$live_urls)); + } + + /** + * Checks if the current site matches a URL + * + * @param Array $arr The URL to match with current site + * + * @return boolean true if there was a match + */ + public static function isENV($arr) + { + if (!isset($_SERVER['SERVER_NAME'])) { + return false; + }; + + foreach ($arr as $url) { + if (stripos($_SERVER['SERVER_NAME'], $url) !== false) { + return true; + } + } + + return false; + } +} diff --git a/core/Template.php b/core/Template.php new file mode 100644 index 0000000..a956095 --- /dev/null +++ b/core/Template.php @@ -0,0 +1,607 @@ + + * + * {{ page_title }} + * + * + *

{{ heading }}

+ *

This page has been viewed {{ hits }} times.

+ * + * + * ~~~ + * + * Templates are used by instantiating the Template class and passing the template URL to the + * constructor. The bind method is used to map the placeholders to content. + * + * ### PHP file: *index.php* + * + * ~~~ php + * use Sleepy\Template; + * + * $page = Template('templates/default.tpl'); + * $page->bind('page_title', 'Sleepy Mustache'); + * $page->bind('heading', 'Hello world!'); + * $page->show(); // Display the compiled template + * ~~~ + * + * #### Components + * + * Components are design to be reusable templates. They can be attached to other templates by using + * the *#include* directive. Good examples are *header.tpl* or *slideshow.tpl*. + * + * ### PHP file: *\app\templates\components\header.tpl* + * + * ~~~ php + * + * + * {{ page_title }} + * + * + * ~~~ + * + * ### PHP file: *\app\templates\components\footer.tpl* + * + * ~~~ php + * + * + * ~~~ + * + * ### Template file: *\app\templates\default.tpl* + * ~~~ php + * {{#include components/header.tpl }} + *

{{ heading }}

+ *

This page has been viewed {{ hits }} times.

+ * {{#include components/footer.tpl }} + * ~~~ + * + * ### Binding Arrays + * + * Many times you need to bind an array of data to a template. For example, a slideshow or list of + * users. In this case, we use the #each directives to loop thru the array. + * + * ### Template file: *\app\templates\users.tpl* + * + * ~~~ php + * {#each u in users} + *
+ *

{{ u.name }}

+ *

{{ u.description }}

+ *
+ * {\each} + * ~~~ + * + * ## Changelog + * + * ### Version 2.0a + * * Converted to PSR-4 + * + * ### Version 1.10.1 + * * Updated documentation + * + * ### Version 1.10 + * * Add rudimentary if statement blocks + * + * ### Version 1.9 + * * Add Action for individual Template Starts per $template name + * + * ### Version 1.8 + * * Allow Template::bind() to take an array to bind multiple values at once + * + * ### Version 1.7 + * * Updated private prefix (_) for consistency + * * Updated documentation + * + * ### Version 1.6 + * * No longer dependant on Hooks Module + * + * @category Core + * @package Sleepy + * @author Jaime A. Rodriguez + * @license http://opensource.org/licenses/MIT; MIT + * @link https://sleepymustache.com + */ + +namespace Sleepy\Core; + +class Template +{ + /** + * The extension for template files + * + * @var string The default template extension + */ + public $extension = '.tpl'; + + /** + * The template directory + * + * @var string + */ + public $directory; + + /** + * The template file + * + * @var string + */ + protected $file; + + /** + * The data bound to the template + * + * @var mixed[] + */ + protected $data = array(); + + /** + * The constructor + * + * @param string $template The name of the template + * @param string $basedir The base directory for template files + * + * @return void + */ + public function __construct($template='', $basedir='') + { + if (class_exists('\Sleepy\Core\Hook')) { + Hook::addAction('template_start'); + Hook::addAction('template_start' . $template); + } + + // If they didn't pass a basedir then try the default + if ($basedir == '') { + if (!defined('DIRBASE')) { + define('DIRBASE', $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'app'); + } + + $this->directory = DIRBASE . DIRECTORY_SEPARATOR . 'templates' . DIRECTORY_SEPARATOR; + } else { + $this->directory = $basedir; + } + + if (!empty($template)) { + $this->setTemplate($template); + } + } + + /** + * Does the template exist? + * + * @param string $file Name of template + * + * @return bool True if template exists + */ + private function _checkTemplate($file) + { + if (empty($file)) { + throw new \Exception('Template file has not been set.'); + } + + // Check that the directory is set correctly + if (!file_exists($this->directory)) { + throw new \Exception("Template directory '{$this->directory}' does not exists."); + } + + // Check if the template exists in the directory + if (!file_exists($this->directory . $file . $this->extension)) { + throw new \Exception("Template '{$this->directory}{$file}{$this->extension}' does not exist."); + } + + return true; + } + + /** + * Given a path, the function returns a piece of $arr. For example + * 'name.first' will return $arr['name']['first'] + * + * @param array $arr An array to search using the $path + * @param string $path A path representing the dimensions of the array + * + * @return mixed A sub-array or string + */ + private function _assignArrayByPath($arr, $path) + { + + $keys = explode('.', $path); + + if (is_array($keys)) { + foreach ($keys as $key) { + if (array_key_exists($key, $arr)) { + $arr = $arr[$key]; + } else { + return false; + } + } + } + + return $arr; + } + + /** + * Renders the template + * + * @param string $template The template to render + * @param mixed[] $data The data bound to the template + * + * @return string The rendered template + */ + private function _render($template, $data) + { + $template = $this->_renderInclude($template); + $template = $this->_renderEach($template, $data); + $template = $this->_renderIf($template, $data); + + if (class_exists('\Sleepy\Core\Hook')) { + $template = Hook::addFilter('prerender_template', $template); + } + + $template = $this->_renderPlaceholder($template, $data); + + return $template; + } + + /** + * Render the if blocks + * + * @param string $template The template string + * @param mixed[] $data The data + * + * @return void + * + * @todo Not very robust, remove eval at a later date + * @todo Add Else blcok + * @todo Add tests + */ + private function _renderIf($template, $data) + { + // Process the #if blocks + if (preg_match_all('/{{\s?#if.+?}}(?:(?>[^{}]+)|(?R))*{{\s?\/if\s?}}/ism', $template, $ifs)) { + + // For every #if + foreach ($ifs[0] as $value) { + // Reset rendered data + $rendered = ''; + + // break statement into 3 pieces (val1) (operator) (val2) + preg_match('/{{\s?#if\s?(?.*?)\s(?.*?)\s(?.*?)\s?}}/', $value, $tokens); + + // Replace placeholders + if (isset($this->data[$tokens[1]])) { + $tokens[1] = &$this->data[$tokens[1]]; + } else { + $tokens[1] = trim(trim($tokens[1], '"'), "'"); + } + + // Replace placeholders + if (isset($this->data[$tokens[3]])) { + $tokens[3] = &$this->data[$tokens[3]]; + } else { + $tokens[3] = trim(trim($tokens[3], '"'), "'"); + } + + // Evaluate if Statement + $truthy = eval("return \$tokens[1] $tokens[2] \$tokens[3];"); + + if ($truthy) { + // replace with the if statements + $new_template = preg_replace('/{{\s?#if.*?}}/s', '', $value, 1); + $new_template = preg_replace('/{{\s?\/if\s?}}$/s', '', $new_template, 1); + } else { + $new_template = str_replace($value, '', $value); + } + + $rendered = $rendered . $this->_render($new_template, $data); + $template = str_replace($value, $rendered, $template); + } + } + + return $template; + } + + /** + * Render the includes + * + * @param string $template The template string + * + * @return void + */ + private function _renderInclude($template) + { + // Process the includes + if (preg_match('/{{\s*#include\s.*}}/', $template, $include)) { + $index = trim(str_replace('{{', '', str_replace('}}', '', $include[0]))); + + if (file_exists( + $this->directory + . str_replace('#include ', '', $index) + . $this->extension + )) { + ob_start(); + include $this->directory + . str_replace('#include ', '', $index) + . $this->extension; + } else { + ob_clean(); // clear buffer in $this->show(); + throw new \Exception( + $this->directory + . str_replace('#include ', '', $index) + . $this->extension + . ' doesn\'t exist. Cannot include file.' + ); + } + + $template = $this->_renderInclude( + str_replace($include[0], ob_get_clean(), $template) + ); + } + + return $template; + } + + /** + * Render the each blocks + * + * @param string $template + * @param mixed[] $data + * + * @return void + */ + private function _renderEach($template, $data) + { + // Process the #each blocks + if (preg_match_all( + '/{{\s?#each.+?}}(?:(?>[^{}]+)|(?R))*{{\s?\/each\s?}}/ism', + $template, + $loops + )) { + // For every #each + foreach ($loops[0] as $value) { + // Reset rendered data + $rendered = ''; + + // Stores the values of and into $forin + preg_match( + '/{{\s?#each\s(?\w+) in (?.*?)\s?}}/', + $value, + $forin + ); + + $forin['in'] = strtolower($forin['in']); + + // Removes the each loop + $new_template = preg_replace('/{{\s?#each.*?}}/s', '', $value, 1); + $new_template = preg_replace( + '/{{\s?\/each\s?}}$/s', + '', + $new_template, + 1 + ); + + // get the array based on the + $in = $this->_assignArrayByPath($data, $forin['in']); + + // for each changelog + if ( + is_array($in) + && array_key_exists(0, $in) + && is_array($in[0]) + ) { + + // Allow hooks to edit the data + if (class_exists('\Sleepy\Core\Hook')) { + $in = Hook::addFilter('template_each_array', array($in)); + } + + $iterator = 0; + + foreach ($in as $newdata) { + $iterator++; + + if (class_exists('\Sleepy\Core\Hook')) { + $newdata = Hook::addFilter('template_each', array($newdata)); + $newdata = Hook::addFilter('template_each_' . $forin['for'], array($newdata)); + } + + $newdata['iterator'] = $iterator; + $newdata['zebra'] = ($iterator % 2) ? 'odd' : 'even'; + + // Make the $newdata match the + $newdata[$forin['for']] = $newdata; + + // render the new template + $rendered = $rendered . $this->_render($new_template, $newdata); + } + } else { + // render the new template + $rendered = $rendered . $this->_render($new_template, $data); + } + + $template = str_replace($value, $rendered, $template); + } + } + + return $template; + } + + /** + * Render the placeholders + * + * @param string $template + * @param mixed[] $data + * @return void + */ + private function _renderPlaceholder($template, $data) + { + // Find all the single placeholders + preg_match_all('/{{\s?(.*?)(\s.*?)?\s?}}/', $template, $matches); + + // For each replace with a value + foreach (array_unique($matches[0]) as $index => $placeholder) { + $key = strtolower($matches[1][$index]); + + $arguments = array( + $this->_assignArrayByPath($data, $key) + ); + + # We trim so that there are no extra blank arguments + $arguments = array_merge($arguments, explode(' ', trim($matches[2][$index]))); + + $boundData = $arguments; + + if (class_exists('\Sleepy\Core\Hook')) { + $boundData = Hook::addFilter('render_placeholder_' . strtolower($key), $boundData); + } + + // Some filters might take arrays and return only a single value, if + // hooks are disabled, lets return only this single value + if (is_array($boundData)) { + $boundData = $boundData[0]; + } + + $template = str_replace($placeholder, $boundData, $template); + } + + return $template; + } + + /** + * Parses the template after it's been setup + * + * @return string The rendered template + */ + private function _parseTemplate() + { + $this->_checkTemplate($this->_file); + + // Render template file + ob_start(); + include $this->directory . $this->_file . $this->extension; + $template = $this->_render(ob_get_clean(), $this->data); + + if (class_exists('\Sleepy\Core\Hook')) { + $template = Hook::addFilter('render_template_' . $this->_file, $template); + $template = Hook::addFilter('render_template', $template); + } + + return $template; + } + + /** + * Sets the template to use. + * + * @param string $file The Filename + * + * @return void + */ + public function setTemplate($file) + { + if ($this->_checkTemplate($file)) { + $this->_file = $file; + } + } + + /** + * Binds data to the template placeholders + * + * @param mixed $placeholder The template placeholder + * @param mixed $value The value that replaced the placeholder + * + * @return void + */ + public function bind($placeholder, $value='') + { + if (!is_array($placeholder)) { + $placeholder = array( + trim(strtolower($placeholder)) => $value + ); + } + + foreach($placeholder as $key => $value) { + $key = trim(strtolower($key)); + + if (!is_array($value)) { + if (class_exists('\Sleepy\Core\Hook')) { + $value = Hook::addFilter('bind_placeholder_' . trim($key), $value); + } + } + + $this->data[$key] = $value; + } + } + + /** + * Starts a buffer that will bind data to the template placeholders. The + * buffer will capture anything you output until $this->bindStop() + * + * @return void + */ + public function bindStart() + { + ob_start(); + } + + /** + * Stops the buffer that binds data to the template placeholders + * + * @param string $placeholder The template placeholder + * @return void + */ + public function bindStop($placeholder) + { + $content = ob_get_clean(); + + if (class_exists('\Sleepy\Core\Hook')) { + $content = Hook::addFilter('bind_placeholder_' . $placeholder, $content); + } + + $this->data[trim(strtolower($placeholder))] = $content; + } + + /** + * Gets the data for a placeholder + * + * @param string $placeholder The placeholder + * + * @return mixed The data stored in the placeholder + */ + public function get($key) + { + $value = $this->data[$key]; + + if (class_exists('\Sleepy\Core\Hook')) { + Hook::addFilter('template_get_' . $key, $value); + } + + return $value; + } + + /** + * Shows the rendered template + * + * @return void + */ + public function show() + { + echo $this->_parseTemplate(); + } + + /** + * Retrieves the rendered template + * + * @return void + */ + public function retrieve() + { + return $this->_parseTemplate(); + } +} \ No newline at end of file diff --git a/mvc/CRUD.php b/mvc/CRUD.php new file mode 100644 index 0000000..80bf93a --- /dev/null +++ b/mvc/CRUD.php @@ -0,0 +1,139 @@ + + * @license http://opensource.org/licenses/MIT; MIT + * @link https://sleepymustache.com + */ + +namespace Sleepy\MVC; + +use Sleepy\MVC\Route; +use Sleepy\MVC\View; + + +/** + * The CRUD class + * + * The CRUD class is a controller that handles the basic CRUC functionality + * automatically + * + * @category Core + * @package Sleepy + * @author Jaime A. Rodriguez + * @license http://opensource.org/licenses/MIT; MIT + * @link https://sleepymustache.com + */ +abstract class CRUD extends Controller +{ + + /** + * Default action routes based on method + * + * @param Route $route The Route + * + * @return View + */ + public function index(Route $route) : View + { + switch ($route->method) { + case 'OPTIONS': + http_response_code(200); + return new View(new Model(), 'default'); + case 'POST': + http_response_code(201); + return $this->create($route); + break; + case 'GET': + if (is_numeric($route->params['id'])) { + http_response_code(200); + return $this->read($route); + } else { + http_response_code(200); + return $this->list($route); + } + break; + case 'DELETE': + http_response_code(204); + return $this->delete($route); + break; + case 'PUT': + http_response_code(204); + return $this->update($route); + } + } + + /** + * Gets a list of items + * + * @param Route $route The Route + * + * @return View + */ + abstract function list(Route $route) : View; + + /** + * Create a new item + * + * @param Route $route The Route + * + * @return View + */ + abstract function create(Route $route) : View; + + /** + * Gets a single item + * + * @param Route $route The Route + * + * @return View + */ + abstract function read(Route $route) : View; + + /** + * Updates a single item + * + * @param Route $route The Route + * + * @return View + */ + abstract public function update(Route $route) : View; + + /** + * Deletes a single item + * + * @param Route $route The Route + * + * @return View + */ + abstract function delete(Route $route) : View; +} \ No newline at end of file diff --git a/mvc/Controller.php b/mvc/Controller.php new file mode 100644 index 0000000..c427daa --- /dev/null +++ b/mvc/Controller.php @@ -0,0 +1,69 @@ + + * @license http://opensource.org/licenses/MIT; MIT + * @link https://sleepymustache.com + */ + +namespace Sleepy\MVC; + +/** + * The controller class must be extended for all Controllers in the routed version + * of sleepyMUSTACHE. + * + * @category MVC + * @package Sleepy + * @author Jaime A. Rodriguez + * @license http://opensource.org/licenses/MIT; MIT + * @link https://sleepymustache.com + */ +abstract class Controller +{ + /** + * The constructor + */ + public function __construct() + { + if (class_exists('Hook')) { + Hook::addFilter('controller_preprocess', $string); + } + } + + /** + * The destructor + */ + public function __destruct() + { + if (class_exists('Hook')) { + Hook::addFilter('controller_postprocess', $string); + } + } +} \ No newline at end of file diff --git a/mvc/Model.php b/mvc/Model.php new file mode 100644 index 0000000..b5318c8 --- /dev/null +++ b/mvc/Model.php @@ -0,0 +1,274 @@ +name = "John Doe"; + * ~~~ + * + * ## Changelog + * + * ### Version 2.0a + * * Converted to PSR-4 + * + * ### Version 1.1 + * * Add filters to the getter and setters + * * filters change if Model is extended + * + * ### Version 1.0 + * * Initial release + * + * php version 7.0.0 + * + * @category MVC + * @package Sleepy + * @author Jaime A. Rodriguez + * @license http://opensource.org/licenses/MIT; MIT + * @link https://sleepymustache.com + */ + +namespace Sleepy\MVC; + +use Sleepy\Core\Hook; + +/** + * The Model Class + * + * All models must extend the Model class + * + * @category MVC + * @package Sleepy + * @author Jaime A. Rodriguez + * @license http://opensource.org/licenses/MIT; MIT + * @link https://sleepymustache.com + */ +class Model implements \Iterator +{ + /** + * The pointer for the Iterator + * + * @var integer + */ + private $_position = 0; + + /** + * The Models data + * + * @var array + */ + private $_data = array(); + + /** + * Sets the $_position to the beginning + * + * @return void + */ + public function rewind(): void + { + $this->_position = 0; + } + + /** + * Returns the current element + * + * @return void + */ + public function current(): mixed + { + $keys = array_keys($this->_data); + return $this->_data[$keys[$this->_position]]; + } + + /** + * Gets the key for the current position + * + * @return string The key of the currently selected item + */ + public function key(): string|int + { + $keys = array_keys($this->_data); + return $keys[$this->_position]; + } + + /** + * Iteratates the $_position + * + * @return void + */ + public function next(): void + { + ++$this->_position; + } + + /** + * Is the current element valid? + * + * @return boolean + */ + public function valid(): bool + { + $keys = array_keys($this->_data); + return isset($keys[$this->_position]); + } + + /** + * Return the name of the Class + * + * @return void + */ + private function _cleanClass() + { + $className = get_class($this); + + if ($pos = strrpos($className, '\\')) { + return substr($className, $pos + 1); + } + + return $className; + } + + /** + * Contructor + * + * @param array $props an array of properties to streamline adding them + */ + public function __construct($props = []) + { + if (class_exists('\Sleepy\Core\Hook')) { + Hook::addAction($this->_cleanClass() . '_preprocess'); + } + + // Clean up the propertys + foreach (array_keys(get_class_vars(get_class($this))) as $var) { + if ($var === '_position') continue; + if ($var === '_data') continue; + $this->__set($var, $this->$var); + unset($this->$var); + } + + foreach ($props as $property => $value) { + if (class_exists('\Sleepy\Core\Hook')) { + $this->_data[$property] = Hook::addFilter( + $this->_cleanClass() . '_set_' . $property, + $value + ); + + $this->_data[$property] = Hook::addFilter( + $this->_cleanClass() . '_set_property', + $value + ); + } else { + $this->_data[$property] = $value; + } + } + } + + /** + * When the Model is destructed + */ + public function __destruct() + { + if (class_exists('\Sleepy\Core\Hook')) { + Hook::addAction($this->_cleanClass() . '_postprocess'); + } + } + + /** + * Getter for all properties + * + * @param string $property The property to retrieve + * + * @return mixed The value stored in the $property + */ + public function __get($property) + { + if (isset($this->_data[$property])) { + if (class_exists('\Sleepy\Core\Hook')) { + $output = Hook::addFilter( + $this->_cleanClass() . '_get_' . $property, + $this->_data[$property] + ); + $output = Hook::addFilter( + $this->_cleanClass() . '_get_property', + $output + ); + + return $output; + + } else { + return $this->_data[$property]; + } + } + } + + /** + * Setter for all properties + * + * @param string $property The property name + * @param mixed $value The value to store + * + * @return void + */ + public function __set($property, $value) + { + if (class_exists('\Sleepy\Core\Hook')) { + if (is_array($value)) { + // Work around + $value = array($value); + } + $this->_data[$property] = Hook::addFilter( + $this->_cleanClass() . '_set_' . $property, + $value + ); + $this->_data[$property] = Hook::addFilter( + $this->_cleanClass() . '_set_property', + $value + ); + } else { + $this->_data[$property] = $value; + } + } + + /** + * Output for var_dump should be from $this->data + * + * @return array + */ + public function __debugInfo() + { + return $this->_data; + } + + /** + * When used as a string, output JSON of $this->data + * + * @return string + */ + public function __toString() + { + return $this->toJson($this->_data); + } + + /** + * When we invoke the object as a function + * + * @return void + */ + public function __invoke() + { + return (object) $this->_data; + } + + /** + * Return the data as JSON + * + * @return void + */ + public function toJson() + { + return json_encode($this->_data); + } +} \ No newline at end of file diff --git a/mvc/Router.php b/mvc/Router.php new file mode 100644 index 0000000..7d69650 --- /dev/null +++ b/mvc/Router.php @@ -0,0 +1,617 @@ +pattern; + * echo "Route was matched using method: ", $route->method; + * echo "The wildcard matched: ", $route->splat; + * echo "Showing user ", $route->params['id'], "
"; + * }); + * ~~~ + * + * ## Changelog + * + * ### Version 1.2.1 + * * Updated documentation + * + * ### Version 1.2 + * * Renamed _Route to Route to help with Typehinting + * + * ### Version 1.1 + * * updated private prefix (_) for consistency + * * updated documentation + * + * ### Version 1.0 + * * With unit tests in place, we're ready to call this 1.0 + * + * ### Version 0.4 + * * Simplified interface, thanks @cameff + * + * php version 7.0.0 + * + * @category MVC + * @package Sleepy + * @author Jaime A. Rodriguez + * @license http://opensource.org/licenses/MIT; MIT + * @link https://sleepymustache.com + */ + +namespace Sleepy\MVC; + +use Sleepy\MVC\RouteNotFound; + +/** + * The Router class + * + * @category MVC + * @package Sleepy + * @author Jaime A. Rodriguez + * @license http://opensource.org/licenses/MIT; MIT + * @link https://sleepymustache.com + */ +class Router +{ + /** + * An array of routes + * + * @var array + * @private + */ + public static $_routes = array(); + + /** + * Has a route been matched? + * + * @var boolean True, if we matched a route + */ + public static $routeFound = false; + + /** + * The delimiter for the route pattern + * + * @var string + */ + public static $delimiter = '/'; + + /** + * If true, parse the querystring instead of the path + * + * @var boolean + */ + public static $querystring = false; + + /** + * An array of parameters, either from the path or querystring + * + * @var array + */ + public static $parameters = array(); + + /** + * Gets an array from a string based on Router::$delimeter + * + * @param string $string a string to explode() + * + * @return array an exploded string + */ + public static function getArray($string) + { + if (substr($string, strlen($string) - 1, 1) == self::$delimiter) { + $string = substr($string, 0, strlen($string) - 1); + } + + if (substr($string, 0, 1) != self::$delimiter) { + $string = self::$delimiter . $string; + } + + return explode(self::$delimiter, $string);; + } + + /** + * Creates a new route + * + * @param string $pattern A pattern to match + * @param function $func A callback function + * + * @return object \Sleepy\Route() + */ + public static function route($pattern, $func) + { + if (is_array($pattern)) { + $route = new Route(md5($pattern[0])); + } else { + $route = new Route(md5($pattern)); + } + + array_push(self::$_routes, $route); + $route->add($pattern, $func); + return $route; + } + + /** + * Creates a new route, uses a controller and view + * + * @param string $pattern A pattern to match + * @param array $defaults The defaults for the :placeholders + * + * @return object \Sleepy\Route() + */ + public static function mvc($pattern, $defaults = array()) + { + self::route( + $pattern, + function ($route) use ($defaults) { + // set default for defaults... (-_-) + $defaults['controller'] = (array_key_exists('controller', $defaults)) + ? $defaults['controller'] + : 'home'; + $defaults['action'] = (array_key_exists('action', $defaults)) + ? $defaults['action'] + : 'index'; + $defaults['id'] = (array_key_exists('id', $defaults)) + ? $defaults['id'] + : ''; + + if (!is_array($route->params)) { + $route->params = array(); + } + + // Set default controller, action, and id + $controller = (array_key_exists('controller', $route->params)) + ? $route->params['controller'] + : $defaults['controller']; + $action = (array_key_exists('action', $route->params)) + ? $route->params['action'] + : $defaults['action']; + $id = (array_key_exists('id', $route->params)) + ? $route->params['id'] + : $defaults['id']; + + // Make all the defaults available in the routes parameters + $route->params = array_merge($defaults, $route->params); + + $controller_file = $_SERVER['DOCUMENT_ROOT'] . '/app/controllers/'; + $controller_file .= strtolower($controller) . '.php'; + + //Sterilize + $controller = strtolower($controller); + $controller = str_replace('-', '', $controller); + $action = str_replace('-', '_', $action); + + // Call Controller::action($route) + if (file_exists($controller_file)) { + include_once $controller_file; + + if (class_exists($controller)) { + $c = new $controller; + + if (method_exists($c, $action)) { + $c->$action($route); + } else { + throw new RouteNotFound( + "Router: Action ($action) does not exist in " + . "Controller ($controller)." + ); + } + } else { + throw new RouteNotFound( + "Router: Controller ($controller) does not exist." + ); + } + } else { + throw new RouteNotFound( + "Router: Controller File ($controller_file) does not exist." + ); + } + } + ); + } + + /** + * Redirects a user to another route + * + * @param Controller $controller The controller + * @param string $action The Action + * @param string $params The parameters + * + * @return void + */ + public static function redirect($controller, $action='index', $params=[]) + { + + + $route = new Route(md5("{{ $controller }}/{{ $action }}/{{ id }}/*")); + + $params["controller"] = isset($params["controller"]) ? $params["controller"] : null; + $params["action"] = isset($params["action"]) ? $params["action"] : null; + $params["id"] = isset($params["id"]) ? $params["id"] : null; + $route->params = $params; + + $controller_file = $_SERVER['DOCUMENT_ROOT'] . '/app/controllers/'; + $controller_file .= strtolower($controller) . '.php'; + + //Sterilize + $controller = strtolower($controller); + $controller = str_replace('-', '', $controller); + $action = str_replace('-', '_', $action); + + // Call Controller::action($route) + if (file_exists($controller_file)) { + include_once $controller_file; + + if (class_exists($controller)) { + $c = new $controller; + + if (method_exists($c, $action)) { + $c->$action($route); + } else { + throw new \Exception( + "Router: Action ($action) does not exist." + ); + } + } else { + throw new \Exception( + "Router: Controller ($controller) does not exist." + ); + } + } else { + throw new \Exception( + "Router: Controller File ($controller_file) does not exist." + ); + } + } + + /** + * Starts parsing the Router::routes + * + * @param string $currentPath The current path + * + * @return boolean true if a route was matched + */ + public static function start($currentPath='') + { + self::$routeFound = false; + + if ($currentPath == '') { + $currentPath = $_SERVER['REQUEST_URI']; + } + + if (self::$querystring) { + $currentPath = str_replace('/?q=', '', $currentPath); + } else { + $currentPath = preg_replace('/\?.*/', '', $currentPath); + } + + // Get all parameters + self::$parameters = self::getArray($currentPath); + + foreach (self::$_routes as $route) { + $route->method = (isset($_SERVER['REQUEST_METHOD'])) + ? $_SERVER['REQUEST_METHOD'] + : 'GET'; + $route->execute(); + } + + if (!self::$routeFound) { + throw new RouteNotFound('Router: Route not found.'); + } + + return self::$routeFound; + } + + /** + * Resets the routes + * + * @return void + */ + public static function reset() + { + self::$_routes = array(); + } +} + +/** + * Private class used by the Router class + * + * ### Usage + * + * This class is private and should not be instatiated outside of the Router + * class + * + * ### Changelog + * + * ## Version 0.4 + * * Bug fixes + * + * @todo Write tests for the class + * + * @category MVC + * @package Sleepy + * @author Jaime A. Rodriguez + * @license http://opensource.org/licenses/MIT; MIT + * @link https://sleepymustache.com + */ +class Route +{ + /** + * A list of (pattern ,callbacks) + * + * @var array + */ + private $_functions = array(); + + /** + * The name of the route, MD5 hash of pattern by default + * + * @var string + */ + public $name; + + /** + * A hash of matched placeholder + * + * @var string[] + */ + public $params; + + /** + * The method that was matched + * + * @var string + */ + public $method; + + /** + * Returns the string matched with a wildcard + * + * @var string + */ + public $splat; + + /** + * Cleans the handlebars from placeholders + * + * @param string $placeholder The full placeholder + * + * @return string The stripped placeholder + */ + private function _cleanPlaceholder($placeholder) + { + $key = str_replace('{{', '', $placeholder); + $key = str_replace('}}', '', $key); + + return trim($key); + } + + /** + * Is this $string a placeholder + * + * @param string $string The possible placeholder + * + * @return boolean True, if it is a placeholder + */ + private function _isPlaceholder($string) + { + return substr($string, 0, 2) + == '{{' && substr($string, strlen($string) - 2, 2) == '}}'; + } + + /** + * Run all the filters for a placeholder + * + * @param string $key The placeholder + * @param string $string The string to parse + * + * @return string The parsed string + */ + private function _runFilters($key, $string) + { + if (class_exists('Hook')) { + $string = Hook::addFilter('route_parameters', $string); + $string = Hook::addFilter('route_parameter_' . $key, $string); + $string = Hook::addFilter( + 'route_' . $this->name . '_parameters', + $string + ); + $string = Hook::addFilter( + 'route_' . $this->name . '_parameter_' . $key, + $string + ); + } + + return $string; + } + + /** + * Does the pattern have a wildcard? + * + * @param string $pattern The pattern to match + * + * @return boolean True, if there is a wildcard + */ + private function _hasWildcard($pattern) + { + if (strlen($pattern) == 0) { + return false; + } else { + return strpos($pattern, '*') !== false; + } + } + + /** + * Store the variables found in the route + + * @param string $key The placeholder + * @param string $value The value + * + * @return boolean True, if we succeeded + */ + private function _storeVariable($key, $value) + { + if ($value == '') { + return false; + } + + $key = $this->_cleanPlaceholder($key); + $value = $this->_runFilters($key, $value); + + // Check for multiple variables, they should match. + if (isset($this->params[$key])) { + if ($value != $this->params[$key]) { + return false; + } + } + + $this->params[$key] = $value; + return true; + } + + /** + * Creates a new route + * + * @param string $name Optional. + * + * @return void + */ + public function __construct($name='') + { + $this->name = $name; + } + + /** + * If URL matches pattern do $func + * + * @param string $pattern a pattern with {{ placeholders }} + * @param function $func Executes if pattern matches; func($variables) + * + * @return void + */ + public function add($pattern, $func) + { + // If we have an array of patterns match those individually + if (is_array($pattern)) { + foreach ($pattern as $p) { + $this->add($p, $func); + } + } else { + array_push($this->_functions, array($pattern, $func)); + } + + return $this; + } + + /** + * Executes the call back functions + * + * @return void + */ + public function execute() + { + $noMatch = false; + + // Exit when there is nothing left to do + if (count($this->_functions) < 1) { + return; + } + + // Shift a function off the queue + $r = array_shift($this->_functions); + $rawPattern = $r[0]; + $func = $r[1]; + + if (Router::$routeFound) { + $noMatch = true; + } else { + // Get array from string + $pattern = Router::getArray($rawPattern); + + // If they are obviously different then stop the route + if (count(Router::$parameters) == count($pattern) + || $this->_hasWildcard($rawPattern) + ) { + // Check for matches, stop if we have a problem + foreach ($pattern as $idx => $value) { + // Store the variable + if ($this->_isPlaceholder($value)) { + if (!$this->_storeVariable( + $value, + @Router::$parameters[$idx] + ) + ) { + $noMatch = true; + break; + } + + continue; + } + + // If we are at a wildcard, we have a match! + if ($value == '*') { + $this->splat = implode( + Router::$delimiter, + array_slice(Router::$parameters, $idx) + ); + break; + } + + // If something doesn't match then stop the route. + if (!isset(Router::$parameters[$idx]) + || $value != Router::$parameters[$idx] + ) { + $noMatch = true; + break; + } + } + } else { + $noMatch = true; + } + } + + if ($noMatch) { + if (class_exists('Hook')) { + Hook::addAction('route_failed'); + Hook::addAction('route_failed_' . $this->name); + } + } else { + // Call route_start actions + if (class_exists('Hook')) { + $continue = Hook::addFilter('route_start', true); + $continue = Hook::addFilter('route_start_' . $this->name, true); + } else { + $continue = $this->name; + } + + if (isset($continue)) { + $this->pattern = $rawPattern; + Router::$routeFound = true; + $func($this); + } + + // Call route_end actions + if (class_exists('Hook')) { + Hook::addAction('route_end'); + Hook::addAction('route_end_' . $this->name); + } + } + + // This wasn't it, let's try the next one + $this->execute(); + } +} + +/** + * Exception: Route not Found + * + * @category Exception + * @package Sleepy + * @author Jaime A. Rodriguez + * @license http://opensource.org/licenses/MIT; MIT + * @link https://sleepymustache.com + */ +class RouteNotFound extends \Exception +{ +} diff --git a/mvc/View.php b/mvc/View.php new file mode 100644 index 0000000..2c3d76a --- /dev/null +++ b/mvc/View.php @@ -0,0 +1,99 @@ + + * @license http://opensource.org/licenses/MIT; MIT + * @link https://sleepymustache.com + */ + +namespace Sleepy\MVC; + +use \Sleepy\Core\Template; + +/** + * The View class + * + * All views must extend the view class + * + * @category MVC + * @package Sleepy + * @author Jaime A. Rodriguez + * @license http://opensource.org/licenses/MIT; MIT + * @link https://sleepymustache.com + */ +class View +{ + /** + * The contstructor + * + * @param Model $model The model for the view + * @param string $template which template to use for rendering the view + */ + public function __construct(Model $model, string $template="default") + { + $this->model = $model; + + $this->page = new Template( + $template, + DIRBASE . DIRECTORY_SEPARATOR . 'views' . DIRECTORY_SEPARATOR + ); + $this->page->model = &$this->model; + $this->_modelToPlaceholder($model); + $this->_render($model); + } + + /** + * Render function used to scope out variables + * + * @param Model $model The model to use + * + * @return void + */ + private function _render($model) + { + $this->page->show(); + } + + /** + * Creates placeholders for all Model properties + * + * @param Model $model The model to use + * + * @return void + */ + private function _modelToPlaceholder($model) + { + foreach ($model as $key => $value) { + $this->page->bind($key, $value); + } + } +} \ No newline at end of file diff --git a/settings.php b/settings.php index 1b5eb6f..7d13ead 100644 --- a/settings.php +++ b/settings.php @@ -1,84 +1,103 @@ + * @license https://opensource.org/licenses/MIT MIT + * @version GIT: 1.0.0 + * @link http://sleepymustache.com + */ + +use Sleepy\Core\Debug; +use Sleepy\Core\SM; // Comma separated URLs that define the environments -define('LIVE_URL', ''); -define('STAGE_URL', ''); +SM::$live_urls = [ 'example.com' ]; +SM::$stage_urls = [ 'stage.example.com' ]; // Server dependant variables (Dev/Stage/Live) -if (SM::isENV(STAGE_URL)) { - define('ENV', 'STAGE'); - - // Base Directory/URL - define('URLBASE', '/'); - define('DIRBASE', realpath(dirname(__FILE__)) . '/app/'); - - // DB Credentials - define ("DBHOST", $WHG_DB_HOST); - define ("DBUSER", $WHG_DB_USER); - define ("DBPASS", $WHG_DB_PASSWD); - define ("DBNAME", $WHG_DB_REPLDB); - - // Email information - define('EMAIL_FROM', ''); - define('EMAIL_TO', ''); - define('EMAIL_CC', ''); - define('EMAIL_BCC', ''); - - // Analytics - define('GA_ACCOUNT', ''); -} elseif (SM::isENV(LIVE_URL)) { - define('ENV', 'LIVE'); - - // Base Directory/URL - define('URLBASE', '/'); - define('DIRBASE', realpath(dirname(__FILE__)) . '/app/'); - - // DB Credentials - define ("DBHOST", $WHG_DB_HOST); - define ("DBUSER", $WHG_DB_USER); - define ("DBPASS", $WHG_DB_PASSWD); - define ("DBNAME", $WHG_DB_REPLDB); - - // Email information - define('EMAIL_FROM', ''); - define('EMAIL_TO', ''); - define('EMAIL_CC', ''); - define('EMAIL_BCC', ''); - - // Analytics - define('GA_ACCOUNT', ''); +if (SM::isStage()) { + + // Base Directory/URL + define('URLBASE', '/'); + define('DIRBASE', $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'app'); + + // DB Credentials + define("DBHOST", ''); + define("DBUSER", ''); + define("DBPASS", ''); + define("DBNAME", ''); + + // Email information + define('EMAIL_FROM', ''); + define('EMAIL_TO', ''); + define('EMAIL_CC', ''); + define('EMAIL_BCC', ''); + + // Analytics + define('GA_ACCOUNT', ''); + + // Set Debugging + Debug::$enableShow = false; // Show debug info on screen + Debug::$enableSend = false; // Send debug info via email + Debug::$enableLog = false; // Log debug info to a db + Debug::$enableConsole = false; // Show debug info in the console + +} elseif (SM::isLive()) { + + // Base Directory/URL + define('URLBASE', '/'); + define('DIRBASE', $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'app'); + + // DB Credentials + define("DBHOST", ''); + define("DBUSER", ''); + define("DBPASS", ''); + define("DBNAME", ''); + + // Email information + define('EMAIL_FROM', ''); + define('EMAIL_TO', ''); + define('EMAIL_CC', ''); + define('EMAIL_BCC', ''); + + // Analytics + define('GA_ACCOUNT', ''); + + // Set Debugging + Debug::$enableShow = false; // Show debug info on screen + Debug::$enableSend = false; // Send debug info via email + Debug::$enableLog = false; // Log debug info to a db + Debug::$enableConsole = false; // Show debug info in the console + } else { - define('ENV', 'DEV'); - - // Base Directory/URL - define('URLBASE', '/'); - define('DIRBASE', realpath(dirname(__FILE__)) . '/app/'); - - // DB Credentials - define ("DBHOST", $WHG_DB_HOST); - define ("DBUSER", $WHG_DB_USER); - define ("DBPASS", $WHG_DB_PASSWD); - define ("DBNAME", $WHG_DB_REPLDB); - - // Email information - define('EMAIL_FROM', ''); - define('EMAIL_TO', ''); - define('EMAIL_CC', ''); - define('EMAIL_BCC', ''); - - // Analytics - define('GA_ACCOUNT', ''); -} -// Set Debugging -if (class_exists('Debug')) { - Debug::$enable_show = false; // Show debug info on screen - Debug::$enable_send = false; // Send debug info via email - Debug::$enable_log = false; // Log debug info to a db - Debug::$enable_console = true; // Show debug info in the console -} \ No newline at end of file + // Base Directory/URL + define('URLBASE', '/'); + define('DIRBASE', $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'app'); + + // DB Credentials + define("DBHOST", ''); + define("DBUSER", ''); + define("DBPASS", ''); + define("DBNAME", ''); + + // Email information + define('EMAIL_FROM', ''); + define('EMAIL_TO', ''); + define('EMAIL_CC', ''); + define('EMAIL_BCC', ''); + + // Analytics + define('GA_ACCOUNT', ''); + + // Set Debugging + Debug::$enableShow = false; // Show debug info on screen + Debug::$enableSend = false; // Send debug info via email + Debug::$enableLog = false; // Log debug info to a db + Debug::$enableConsole = true; // Show debug info in the console +} diff --git a/sleepy.php b/sleepy.php deleted file mode 100644 index 380f791..0000000 --- a/sleepy.php +++ /dev/null @@ -1,27 +0,0 @@ - -* require_once('/app/core/sleepy.php'); -* -* -* ### Changelog -* -* ## Version 1.1 -* * Added documentation -* -* -* @date July 18, 2016 -* @author Jaime A. Rodriguez -* @version 1.1 -* @license http://opensource.org/licenses/MIT -*/ - -require_once('class.sm.php'); - -SM::initialize(); \ No newline at end of file