<?php /** * PtAction base class file * * PHP Version PHP 5 * * LICENSE: The version 3.0 of PHP License. * * @author Changsheng Jiang <pointer@tom.com> */ define('PT_BASE_ROOT', dirname(__FILE__).DIRECTORY_SEPARATOR); require_once 'func.lib.php'; /** * PtConfig * * The base configuration class with some static function for convenient. */ class PtConfig { /** * Get the static properties, this e.g can be served as a class * configuration. * * @param string $name component name, usually a class name * @param string $var the variable name * @return mixed the property */ public static function &getStaticProperty($name, $var) { static $properties; return $properties[$name][$var]; } public static function setStaticProperty($configs) { foreach ($configs as $class=>$config) { foreach ($config as $k=>$v) { $config = & self::getStaticProperty($class, $k); $config = $v; } } } } /** * PtAppConfiguration * * A module/application configuration class */ class PtAppConfiguration extends PtConfig { } /** * PtUser * */ class PtUser extends PtComponent { /** * @var array $userData * @access protected */ protected $userData; var $id; var $username = ''; var $password = ''; var $privilege = -1; /** * set user data form array, the array must has the key * 'username', 'password', 'privilege' seted. * * @param array $ua * @access public */ public function fromArray($ua) { foreach ($ua as $key=>$value) { $this->userData[$key]=$value; } $this->username = getValue($this->userData, 'username', ''); $this->password = getValue($this->userData, 'password', ''); $this->privilege = getValue($this->userData, 'privilege', 0); $this->id = getValue($this->userData, 'id', 0); } /** * Load user data from session * * @access public * @return bool true if session has user data. */ public function getSession() { if(isset($_SESSION['user'])) { $this->fromArray($_SESSION['user']); return true; } return false; } /** * Return user data as a array */ public function toArray() { return $this->userData; } /** * set the session */ public function setSession() { foreach($this->userData as $key=>$value) { $_SESSION['user'][$key]=$value; } } /** * check is login, get session auto. */ public function isLogin() { if ($this->privilege < 0) { $this->getSession(); } return $this->privilege > 0; } /** * login, abstract function ... */ public function login() { } /** * logout, reset the session */ public function logout() { unset($_SESSION['user']); $this->privilege=0; } /** * check user has the privilege do admin */ public function isCanAdmin() { $level = PtConfig::getStaticProperty(get_class($this), 'admin_privilege'); if (!$level) $level = 10000; return $this->privilege >= $level; } /** * check if user is is root. */ public function isRoot() { $level = PtConfig::getStaticProperty(get_class($this), 'root_privilege'); if (!$level) $level = 30000; return $this->privilege >= $level; } } /** * PtComponent * * The PtComponent class is the base class of all classes which has * prefix Pt. * * All common feature of MVC should be place here. * */ class PtComponent { /** * toggle debug message out or not. * * @access public * @var integer */ public $debugging = 0; /** * The number for generating a unique id * * @access private * @var integer * @see getUniqueId */ private static $_uniqueid =0; /** * The component unique id * * @access public * @var string */ public $componentId = ""; /** * The parameters about the instance. * * @access protected * @var array * @see getParam, setParam */ protected $params = array(); /** * Return a unique id as component * * @access public * @return integer */ public static function getUniqueId(){ return self::$_uniqueid++; } /** * Get Parameter by name with default if the parameter is not * seted. * * @access public * @param string $name the key of the parameter * @param mixed $default the default value if parameter is not seted. * @return mixed */ public function getParam($name, $default = false) { return isset($this->params[$name]) ? $this->params[$name] : $default; } /** * Unset the parameter * * @access public * @param string $name the key of the parameter */ public function unsetParam($name) { unset($this->params[$name]); } /** * Set a parameter * * @access public * @param string $name the key of the parameter * @param mixed $value the value of the parameter */ public function setParam($name, $value ) { unset($this->params[$name]);//unset first to prevent type overload $this->params[$name] = $value; } /** * Set parameters * * @access public * @param array $params the parameters be seted */ public function setParams($params) { if (is_array($params)) { $this->params = array_merge($this->params, $params); } throw new Exception("inner error: invalid argument in setParams"); } /** * Get the component name * * @access public * @return string */ function getComponentName() { if (is_object($this->module) && !empty($this->module->name)) return $this->module->name . ':' . get_class( $this ); else return get_class( $this ); } /** * Initialize * @access public */ public function initialize() { } /** * dispose function as the module dispose. * * @access public */ public function dispose() { } /** * debuge message, check debugging level * * @access public */ public function debugMsg($message, $level=0) { if ($this->debugging && $this->debugging > $level ) { echo $message; } } } /** * PtModel * * Abstract base class of all Model, generally this will just empty, * dispatch the call to really DB. */ abstract class PtModel extends PtComponent { } /** * PtAction * * Abstract base class of all Command/Action. * A subclass must overload the execute function. */ abstract class PtAction extends PtComponent { /** * data for a view to show * * @var array * @access protected * @see setViewData */ protected $view_data; /** * the action module * * @var mixed * @access public */ var $module; /** * check is the request method post * * @access public */ public function isPost() { return( isset( $_SERVER['REQUEST_METHOD'] ) && $_SERVER['REQUEST_METHOD'] === 'POST' ); } /** * Main function, action take here. * * @access public */ public function run($action) { $this->setViewData('curlevel', $this->module->getActionLevel($action)); $this->setViewData('isLogin', $this->module->user->isLogin()); $this->setViewData('isRoot', $this->module->user->isRoot()); $this->setViewData('user', $this->module->user->toArray()); } public function addViewData($key, $value) { if (is_array($value)) { $this->view_data[$key]=array_merge($this->view_data[$key], $value); } else { $this->view_data[$key]=$value; } } public function setViewData($key, $value) { $this->view_data[$key]=$value; } public function getViewData($key, $args) { if(isset($this->view_data[$key])) { $data=$this->view_data[$key]; } else { return null; } foreach ($args as $k=>$v) { if(is_integer($k)) { if (isset($data[$v])) { $data = $data[$v]; } else { return null; } } else { throw new Exception("try to get view data with not supported parameters"); } } return $data; } /** * The privilege level required to take action * * @access public */ public function getLevel() { if (isset($this->_level)) { return $this->_level; } else { $level = PtConfig::getStaticProperty(get_class($this),'level'); if ($level !== null ) { return $level; } } return 0;// default level, should this need to get from PtConfig? } } abstract class PtView extends PtComponent { /** * The action of the view for * * @access public */ var $action; var $module; /** * the view id, use to cache */ var $viewId; /** * get view data */ public function getData() { $args = func_get_args(); $key = array_shift($args); return $this->action->getViewData($key, $args); } /** * get view data with default value * */ public function getDataDefault() { $args = func_get_args(); $key = array_shift($args); $default = array_shift($args); $data=$this->action->getViewData($key, $args); if (isset($data)) { return $data; } else { return $default; } } /** * the main function to display the view */ public function display () { } } /** * PtController * * base class of all controller. */ class PtController extends PtComponent { /** * The content filters. * * @access protected * @var array */ protected $_filters = array(); protected $options; /** * register filters * * @access public * @param mixed $filter the filter */ function registerFilter(&$filter) { $this->_filters[] =& $filter; } /** * The main and door funciton of a controller * This follow to process which take module run and which then take action run */ public function run() { foreach ($this->_filters as $filter) { $filter->preFilter(); } try { $this->process(); } catch (Exception $e) { echo $e->getMessage(); } foreach (array_reverse($this->_filters) as $filter) { $filter->postFilter(); } } /** * The main proces function */ public function process() { $options =& PtConfig::getStaticProperty(get_class($this), 'options'); $do = getValue($options, 'modaction_url', 'do'); $action = getValue($_REQUEST, $do, ''); if (strlen($action) == 0) { $action = PtConfig::getStaticProperty(get_class($this), 'default_action'); } if (strpos($action, ':') != false) { list( $moduleName, $remaction ) = explode(':', $action); } else { $moduleName=getValue($options, "default_module", "PtModule"); $remaction=$action; } $module = &$this->loadModule($moduleName); $module->initialize(); $module->run($remaction); } /** * load module by module name use config or default */ protected function loadModule($moduleName) { $map = &PtConfig::getStaticProperty(get_class($this), 'module_map'); $moduleName = getValue($map, $moduleName, $moduleName); $module =& PtModule::factory($moduleName); $module->supcontroller = &$this; return $module; } /** * abort, the more action can be done such as components dispose. */ public function abort() {//do some more to abort. exit(); } /** * redirect to other url, then abort */ public function redirect( $url ) { header( 'Location: ' . $url ); $this->abort(); } /** * get full url by module:action */ public function getUrl($modaction) { $options = PtConfig::getStaticProperty(get_class($this), 'options'); $do = getValue($options, 'modaction_url', 'do'); return 'http://'.$_SERVER['SERVER_NAME'].$_SERVER["SCRIPT_NAME"] . '?'.$do .'='.$modaction; } /** * redirect to do a module:action */ public function transfer($modaction) { $options = PtConfig::getStaticProperty(get_class($this), 'options'); $do = getValue($options, 'modaction_url', 'do'); $this->redirect($this->getUrl($modaction)); } } /** * PtModule * * Base class of all Module. */ class PtModule extends PtController { // yes, a module is a controller! /** * The controller which call this module. * * @access public * @var mixed Controller */ var $supcontroller = null; /** * The module name */ var $name; var $user; /** * check action's privilege and current user's privilege */ public function isCanRun($action) { $level = $this->getActionLevel($action); $ulevel = $this->getCurLevel(); if ($ulevel < 0 || $level < 0) return false; if ($ulevel >= $level ) { return true; } else { return false; } } /** * get action privilege level */ public function getActionLevel($action) { $levels = PtConfig::getStaticProperty(get_class($this), 'levels'); if ( !isset($levels) ) { $level = 0; } else { $level = getValue($levels, $action, 0); } return $level; } public function getCurLevel() { if (isset($_SESSION['USER'])) { $ulevel = getValue($_SESSION['USER'], 'level', 0); } else { $ulevel = 0; } return $ulevel; } public function isAuthed($action) { if ($this->isCanRun($action)) { return true; } return false; } /** * The main function to process action as module part. * * First load check auth, load action, initialize it, and take * action run, then from the result get the proper view by config * or default, display the view's content * * @param string $action */ public function run($action) { $user = new PtUser(); $user->privilege = 0; $user->getSession(); $this->user=&$user; if (strlen($action) == 0) { $action = PtConfig::getStaticProperty(get_class($this), 'default_action'); } if (strlen($action) == 0) { throw new Exception("nothing to do, please set 'default_action'"); } if (!$this->isAuthed($action)) { throw new Exception('not authed, failed at moudle.'); } $this->controller = &$this->supcontroller;// if not reset by command initialize $command = &$this->loadAction($action); $command->initialize(); $result = $command->run($action); if (strlen($result) == 0) { $result = 'success'; } $view = &$this->loadView($command, $action, $result); $view->initialize(); $view->display(); //var_dump($_SESSION); } /** * load action class */ public function loadAction($action) { $map = &PtConfig::getStaticProperty(get_class($this), 'action_map'); if(isset($map[$action])) { $action = getValue($map[$action], 'action', $action); } $command =& $this->doLoadAction($action); $command->module = &$this; return $command; } protected function doLoadAction($action) { $options = &PtConfig::getStaticProperty(get_class($this), 'options'); $actionName = getValue($options, 'action_name_prefix', 'Action_').$action; $actiondir = getValue($options, 'action_dir', 'module'.DIRECTORY_SEPARATOR.$this->name .DIRECTORY_SEPARATOR.'action'.DIRECTORY_SEPARATOR); $actionbasedir = getValue($options, 'action_base_dir', PT_BASE_ROOT); if (class_exists($actionName, false) || @include_once $actionbasedir.$actiondir.$actionName.".php") { if (class_exists($actionName, false)) { if(!is_subclass_of($actionName, 'PtAction')){ throw new Exception("'$action' not a valid action"); } $command=new $actionName; return $command; } else { throw new Exception("action '$action's Class not found"); } } else { throw new Exception("action '$action's file not found"); } } /** * load view class */ public function loadView(&$command, $action, $result) { $actionmap = &PtConfig::getStaticProperty(get_class($this), 'action_map'); $viewName = $action; if (isset($actionmap[$action])) { if (isset($actionmap[$action]['view'][$result]) ) { $viewName = $actionmap[$action]['view'][$result]; } else { $viewName = $actionmape[$action]; } } $viewName = getValue($options, 'view_name_prefix', 'View_').$viewName; $viewdir = getValue($options, 'view_dir', 'module'.DIRECTORY_SEPARATOR.$this->name .DIRECTORY_SEPARATOR.'view'.DIRECTORY_SEPARATOR); $viewbasedir = getValue($options, 'view_base_dir', PT_BASE_ROOT); if (class_exists($viewName, false) || @include_once $viewbasedir.$viewdir.$viewName.".php") { if (class_exists($viewName, false)) { if (!is_subclass_of($viewName, 'PtView')) { throw new Exception("action '$action' with result '$result' has not a valid view"); } $view=new $viewName; } else { throw new Exception("view '$viewName's Class not found"); } } else { throw new Exception("view '$viewName's file not found"); } $view->action=&$command; $view->module=&$this; return $view; } /** * Singleton function, get the singleton instance. Usually this * should be called after factory has load the class file. * * @access public * @return PtModule a instance of PtModule */ public static function &singleton($className, $name){ if (!class_exists($className, false)) { throw new Exception("'$className' not a valid module or not found."); } if ($className!=__CLASS__ && !is_subclass_of($className, __CLASS__)){ throw new Exception("class '$className' not a module"); } if (!$name) { $name=$className; } if (isset($GLOBALS['_PtMoulde_SINGLETON'][$name])) { if ($GLOBALS['_PtMoulde_SINGLETON'][$name] instanceof $className) { return $GLOBALS['_PtMoulde_SINGLETON'][$name]; } else { throw new Exception("the module $name is not a $className"); } } $module=new $className; $GLOBALS['_PtMoulde_SINGLETON'][$name]=&$module; $module->name=$name; return $module; } public function __clone() { trigger_error('Moulde Clone is not allowed.', E_USER_ERROR); } /** * Try to load the $name module, and return a instance. A * sub-module who wants to has it's own factory, should overload * this function, since the __CLASS__ is hardcoded. * * @access public * @param string $name * @param mixed $param * @return PtModule a instance of PtModule if success, or throw PtInvalidModuleException */ public static function factory($name) { if($name == __CLASS__) { return self::singleton($name, $name); } $options = &PtConfig::getStaticProperty(__CLASS__, "options"); $moduledir = getValue($options, 'module_dir', 'module'.DIRECTORY_SEPARATOR); $modulebasedir = getValue($options, 'module_base_dir', PT_BASE_ROOT); $className = getValue($options, 'class_name_prefix', "Module_").$name; $moduledir = $modulebasedir.$moduledir; return self::_in_factory($name, $className, $moduledir); } protected static function _in_factory($name, $className, $moduledir) { if (class_exists($className, false) || @include_once $moduledir.$name.".php"){ $module= &self::singleton($className, $name); } else { throw new Exception("Module '$name's file '${moduledir}${name}' not found"); } return $module; } } ?>
一个 PHP MVC 的实现
一切见诸代码, 注释应该是无声的.....
Subscribe to:
Post Comments (Atom)
-
不是我折腾矩阵和向量, 是矩阵和向量折腾我. 早期为速度, 使用 cblas 比较多. cblas 非常不好用, double, float 函数各一 还好说, 关键是大部分函数的参数太多了, 如 void cblas_dgemm ( const enum CBLAS_...
-
几种简单的排序算法比较次数比较 1 说明 几种排序算法, 有一些是简单实现, 另有 glibc 的 qsort 和 GNU C++ 库的 std::sort. 下面的时间是排序 long 型数组的时间. 其实, 是一个 C 里 Sequence, 但...
-
I have used secure sharing to distribute my private encrypted data for many years. And i have a demo project in my github. FYI, this demo ...
No comments:
Post a Comment