├── tests ├── mvc │ ├── index.php │ ├── content │ │ └── images │ │ │ ├── mvc.png │ │ │ └── php.png │ ├── filters │ │ ├── EmptyFilter.php │ │ ├── NoResultErrorFilter.php │ │ ├── ExecutingWorldFilter.php │ │ ├── ErrorFilter.php │ │ └── ExecutedWorldFilter.php │ ├── views │ │ ├── shared │ │ │ ├── _empty.php │ │ │ ├── footer.php │ │ │ ├── error.php │ │ │ ├── _lite.php │ │ │ ├── header.php │ │ │ ├── _default.php │ │ │ └── _parent.php │ │ ├── home │ │ │ ├── prog.php │ │ │ ├── hello.php │ │ │ └── index.php │ │ └── account │ │ │ └── login.php │ ├── models │ │ ├── HomePage.php │ │ └── Login.php │ └── controllers │ │ ├── AccountController.php │ │ ├── FilterController.php │ │ ├── OutputCacheController.php │ │ └── HomeController.php ├── models │ ├── ModelA.php │ ├── ModelB.php │ └── ModelC.php ├── autoload.php ├── HttpRequest.php ├── HttpContextInfo.php ├── RouteCollectionTest.php ├── HttpResponse.php ├── UrlHelperTest.php ├── PathUtilityTest.php ├── FilterTest.php ├── HttpContext.php └── ArrayToObjectTest.php ├── .gitignore ├── .vscode └── tasks.json ├── composer.json ├── LICENSE └── src ├── Info.php ├── UrlParameter.php ├── HttpAntiForgeryException.php ├── ActionNameValidationException.php ├── EventArgs.php ├── HttpRequest.php ├── CrossSiteScriptingValidation.php ├── ActionResult.php ├── FileCacheProviderConfig.php ├── RouteParsingException.php ├── HttpContext.php ├── EmptyResult.php ├── Loader.php ├── HttpContextInfo.php ├── SelectListGroup.php ├── RouteOptions.php ├── ModelStateEntry.php ├── ViewNotFoundException.php ├── ActionFilter.php ├── ExceptionResult.php ├── ActionExecutingContext.php ├── HttpRequestValidationException.php ├── RouteSegment.php ├── ModelDataAnnotation.php ├── Filter.php ├── OutputCacheLocation.php ├── index.php ├── ContentResult.php ├── HttpStatusCodeResult.php ├── ErrorHandlerEventArgs.php ├── ValidateAntiForgeryToken.php ├── UrlHelper.php ├── SelectListItem.php ├── HttpResponse.php ├── RedirectResult.php ├── JsonResult.php ├── ViewResult.php ├── FileResult.php ├── ExceptionContext.php ├── CacheProvider.php ├── ActionExecutedContext.php ├── RedirectToActionResult.php ├── IdleCacheProvider.php ├── Cache.php ├── ViewContext.php ├── HttpSessionProvider.php ├── PathUtility.php ├── View.php ├── RouteProvider.php ├── HttpContextBase.php └── ModelState.php /tests/mvc/index.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | /composer.lock 3 | /docs 4 | /output 5 | /cache 6 | /tests/mvc/cache 7 | -------------------------------------------------------------------------------- /tests/mvc/content/images/mvc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php-mvc-project/php-mvc/HEAD/tests/mvc/content/images/mvc.png -------------------------------------------------------------------------------- /tests/mvc/content/images/php.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php-mvc-project/php-mvc/HEAD/tests/mvc/content/images/php.png -------------------------------------------------------------------------------- /tests/mvc/filters/EmptyFilter.php: -------------------------------------------------------------------------------- 1 | 5 | 6 | -------------------------------------------------------------------------------- /tests/models/ModelA.php: -------------------------------------------------------------------------------- 1 | 4 | 5 |

Index

6 |

This is another page of the most wonderful site in the world!

-------------------------------------------------------------------------------- /tests/models/ModelB.php: -------------------------------------------------------------------------------- 1 | addPsr4("PhpMvcTest\\", __DIR__ . '/mvc', true); 7 | $classLoader->register(); -------------------------------------------------------------------------------- /tests/mvc/views/home/hello.php: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 |

Model

14 | -------------------------------------------------------------------------------- /tests/mvc/views/shared/footer.php: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /tests/HttpRequest.php: -------------------------------------------------------------------------------- 1 | 11 | 12 | 13 | 14 |

Index

15 |

This is the main page of the most wonderful site in the world!

16 | -------------------------------------------------------------------------------- /tests/mvc/views/shared/error.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Error 7 | 8 | 9 |
10 |

Error.

11 |

An error occurred while processing the request.

12 |
13 | 14 | -------------------------------------------------------------------------------- /tests/models/ModelC.php: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | <?=Html::getTitle('Lite layout')?> - PHP MVC Test project 9 | 10 | 11 |

Lite layout

12 | 13 |
14 | 15 |
16 | 17 | -------------------------------------------------------------------------------- /tests/mvc/filters/NoResultErrorFilter.php: -------------------------------------------------------------------------------- 1 | setExceptionHandled(true); 18 | } 19 | 20 | } -------------------------------------------------------------------------------- /tests/HttpContextInfo.php: -------------------------------------------------------------------------------- 1 | setResult(new ContentResult('executing the world!')); 18 | } 19 | 20 | } -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "php-mvc-project/php-mvc", 3 | "description": "Implementation of the MVC (Model-View-Controller) architectural pattern in PHP.", 4 | "keywords": ["mvc"], 5 | "license": "MIT", 6 | "type": "library", 7 | "authors": [ 8 | { 9 | "name": "Meet Aleksey", 10 | "homepage": "https://github.com/meet-aleksey" 11 | } 12 | ], 13 | "require": { 14 | "php": ">=7.0" 15 | }, 16 | "require-dev": { 17 | "phpunit/phpunit": "^7" 18 | }, 19 | "autoload": { 20 | "psr-4": { "PhpMvc\\": "src" } 21 | } 22 | } -------------------------------------------------------------------------------- /tests/mvc/filters/ErrorFilter.php: -------------------------------------------------------------------------------- 1 | setResult(new ViewResult('error')); 19 | // $exceptionContext->setResult(new ContentResult('hello exception!')); 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /tests/mvc/filters/ExecutedWorldFilter.php: -------------------------------------------------------------------------------- 1 | getException()) === null) { 18 | $actionExecutedContext->setResult(new ContentResult('executed the world!')); 19 | } 20 | else { 21 | $actionExecutedContext->setResult(new ContentResult($ex->getMessage())); 22 | } 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /tests/mvc/views/shared/header.php: -------------------------------------------------------------------------------- 1 | 8 | 9 |
10 | 26 |
-------------------------------------------------------------------------------- /tests/mvc/views/shared/_default.php: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | <?=Html::getTitle('Default layout')?> - PHP MVC Test project 9 | 10 | 11 | 12 | 13 |
14 |

Default layout

15 | 16 | 17 | 18 | 19 | 20 |

Model

21 | 22 | 23 |

ViewData

24 | 25 | 26 |

ModelState

27 | 28 |
29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /tests/mvc/views/shared/_parent.php: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | <?=Html::getTitle('Default layout with empty parent')?> - PHP MVC Test project 10 | 11 | 12 | 13 | 14 |
15 |

Default layout with empty parent

16 | 17 | 18 | 19 | 20 | 21 |

Model

22 | 23 | 24 |

ViewData

25 | 26 | 27 |

ModelState

28 | 29 |
30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Aleksey 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /tests/RouteCollectionTest.php: -------------------------------------------------------------------------------- 1 | expectExceptionMessageRegExp('/must not be empty/'); 18 | 19 | $routes = new RouteCollection('test'); 20 | 21 | $route = new Route(); 22 | 23 | $routes->add($route); 24 | } 25 | 26 | public function testAddEmptyTemplateException(): void 27 | { 28 | $this->expectExceptionMessageRegExp('/template/'); 29 | 30 | $routes = new RouteCollection('test'); 31 | 32 | $route = new Route(); 33 | $route->name = 'default'; 34 | 35 | $routes->add($route); 36 | } 37 | 38 | public function testAddNonUniqueNameException(): void 39 | { 40 | $this->expectExceptionMessageRegExp('/unique name/'); 41 | 42 | $routes = new RouteCollection('test'); 43 | 44 | $route = new Route(); 45 | $route->name = 'default'; 46 | $route->template = '{controller}'; 47 | 48 | $routes->add($route); 49 | 50 | $route = new Route(); 51 | $route->name = 'default'; 52 | $route->template = '{controller}'; 53 | 54 | $routes->add($route); 55 | } 56 | 57 | } -------------------------------------------------------------------------------- /tests/mvc/controllers/AccountController.php: -------------------------------------------------------------------------------- 1 | isPost()) { 33 | $modelState = $this->getModelState(); 34 | 35 | if ($modelState->isValid()) { 36 | $this->setData('success', true); 37 | return $this->view(); 38 | } 39 | } 40 | 41 | if (!isset($model)) { 42 | $model = new \PhpMvcTest\Models\Login(); 43 | } 44 | 45 | return $this->view($model); 46 | } 47 | 48 | } -------------------------------------------------------------------------------- /src/Info.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * Contains information about PhpMvc. 30 | */ 31 | final class Info { 32 | 33 | const VERSION = '1.2.0'; 34 | 35 | } -------------------------------------------------------------------------------- /src/UrlParameter.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * Contains the read-only value for the optional parameter. 30 | */ 31 | final class UrlParameter { 32 | 33 | /** 34 | * The value indicates that the URL parameter is optional. 35 | * 36 | * @var string 37 | */ 38 | const OPTIONAL = '%OPTIONAL%'; 39 | 40 | } -------------------------------------------------------------------------------- /src/HttpAntiForgeryException.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * An exception occurs when a fake HTTP security token is detected. 30 | */ 31 | final class HttpAntiForgeryException extends \Exception { 32 | 33 | /** 34 | * Initializes a new instance of the HttpAntiForgeryException. 35 | * 36 | */ 37 | public function __construct() { 38 | parent::__construct('Failed to decrypt the anti-forgery token.'); 39 | } 40 | 41 | } -------------------------------------------------------------------------------- /src/ActionNameValidationException.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * Occurs if the action name contains illegal characters. 30 | */ 31 | final class ActionNameValidationException extends \Exception { 32 | 33 | /** 34 | * Initializes a new instance of the ActionNameValidationException. 35 | * 36 | */ 37 | public function __construct() { 38 | parent::__construct('Action names can not begin with a "_".'); 39 | } 40 | 41 | } -------------------------------------------------------------------------------- /src/EventArgs.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * Represents the base class for classes that contain event data, and provides a value to use for events that do not include event data. 30 | */ 31 | class EventArgs { 32 | 33 | /** 34 | * Provides a value to use with events that do not have event data. 35 | * 36 | * @return EventArgs 37 | */ 38 | public static function getEmpty() { 39 | return new EventArgs(); 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /src/HttpRequest.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * Represents current request. 30 | */ 31 | final class HttpRequest extends HttpRequestBase { 32 | 33 | /** 34 | * Initializes a new instance of the HttpRequest for the current request. 35 | */ 36 | public function __construct() { 37 | parent::__construct( 38 | $_SERVER, 39 | $_COOKIE, 40 | $_GET, 41 | $_POST, 42 | $_FILES 43 | ); 44 | } 45 | 46 | } -------------------------------------------------------------------------------- /src/CrossSiteScriptingValidation.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * Detection of unsafe strings from the client. 30 | */ 31 | final class CrossSiteScriptingValidation { 32 | 33 | /** 34 | * Checks whether the specified line is safe or not. 35 | * 36 | * @param string $value The value to check. 37 | * 38 | * @return bool 39 | */ 40 | public static function IsDangerousString($value) { 41 | return preg_match('/(\x3c([A-Za-z\x21\x2f\x3f]+))|(\x26\x23)/', $value) === 1; 42 | } 43 | 44 | } -------------------------------------------------------------------------------- /src/ActionResult.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * Defines a contract that represents the result of an action method. 30 | */ 31 | interface ActionResult { 32 | 33 | /** 34 | * Executes the action and outputs the result. 35 | * 36 | * @param ActionContext $actionContext The context in which the result is executed. 37 | * The context information includes information about the action that was executed and request information. 38 | * 39 | * @return void 40 | */ 41 | function execute($actionContext); 42 | 43 | } -------------------------------------------------------------------------------- /tests/mvc/controllers/FilterController.php: -------------------------------------------------------------------------------- 1 | content('index'); 31 | } 32 | 33 | public function executingWorld() { 34 | return $this->content('this result will be redefined!'); 35 | } 36 | 37 | public function executedWorld() { 38 | return $this->content('this result will be redefined!'); 39 | } 40 | 41 | public function executeWorld() { 42 | return $this->content('this result will be redefined!'); 43 | } 44 | 45 | public function executeWorld2() { 46 | return $this->content('this result will be redefined!'); 47 | } 48 | 49 | public function error() { 50 | throw new \Exception('ой!'); 51 | } 52 | 53 | public function errorNoResult() { 54 | throw new \Exception('error'); 55 | } 56 | 57 | public function errorRewrited() { 58 | throw new \Exception('just make an exception in this world!'); 59 | } 60 | 61 | } -------------------------------------------------------------------------------- /src/FileCacheProviderConfig.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * Represents a standard cache provider for storing the cache in the file system. 30 | */ 31 | final class FileCacheProviderConfig { 32 | 33 | /** 34 | * The path to the cache files directory. 35 | * 36 | * @var string 37 | */ 38 | public $cachePath; 39 | 40 | /** 41 | * The timeout of access to cache data, in milliseconds. 42 | * 43 | * @var int 44 | */ 45 | public $accessTime; 46 | 47 | /** 48 | * Hash algorithm. 49 | * 50 | * @var string|callback 51 | */ 52 | public $hash; 53 | 54 | } -------------------------------------------------------------------------------- /src/RouteParsingException.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * Occurs when errors are detected during route parsing. 30 | */ 31 | class RouteParsingException extends \Exception { 32 | 33 | /** 34 | * Initializes a new instance of the RouteSegmentsRequiredException. 35 | * 36 | * @param Route $route The route. 37 | * @param string|null $message The error message. 38 | */ 39 | public function __construct($route, $message = null) { 40 | if (!empty($message)) { 41 | parent::__construct($message); 42 | } 43 | else { 44 | parent::__construct('One or more errors occurred while parsing the route "' . $route->name . '"'); 45 | } 46 | } 47 | 48 | } -------------------------------------------------------------------------------- /src/HttpContext.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * Represents current HTTP context. 30 | */ 31 | final class HttpContext extends HttpContextBase { 32 | 33 | /** 34 | * Gets or sets current HttpContext. 35 | * 36 | * @var HttpContextBase 37 | */ 38 | private static $current; 39 | 40 | /** 41 | * Initializes a new instance of the HttpContext for the current request. 42 | */ 43 | public function __construct($info) { 44 | parent::__construct($info); 45 | } 46 | 47 | /** 48 | * Returs current HttpContext. 49 | * 50 | * @return HttpContextBase 51 | */ 52 | public static function getCurrent() { 53 | return self::$current; 54 | } 55 | 56 | } -------------------------------------------------------------------------------- /src/EmptyResult.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * Represents a result that does nothing. 30 | */ 31 | class EmptyResult implements ActionResult { 32 | 33 | /** 34 | * Initializes a new instance of EmptyResult. 35 | */ 36 | public function __construct() { 37 | } 38 | 39 | /** 40 | * Executes the action and outputs the result. 41 | * 42 | * @param ActionContext $actionContext The context in which the result is executed. 43 | * The context information includes information about the action that was executed and request information. 44 | * 45 | * @return void 46 | */ 47 | public function execute($actionContext) { 48 | $actionContext->getHttpContext()->getResponse()->end(); 49 | } 50 | 51 | } -------------------------------------------------------------------------------- /src/Loader.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | spl_autoload_register(function ($name) { 27 | $segments = explode('\\', $name); 28 | $fileName = array_slice($segments, -1)[0]; 29 | 30 | array_pop($segments); 31 | 32 | if (!empty(PHPMVC_APP_NAMESPACE) && count($segments) > 0 && $segments[0] == PHPMVC_APP_NAMESPACE) { 33 | array_shift($segments); 34 | } 35 | 36 | $path = PHPMVC_ROOT_PATH . implode(PHPMVC_DS, $segments) . PHPMVC_DS . $fileName . '.php'; 37 | 38 | if (!is_file($path)) { 39 | $segments = array_map('strtolower', $segments); 40 | $path = PHPMVC_ROOT_PATH . implode(PHPMVC_DS, $segments) . PHPMVC_DS . $fileName . '.php'; 41 | } 42 | 43 | if (!is_file($path)) { 44 | return false; 45 | } 46 | 47 | require_once $path; 48 | }); -------------------------------------------------------------------------------- /src/HttpContextInfo.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * Represents the information needed to create an HTTP request context. 30 | */ 31 | class HttpContextInfo { 32 | 33 | /** 34 | * Gets or sets route provider. 35 | * 36 | * @var RouteProvider 37 | */ 38 | public $routeProvider; 39 | 40 | /** 41 | * Gets or sets cache provider. 42 | * 43 | * @var CacheProvider 44 | */ 45 | public $cacheProvider; 46 | 47 | /** 48 | * Gets or sets request. 49 | * 50 | * @var HttpRequestBase 51 | */ 52 | public $request; 53 | 54 | /** 55 | * Gets or sets response. 56 | * 57 | * @var HttpResponseBase 58 | */ 59 | public $response; 60 | 61 | /** 62 | * Gets or sets session variables. 63 | * 64 | * @var HttpSessionProvider 65 | */ 66 | public $session; 67 | 68 | } -------------------------------------------------------------------------------- /src/SelectListGroup.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * Represents the optgroup HTML element and its attributes. 30 | */ 31 | class SelectListGroup { 32 | 33 | /** 34 | * Gets or sets a value that indicates whether this SelectListGroup is disabled. 35 | * 36 | * @var bool 37 | */ 38 | public $disabled; 39 | 40 | /** 41 | * Represents the value of the optgroup's label. 42 | * 43 | * @var string 44 | */ 45 | public $name; 46 | 47 | /** 48 | * Initializes a new instance of the SelectListGroup. 49 | * 50 | * @param string $name The value of the optgroup's label. 51 | * @param bool $disabled The value that indicates whether this SelectListGroup is disabled. 52 | */ 53 | public function __construct($name = null, $disabled = false) { 54 | $this->name = $name; 55 | $this->disabled = $disabled; 56 | } 57 | 58 | } -------------------------------------------------------------------------------- /src/RouteOptions.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * Represents route settings. 30 | */ 31 | class RouteOptions { 32 | 33 | /** 34 | * Gets or sets a value indicating whether all generated URLs are lower-case. 35 | * Default: TRUE. 36 | * 37 | * @var bool 38 | */ 39 | public $lowercaseUrls = true; 40 | 41 | /** 42 | * Gets or sets a value indicating whether a trailing slash should be appended to the generated URLs. 43 | * Default: FALSE. 44 | * 45 | * @var bool 46 | */ 47 | public $appendTrailingSlash = false; 48 | 49 | /** 50 | * Indicates that the last segment should be deleted if the segment value is the default value. 51 | * Default: TRUE. 52 | * 53 | * @var bool 54 | */ 55 | public $removeLastSegmentIfValueIsDefault = true; 56 | 57 | /** 58 | * Other settings. 59 | * 60 | * @var array 61 | */ 62 | public $extendedFields = array(); 63 | 64 | } -------------------------------------------------------------------------------- /src/ModelStateEntry.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * Represents an entry in a ModelState. 30 | */ 31 | class ModelStateEntry { 32 | 33 | /** 34 | * Gets or sets the key for this entry. 35 | * 36 | * @var string 37 | */ 38 | public $key; 39 | 40 | /** 41 | * Gets or sets the value for this entry. 42 | * 43 | * @var mixed 44 | */ 45 | public $value; 46 | 47 | /** 48 | * Get or sets the validation state for this entry. 49 | * 50 | * @var bool|null 51 | */ 52 | public $validationState; 53 | 54 | /** 55 | * Initializes a new instance of ModelStateEntry with the specified key and value. 56 | * 57 | * @param string $key The key of element. 58 | * @param string $value The value of element. 59 | */ 60 | public function __construct($key, $value) { 61 | $this->key = $key; 62 | $this->value = $value; 63 | $this->validationState = null; 64 | } 65 | 66 | } -------------------------------------------------------------------------------- /tests/mvc/views/account/login.php: -------------------------------------------------------------------------------- 1 | 11 | 12 | 18 | 62 | -------------------------------------------------------------------------------- /src/ViewNotFoundException.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * Occurs when the view file could not be found. 30 | */ 31 | class ViewNotFoundException extends \Exception { 32 | 33 | /** 34 | * Initializes a new instance of the ViewNotFoundException. 35 | * 36 | * @param string $path The path to the view file. 37 | */ 38 | public function __construct($path) { 39 | $message = "The view file could not be found. Search paths:\r\n"; 40 | $message .= $path . "\r\n"; 41 | $message .= PHPMVC_VIEW_PATH . PHPMVC_VIEW . PHPMVC_DS . $path . "\r\n"; 42 | $message .= PHPMVC_SHARED_PATH . $path . "\r\n"; 43 | 44 | if (strlen($path) > 4 && substr($path, -4) != '.php') { 45 | $path .= '.php'; 46 | $message .= $path . "\r\n"; 47 | $message .= PHPMVC_VIEW_PATH . PHPMVC_VIEW . PHPMVC_DS . $path . "\r\n"; 48 | $message .= PHPMVC_SHARED_PATH . $path . "\r\n"; 49 | } 50 | 51 | parent::__construct($message); 52 | } 53 | 54 | } -------------------------------------------------------------------------------- /src/ActionFilter.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * Represents the base class for action filters. 30 | */ 31 | abstract class ActionFilter { 32 | 33 | /** 34 | * Called before the action method executes. 35 | * 36 | * @param ActionExecutingContext $actionExecutingContext The context of the executing action. 37 | * 38 | * @return void 39 | */ 40 | public function actionExecuting($actionExecutingContext) { 41 | 42 | } 43 | 44 | /** 45 | * Called after the action method executes. 46 | * 47 | * @param ActionExecutedContext $actionExecutedContext The context of the action executed. 48 | * 49 | * @return void 50 | */ 51 | public function actionExecuted($actionExecutedContext) { 52 | 53 | } 54 | 55 | /** 56 | * Called when an exception occurs. 57 | * 58 | * @param ExceptionContext $exceptionContext The context of action exception. 59 | * 60 | * @return void 61 | */ 62 | public function exception($exceptionContext) { 63 | 64 | } 65 | 66 | } -------------------------------------------------------------------------------- /src/ExceptionResult.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * Represents a result containing an exception. 30 | */ 31 | class ExceptionResult implements ActionResult { 32 | 33 | /** 34 | * Gets or sets exception instance. 35 | * 36 | * @var \Exception 37 | */ 38 | private $exception; 39 | 40 | /** 41 | * Initializes a new instance of ExceptionResult. 42 | * 43 | * @param \Exception $exception The exception instance. 44 | */ 45 | public function __construct($exception) { 46 | $this->exception = $exception; 47 | } 48 | 49 | /** 50 | * Executes the action and outputs the result. 51 | * 52 | * @param ActionContext $actionContext The context in which the result is executed. 53 | * The context information includes information about the action that was executed and request information. 54 | * 55 | * @return void 56 | */ 57 | public function execute($actionContext) { 58 | } 59 | 60 | /** 61 | * Returns exception instance. 62 | * 63 | * @return \Exception 64 | */ 65 | public function getException() { 66 | return $this->exception; 67 | } 68 | 69 | } -------------------------------------------------------------------------------- /src/ActionExecutingContext.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * Provides the context for the actionExecuting method of the ActionFilter class. 30 | */ 31 | final class ActionExecutingContext extends ActionContext { 32 | 33 | /** 34 | * Gets or sets the result that is returned by the action method. 35 | * 36 | * @var ActionResult 37 | */ 38 | private $result; 39 | 40 | /** 41 | * Initializes a new instance of the ActionExecutingContext. 42 | * 43 | * @param ActionContext $actionContext The context of the action. 44 | */ 45 | public function __construct($actionContext) { 46 | parent::__construct($actionContext); 47 | } 48 | 49 | /** 50 | * Gets the result that is returned by the action method. 51 | * 52 | * @return void 53 | */ 54 | public function getResult() { 55 | return $this->result; 56 | } 57 | 58 | /** 59 | * Sets the result that is returned by the action method. 60 | * 61 | * @param mixed $value The result to set. 62 | * 63 | * @return void 64 | */ 65 | public function setResult($value) { 66 | $this->result = $value; 67 | } 68 | 69 | } -------------------------------------------------------------------------------- /src/HttpRequestValidationException.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * The exception that is thrown when a potentially malicious input string is received from the client as part of the request data. 30 | */ 31 | final class HttpRequestValidationException extends \Exception { 32 | 33 | /** 34 | * Initializes a new instance of the HttpRequestValidationException. 35 | * 36 | */ 37 | public function __construct($source = null, $key = null, $value = null) { 38 | $specific = ''; 39 | 40 | if (!empty($source) && !empty($key) && !empty($value)) { 41 | $specific = 'A potentially dangerous ' . $source . ' value was obtained from the client (' . $key . ' = "' . $value . '").' . chr(10) . chr(10); 42 | } 43 | 44 | parent::__construct( 45 | $specific . 46 | 'Request validation detected a potentially dangerous input value from the client and aborted the request. ' . 47 | 'This might be an attemp of using cross-site scripting to compromise the security of your site. ' . 48 | 'You can disable request validation using the code AppBuilder::useValidation(array(\'crossSiteScripting\' => false)).' 49 | ); 50 | } 51 | 52 | } -------------------------------------------------------------------------------- /src/RouteSegment.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * Represents segment of route. 30 | */ 31 | class RouteSegment { 32 | 33 | /** 34 | * Segment name. 35 | * 36 | * @var string 37 | */ 38 | public $name; 39 | 40 | /** 41 | * Regular expressions pattern. 42 | * 43 | * @var string 44 | */ 45 | public $pattern; 46 | 47 | /** 48 | * Indicates that the parameter is optional.. 49 | * 50 | * @var bool 51 | */ 52 | public $optional; 53 | 54 | /** 55 | * Default value. 56 | * 57 | * @return string 58 | */ 59 | public $default; 60 | 61 | /** 62 | * Before text. 63 | * 64 | * @var string 65 | */ 66 | public $before; 67 | 68 | /** 69 | * After text. 70 | * 71 | * @var string 72 | */ 73 | public $after; 74 | 75 | /** 76 | * Glue to the previous segment. 77 | * 78 | * @var bool 79 | */ 80 | public $glued; 81 | 82 | /** 83 | * Is pre-end. 84 | * 85 | * @var bool 86 | */ 87 | public $preEnd; 88 | 89 | /** 90 | * The end :) 91 | * 92 | * @var bool 93 | */ 94 | public $end; 95 | 96 | } -------------------------------------------------------------------------------- /src/ModelDataAnnotation.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * Represents metadata for models. 30 | */ 31 | final class ModelDataAnnotation { 32 | 33 | /** 34 | * The display name of the model element. 35 | * 36 | * @var string 37 | */ 38 | public $displayName; 39 | 40 | /** 41 | * The description of the model element. 42 | * 43 | * @var string 44 | */ 45 | public $displayText; 46 | 47 | /** 48 | * Indicates that the model element is required and must contain a non-empty value. 49 | * 50 | * @var array 51 | */ 52 | public $required; 53 | 54 | /** 55 | * Specifies the comparison of the model value with the value of another model parameter. 56 | * 57 | * @var array 58 | */ 59 | public $compareWith; 60 | 61 | /** 62 | * Specifies the text size check parameter in the model value. 63 | * 64 | * @var array 65 | */ 66 | public $stringLength; 67 | 68 | /** 69 | * Gets or sets parameters to check whether the model value falls within the specified range. 70 | * 71 | * @var array 72 | */ 73 | public $range; 74 | 75 | /** 76 | * Specifies a user-defined function to check the model value. 77 | * 78 | * @var array 79 | */ 80 | public $customValidation; 81 | 82 | } -------------------------------------------------------------------------------- /src/Filter.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * Represents static methods for adding filters. 30 | */ 31 | final class Filter { 32 | 33 | /** 34 | * List of filters. 35 | * 36 | * @var array 37 | */ 38 | private static $filters = array(); 39 | 40 | /** 41 | * Defines ActionContext. 42 | * 43 | * @var ActionContext 44 | */ 45 | private static $actionContext; 46 | 47 | /** 48 | * Adds a filter. 49 | * 50 | * @param string $actionOrFilterName The action name or filter name, if the filter should be used for the current controller. 51 | * @param string $filterName The name of the filter, if the name of the action is specified in the first parameter. 52 | * 53 | * @return void 54 | */ 55 | public static function add($actionOrFilterName, $filterName = null) { 56 | if (empty($filterName)) { 57 | $filterName = $actionOrFilterName; 58 | $actionOrFilterName = '.'; 59 | } 60 | 61 | if ($actionOrFilterName != '.' && !self::$actionContext->actionNameEquals($actionOrFilterName)) { 62 | return; 63 | } 64 | 65 | if (!isset(self::$filters[$actionOrFilterName])) { 66 | self::$filters[$actionOrFilterName] = array(); 67 | } 68 | 69 | self::$filters[$actionOrFilterName][] = $filterName; 70 | } 71 | 72 | } -------------------------------------------------------------------------------- /src/OutputCacheLocation.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * Specifies the valid values for controlling the location of the output-cached HTTP response for a resource. 30 | */ 31 | final class OutputCacheLocation { 32 | 33 | /** 34 | * The output cache can be located on the browser client (where the request originated), on a proxy server (or any other server) participating in the request, or on the server where the request was processed. 35 | * 36 | * @var int 37 | */ 38 | const ANY = 0; 39 | 40 | /** 41 | * The output cache is located on the browser client where the request originated. 42 | * 43 | * @var int 44 | */ 45 | const CLIENT = 1; 46 | 47 | /** 48 | * The output cache can be stored in any HTTP 1.1 cache-capable devices other than the origin server. 49 | * 50 | * @var int 51 | */ 52 | const DOWNSTREAM = 2; 53 | 54 | /** 55 | * The output cache is disabled for the requested page. 56 | * 57 | * @var int 58 | */ 59 | const NONE = 3; 60 | 61 | /** 62 | * The output cache is located on the Web server where the request was processed. 63 | * 64 | * @var int 65 | */ 66 | const SERVER = 4; 67 | 68 | /** 69 | * The output cache can be stored only at the origin server or at the requesting client. 70 | * 71 | * @var int 72 | */ 73 | const SERVER_AND_CLIENT = 5; 74 | 75 | } -------------------------------------------------------------------------------- /tests/HttpResponse.php: -------------------------------------------------------------------------------- 1 | noOutputHeaders = $noOutputHeaders; 10 | } 11 | 12 | public function setNoOutputHeaders($value) { 13 | $this->noOutputHeaders = $value; 14 | } 15 | 16 | /** 17 | * Clears all headers and content output from the current response. 18 | * 19 | * @return void 20 | */ 21 | public function clear() { 22 | $this->header = array(); 23 | $this->cookies = array(); 24 | $this->files = array(); 25 | $this->statusCode = null; 26 | $this->statusDescription = null; 27 | $this->output = ''; 28 | } 29 | 30 | /** 31 | * Sends all currently buffered output to the client. 32 | * 33 | * @return void 34 | */ 35 | public function flush() { 36 | $this->output(); 37 | parent::flush(); 38 | } 39 | 40 | /** 41 | * Sends all currently buffered output to the client and stops execution of the requested process. 42 | * 43 | * @return void 44 | */ 45 | public function end() { 46 | parent::preSend(); 47 | $this->output(); 48 | parent::end(); 49 | 50 | $this->clear(); 51 | } 52 | 53 | private function output() { 54 | if (!$this->outputStarted() && empty($this->files) && !$this->noOutputHeaders) { 55 | // status code and message 56 | if (!empty($this->statusCode) || !empty($this->statusDescription)) { 57 | $statusCode = $this->statusCode; 58 | 59 | if (empty($statusCode)) { 60 | $statusCode = 200; 61 | } 62 | 63 | echo 'HTTP/1.1 ' . $statusCode . ' ' . $this->statusDescription; 64 | } 65 | else { 66 | echo 'HTTP/1.1 200 OK'; 67 | } 68 | 69 | echo chr(10); 70 | 71 | // headers 72 | foreach ($this->headers as $name => $value) { 73 | echo $name . ': ' . $value . chr(10); 74 | } 75 | 76 | // cookies 77 | foreach ($this->cookies as $cookie) { 78 | echo 'Set-Cookie: ' . implode('; ', $cookie) . chr(10); 79 | } 80 | 81 | echo chr(10); 82 | } 83 | 84 | // files 85 | foreach ($this->files as $file) { 86 | $fp = fopen($file, 'rb'); 87 | echo bin2hex(fread($fp, 10)); 88 | fclose($fp); 89 | } 90 | 91 | // text 92 | if (!empty($this->output)) { 93 | echo $this->output; 94 | } 95 | } 96 | 97 | } -------------------------------------------------------------------------------- /src/index.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | require_once 'InternalHelper.php'; 27 | require_once 'UrlParameter.php'; 28 | require_once 'RouteOptions.php'; 29 | require_once 'RouteCollection.php'; 30 | require_once 'RouteSegment.php'; 31 | require_once 'Route.php'; 32 | require_once 'RouteProvider.php'; 33 | require_once 'DefaultRouteProvider.php'; 34 | require_once 'CacheProvider.php'; 35 | require_once 'IdleCacheProvider.php'; 36 | require_once 'HttpContextBase.php'; 37 | require_once 'HttpRequestBase.php'; 38 | require_once 'HttpResponseBase.php'; 39 | require_once 'HttpSessionProvider.php'; 40 | require_once 'HttpContextInfo.php'; 41 | require_once 'HttpContext.php'; 42 | require_once 'HttpRequest.php'; 43 | require_once 'HttpResponse.php'; 44 | require_once 'HttpSession.php'; 45 | require_once 'EventArgs.php'; 46 | require_once 'ErrorHandlerEventArgs.php'; 47 | require_once 'Model.php'; 48 | require_once 'Filter.php'; 49 | require_once 'OutputCacheLocation.php'; 50 | require_once 'OutputCache.php'; 51 | require_once 'ValidateAntiForgeryToken.php'; 52 | require_once 'ModelState.php'; 53 | require_once 'ModelStateEntry.php'; 54 | require_once 'AppContext.php'; 55 | require_once 'ActionContext.php'; 56 | require_once 'ActionResult.php'; 57 | require_once 'ViewResult.php'; 58 | require_once 'ViewContext.php'; 59 | require_once 'PathUtility.php'; 60 | require_once 'View.php'; 61 | require_once 'Html.php'; 62 | require_once 'ActionExecutingContext.php'; 63 | require_once 'ActionExecutedContext.php'; 64 | require_once 'AppBuilder.php'; -------------------------------------------------------------------------------- /src/ContentResult.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * Represents a user-defined content type that is the result of an action method. 30 | */ 31 | class ContentResult implements ActionResult { 32 | 33 | /** 34 | * Gets or sets the content. 35 | * 36 | * @var mixed 37 | */ 38 | private $content; 39 | 40 | /** 41 | * Gets or sets the type of the content. For example: text/plain, text/html. 42 | * 43 | * @var string 44 | */ 45 | private $contentType; 46 | 47 | /** 48 | * Initializes a new instance of ContentResult. 49 | * 50 | * @param string $content The content. 51 | * @param string $contentType The content type. Default: text/plain. 52 | */ 53 | public function __construct($content, $contentType = 'text/plain') { 54 | $this->content = $content; 55 | $this->contentType = $contentType; 56 | } 57 | 58 | /** 59 | * Executes the action and outputs the result. 60 | * 61 | * @param ActionContext $actionContext The context in which the result is executed. 62 | * The context information includes information about the action that was executed and request information. 63 | * 64 | * @return void 65 | */ 66 | public function execute($actionContext) { 67 | $response = $actionContext->getHttpContext()->getResponse(); 68 | $response->addHeader('Content-Type', (!empty($this->contentType) ? $this->contentType : 'text/plain')); 69 | $response->write($this->content); 70 | $response->end(); 71 | } 72 | 73 | } -------------------------------------------------------------------------------- /src/HttpStatusCodeResult.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * Provides a way to return an action result with a specific HTTP response status code and description. 30 | */ 31 | class HttpStatusCodeResult implements ActionResult { 32 | 33 | /** 34 | * Gets the HTTP status code. 35 | * 36 | * @var int 37 | */ 38 | private $statusCode; 39 | 40 | /** 41 | * Gets the HTTP status description. 42 | * 43 | * @var string 44 | */ 45 | private $statusDescription; 46 | 47 | /** 48 | * Initializes a new instance of HttpStatusCodeResult. 49 | * 50 | * @param int $statusCode The HTTP status code. 51 | * @param string $statusDescription The HTTP status description. 52 | */ 53 | public function __construct($statusCode, $statusDescription = null) { 54 | $this->statusCode = $statusCode; 55 | $this->statusDescription = $statusDescription; 56 | } 57 | 58 | /** 59 | * Executes the action and outputs the result. 60 | * 61 | * @param ActionContext $actionContext The context in which the result is executed. 62 | * The context information includes information about the action that was executed and request information. 63 | * 64 | * @return void 65 | */ 66 | public function execute($actionContext) { 67 | $response = $actionContext->getHttpContext()->getResponse(); 68 | $response->setStatusCode($this->statusCode); 69 | $response->setStatusDescription($this->statusDescription); 70 | $response->write($result); 71 | $response->end(); 72 | } 73 | 74 | } -------------------------------------------------------------------------------- /src/ErrorHandlerEventArgs.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * Represents the arguments to the error event handler. 30 | */ 31 | final class ErrorHandlerEventArgs extends EventArgs { 32 | 33 | /** 34 | * Exception instance. 35 | * 36 | * @var \Exception 37 | */ 38 | private $exception; 39 | 40 | /** 41 | * Indicates that the processing is done and you do not need to run other handlers, including the standard handler. 42 | * 43 | * @var bool 44 | */ 45 | private $handled = false; 46 | 47 | /** 48 | * Initializes a new instance of ErrorHandlerEventArgs. 49 | * 50 | * @param \Exception $exception The exception instance. 51 | */ 52 | public function __construct($exception) { 53 | $this->exception = $exception; 54 | } 55 | 56 | /** 57 | * Gets exception. 58 | * 59 | * @return \Exception 60 | */ 61 | public function getException() { 62 | return $this->exception; 63 | } 64 | 65 | /** 66 | * Gets exception message. 67 | * 68 | * @return string 69 | */ 70 | public function getMessage() { 71 | return $this->exception->getMessage(); 72 | } 73 | 74 | /** 75 | * Gets handled status. 76 | * 77 | * @return bool 78 | */ 79 | public function getHandled() { 80 | return $this->handled; 81 | } 82 | 83 | /** 84 | * Sets handled status. 85 | * 86 | * @param bool $value 87 | * 88 | * @return void 89 | */ 90 | public function setHandled($value) { 91 | $this->handled = $value; 92 | } 93 | 94 | } -------------------------------------------------------------------------------- /src/ValidateAntiForgeryToken.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * Represents methods for managing the AntiForgeryToken validation. 30 | */ 31 | final class ValidateAntiForgeryToken { 32 | 33 | /** 34 | * Defines ActionContext. 35 | * 36 | * @var ActionContext 37 | */ 38 | private static $actionContext; 39 | 40 | /** 41 | * Gets or sets mode. 42 | * 43 | * @var bool|null 44 | */ 45 | private static $enable = null; 46 | 47 | /** 48 | * Disables verification for the specified action. 49 | * 50 | * @param string $actionName Action name. 51 | * 52 | * @return void 53 | */ 54 | public static function disable($actionName = null) { 55 | self::set($actionName, false); 56 | } 57 | 58 | /** 59 | * Enables verification for the specified action. 60 | * 61 | * @param string $actionName Action name. 62 | * 63 | * @return void 64 | */ 65 | public static function enable($actionName = null) { 66 | self::set($actionName, true); 67 | } 68 | 69 | /** 70 | * Sets verification mode for the specified action. 71 | * 72 | * @param string $actionName Action name. 73 | * @param bool $enable Enable (true) or disable (false) verification. 74 | * 75 | * @return void 76 | */ 77 | public static function set($actionName = null, $enable) { 78 | $actionName = ($actionName === null ? '.' : $actionName); 79 | 80 | if ($actionName != '.' && !self::$actionContext->actionNameEquals($actionName)) { 81 | return; 82 | } 83 | 84 | self::$enable = $enable; 85 | } 86 | 87 | } -------------------------------------------------------------------------------- /src/UrlHelper.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * Helper class for building URI. 30 | */ 31 | final class UrlHelper { 32 | 33 | /** 34 | * Generates a URL with an absolute path for an action method, which contains the 35 | * action name, controller name, route values, protocol to use, host name, and fragment. 36 | * Generates an absolute URL if $schema and $host are non-null. 37 | * 38 | * @param ActionContext $actionContext The current context of the action. 39 | * @param string $actionName The name of the action. 40 | * @param string $controllerName The name of the controller. Default: current controller. 41 | * @param array $routeValues An array that contains the parameters for a route. 42 | * @param string $fragment The URL fragment name (the anchor name). 43 | * @param string $schema The protocol for the URL, such as "http" or "https". 44 | * @param string $host The host name for the URL. 45 | * 46 | * @return string 47 | */ 48 | public static function action($actionContext, $actionName, $controllerName = null, $routeValues = null, $fragment = null, $schema = null, $host = null) { 49 | if (empty($actionContext) || !$actionContext instanceof ActionContext) { 50 | throw new \Exception('The $actionContext is requred and type must be derived from "\PhpMvc\ActionContext".'); 51 | } 52 | 53 | if (empty($actionName)) { 54 | $modelState->addError($key, '$actionName is required. Value must not be empty.'); 55 | } 56 | 57 | return $actionContext->getHttpContext()->tryBuildUrl($actionName, $controllerName, $routeValues, $fragment, $schema, $host); 58 | } 59 | 60 | } -------------------------------------------------------------------------------- /tests/mvc/controllers/OutputCacheController.php: -------------------------------------------------------------------------------- 1 | getHttpContext()->getRequest()->userLanguages(); 30 | 31 | if (isset($userLanguages['en'])) { 32 | return true; 33 | } 34 | else { 35 | return false; 36 | } 37 | }); 38 | OutputCache::setDuration('varybyCustom', 30); 39 | } 40 | 41 | public function index($time) { 42 | return $this->content('time => ' . $time); 43 | } 44 | 45 | public function nocache($time) { 46 | return $this->content('time => ' . $time); 47 | } 48 | 49 | public function duration10($time) { 50 | return $this->content('time => ' . $time); 51 | } 52 | 53 | public function locationServer($time) { 54 | return $this->content('time => ' . $time); 55 | } 56 | 57 | public function locationClient($time) { 58 | return $this->content('time => ' . $time); 59 | } 60 | 61 | public function locationServerAndClient($time) { 62 | return $this->content('time => ' . $time); 63 | } 64 | 65 | public function locationDownstream($time) { 66 | return $this->content('time => ' . $time); 67 | } 68 | 69 | public function varyByParam($id, $time) { 70 | return $this->content($id . ' => ' . $time); 71 | } 72 | 73 | public function varyByParam2($id, $abc, $time) { 74 | return $this->content($id . ' => ' . $abc . ' => ' . $time); 75 | } 76 | 77 | public function varyByHeader($id, $time) { 78 | return $this->content($this->getRequest()->userAgent() . ' => ' . $time); 79 | } 80 | 81 | public function varyByCustom() { 82 | $languages = $this->getHttpContext()->getRequest()->userLanguages(); 83 | return $this->content($this->getRequest()->get('time')); 84 | } 85 | 86 | } -------------------------------------------------------------------------------- /src/SelectListItem.php: -------------------------------------------------------------------------------- 1 | 4 | * 5 | * Copyright (c) 2018 Aleksey 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | namespace PhpMvc; 27 | 28 | /** 29 | * Represents an item (