├── .gitignore ├── README.md ├── app ├── Bootstrap.php ├── controllers │ ├── Admin.php │ ├── Application.php │ ├── Backend │ │ ├── Backend.php │ │ ├── Index.php │ │ └── Posts.php │ ├── Error.php │ ├── Index.php │ └── Restfull.php ├── models │ └── Post.php ├── modules │ └── Admin │ │ ├── _init.php │ │ ├── config │ │ └── routes.ini │ │ ├── controllers │ │ ├── Index.php │ │ ├── Pages.php │ │ └── Posts.php │ │ └── views │ │ ├── index │ │ └── index.phtml │ │ ├── layouts │ │ └── admin.phtml │ │ ├── pages │ │ └── index.phtml │ │ └── posts │ │ └── index.phtml ├── plugins │ ├── AuthToken.php │ └── Log.php └── views │ ├── application │ └── notfound.phtml │ ├── backend │ ├── index │ │ └── index.phtml │ └── posts │ │ └── index.phtml │ ├── error │ └── error.phtml │ ├── index │ └── index.phtml │ ├── layouts │ ├── backend.phtml │ └── frontend.phtml │ └── restfull │ ├── edit.phtml │ ├── form.phtml │ ├── index.phtml │ ├── new.phtml │ └── show.phtml ├── config ├── application.ini.default └── routing.ini ├── lib ├── Helper │ └── Html.php ├── Lycan │ └── Validations │ │ ├── Errors.php │ │ ├── ValidatableInterface.php │ │ ├── Validate.php │ │ ├── Validator.php │ │ └── Validators │ │ ├── Acceptance.php │ │ ├── Clusivity.php │ │ ├── Confirmation.php │ │ ├── Each.php │ │ ├── Email.php │ │ ├── Exclusion.php │ │ ├── Format.php │ │ ├── Inclusion.php │ │ ├── Length.php │ │ ├── Numericality.php │ │ └── Presence.php └── eYaf │ ├── Layout.php │ ├── Logger.php │ └── Request.php ├── log └── .gitignore ├── public ├── .htaccess ├── css │ ├── admin │ │ └── style.css │ └── style.css ├── img │ └── ap.jpg ├── index.php └── js │ └── app.js └── vendor └── .gitignore /.gitignore: -------------------------------------------------------------------------------- 1 | log/* 2 | tests/* 3 | config/application.ini 4 | public/favicon.ico 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # A base application for Yaf framework 2 | 3 | Yaf framework documentation can be found at [php.net](http://www.php.net/manual/en/book.yaf.php) 4 | 5 | ## Requirements 6 | 7 | * Yaf php extension. Download and install from [Pecl](http://pecl.php.net/package/yaf) 8 | * PHP 5.3+ 9 | * Mysql server 10 | * Apache, Nginx or Lighttpd web server. 11 | * mod_rewrite and .htaccess enabled for Apache web server. 12 | 13 | ## Configuration 14 | 15 | * Info about setting up a server for Yaf can be found [here](http://www.php.net/manual/en/yaf.examples.php) 16 | * Rename `config/application.ini.default` to `config/application.ini` 17 | * If you have PHP 5.4 you can use the internal web server to test the project. 18 | * `cd yaf_base_application/public` 19 | * `php -S localhost:8000` 20 | * This project uses PHP 5.3 namespaces so `yaf.use_namespace` should be turned on. 21 | 22 | ## Additions 23 | 24 | * ~~A simple ORM database layer `lib/Orm`. Yaf Models extend `lib/Orm/Entity` class. (More documentation soon at wiki)~~ 25 | * Validation library `lib/Validations` from [another project](https://github.com/akDeveloper/Lycan) of mine for validating classes. 26 | * A Layout class that allows to render views inside a base html layout `lib/Layout.php`. Layouts directory can be defined in application.ini 27 | * A Logger class `lib/Logger.php` and a `LoggerPlugin` to log info about requests and database queries. (Make sure that log directory is readable.) 28 | * A custom Request class `lib/Request.php` that extends `Yaf\Request\Http` and offers input filter for request params, posts and queries. 29 | * ~~A Paginator `lib/Paginator` forked from Laravel framework and adjust it to work with `lib/Orm`~~ 30 | * An Authenticity token plugin `AuthTokenPlugin`to prevent Cross-site request forgery (csrf). Can be turned on/off from application.ini 31 | * A base `ApplicationController` which adds some base functionality like 404 not found page. 32 | * A `RestfullController` to make easy crud (create, read, update, delete) actions. 33 | * An `ErrorController` to catch all exceptions and display a page with error info and bugtrace. 34 | * Custom error_handler to catch errors and throws Exceptions. 35 | * Custom _init.php file for modules for extra configuration. 36 | * Some base helper classes `lib/Helper` 37 | -------------------------------------------------------------------------------- /app/Bootstrap.php: -------------------------------------------------------------------------------- 1 | setErrorHandler(array(get_class($this),'error_handler')); 14 | } 15 | 16 | public function _initConfig(Yaf\Dispatcher $dispatcher) 17 | { 18 | $this->config = Yaf\Application::app()->getConfig(); 19 | } 20 | 21 | public function _initRequest(Yaf\Dispatcher $dispatcher) 22 | { 23 | $dispatcher->setRequest(new Request()); 24 | } 25 | 26 | public function _initDatabase(Yaf\Dispatcher $dispatcher) 27 | { 28 | 29 | } 30 | 31 | public function _initPlugins(Yaf\Dispatcher $dispatcher) 32 | { 33 | $dispatcher->registerPlugin(new LogPlugin()); 34 | 35 | $this->config->application->protect_from_csrf && 36 | $dispatcher->registerPlugin(new AuthTokenPlugin()); 37 | 38 | } 39 | 40 | public function _initLoader(Yaf\Dispatcher $dispatcher) 41 | { 42 | } 43 | 44 | public function _initRoute(Yaf\Dispatcher $dispatcher) 45 | { 46 | $config = new Yaf\Config\Ini(APP_PATH . '/config/routing.ini'); 47 | $dispatcher->getRouter()->addConfig($config); 48 | } 49 | 50 | /** 51 | * Custom init file for modules. 52 | * 53 | * Allows to load extra settings per module, like routes etc. 54 | */ 55 | public function _initModules(Yaf\Dispatcher $dispatcher) 56 | { 57 | $app = $dispatcher->getApplication(); 58 | 59 | $modules = $app->getModules(); 60 | foreach ($modules as $module) { 61 | if ('index' == strtolower($module)) continue; 62 | 63 | require_once $app->getAppDirectory() . "/modules" . "/$module" . "/_init.php"; 64 | } 65 | } 66 | 67 | public function _initLayout(Yaf\Dispatcher $dispatcher) 68 | { 69 | $layout = new Layout($this->config->application->layout->directory); 70 | $dispatcher->setView($layout); 71 | } 72 | 73 | /** 74 | * Custom error handler. 75 | * 76 | * Catches all errors (not exceptions) and creates an ErrorException. 77 | * ErrorException then can caught by Yaf\ErrorController. 78 | * 79 | * @param integer $errno the error number. 80 | * @param string $errstr the error message. 81 | * @param string $errfile the file where error occured. 82 | * @param integer $errline the line of the file where error occured. 83 | * 84 | * @throws ErrorException 85 | */ 86 | public static function error_handler($errno, $errstr, $errfile, $errline) 87 | { 88 | // Do not throw exception if error was prepended by @ 89 | // 90 | // See {@link http://www.php.net/set_error_handler} 91 | // 92 | // error_reporting() settings will have no effect and your error handler 93 | // will be called regardless - however you are still able to read 94 | // the current value of error_reporting and act appropriately. 95 | // Of particular note is that this value will be 0 96 | // if the statement that caused the error was prepended 97 | // by the @ error-control operator. 98 | // 99 | if (error_reporting() === 0) return; 100 | 101 | throw new ErrorException($errstr, 0, $errno, $errfile, $errline); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /app/controllers/Admin.php: -------------------------------------------------------------------------------- 1 | getView()->setLayout($this->layout); 50 | 51 | //Set session. 52 | $this->session = Yaf\Session::getInstance(); 53 | 54 | // Assign session to views too. 55 | $this->getView()->session = $this->session; 56 | 57 | // Assign application config file to this controller 58 | $this->config = Yaf\Application::app()->getConfig(); 59 | 60 | // Assign config file to views 61 | $this->getView()->config = $this->config; 62 | } 63 | 64 | /** 65 | * When assign a public property to controller, this property will be 66 | * available to action view template too. 67 | * 68 | * @param string $name the name of the property 69 | * @param mixed $value the value of the property 70 | * 71 | * @return void 72 | */ 73 | public function __set($name, $value) 74 | { 75 | $this->$name = $value; 76 | $this->getView()->assignRef($name, $value); 77 | } 78 | 79 | public function getConfig() 80 | { 81 | return $this->config; 82 | } 83 | 84 | /** 85 | * Cancel current action proccess and forward to {@link notFound()} method. 86 | * 87 | * @return false 88 | */ 89 | public function forwardTo404() 90 | { 91 | $this->forward('Index','application','notFound'); 92 | $this->getView()->setScriptPath($this->getConfig()->application->directory 93 | . "/views"); 94 | header('HTTP/1.0 404 Not Found'); 95 | return false; 96 | } 97 | 98 | /** 99 | * Renders a 404 Not Found template view 100 | * 101 | * @return void 102 | */ 103 | public function notFoundAction() 104 | { 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /app/controllers/Backend/Backend.php: -------------------------------------------------------------------------------- 1 | getView()->setLayout(null); 8 | 9 | // fallback views path to global when error occured in modules. 10 | $config = Yaf\Application::app()->getConfig(); 11 | $this->getView()->setScriptPath($config->application->directory 12 | . "/views"); 13 | 14 | $this->getView()->e = $exception; 15 | $this->getView()->e_class = get_class($exception); 16 | $this->getView()->e_string_trace = $exception->getTraceAsString(); 17 | 18 | $params = $this->getRequest()->getParams(); 19 | unset($params['exception']); 20 | $this->getView()->params = array_merge( 21 | array(), 22 | $params, 23 | $this->getRequest()->getPost(), 24 | $this->getRequest()->getQuery() 25 | ); 26 | 27 | eYaf\Logger::getLogger()->logException($exception); 28 | 29 | switch ($exception->getCode()) { 30 | case YAF\ERR\AUTOLOAD_FAILED: 31 | case YAF\ERR\NOTFOUND\MODULE: 32 | case YAF\ERR\NOTFOUND\CONTROLLER: 33 | case YAF\ERR\NOTFOUND\ACTION: 34 | header('HTTP/1.1 404 Not Found'); 35 | break; 36 | case 401: 37 | $this->forward('Index','application','accessDenied'); 38 | header('HTTP/1.1 401 Unauthorized'); 39 | Yaf\Dispatcher::getInstance()->disableView(); 40 | echo $this->render('accessdenied'); 41 | break; 42 | default: 43 | header("HTTP/1.1 500 Internal Server Error"); 44 | break; 45 | } 46 | 47 | eYaf\Logger::stopLogging(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /app/controllers/Index.php: -------------------------------------------------------------------------------- 1 | heading = 'Home Page'; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /app/controllers/Restfull.php: -------------------------------------------------------------------------------- 1 | getResourceCollection(); 34 | $this->getView()->assign('collection', $collection); 35 | } 36 | 37 | /** 38 | * Loads and displays a single resource asccording to Request::getParams() 39 | * values. 40 | * 41 | * By default the uri to show a resource is /module/controller/show/id/1 42 | * 43 | * @param int $id The id of resource to load 44 | */ 45 | public function showAction($id) 46 | { 47 | $resource = $this->getResource($id); 48 | 49 | if (null === $resource) { 50 | return $this->forwardTo404(); 51 | } else { 52 | $this->getView()->assign('resource', $resource); 53 | } 54 | } 55 | 56 | public function newAction() 57 | { 58 | $model = $this->get_model_name(); 59 | $resource = new $model(); 60 | $this->get_index_url(); 61 | $this->getView()->assign('resource', $resource); 62 | } 63 | 64 | public function createAction() 65 | { 66 | $model = $this->get_model_name(); 67 | 68 | $resource = new $model($this->get_resource_params($model)); 69 | 70 | if ($resource->save()) { 71 | $this->redirect($this->get_index_url()); 72 | return false; 73 | } else { 74 | Yaf\Dispatcher::getInstance()->disableView(); 75 | echo $this->render('new', array('resource'=>$resource, 76 | 'index_url'=>$this->get_index_url())); 77 | return false; 78 | } 79 | } 80 | 81 | public function editAction($id) 82 | { 83 | 84 | $resource = $this->getResource($id); 85 | 86 | if (null === $resource) { 87 | return $this->forwardTo404(); 88 | } else { 89 | $this->get_index_url(); 90 | $this->getView()->assign('resource', $resource); 91 | } 92 | } 93 | 94 | public function updateAction($id) 95 | { 96 | $resource = $this->getResource($id); 97 | 98 | if (null === $resource) { 99 | return $this->forwardTo404(); 100 | } 101 | 102 | $model = $this->get_model_name(); 103 | 104 | if ($resource->updateAttributes($this->get_resource_params($model))) { 105 | $this->redirect($this->get_index_url()); 106 | return false; 107 | } else { 108 | Yaf\Dispatcher::getInstance()->disableView(); 109 | echo $this->render('edit', array('resource'=>$resource, 110 | 'index_url'=>$this->get_index_url())); 111 | return false; 112 | } 113 | } 114 | 115 | public function deleteAction() 116 | { 117 | $resource = $this->getResource(); 118 | 119 | if (null === $resource) { 120 | return $this->forwardTo404(); 121 | } 122 | 123 | $this->resource->destroy(); 124 | 125 | $this->redirect($this->get_index_url()); 126 | return false; 127 | } 128 | 129 | /** 130 | * Creates a resource collection. 131 | * 132 | * By default it finds all elements of the resource. You can overload this 133 | * methods to return custom queries of the resource like pagination and/or 134 | * search. 135 | * 136 | * @return Orm\Mysql\Collection A collection object handling elements of 137 | * the resource 138 | */ 139 | public function getResourceCollection() 140 | { 141 | $model = $this->get_model_name(); 142 | 143 | return $model::find()->fetchAll(); 144 | } 145 | 146 | /** 147 | * Creates a resource by a given id. 148 | * 149 | * By default it finds the resource for the given id. 150 | * Overload this method if you want to load a resource with additional 151 | * criteria. 152 | * 153 | * @param int $id The id of resource to load. 154 | */ 155 | public function getResource($id) 156 | { 157 | if (null === $this->_resource) { 158 | $model = $this->get_model_name(); 159 | $this->_resource = $model::findById($id) 160 | ->fetch(); 161 | } 162 | return $this->_resource; 163 | } 164 | 165 | protected function get_model_name() 166 | { 167 | return Inflect::singularize($this->getRequest()->getControllerName()) 168 | . "Model"; 169 | } 170 | 171 | protected function get_resource_params($model) 172 | { 173 | $param_name = Inflect::underscore(str_replace('Model', '', $model)); 174 | $post = $this->getRequest()->getPost(); 175 | 176 | return $post[$param_name]; 177 | } 178 | 179 | protected function get_index_url() 180 | { 181 | 182 | if (null !== $this->_index_url) { 183 | return $this->_index_url; 184 | } 185 | 186 | $module = $this->getRequest()->getModuleName(); 187 | 188 | $this->_index_url = "/" 189 | . ('index' == strtolower($module) ? null : $module. "/") 190 | . Inflect::underscore($this->getRequest()->getControllerName()) 191 | . "/index"; 192 | 193 | $this->getView()->assign('index_url', $this->_index_url); 194 | return $this->_index_url; 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /app/models/Post.php: -------------------------------------------------------------------------------- 1 | getRouter()->addConfig($routes->admin); 7 | -------------------------------------------------------------------------------- /app/modules/Admin/config/routes.ini: -------------------------------------------------------------------------------- 1 | ;Admin routes 2 | admin.admin_index.type="rewrite" 3 | admin.admin_index.match="/(admin|admin/)$" 4 | admin.admin_index.route.module="admin" 5 | admin.admin_index.route.controller="index" 6 | admin.admin_index.route.action="index" 7 | -------------------------------------------------------------------------------- /app/modules/Admin/controllers/Index.php: -------------------------------------------------------------------------------- 1 | getView()->setLayoutPath( 12 | $this->getConfig()->application->directory 13 | . "/modules" . "/Admin" . "/views" . "/layouts" 14 | ); 15 | } 16 | 17 | public function indexAction() 18 | { 19 | $this->heading = "Dashboard"; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/modules/Admin/controllers/Pages.php: -------------------------------------------------------------------------------- 1 | heading = 'Posts'; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /app/modules/Admin/views/index/index.phtml: -------------------------------------------------------------------------------- 1 | 2 |
15 | *
16 | *
17 | *
18 | * After submission of the form, the plugin will attempt to validate the
19 | * auth_token an will throw an \Exception if tokens are not equal.
20 | */
21 | class AuthTokenPlugin extends Yaf\Plugin_Abstract
22 | {
23 |
24 | public function routerShutdown(Yaf\Request_Abstract $request ,
25 | Yaf\Response_Abstract $response
26 | ) {
27 | $this->auth_token();
28 | }
29 |
30 | public function dispatchLoopStartup(Yaf\Request_Abstract $request,
31 | Yaf\Response_Abstract $response
32 | ){
33 |
34 | $this->verify_auth_token($request);
35 | }
36 |
37 | protected function verify_auth_token($request)
38 | {
39 | $config = Yaf\Application::app()->getConfig();
40 |
41 | if ( $config['application']['protect_from_csrf']
42 | && $request->isPost()
43 | ) {
44 |
45 | $post = $request->getPost();
46 |
47 | if ( !isset($post['_auth_token'])
48 | || $post['_auth_token'] !== $this->auth_token()
49 | ){
50 | throw new \Exception('Invalid authenticity token!');
51 | } else {
52 | $session = Yaf\Session::getInstance();
53 | $session->auth_token = NULL;
54 | $this->auth_token();
55 | }
56 | }
57 | }
58 |
59 | /**
60 | * Creates a random token, ancodes it with Base64 and stores it to session
61 | *
62 | * @return string The authenticity token string.
63 | */
64 | protected function auth_token()
65 | {
66 | $session = Yaf\Session::getInstance();
67 | $session->auth_token = $session->auth_token
68 | ?: base64_encode(sha1(uniqid(rand(), true)));
69 | return $session->auth_token;
70 | }
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/app/plugins/Log.php:
--------------------------------------------------------------------------------
1 | log("[{$request->getRequestUri()}]");
16 | }
17 |
18 | public function routerShutdown(Yaf\Request_Abstract $request,
19 | Yaf\Response_Abstract $response
20 | ){
21 | Logger::getLogger()->logRequest($request);
22 | }
23 |
24 | public function dispatchLoopStartup(Yaf\Request_Abstract $request,
25 | Yaf\Response_Abstract $response
26 | ){
27 |
28 | }
29 |
30 | public function preDispatch(Yaf\Request_Abstract $request ,
31 | Yaf\Response_Abstract $response
32 | ){
33 |
34 | }
35 |
36 | public function postDispatch(Yaf\Request_Abstract $request,
37 | Yaf\Response_Abstract $response
38 | ){
39 | }
40 |
41 | public function dispatchLoopShutdown(Yaf\Request_Abstract $request,
42 | Yaf\Response_Abstract $response
43 | ){
44 | Logger::stopLogging();
45 | }
46 |
47 |
48 | public function preResponse(Yaf\Request_Abstract $request,
49 | Yaf\Response_Abstract $response
50 | ){
51 |
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/app/views/application/notfound.phtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | = $this->title ?>
3 | -------------------------------------------------------------------------------- /app/views/backend/posts/index.phtml: -------------------------------------------------------------------------------- 1 | title = 'Posts' ?> 2 |Posts Index
3 | -------------------------------------------------------------------------------- /app/views/error/error.phtml: -------------------------------------------------------------------------------- 1 | 2 | 3 |: getFile()?> at line getLine()?>34 | 35 | in file
getTraceAsString()?>
38 |
40 |
41 |
42 | 45 | Parameters: 46 |
47 | 48 |49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /app/views/index/index.phtml: -------------------------------------------------------------------------------- 1 | title = "Home";?> 2 |
95 | * = $this->javascripts ?>
96 | *
97 | * This is the place where additional javascript files would appear.
98 | *
99 | * @param View_Interface $view The view instance
100 | * @param string|array $args An array of javascript paths or a
101 | * string with javascript path to load.
102 | */
103 | public static function appendJavascript(ViewInterface $view, $args)
104 | {
105 | if ( !isset($view->javascripts)) {
106 | $view->assign('javascripts', '');
107 | }
108 |
109 | if ( !is_array($args)) {
110 | $args = array($args);
111 | }
112 |
113 | foreach ($args as $arg) {
114 | $url = strpos($arg, 'http') === 0 || strpos($arg, '/') === 0
115 | ? $arg
116 | : '/javascripts/'.$arg;
117 | $view->javascripts .= self::javascript($url . '.js');
118 | }
119 | }
120 |
121 | /**
122 | * Appends a stylesheet file from current view.
123 | *
124 | * Some stylesheet files are required to load only in specific action
125 | * views. You can add them with this method.
126 | *
127 | * Notice that you have to add a line to your layout file like:
128 | *
129 | * = $this->css ?>
130 | *
131 | * This is the place where additional stylesheet files would appear.
132 | *
133 | * @param View_Interface $view The view instance
134 | * @param string|array $args An array of stylesheet paths or a
135 | * string with stylesheet path to load.
136 | */
137 | public static function appendCss(ViewInterface $view, $args)
138 | {
139 | if ( !isset($view->stylesheets)) {
140 | $view->assign('stylesheets', '');
141 | }
142 |
143 | if ( !is_array($args)) {
144 | $args = array($args);
145 | }
146 |
147 | foreach ($args as $arg) {
148 | $url = strpos($arg, 'http') === 0 || strpos($arg, '/') === 0
149 | ? $arg
150 | : '/stylesheets/'.$arg;
151 | $view->stylesheets .= self::css($url.'.css');
152 | }
153 | }
154 |
155 | public static function attributes($array)
156 | {
157 | if (empty($array)) return null;
158 |
159 | $o = "";
160 | foreach ($array as $k => $v) {
161 | if ( null !== $v )
162 | $o .= ' ' . $k . '="' . self::encode($v) . '"';
163 | }
164 | return ' '.$o;
165 | }
166 |
167 | }
168 |
--------------------------------------------------------------------------------
/lib/Lycan/Validations/Errors.php:
--------------------------------------------------------------------------------
1 | getArrayCopy();
17 |
18 | foreach ($array as $k=>$v) $this->offsetUnset($k);
19 | }
20 |
21 | public function isEmpty()
22 | {
23 | return $this->count() == 0;
24 | }
25 |
26 | public function contains($attribute)
27 | {
28 | return $this->offsetExists($attribute);
29 | }
30 |
31 | public function add($attribute, $message=null, $options=array())
32 | {
33 | $message = $this->_normalize_message($attribute, $message, $options);
34 | !$this->offsetExists($attribute) ? $this->offsetSet($attribute, array()) : null;
35 | $val = $this->offsetGet($attribute);
36 | array_push($val, $message);
37 | $this->offsetSet($attribute, $val);
38 | }
39 |
40 | private function _normalize_message($attribute, $message, $options)
41 | {
42 | $message = $message ?: ':invalid';
43 |
44 | if ( 0 === strpos($message, ':') ) {
45 | return $this->generateMessage($attribute, $message, $options);
46 | } elseif (is_callable($message)) {
47 | return $message();
48 | } else {
49 | return $message;
50 | }
51 | }
52 |
53 | public function generateMessage($attribute, $type=':invalid', $options=array())
54 | {
55 | $message = null;
56 | $type = substr($type, 1);
57 |
58 | if (isset($options['message'])) {
59 | if (0 === strpos($options['message'], ':'))
60 | $type = substr($options['message'], 1);
61 | else
62 | $message = $options['message'];
63 | }
64 |
65 | return $message ?: $type;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/lib/Lycan/Validations/ValidatableInterface.php:
--------------------------------------------------------------------------------
1 |
22 | * Array(
23 | * 'class_attribute_name' => Array(
24 | * [0] => 'Message',
25 | * [1] => 'Message',
26 | * ),
27 | * 'another_class_attribute_name' => Array(
28 | * [0] => 'Message',
29 | * ),
30 | * )
31 | *
32 | *
33 | * @retrun array|ArrayIterator
34 | */
35 | public function getErrors();
36 | }
37 |
--------------------------------------------------------------------------------
/lib/Lycan/Validations/Validate.php:
--------------------------------------------------------------------------------
1 |
14 | * class MyClass
15 | * {
16 | * use Lycan\Validations\Validate;
17 | *
18 | * protected function validations()
19 | * {
20 | * $this->validates('property', array('Validator'=>$options);
21 | * }
22 | *
23 | * }
24 | *
25 | */
26 | trait Validate
27 | {
28 | protected $default_keys = array('if', 'on', 'allow_empty', 'allow_null');
29 |
30 | private $_errors;
31 |
32 | /**
33 | * Returns errors that occured after the validation of the class.
34 | *
35 | * @see \Lycan"validations\Errors
36 | *
37 | * @return \ArrayIterator
38 | */
39 | public function errors()
40 | {
41 | $this->_errors = $this->_errors ?: new Errors();
42 | return $this->_errors;
43 | }
44 |
45 | public function getErrors()
46 | {
47 | return $this->errors();
48 | }
49 |
50 | /**
51 | * Checks if a class is valid
52 | *
53 | * @return boolean
54 | */
55 | public function isValid()
56 | {
57 | $this->errors()->clear();
58 | $this->run_validations();
59 | return $this->errors()->isEmpty();
60 | }
61 |
62 | /**
63 | * Checks if a class is invalid
64 | *
65 | * @return boolean
66 | */
67 | public function isInvalid()
68 | {
69 | return !$this->isValid();
70 | }
71 |
72 | /**
73 | * Validates properties of a class against validators.
74 | *
75 | * validations array must contain the name of Validator class without the
76 | * namespace and the options for this validator.
77 | *
78 | *
79 | * $validations = array('Validator' => array('message'=>'my error message'));
80 | *
81 | * $validations = array('Validator' => true); // you must pass true if
82 | * options are not exist.
83 | *
84 | *
85 | * On examples above the Lycan\Validations\Validators\Validator will be
86 | * called.
87 | *
88 | * @params string|array $attrs the properties of class to validate
89 | * @params array $validations an array of Validator name class and
90 | * its options.
91 | *
92 | * @throws \Exception if a Validator class does not exist.
93 | *
94 | * @return void
95 | */
96 | final public function validates($attrs, array $validations)
97 | {
98 | foreach ($validations as $key=>$options) {
99 |
100 | $validator = "\\Lycan\\Validations\\Validators\\" . $key;
101 |
102 | if (!class_exists($validator)) {
103 | throw new \Exception("Unknown validator: {$key}");
104 | }
105 |
106 | $defaults = $this->_parse_validates_options($options);
107 | $defaults['attributes'] = $attrs;
108 | $vtor = new $validator($defaults);
109 | $vtor->validate($this);
110 | }
111 | }
112 |
113 | public function readAttributeForValidation($attribute)
114 | {
115 | return isset($this->$attribute) ? $this->$attribute : null;
116 | }
117 |
118 | protected function validations()
119 | {
120 | return true;
121 | }
122 |
123 | protected function run_validations()
124 | {
125 | $this->validations();
126 |
127 | return $this->errors()->count() == 0;
128 | }
129 |
130 | private function _parse_validates_options($options)
131 | {
132 | if (is_array($options)) {
133 |
134 | return $options;
135 | } elseif(is_bool($options)) {
136 |
137 | return array();
138 | } else {
139 |
140 | return array('with' => $options);
141 | }
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/lib/Lycan/Validations/Validator.php:
--------------------------------------------------------------------------------
1 | options = $options;
15 | }
16 |
17 | public function kind()
18 | {
19 | if (null == $this->kind) {
20 | $name = explode('\\',get_class($this));
21 | $this->kind = strtolower(array_pop($name));
22 | }
23 |
24 | return $this->kind;
25 | }
26 |
27 | abstract public function validate($record);
28 |
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/lib/Lycan/Validations/Validators/Acceptance.php:
--------------------------------------------------------------------------------
1 |
27 | * $options = array('Acceptance' => true);
28 | * $this->validates('terms_of_service', $options);
29 | *
30 | * $options = array('Acceptance' => array(
31 | * 'message'=> 'accept the terms or else ...',
32 | * 'if' => function($class){
33 | * return !$class->isNeedToAccept;
34 | * }
35 | * ));
36 | *
37 | * $this->validates('terms_of_service',$options);
38 | *
39 | *
40 | * @vendor Lycan
41 | * @package Validations
42 | * @author Andreas Kollaros
36 | * application/views/index/index.phtml
37 | *
38 | * title = "Index Action" ?>
39 | * Index Action
40 | *
41 | *
42 | * @author Andreas Kollaros