/** * constructor; * * @access public * @param array $aConfig configuration array * @return void */ public function __construct(array $aConfig = array()) { // write configs into registry $this->saveConfigToRegistry($aConfig); // add a CLI wrapper to enable requests from command line true === filter_var(Registry::get('MVC_CLI'), FILTER_VALIDATE_BOOLEAN) ? $this->cliWrapper() : false; Log::WRITE(str_repeat('#', 10) . "\tnew Request" . "\t" . php_sapi_name() . "\t" . (array_key_exists('REQUEST_METHOD', $_SERVER) ? $_SERVER['REQUEST_METHOD'] : '') . ' ' . (array_key_exists('REQUEST_URI', $_SERVER) ? $_SERVER['REQUEST_URI'] : '')); // handle Errors new Error(); // handle Routing new Router(); // Run target Controller's __preconstruct() self::runTargetClassPreconstruct(Request::getInstance()->getQueryArray()); // Set Session self::setSession(); // Run Intrusion Detection System (phpids) new IDS(); // consider Policy Rules // e.g. maybe the requested target controller may not be called due to some reason // and should be protected from any requesting new Policy(); // Run the requested target Controller new Controller(Request::getInstance()); Event::RUN('mvc.application.construct.finished'); }
/** * Constructor * * @access protected * @return void */ protected function __construct() { $this->_sNamespace = Registry::get('MVC_SESSION_NAMESPACE'); $this->_aOption = Registry::get('MVC_SESSION_OPTIONS'); foreach ($this->_aOption as $sKey => $mValue) { ini_set('session.' . $sKey, $mValue); Log::WRITE('ini_set("session.' . $sKey . '", ' . $mValue . ');'); } session_start(); session_cache_limiter('nocache'); session_cache_expire(0); $this->setNamespace(); }
/** * Constructor * * @access public * @return void */ public function __construct() { // default: class \MVC\RouterJsonfile // @see /application/config/config*.php $sClass = Registry::get('MVC_ROUTING_HANDLING'); $oRouterObject = new $sClass(); $sClassToCheck = Registry::get('MVC_ROUTER_JSON'); $sInterfaceToCheck = Registry::get('MVC_INTERFACE_ROUTER_JSON'); if (FALSE === is_subclass_of($oRouterObject, $sClassToCheck)) { $sMsg = 'ERROR: <br />Make sure `' . $sClass . '` <b>extends</b> ' . $sClassToCheck; Error::addERROR($sMsg); Log::WRITE(strip_tags($sMsg)); Helper::STOP($sMsg); } if (FALSE === filter_var($oRouterObject instanceof $sInterfaceToCheck, FILTER_VALIDATE_BOOLEAN)) { $sMsg = 'ERROR: <br />Make sure `' . $sClass . '` <b>implements</b> ' . $sInterfaceToCheck; Error::addERROR($sMsg); Log::WRITE(strip_tags($sMsg)); Helper::STOP($sMsg); } // save to registry $oRouterObject::SAVEROUTINGTOREGISTRY($oRouterObject->_aRouting, $oRouterObject->_sRequestUri); }
/** * reads the routing.json file and looks for matching routes<br /> * The Get-Param `a` will be passed through in both cases * * @access public * @return boolean */ public function __construct() { // call the Routing Json building class to get the proper routing // @see config Registry::isRegistered('MVC_ROUTING_JSON_BUILDER') ? $sRoutingBuilder = Registry::get('MVC_ROUTING_JSON_BUILDER') : false; if (!isset($sRoutingBuilder)) { Error::addERROR('config MVC_ROUTING_JSON_BUILDER is not set.'); return false; } $this->_oRoutingBuilder = new $sRoutingBuilder(); $this->_sRoutingJson = $this->_oRoutingBuilder->getRoutingJson(); $this->_aRouting = json_decode($this->_sRoutingJson, true); $this->_sRequestUri = Request::getInstance()->getRequestUri(); // add path isset($this->_aRouting[$this->_sRequestUri]) ? $this->_aRouting[$this->_sRequestUri]['path'] = $this->_sRequestUri : false; // add class, method if (array_key_exists($this->_sRequestUri, $this->_aRouting)) { if (array_key_exists('query', $this->_aRouting[$this->_sRequestUri])) { // add Target Class parse_str($this->_aRouting[$this->_sRequestUri]['query'], $sQuery); $this->_aRouting[$this->_sRequestUri]['class'] = ucfirst($sQuery[Registry::get('MVC_GET_PARAM_MODULE')]) . '\\Controller\\' . ucfirst($sQuery[Registry::get('MVC_GET_PARAM_C')]); $this->_aRouting[$this->_sRequestUri]['method'] = Request::getInstance()->getMethod(); } } Log::WRITE('routing table built by: ' . $sRoutingBuilder); Log::WRITE('routing handling done by: ' . Registry::get('MVC_ROUTING_HANDLING')); Log::WRITE('routes (cutout): ' . substr(preg_replace('/\\s+/', '', $this->_sRoutingJson), 0, 25) . ' [..]'); if (false === filter_var($this->_oRoutingBuilder instanceof \MVC\MVCInterface\RouterJsonBuilder, FILTER_VALIDATE_BOOLEAN)) { /** * @todo ERROR */ $sMsg = 'ERROR: <br />Make sure `' . $sRoutingBuilder . '` <b>implements</b> \\MVC\\MVCInterface\\RouterJsonBuilder'; Error::addERROR($sMsg); Helper::STOP($sMsg); } return true; }
/** * Uncaught exception handler * * @access public * @static * @param \ErrorException $oErrorException * @return void */ public static function EXCEPTION(\ErrorException $oErrorException) { $sLogfile = 'error.log'; $sMsg = ''; if (method_exists($oErrorException, 'getSeverity')) { $iSeverity = $oErrorException->getSeverity(); $sMsg .= 'Severity: ' . $iSeverity . "\t"; if (in_array($iSeverity, array(E_WARNING, E_USER_WARNING))) { $sLogfile = 'warning.log'; } if (in_array($iSeverity, array(E_NOTICE, E_USER_NOTICE, E_DEPRECATED))) { $sLogfile = 'notice.log'; } } $sMsg .= '(Code: ' . $oErrorException->getCode() . ' / Class: ' . get_class($oErrorException) . '), File: ' . $oErrorException->getFile() . ', Line: ' . $oErrorException->getLine() . ', Message: ' . $oErrorException->getMessage() . ', Trace: ' . $oErrorException->getTraceAsString(); self::addERROR($sMsg); Log::WRITE($sMsg, $sLogfile); true === filter_var(Registry::get('MVC_DEBUG'), FILTER_VALIDATE_BOOLEAN) ? Helper::DISPLAY(print_r($oErrorException, true)) : false; }
/** * reads the routing.json file and looks for matching routes<br /> * The Get-Param `a` will be passed through in both cases * * @access public * @return void */ public function __construct() { parent::__construct(); if (is_array($this->_aRouting) && array_key_exists('QUERY_STRING', $_SERVER)) { // right found (GET Params String) // means a request as e.g. // http://dev.mvc.de/?module=custom&c=index&m=index foreach ($this->_aRouting as $sKey => $aValue) { // if there is no route sepcified in the routing.json (empty), take the MVC fallback routing if (!array_key_exists('query', $aValue) || $aValue['query'] === '') { $aValue['query'] = Registry::get('MVC_ROUTING_FALLBACK'); // add Target Class parse_str($aValue['query'], $sQuery); $this->_aRouting[$this->_sRequestUri]['class'] = '\\' . ucfirst($sQuery[Registry::get('MVC_GET_PARAM_MODULE')]) . '\\Controller\\' . ucfirst($sQuery[Registry::get('MVC_GET_PARAM_C')]); } DETECT_APPENDINGS: $sAppend = ''; $sAppend = trim(substr($_SERVER['QUERY_STRING'], strlen($aValue['query']))); // if query string contains the fallback string, cut it out if (substr($sAppend, 0, strlen(Registry::get('MVC_ROUTING_FALLBACK'))) == Registry::get('MVC_ROUTING_FALLBACK')) { $sAppend = substr($sAppend, strlen(Registry::get('MVC_ROUTING_FALLBACK'))); } $sAppend = '?' . trim(substr($sAppend, 1, strlen($sAppend))); $sAppend === '?' ? $sAppend = '' : FALSE; // redirect to the SEO Url, which is $sKey here if ($aValue['query'] === substr($_SERVER['QUERY_STRING'], 0, strlen($aValue['query']))) { Request::REDIRECT($sKey . $sAppend); } } } // SEO Url 1:1 Match if (array_key_exists($this->_sRequestUri, $this->_aRouting)) { $aQueryString = $this->_aRouting[$this->_sRequestUri]; // use the MVC fallback routing if none is specified in routing.json. @see config if (empty($aQueryString['query'])) { $aQueryString['query'] = Registry::get('MVC_ROUTING_FALLBACK'); Log::WRITE('MVC Fallback: ' . $aQueryString['query']); } // copy to QUERY_STRING $_SERVER['QUERY_STRING'] = $aQueryString['query']; $aParts = explode('&', $aQueryString['query']); // copy to GET foreach ($aParts as $aValue['query']) { $aPiece = explode('=', $aValue['query']); array_key_exists(1, $aPiece) ? $_GET[$aPiece[0]] = $aPiece[1] : FALSE; array_key_exists(Registry::get('MVC_GET_PARAM_MODULE'), $_GET) ? $_GET[Registry::get('MVC_GET_PARAM_MODULE')] = ucfirst($_GET[Registry::get('MVC_GET_PARAM_MODULE')]) : FALSE; array_key_exists(Registry::get('MVC_GET_PARAM_C'), $_GET) ? $_GET[Registry::get('MVC_GET_PARAM_C')] = ucfirst($_GET[Registry::get('MVC_GET_PARAM_C')]) : FALSE; } Request::getInstance()->saveRequest()->prepareQueryVarsForUsage(); } else { foreach ($this->_aRouting as $sIndex => $aValue) { if (substr($sIndex, -1) === '*') { $sWildcard = substr($sIndex, 0, -1); if (substr($_SERVER['REQUEST_URI'], 0, strlen($sWildcard)) === $sWildcard) { // e.g.: module=default&c=index&m=action $aQuery = explode('&', $this->_aRouting[$sIndex]['query']); foreach ($aQuery as $sValue) { $aEx = explode('=', $sValue); $_GET[$aEx[0]] = $aEx[1]; } $this->_aRouting[$sIndex]['path'] = $sIndex; $this->_aRouting[$sIndex]['class'] = ucfirst($_GET['module']) . '\\Controller\\' . ucfirst($_GET['c']); $this->_aRouting[$sIndex]['index'] = $sIndex; $this->_sRequestUri = $sIndex; $this->_addParam(); Request::getInstance()->saveRequest()->prepareQueryVarsForUsage(); return true; break; } } } } }
/** * unbinds (delete) one or all events * * @access public * @static * @param string $sEvent eventname<br /> * deletes the given event.<br /> * if this parameter not is set, *all* events are going to be deleted * * @return boolean success */ public static function UNBIND($sEvent) { $aBacktrace = debug_backtrace(); $sDebug = ''; isset($aBacktrace[0]['file']) ? $sDebug .= $aBacktrace[0]['file'] : FALSE; isset($aBacktrace[0]['line']) ? $sDebug .= ', ' . $aBacktrace[0]['line'] : FALSE; isset($aBacktrace[0]['class']) ? $sDebug .= ' > ' : FALSE; if (!isset(self::$aEvent[$sEvent])) { Event::addToRegistry('UNBIND', 'UNBIND: All Events deleted --> called in: ' . $sDebug); self::$aEvent = array(); Log::WRITE('UNBIND: All Events deleted --> called in: ' . $sDebug); return true; } Event::addToRegistry('UNBIND', 'UNBIND: Event `' . $sEvent . '` deleted --> called in: ' . $sDebug); self::$aEvent[$sEvent] = NULL; unset(self::$aEvent[$sEvent]); Log::WRITE('UNBIND: Event `' . $sEvent . '` deleted --> called in: ' . $sDebug); return true; }
/** * makes sure the requested page will be delivered with the correct protocol (http|https) * * @access public * @static * @deprecated will be removed in future versions. use instead: \MVC\Request::ENSURECORRECTPROTOCOL(); * @return void */ public static function ENSURECORRECTPROTOCOL() { $aDebug = self::PREPAREBACKTRACEARRAY(debug_backtrace()); Log::WRITE("DEPRECATED: " . __METHOD__ . "\tReplaced by:\t" . '\\MVC\\Request::ENSURECORRECTPROTOCOL(); --> called in: ' . $aDebug['sFile'] . ', ' . $aDebug['sLine'], 'notice.log'); // Replaced by: Request::ENSURECORRECTPROTOCOL(); }
/** * redirects to given URI * * @access public * @static * @param string $sLocation * @param string $sHeader * @return void */ public static function REDIRECT($sLocation, $sHeader = '') { // source $aBacktrace = debug_backtrace(); array_key_exists('file', $aBacktrace[0]) ? $sFile = $aBacktrace[0]['file'] : ($sFile = ''); array_key_exists('line', $aBacktrace[0]) ? $sLine = $aBacktrace[0]['line'] : ($sLine = ''); array_key_exists('line', $aBacktrace) ? $sLine = $aBacktrace['line'] : FALSE; // standard Log::WRITE('Redirect to: ' . $sLocation . ' --> called in: ' . $sFile . ', ' . $sLine); // CLI if (true === filter_var(Registry::get('MVC_CLI'), FILTER_VALIDATE_BOOLEAN)) { echo shell_exec('php index.php "' . $sLocation . '"'); exit; } header('Location: ' . $sLocation); exit; }
/** * executes the target (requested) controller class and its method * * @access public * @param array $aQueryArray * @return boolean */ public function reflect(array $aQueryArray = array()) { Event::RUN('mvc.reflect.start'); if (empty($aQueryArray)) { return FALSE; } array_key_exists(Registry::get('MVC_GET_PARAM_MODULE'), $aQueryArray['GET']) ? $sModule = $aQueryArray['GET'][Registry::get('MVC_GET_PARAM_MODULE')] : ($sModule = ''); array_key_exists(Registry::get('MVC_GET_PARAM_C'), $aQueryArray['GET']) ? $sClass = $aQueryArray['GET'][Registry::get('MVC_GET_PARAM_C')] : ($sClass = ''); array_key_exists(Registry::get('MVC_GET_PARAM_M'), $aQueryArray['GET']) ? $sMethod = $aQueryArray['GET'][Registry::get('MVC_GET_PARAM_M')] : ($sMethod = ''); array_key_exists(Registry::get('MVC_GET_PARAM_A'), $aQueryArray['GET']) ? $sArgs = $aQueryArray['GET'][Registry::get('MVC_GET_PARAM_A')] : ($sArgs = ''); // Fallback Target if ($sModule == '' && $sClass == '') { parse_str(Registry::get('MVC_ROUTING_FALLBACK'), $aParse); $sControllerClassName = '\\' . ucfirst($aParse[Registry::get('MVC_GET_PARAM_MODULE')]) . '\\Controller\\' . ucfirst($aParse[Registry::get('MVC_GET_PARAM_C')]); } else { $sControllerClassName = '\\' . ucfirst($sModule) . '\\Controller\\' . ucfirst($sClass); } $sControllerFilename = Registry::get('MVC_MODULES') . '/' . $sModule . '/Controller/' . $sClass . '.php'; $sFile = Registry::get('MVC_MODULES') . '/' . str_replace('\\', '/', $sControllerClassName) . '.php'; if (file_exists($sControllerFilename)) { if (class_exists($sControllerClassName)) { // Singleton or New if (method_exists($sControllerClassName, 'getInstance')) { $oReflectionObject = $sControllerClassName::getInstance($sArgs); } else { $oReflectionObject = new $sControllerClassName($sArgs); } if (FALSE === filter_var($oReflectionObject instanceof \MVC\MVCInterface\Controller, FILTER_VALIDATE_BOOLEAN)) { //@todo ERROR $sMsg = 'ERROR: <br />Make sure `' . $sControllerClassName . '` <b>implements</b> \\MVC\\MVCInterface\\Controller'; Log::WRITE(strip_tags($sMsg)); Helper::STOP($sMsg); } if ($sMethod != '') { try { $oReflectionMethod = new \ReflectionMethod($sControllerClassName, $sMethod); } catch (\ReflectionException $oReflectionException) { return FALSE; } // run an event and store the object of the target class within Event::RUN('mvc.reflect.targetObject.before', $oReflectionObject); // run an event which KEY is // Class::method // of the requested Target // and store the object of the target class within Event::RUN($sControllerClassName . '::' . $sMethod, $oReflectionObject); // static Method or not-static if (true === filter_var($oReflectionMethod->isStatic(), FILTER_VALIDATE_BOOLEAN)) { $oReflectionObject::$sMethod($sArgs); } else { $oReflectionObject->{$sMethod}($sArgs); } Event::RUN('mvc.reflect.targetObject.after', $oReflectionObject); return true; } else { return FALSE; } } else { return FALSE; } } return FALSE; }