/** * Get an instance of a preexisting Connection or a new instance. * * @param array $group * @return \HMC\Database\Connection */ public static function get($group = false) { // Determining if exists or it's not empty, then use default group defined in config $group = !$group ? array('type' => \HMC\Config::DATABASE_TYPE(), 'host' => \HMC\Config::DATABASE_HOST(), 'name' => \HMC\Config::DATABASE_NAME(), 'user' => \HMC\Config::DATABASE_USER(), 'pass' => \HMC\Config::DATABASE_PASS()) : $group; // Group information $type = $group['type']; $host = $group['host']; $name = $group['name']; $user = $group['user']; $pass = $group['pass']; // ID for database based on the group information $id = "{$type}.{$host}.{$name}.{$user}.{$pass}"; // Checking if the same if (isset(self::$instances[$id])) { return self::$instances[$id]; } try { // I've run into problem where // SET NAMES "UTF8" not working on some hostings. // Specifiying charset in DSN fixes the charset problem perfectly! $instance = new Connection("{$type}:host={$host};dbname={$name};charset=utf8", $user, $pass); $instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Setting Database into $instances to avoid duplication self::$instances[$id] = $instance; return $instance; } catch (PDOException $e) { $msg = Logger::buildExceptionMessage($e); \HMC\Error::showError(501, $msg); } }
/** * Show an error message to the user and log the error if needed. * Current 404 errors are not logged. This function ends execution. * @param $errNum int the HTTP error code to return, typically 404 for missing page or 500. * @param $info string (optional) with the message to log, not displayed in production. */ public static function showError($errNum, $info = null) { Language::load('Errors'); ob_get_clean(); $defError = Language::tr('500_default_error'); switch ($errNum) { case 404: Error::error404(); die; break; case 500: default: break; } if ($info != null) { Logger::error('[' . $errNum . '] ' . strip_tags($info)); } $data['title'] = Language::tr('500_title'); $data['error'] = $info != null ? Config::SITE_ENVIRONMENT() == 'development' ? $defError . '<br/>' . $info : $defError : $defError; View::addHeader("HTTP/1.0 500 Internal Server Error"); View::renderTemplate('header', $data); View::render('error/500', $data); View::renderTemplate('footer', $data); die; }
/** * created the relative address to the template folder * @return string url to template folder */ public static function relativeTemplatePath($admin = false) { if ($admin == false) { return "app/templates/" . \HMC\Config::SITE_TEMPLATE() . "/"; } else { return "app/templates/" . \HMC\Config::SITE_TEMPLATE() . "/"; } }
/** * return absolute path to selected template directory * @param string $path path to file from views folder * @param array $data array of data * @param string $custom path to template folder */ public static function renderTemplate($path, $data = false, $custom = false) { self::init(); if (!headers_sent()) { foreach (self::$headers as $header) { header($header, true); } } $file = "app/Templates/" . \HMC\Config::SITE_TEMPLATE() . "/{$path}.php"; if ($custom == false) { if (file_exists($file)) { require $file; } else { Logger::error('File (' . $file . ') was not found.'); Error::showError(500); die; } } else { require "app/Templates/{$custom}/{$path}.php"; } }
/** * pLoad language function * @param string $name - the name of the language file to load * @param string $code - (optional, defaults to SITE_LANGUAGE) the language code to load, i.e. en = english, fr = french * @param string $fileTemplate - (optional, defaults to app/Language dir) for plugins to load their lang files */ public static function pload($name, $icode = null, $fileTemplate = 'app/Language/[code]/[name].php') { if ($icode == null) { self::$code = \HMC\Config::SITE_LANGUAGE(); } else { self::$code = $icode; } // lang file $file = str_replace('[code]', self::$code, $fileTemplate); $file = str_replace('[name]', $name, $file); // check if is readable if (is_readable($file)) { // require file if (!isset(self::$array[$name])) { self::$array[$name] = array(); } if (empty(self::$array[$name][self::$code])) { self::$array[$name][self::$code] = (include $file); } return true; } else { return false; } }
<?php use HMC\Config; use HMC\Hooks; ?> <!DOCTYPE html> <html> <head> <title><?php echo $data['title']; ?> | <?php echo Config::SITE_TITLE(); ?> </title> <?php Hooks::run('meta'); Hooks::run('css'); //use Assets::css or combine_css to inject stylesheets ?> </head> <body>
public static function sendEmail($message) { if (self::$emailError == true) { $mail = new Mail(); $mail->setFrom(\HMC\Config::SITE_EMAIL()); $mail->addAddress(\HMC\Config::SITE_EMAIL()); $mail->subject('New error on ' . \HMC\Config::SITE_TITLE()); $mail->body($message); $mail->send(); } }
/** * saves error message from exception * @param numeric $number error number * @param string $message the error * @param string $file file originated from * @param numeric $line line number */ public static function errorHandler($number, $message, $file, $line) { if (Config::SITE_ENVIRONMENT() == 'development') { Error::showError(500, '(' . $number . ') ' . $file . ':' . $line . ' => ' . $message); die; } $msg = "{$message} in {$file} on line {$line}"; if (self::$logger != null) { self::error($number . $msg); } else { if ($number !== E_NOTICE && $number < 2048) { self::errorMessage($msg); self::customErrorMsg(); } } return 0; }
/** * empties and destroys the session */ public static function destroy($key = '') { if (self::$sessionStarted == true) { if (empty($key)) { session_unset(); session_destroy(); } else { unset($_SESSION[\HMC\Config::SESSION_PREFIX() . $key]); } } }
width="45.456867" height="132.32999" x="167.68532" y="770.5296" /> </g> </g> </svg> <ul> <li><?php echo Language::tr('404_help_check_address'); ?> </li> <?php if (\HMC\Config::SITE_EMAIL() !== '') { ?> <li><?php echo Language::tr('404_help_email_admin'); ?> </li> <?php } ?> <li><?php echo Language::tr('404_help_goto_home'); ?> </li> </ul>
<?php use HMC\Config; use HMC\Language; ?> <div class="page-header"> <h1><?php echo $data['title']; ?> </h1> </div> <p><?php echo $data['welcome_message']; ?> </p> <a class="btn btn-md btn-success" href="<?php echo Config::SITE_URL(); ?> /subpage"> <?php echo Language::tr('open_subpage'); ?> </a>
} else { echo "<h1>Please install via composer.json</h1>"; echo "<p>Install Composer instructions: <a href='https://getcomposer.org/doc/00-intro.md#globally'>https://getcomposer.org/doc/00-intro.md#globally</a></p>"; echo "<p>Once composer is installed navigate to the working directory in your terminal/command promt and enter 'composer install'</p>"; exit; } use HMC\Config; use HMC\Hooks; use HMC\Router; use HMC\View; //Routes are defined in the config file. $configFile = '.app_config.json'; //initiate config Hooks::run('init'); $configFile = Hooks::run('pre-config', $configFile); $config = Config::init($configFile); Hooks::run('config-ready'); Hooks::addHook('headers', 'addNotice'); //Initialize Router Router::init($config); //if no route found //Router::error('Core\Error@index'); //To route with the url/Controller/Method/args schema uncomment this. Router::$fallback = true; Hooks::run('pre-dispatch'); //execute matched routes Router::dispatch(); function addNotice() { View::addHeader('X-Uses: HMC-soft MVC'); }
/** * Runs the callback for the given request */ public static function dispatch() { $uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); $method = $_SERVER['REQUEST_METHOD']; $searches = array_keys(static::$patterns); $replaces = array_values(static::$patterns); self::$routes = str_replace('//', '/', self::$routes); $found_route = false; // parse query parameters $query = ''; $q_arr = array(); if (strpos($uri, '&') > 0) { $query = substr($uri, strpos($uri, '&') + 1); $uri = substr($uri, 0, strpos($uri, '&')); $q_arr = explode('&', $query); foreach ($q_arr as $q) { $qobj = explode('=', $q); $q_arr[] = array($qobj[0] => $qobj[1]); if (!isset($_GET[$qobj[0]])) { $_GET[$qobj[0]] = $qobj[1]; } } } // check if route is defined without regex if (in_array($uri, self::$routes)) { $route_pos = array_keys(self::$routes, $uri); // foreach route position foreach ($route_pos as $route) { if (self::$methods[$route] == $method || self::$methods[$route] == 'ANY') { $found_route = true; //if route is not an object if (!is_object(self::$callbacks[$route])) { //call object controller and method self::invokeObject(self::$callbacks[$route]); if (self::$halts) { return; } } else { //call closure call_user_func(self::$callbacks[$route]); if (self::$halts) { return; } } } } // end foreach } else { // check if defined with regex $pos = 0; // foreach routes foreach (self::$routes as $route) { $route = str_replace('//', '/', $route); if (strpos($route, ':') !== false) { $route = str_replace($searches, $replaces, $route); } if (preg_match('#^' . $route . '$#', $uri, $matched)) { if (self::$methods[$pos] == $method || self::$methods[$pos] == 'ANY') { $found_route = true; //remove $matched[0] as [1] is the first parameter. array_shift($matched); if (!is_object(self::$callbacks[$pos])) { //call object controller and method self::invokeObject(self::$callbacks[$pos], $matched); if (self::$halts) { return; } } else { //call closure call_user_func_array(self::$callbacks[$pos], $matched); if (self::$halts) { return; } } } } $pos++; } // end foreach } if (self::$fallback) { //call the auto dispatch method $found_route = self::autoDispatch(); } // run the error callback if the route was not found if (!$found_route) { //first check if we have a satisfiable static route. if (count(self::$static_routes) > 0) { $test_sr = str_replace(Config::SITE_PATH() . '/', '', $uri); foreach (self::$static_routes as $sr) { if (file_exists($sr . $test_sr)) { $ext = \HMC\Document\Document::getExtension($test_sr); switch ($ext) { case 'html': case 'htm': require $sr . $test_sr; break; default: header("Location: {$sr}{$test_sr}"); } die; } else { //for security you cannot access php files directly so //if there's no extension we test for a php file with that name. if (file_exists($sr . $test_sr . '.php')) { require $sr . $test_sr . '.php'; die; } } } } if (!self::$errorCallback) { self::$errorCallback = function () { Error::showError(404); }; } if (!is_object(self::$errorCallback)) { //call object controller and method self::invokeObject(self::$errorCallback, null, 'No routes found.'); if (self::$halts) { return; } } else { call_user_func(self::$errorCallback); if (self::$halts) { return; } } } }
/** * Output optimized stylesheet. * This function will combine multiple stylesheets into a single sheet. * It will also perform some basic optimizations to reduce download size. * @param $files - array of files to include * @param $outputdir - where to store generated file(s), default is typically adequate. */ public static function combine_css($files, $outputdir = 'static/generated/') { if (\HMC\Config::SITE_ENVIRONMENT() == 'development') { Assets::css($files); return; } $ofiles = is_array($files) ? $files : array($files); $hashFileName = md5(join($ofiles)); $dirty = false; if (file_exists($outputdir . $hashFileName . '.css')) { $hfntime = filemtime($outputdir . $hashFileName . '.css'); foreach ($ofiles as $vfile) { $file = str_replace(\HMC\Config::SITE_URL(), \HMC\Config::SITE_PATH(), $vfile); if (!$dirty) { $fmtime = filemtime($file); if ($fmtime > $hfntime) { $dirty = true; } } } } else { $dirty = true; } if ($dirty) { $buffer = ""; foreach ($ofiles as $vfile) { $cssFile = str_replace(\HMC\Config::SITE_URL(), \HMC\Config::SITE_PATH(), $vfile); $buffer .= "\n" . file_get_contents($cssFile); } // Remove comments $buffer = preg_replace('!/\\*[^*]*\\*+([^/][^*]*\\*+)*/!', '', $buffer); // Remove space after colons $buffer = str_replace(': ', ':', $buffer); // Remove whitespace $buffer = str_replace(array("\r\n", "\r", "\n", "\t", ' ', ' ', ' '), '', $buffer); ob_start(); // Write everything out echo $buffer; $fc = ob_get_clean(); file_put_contents(\HMC\Config::SITE_PATH() . $outputdir . $hashFileName . '.css', $fc); } static::resource(str_replace(':||', '://', str_replace('//', '/', str_replace('://', ':||', \HMC\Config::SITE_URL() . $outputdir . $hashFileName . '.css'))), 'css'); }