├── .bin └── coveralls ├── .coveralls.yml ├── .editorconfig ├── .gitattributes ├── .gitignore ├── .php_cs ├── .travis.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── appveyor.yml ├── composer.json ├── phpunit.xml.dist ├── src ├── App.php ├── AppInterface.php ├── Autoload.php ├── Config │ ├── AppFileLocator.php │ ├── ConfigLoader.php │ ├── ConfigManager.php │ ├── ConfigurationProviderInterface.php │ ├── FileLocator.php │ ├── Loader │ │ ├── ArrayLoader.php │ │ ├── DelegatingLoader.php │ │ ├── IniFileLoader.php │ │ ├── PhpFileLoader.php │ │ └── YamlFileLoader.php │ └── README.md ├── Console │ ├── Application.php │ ├── Command │ │ ├── AbstractCommand.php │ │ ├── AssetsInstallCommand.php │ │ ├── CacheClearCommand.php │ │ ├── ConfigDebugCommand.php │ │ ├── ModuleCreateCommand.php │ │ ├── ModuleDebugCommand.php │ │ ├── RouterDebugCommand.php │ │ ├── RouterMatchCommand.php │ │ └── ServiceManagerDebugCommand.php │ ├── README.md │ └── Shell.php ├── Debug │ ├── ExceptionHandler.php │ └── README.md ├── Exception │ ├── NotImplementedException.php │ └── README.md ├── Http │ ├── README.md │ ├── Request.php │ ├── Response.php │ └── Stream.php ├── MicroApp.php ├── Module │ ├── AbstractModule.php │ ├── Controller.php │ ├── Controller │ │ ├── ControllerNameParser.php │ │ └── ControllerResolver.php │ ├── Listener │ │ ├── DefaultListenerAggregate.php │ │ └── ListenerOptions.php │ ├── Module.php │ ├── ModuleInterface.php │ ├── ModuleManager.php │ ├── README.md │ ├── RoutesProviderInterface.php │ ├── Routing │ │ └── SymfonyTrait.php │ ├── Service.php │ └── ServiceLocator.php ├── Router │ ├── ChainRouter.php │ ├── LaravelRouter.php │ ├── Loader │ │ ├── LaravelRoutesLoader.php │ │ └── YamlFileLoader.php │ ├── README.md │ ├── RoutePluginManager.php │ ├── Router.php │ ├── RouterListener.php │ ├── RoutingHelper.php │ └── Wrapper │ │ ├── AuraRouterWrapper.php │ │ └── SymfonyRouterWrapper.php ├── ServiceManager │ ├── Config │ │ ├── AbstractConfig.php │ │ ├── MonologConfig.php │ │ ├── ServiceManagerConfig.php │ │ ├── SessionConfig.php │ │ └── TemplatingConfig.php │ ├── Factory │ │ ├── AbstractFactory.php │ │ ├── AbstractPluginManagerFactory.php │ │ ├── ConfigFactory.php │ │ ├── ControllerNameParserFactory.php │ │ ├── ControllerResolverFactory.php │ │ ├── DataSourceFactory.php │ │ ├── EventManagerFactory.php │ │ ├── FileLocatorFactory.php │ │ ├── MicroRouterFactory.php │ │ ├── MicroRouterListenerFactory.php │ │ ├── ModuleDefaultListenerFactory.php │ │ ├── ModuleManagerFactory.php │ │ ├── RequestFactory.php │ │ ├── RequestStackFactory.php │ │ ├── ResponseFactory.php │ │ ├── RoutePluginManagerFactory.php │ │ ├── RouterFactory.php │ │ ├── RouterListenerFactory.php │ │ ├── RouterRequestContextFactory.php │ │ ├── RoutingHelperFactory.php │ │ └── ServiceListenerFactory.php │ ├── ParameterBag.php │ ├── README.md │ ├── ServiceManager.php │ └── ServiceManagerBuilder.php └── View │ ├── DelegatingEngine.php │ ├── EngineInterface.php │ ├── GlobalVariables.php │ ├── Helper │ ├── RouterHelper.php │ └── SessionHelper.php │ ├── Mustache │ ├── Loader │ │ └── FileSystemLoader.php │ └── MustacheEngine.php │ ├── README.md │ ├── Smarty │ ├── Extension │ │ ├── AssetsExtension.php │ │ └── RouterExtension.php │ └── SmartyEngine.php │ ├── TemplateLocator.php │ ├── TemplateNameParser.php │ ├── TemplateReference.php │ └── Twig │ ├── Extension │ ├── AssetsExtension.php │ └── RouterExtension.php │ ├── Loader │ └── FileSystemLoader.php │ └── TwigEngine.php └── tests ├── AppTest.php ├── Fixtures ├── AppForDispatchTest.php ├── AppForTest.php └── ControllerForAppTest.php ├── Router ├── ChainRouterTest.php ├── Fixtures │ ├── RoutePluginManagerForTest.php │ ├── empty.yml │ ├── nonesense_resource_plus_path.yml │ ├── nonesense_type_without_resource.yml │ ├── nonvalid.yml │ ├── nonvalid2.yml │ ├── nonvalidkeys.yml │ ├── special_route_name.yml │ ├── validpattern.yml │ └── validresource.yml ├── Loader │ └── YamlFileLoaderTest.php ├── RoutePluginManagerTest.php ├── RouterListenerTest.php ├── RouterTest.php └── RoutingHelperTest.php └── ServiceManager ├── Fixtures ├── AbstractFactoryWithMutableCreationOptions.php ├── Bar.php ├── BarAbstractFactory.php ├── CallableWithMutableCreationOptions.php ├── CircularDependencyAbstractFactory.php ├── Foo.php ├── FooAbstractFactory.php ├── FooCounterAbstractFactory.php ├── FooException.php ├── FooFactory.php ├── FooFake.php ├── FooFakeAbstractFactory.php ├── FooInitializer.php ├── GlobIteratorService.php ├── MockSelfReturningDelegatorFactory.php ├── TrollAbstractFactory.php └── WaitingAbstractFactory.php ├── ServiceManagerBuilderTest.php └── ServiceManagerTest.php /.bin/coveralls: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | COVERALLS_RUN_LOCALLY=1 vendor/bin/coveralls -v -------------------------------------------------------------------------------- /.coveralls.yml: -------------------------------------------------------------------------------- 1 | coverage_clover: build/clover.xml 2 | json_path: build/coveralls-upload.json 3 | service_name: travis-ci -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | ; top-most EditorConfig file 2 | root = true 3 | 4 | ; Unix-style newlines 5 | [*] 6 | end_of_line = LF 7 | 8 | [*.php] 9 | indent_style = space 10 | indent_size = 4 11 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # gitattributes - defining attributes per path 2 | # http://git-scm.com/docs/gitattributes 3 | 4 | * text=auto -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # gitignore - Specifies intentionally untracked files to ignore 2 | # http://git-scm.com/docs/gitignore 3 | 4 | # Project-specific ignores 5 | # ------------------------ 6 | 7 | ### Composer 8 | 9 | vendor 10 | composer.phar 11 | composer.lock 12 | 13 | # Common unintentionally generated files 14 | # -------------------------------------- 15 | 16 | # Note: In a saner world, the following rules would be in every contributors 17 | # global configuration. For sanity however, we'll retain the whole shebang. 18 | 19 | ### Numerous always-ignore extensions 20 | 21 | *.diff 22 | *.err 23 | *.orig 24 | *.log 25 | *.rej 26 | *.swo 27 | *.swp 28 | *.vi 29 | *~ 30 | *.sass-cache 31 | *.php_cs.cache 32 | 33 | ### OS or Editor folders 34 | 35 | .DS_Store 36 | ._* 37 | Thumbs.db 38 | .cache 39 | .project 40 | .settings 41 | .tmproj 42 | nbproject 43 | *.kate-swp 44 | *.sublime-project 45 | *.sublime-workspace 46 | 47 | #### Dreamweaver added files 48 | 49 | _notes 50 | dwsync.xml 51 | 52 | #### Komodo 53 | 54 | *.komodoproject 55 | .komodotools 56 | 57 | #### Espresso 58 | 59 | *.esproj 60 | *.espressostorage 61 | 62 | ### Rubinius 63 | 64 | *.rbc 65 | 66 | ### Folders to ignore 67 | 68 | .hg 69 | .svn 70 | .CVS 71 | intermediate 72 | publish 73 | .idea 74 | build 75 | 76 | ### PHP-CS-Fixer 77 | 78 | .php_cs.cache 79 | 80 | ### Coveralls 81 | 82 | .coveralls.yml 83 | -------------------------------------------------------------------------------- /.php_cs: -------------------------------------------------------------------------------- 1 | exclude([ 10 | 'vendor', 11 | ]) 12 | ->in([ 13 | 'src', 14 | 'tests', 15 | ]); 16 | 17 | // CS issues to fix 18 | $config = Config::create() 19 | ->level(FixerInterface::PSR2_LEVEL) 20 | ->fixers( 21 | [ 22 | 'array_element_no_space_before_comma', 23 | 'array_element_white_space_after_comma', 24 | 'blankline_after_open_tag', 25 | 'concat_with_spaces', 26 | 'double_arrow_multiline_whitespaces', 27 | 'duplicate_semicolon', 28 | 'empty_return', 29 | 'extra_empty_lines', 30 | 'include', 31 | 'join_function', 32 | 'list_commas', 33 | 'method_argument_default_value', 34 | 'multiline_array_trailing_comma', 35 | 'multiline_spaces_before_semicolon', 36 | 'namespace_no_leading_whitespace', 37 | 'new_with_braces', 38 | 'no_blank_lines_after_class_opening', 39 | 'object_operator', 40 | 'operators_spaces', 41 | 'ordered_use', 42 | 'phpdoc_indent', 43 | 'phpdoc_no_empty_return', 44 | 'phpdoc_no_package', 45 | 'phpdoc_order', 46 | 'phpdoc_params', 47 | 'phpdoc_scalar', 48 | 'phpdoc_separation', 49 | 'phpdoc_short_description', 50 | 'phpdoc_to_comment', 51 | 'phpdoc_trim', 52 | 'phpdoc_type_to_var', 53 | 'phpdoc_types', 54 | 'phpdoc_var_without_name', 55 | 'print_to_echo', 56 | 'remove_leading_slash_use', 57 | 'remove_lines_between_uses', 58 | 'return', 59 | 'self_accessor', 60 | // 'short_array_syntax', 61 | 'short_bool_cast', 62 | 'single_array_no_trailing_comma', 63 | 'single_blank_line_before_namespace', 64 | // 'single_quote', 65 | 'spaces_before_semicolon', 66 | 'spaces_cast', 67 | 'standardize_not_equal', 68 | 'ternary_spaces', 69 | 'trim_array_spaces', 70 | 'trailing_spaces', 71 | 'unneeded_control_parentheses', 72 | 'unused_use', 73 | 'whitespacy_lines', 74 | ] 75 | ) 76 | ->setUsingLinter(true) 77 | ->setUsingCache(true) 78 | ->finder($finder); 79 | 80 | return $config; 81 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | 3 | language: php 4 | 5 | cache: 6 | directories: 7 | - $HOME/.composer/cache 8 | - vendor 9 | 10 | matrix: 11 | fast_finish: true 12 | include: 13 | - php: 5.4 14 | env: 15 | - EXECUTE_CS_CHECK=true 16 | - php: 5.5 17 | env: 18 | - EXECUTE_CS_CHECK=true 19 | - php: 5.6 20 | env: 21 | - EXECUTE_TEST_COVERALLS=true 22 | - php: 7 23 | - php: hhvm 24 | allow_failures: 25 | - php: 7 26 | - php: hhvm 27 | 28 | before_install: 29 | - if [[ $EXECUTE_TEST_COVERALLS != 'true' ]]; then phpenv config-rm xdebug.ini || return 0 ; fi 30 | - composer self-update 31 | - if [[ $EXECUTE_TEST_COVERALLS == 'true' ]]; then composer require --dev --no-update satooshi/php-coveralls:dev-master ; fi 32 | 33 | install: 34 | - travis_retry composer install --no-interaction --ignore-platform-reqs 35 | - composer info -i 36 | 37 | script: 38 | - if [[ $EXECUTE_TEST_COVERALLS == 'true' ]]; then ./vendor/bin/phpunit --coverage-clover build/clover.xml ; fi 39 | - if [[ $EXECUTE_TEST_COVERALLS != 'true' ]]; then ./vendor/bin/phpunit ; fi 40 | - if [[ $EXECUTE_CS_CHECK == 'true' ]]; then ./vendor/bin/php-cs-fixer fix -v --diff --dry-run ; fi 41 | 42 | after_script: 43 | - if [[ $EXECUTE_TEST_COVERALLS == 'true' ]]; then ./vendor/bin/coveralls -v ; fi 44 | 45 | notifications: 46 | irc: "irc.freenode.org#ppi" 47 | webhooks: 48 | urls: 49 | - https://webhooks.gitter.im/e/fc85ea3e366a33e217d5 50 | on_success: change 51 | on_failure: always 52 | on_start: false 53 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | 3 | ## 2.0.1 (2015-12-14) 4 | 5 | - [#141](https://github.com/ppi/framework/issues/141) - Error on composer install: "zendframework/Component_ZendStdlib - Repository not found" -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # CONTRIBUTING 2 | 3 | [@gitter]: https://gitter.im/ppi/framework "Gitter" 4 | [@gitweb]: https://github.com/ppi/framework "ppi/framework" 5 | [@gplus]: https://plus.google.com/communities/100606932222119087997 "PPI on Google+" 6 | [@twitter]: https://twitter.com/ppi_framework "PPI Framework at Twitter" 7 | 8 | PPI is an open source, community-driven project. If you'd like to contribute, check out our issues list. You can find us 9 | on [Gitter][@gitter], IRC, [Google Plus][@gplus] or Twitter ([@ppi_framework][@twitter]). 10 | 11 | Code of Conduct 12 | --------------- 13 | 14 | Please note that this project is released with a 15 | [Contributor Code of Conduct](http://contributor-covenant.org/version/1/2/0/). 16 | By participating in this project you agree to abide by its terms. 17 | 18 | Contributing policy 19 | ------------------- 20 | 21 | If you're submitting a pull request, please do so on your own branch on [GitHub][@gitweb]. 22 | 23 | Start by forking the PPI Framework repository and cloning your fork locally: 24 | 25 | $ git clone git@github.com:YOUR_USERNAME/framework.git 26 | $ git remote add upstream git://github.com/ppi/framework.git 27 | $ git checkout -b feature/BRANCH_NAME master 28 | 29 | Apply PPI Coding Standards using the PHP-CS-Fixer tool (uses PPI custom fixers): 30 | 31 | $ ./vendor/bin/php-cs-fixer fix -v 32 | 33 | After your work is finished rebase the feature branch and push it: 34 | 35 | $ git checkout master 36 | $ git fetch upstream 37 | $ git merge upstream/master 38 | $ git checkout feature/BRANCH_NAME 39 | $ git rebase master 40 | $ git push --force origin feature/BRANCH_NAME 41 | 42 | Go to GitHub again and make a pull request on the `ppi/framework` repository. Thank you for making PPI better! 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2016 Paul Dragoonis 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # PPI Framework 3 | 4 | [@website]: http://www.ppi.io/ "PPI Framework" 5 | [@documentation]: http://docs.ppi.io "PPI Framework Documentation" 6 | [@download]: http://www.ppi.io/files/ppi-skeletonapp-without-vendors.tar.gz 7 | [@gitweb]: https://github.com/ppi/framework "ppi/framework" 8 | [@php]: http://php.net/ "PHP: Hypertext Preprocessor" 9 | [@twitter]: https://twitter.com/ppi_framework "PPI Framework at Twitter" 10 | 11 | [![Gitter](https://badges.gitter.im/ppi/framework.svg)](https://gitter.im/ppi/framework?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) 12 | [![Latest Stable Version](https://poser.pugx.org/ppi/framework/v/stable.png)](https://packagist.org/packages/ppi/framework) 13 | [![Latest Unstable Version](https://poser.pugx.org/ppi/framework/v/unstable.png)](https://packagist.org/packages/ppi/framework) 14 | [![Travis-CI Build Status](https://secure.travis-ci.org/ppi/framework.png?branch=master)](http://travis-ci.org/ppi/framework) 15 | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/ppi/framework/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/ppi/framework/?branch=master) 16 | [![License](https://poser.pugx.org/ppi/framework/license.png)](https://packagist.org/packages/ppi/framework) 17 | 18 | [PPI][@website] is the PHP Interoperability Framework. It provides an equal and open platform to empower PHP developers to pick the best tools from the best PHP frameworks 19 | 20 | PPI bootstraps framework components for you from the top frameworks such as ZendFramework2, Symfony2, Laravel4 and FuelPHP. 21 | 22 | * [Official website][@website] 23 | * [Download][@download] 24 | * [Documentation][@documentation] 25 | 26 | ## Requirements 27 | 28 | * [PHP][@php] 5.4.0 or above 29 | 30 | ## Installation 31 | 32 | There is no actual "installation" of PPI, you can download it from 33 | http://www.ppi.io/downloads and drop it in your document root. 34 | 35 | ## Contributing 36 | 37 | PPI is an open source, community-driven project. If you'd like to contribute, check out our issues list. You can find us 38 | on IRC, Google Plus or Twitter ([@ppi_framework][@twitter]). 39 | 40 | If you're submitting a pull request, please do so on your own branch on [GitHub][@gitweb]. 41 | 42 | Start by forking the PPI Framework repository and cloning your fork locally: 43 | 44 | $ git clone git@github.com:YOUR_USERNAME/framework.git 45 | $ git remote add upstream git://github.com/ppi/framework.git 46 | $ git checkout -b feature/BRANCH_NAME master 47 | 48 | Apply PPI Coding Standards using the PHP-CS-Fixer tool (uses PPI custom fixers): 49 | 50 | $ ./vendor/bin/php-cs-fixer fix -v 51 | 52 | After your work is finished rebase the feature branch and push it: 53 | 54 | $ git checkout master 55 | $ git fetch upstream 56 | $ git merge upstream/master 57 | $ git checkout feature/BRANCH_NAME 58 | $ git rebase master 59 | $ git push --force origin feature/BRANCH_NAME 60 | 61 | Go to GitHub again and make a pull request on the ppi/framework repository. Thank you for making PPI better! 62 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | build: false 2 | shallow_clone: true 3 | platform: x86 4 | clone_folder: c:\projects\ppi-framework 5 | 6 | cache: 7 | - c:\php -> appveyor.yml 8 | - .phpunit -> phpunit 9 | 10 | init: 11 | - SET PATH=c:\php;%PATH% 12 | - SET COMPOSER_NO_INTERACTION=1 13 | - SET PHP=1 14 | - SET ANSICON=121x90 (121x90) 15 | 16 | install: 17 | - IF EXIST c:\php (SET PHP=0) ELSE (mkdir c:\php) 18 | - cd c:\php 19 | - IF %PHP%==1 appveyor DownloadFile http://windows.php.net/downloads/releases/archives/php-5.5.9-nts-Win32-VC11-x86.zip 20 | - IF %PHP%==1 7z x php-5.5.9-nts-Win32-VC11-x86.zip -y >nul 21 | - IF %PHP%==1 del /Q *.zip 22 | - IF %PHP%==1 cd ext 23 | - IF %PHP%==1 appveyor DownloadFile http://windows.php.net/downloads/pecl/releases/apcu/4.0.10/php_apcu-4.0.10-5.5-nts-vc11-x86.zip 24 | - IF %PHP%==1 7z x php_apcu-4.0.10-5.5-nts-vc11-x86.zip -y >nul 25 | - IF %PHP%==1 appveyor DownloadFile http://windows.php.net/downloads/pecl/releases/memcache/3.0.8/php_memcache-3.0.8-5.5-nts-vc11-x86.zip 26 | - IF %PHP%==1 7z x php_memcache-3.0.8-5.5-nts-vc11-x86.zip -y >nul 27 | - IF %PHP%==1 del /Q *.zip 28 | - IF %PHP%==1 cd .. 29 | - IF %PHP%==1 echo @php %%~dp0composer.phar %%* > composer.bat 30 | - IF %PHP%==1 copy /Y php.ini-development php.ini-min 31 | - IF %PHP%==1 echo max_execution_time=1200 >> php.ini-min 32 | - IF %PHP%==1 echo date.timezone="UTC" >> php.ini-min 33 | - IF %PHP%==1 echo extension_dir=ext >> php.ini-min 34 | - IF %PHP%==1 echo extension=php_openssl.dll >> php.ini-min 35 | - IF %PHP%==1 copy /Y php.ini-min php.ini-max 36 | - IF %PHP%==1 echo extension=php_apcu.dll >> php.ini-max 37 | - IF %PHP%==1 echo apc.enable_cli=1 >> php.ini-max 38 | - IF %PHP%==1 echo extension=php_memcache.dll >> php.ini-max 39 | - IF %PHP%==1 echo extension=php_intl.dll >> php.ini-max 40 | - IF %PHP%==1 echo extension=php_mbstring.dll >> php.ini-max 41 | - IF %PHP%==1 echo extension=php_fileinfo.dll >> php.ini-max 42 | - IF %PHP%==1 echo extension=php_pdo_sqlite.dll >> php.ini-max 43 | - IF %PHP%==1 echo extension=php_ldap.dll >> php.ini-max 44 | - appveyor DownloadFile https://getcomposer.org/composer.phar 45 | - copy /Y php.ini-max php.ini 46 | - cd c:\projects\ppi-framework 47 | - mkdir %APPDATA%\Composer 48 | - IF %APPVEYOR_REPO_BRANCH%==master (SET COMPOSER_ROOT_VERSION=dev-master) ELSE (SET COMPOSER_ROOT_VERSION=%APPVEYOR_REPO_BRANCH%.x-dev) 49 | - composer update --prefer-source --no-progress --ansi 50 | 51 | test_script: 52 | - cd c:\projects\ppi-framework 53 | - Setlocal EnableDelayedExpansion 54 | - SET X=0 55 | - copy /Y c:\php\php.ini-min c:\php\php.ini 56 | - vendor\bin\phpunit.bat || SET X=!errorlevel! 57 | - copy /Y c:\php\php.ini-max c:\php\php.ini 58 | - vendor\bin\phpunit.bat || SET X=!errorlevel! 59 | - exit %X% -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ppi/framework", 3 | "description": "PPI Framework - The PHP Interoperability Framework!", 4 | "homepage": "http://www.ppi.io", 5 | "license": "MIT", 6 | "keywords": [ 7 | "framework" 8 | ], 9 | "type": "library", 10 | "authors": [ 11 | { 12 | "name": "Paul Dragoonis", 13 | "email": "paul@ppi.io" 14 | }, 15 | { 16 | "name": "Vítor Brandão", 17 | "email": "vitor@ppi.io" 18 | }, 19 | { 20 | "name": "PPI Community", 21 | "homepage": "http://www.ppi.io/contributors" 22 | } 23 | ], 24 | "require": { 25 | "php": ">=5.4", 26 | "psr/log": "^1.0", 27 | "psr/http-message": "^1.0", 28 | "symfony/class-loader": "^2.7", 29 | "symfony/dependency-injection": "^2.7", 30 | "symfony/config": "^2.7", 31 | "symfony/console": "^2.7", 32 | "symfony/debug": "^2.7", 33 | "symfony/finder": "^2.7", 34 | "symfony/http-foundation": "^2.7", 35 | "symfony/routing": "^2.7", 36 | "symfony/templating": "^2.7", 37 | "symfony/yaml": "^2.7", 38 | "symfony/http-kernel": "^2.7", 39 | "symfony/framework-bundle": "^2.7", 40 | "zendframework/zend-eventmanager": "^2.3", 41 | "zendframework/zend-modulemanager": "^2.3", 42 | "zendframework/zend-servicemanager": "^2.3", 43 | "zendframework/zend-loader": "^2.3", 44 | "zendframework/zend-view": "^2.3", 45 | "symfony-cmf/routing": "1.3.0" 46 | }, 47 | "require-dev": { 48 | "fabpot/php-cs-fixer": "^1.5", 49 | "phpunit/phpunit": "~4.0" 50 | }, 51 | "suggest": { 52 | "roave/security-advisories": "Prevents installation of composer packages with known security vulnerabilities" 53 | }, 54 | "autoload": { 55 | "psr-4": { 56 | "PPI\\Framework\\": "src/", 57 | "PPI\\FrameworkTest\\": "tests/" 58 | } 59 | }, 60 | "extra": { 61 | "branch-alias": { 62 | "dev-master": "2.2-dev" 63 | } 64 | }, 65 | "scripts": { 66 | "coveralls": ".bin/coveralls" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | ./tests/ 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/AppInterface.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework; 12 | 13 | /** 14 | * The PPI App interface. 15 | * 16 | * This class sets various app settings, and allows you to override classes used 17 | * in the bootup process. 18 | * 19 | * @author Vítor Brandão 20 | * 21 | * @api 22 | */ 23 | interface AppInterface extends \Serializable 24 | { 25 | /** 26 | * Gets the name of the application. 27 | * 28 | * @return string The application name 29 | * 30 | * @api 31 | */ 32 | public function getName(); 33 | 34 | /** 35 | * Gets the version of the application. 36 | * 37 | * @return string The application version 38 | * 39 | * @api 40 | */ 41 | public function getVersion(); 42 | 43 | /** 44 | * Get the environment mode the application is in. 45 | * 46 | * @return string The current environment 47 | * 48 | * @api 49 | */ 50 | public function getEnvironment(); 51 | 52 | /** 53 | * Checks if debug mode is enabled. 54 | * 55 | * @return bool true if debug mode is enabled, false otherwise 56 | * 57 | * @api 58 | */ 59 | public function isDebug(); 60 | 61 | /** 62 | * Gets the application root dir. 63 | * 64 | * @return string The application root dir 65 | * 66 | * @api 67 | */ 68 | public function getRootDir(); 69 | 70 | /** 71 | * Get the locator object. 72 | * 73 | * @return \Zend\ServiceManager\ServiceLocatorInterface 74 | * 75 | * @api 76 | */ 77 | public function getServiceManager(); 78 | 79 | /** 80 | * Gets the cache directory. 81 | * 82 | * @return string The cache directory 83 | * 84 | * @api 85 | */ 86 | public function getCacheDir(); 87 | 88 | /** 89 | * Gets the log directory. 90 | * 91 | * @return string The log directory 92 | * 93 | * @api 94 | */ 95 | public function getLogDir(); 96 | 97 | /** 98 | * Gets the charset of the application. 99 | * 100 | * @return string The charset 101 | * 102 | * @api 103 | */ 104 | public function getCharset(); 105 | } 106 | -------------------------------------------------------------------------------- /src/Autoload.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework; 12 | 13 | /** 14 | * The PPI Autoloader. 15 | * 16 | * It is able to load classes that use either: 17 | * 18 | * * The technical interoperability standards for PHP 5.3 namespaces and 19 | * class names (https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md); 20 | * 21 | * Example usage: 22 | * 23 | * PPI\Framework\Autoload::add('Symfony', PPI_VENDOR_PATH . '/path/to/src/Symfony') 24 | * PPI\Framework\Autoload::register(); 25 | */ 26 | class Autoload 27 | { 28 | /** 29 | * The ClassLoader object. 30 | * 31 | * @var null|object 32 | * 33 | * @static 34 | */ 35 | protected static $_loader = null; 36 | 37 | /** 38 | * @todo Add inline documentation. 39 | * 40 | * @var array 41 | * 42 | * @static 43 | */ 44 | public static $_options = array(); 45 | 46 | /** 47 | * @todo Add inline documentation. 48 | * 49 | * @var array 50 | * 51 | * @static 52 | */ 53 | protected static $_registeredNamespaces = array(); 54 | 55 | /** 56 | * Add some items to the class config. 57 | * 58 | * @param array $config 59 | * 60 | * 61 | * @static 62 | */ 63 | public static function config(array $config) 64 | { 65 | self::$_options = array_merge($config, self::$_options); 66 | } 67 | 68 | /** 69 | * Add a namespace to the autoloader path. 70 | * 71 | * @param string $key 72 | * @param string $path 73 | * 74 | * 75 | * @static 76 | */ 77 | public static function add($key, $path) 78 | { 79 | self::$_registeredNamespaces[$key] = true; 80 | self::$_options['loader']->addPsr4($key, $path); 81 | } 82 | 83 | /** 84 | * Register the autoloader namespaces or prefixes thus far. 85 | * 86 | * 87 | * @static 88 | */ 89 | public static function register() 90 | { 91 | self::$_options['loader']->register(); 92 | } 93 | 94 | /** 95 | * Check if a namespace has been registered. This is a workaround as the default self::$_options['loader'] 96 | * class does not have an exists() method. 97 | * 98 | * @param string $key 99 | * 100 | * @return bool 101 | * 102 | * @static 103 | */ 104 | public static function exists($key) 105 | { 106 | return isset(self::$_registeredNamespaces[$key]); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/Config/AppFileLocator.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Config; 12 | 13 | use PPI\Framework\Module\ModuleManager; 14 | 15 | /** 16 | * AppFileLocator uses ModuleManager to locate resources in modules. 17 | * 18 | * @author Paul Dragoonis 19 | * @author Vítor Brandão 20 | */ 21 | class AppFileLocator extends FileLocator 22 | { 23 | protected $moduleManager; 24 | protected $path; 25 | 26 | /** 27 | * Constructor. 28 | * 29 | * @param ModuleManager $moduleManager A ModuleManager instance 30 | * @param null|string $path The path the global resource directory 31 | * @param array $paths An array of paths where to look for resources 32 | */ 33 | public function __construct(ModuleManager $moduleManager, $path = null, array $paths = array()) 34 | { 35 | $this->moduleManager = $moduleManager; 36 | if (null !== $path) { 37 | $this->path = $path; 38 | $paths[] = $path; 39 | } 40 | 41 | parent::__construct($paths); 42 | } 43 | 44 | /** 45 | * {@inheritdoc} 46 | */ 47 | public function locate($file, $currentPath = null, $first = true) 48 | { 49 | if ('@' === $file[0]) { 50 | return $this->moduleManager->locateResource($file, $this->path, $first); 51 | } 52 | 53 | return parent::locate($file, $currentPath, $first); 54 | } 55 | 56 | /** 57 | * Returns the path to the app directory. 58 | * 59 | * @return string The path to the app directory. 60 | */ 61 | public function getAppPath() 62 | { 63 | return $this->path; 64 | } 65 | 66 | /** 67 | * Returns an array of paths to modules. 68 | * 69 | * @return array An array of paths to each loaded module 70 | */ 71 | public function getModulesPath() 72 | { 73 | $paths = array(); 74 | foreach ($this->moduleManager->getLoadedModules(true) as $module) { 75 | $paths[$module->getName()] = $module->getPath(); 76 | } 77 | 78 | return $paths; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/Config/ConfigLoader.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Config; 12 | 13 | use PPI\Framework\Config\Loader\ArrayLoader; 14 | use PPI\Framework\Config\Loader\DelegatingLoader; 15 | use PPI\Framework\Config\Loader\IniFileLoader; 16 | use PPI\Framework\Config\Loader\PhpFileLoader; 17 | use PPI\Framework\Config\Loader\YamlFileLoader; 18 | use Symfony\Component\Config\Loader\LoaderInterface; 19 | use Symfony\Component\Config\Loader\LoaderResolver; 20 | 21 | /** 22 | * FileLocator uses an array of pre-defined paths to find files. 23 | * 24 | * @author Vítor Brandão 25 | */ 26 | class ConfigLoader 27 | { 28 | /** 29 | * @var array 30 | */ 31 | protected $paths; 32 | 33 | /** 34 | * @var DelegatingLoader 35 | */ 36 | protected $loader; 37 | 38 | /** 39 | * Constructor. 40 | * 41 | * @param string|array $paths A path or an array of paths where to look for resources 42 | */ 43 | public function __construct($paths = array()) 44 | { 45 | $this->paths = (array) $paths; 46 | } 47 | 48 | /** 49 | * Loads a resource. 50 | * 51 | * @param mixed $resource The resource 52 | * @param string $type The resource type 53 | * 54 | * @return array 55 | */ 56 | public function load($resource, $type = null) 57 | { 58 | return $this->getLoader()->load($resource, $type); 59 | } 60 | 61 | /** 62 | * Returns a loader to handle config loading. 63 | * 64 | * @return DelegatingLoader The loader 65 | */ 66 | public function getLoader() 67 | { 68 | if (null === $this->loader) { 69 | $locator = new FileLocator($this->paths); 70 | $resolver = new LoaderResolver(array( 71 | new YamlFileLoader($locator), 72 | new PhpFileLoader($locator), 73 | new IniFileLoader($locator), 74 | new ArrayLoader(), 75 | )); 76 | 77 | $this->loader = new DelegatingLoader($resolver); 78 | } 79 | 80 | return $this->loader; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/Config/ConfigManager.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Config; 12 | 13 | use Symfony\Component\Filesystem\Filesystem; 14 | use Zend\Stdlib\ArrayUtils; 15 | 16 | /** 17 | * ConfigManager extends ConfigLoader capabilities with lazy-loading and a caching mechanism,. 18 | * 19 | * @author Vítor Brandão 20 | */ 21 | class ConfigManager extends ConfigLoader 22 | { 23 | /** 24 | * @var string 25 | */ 26 | protected $cachePath; 27 | 28 | /** 29 | * @var bool 30 | */ 31 | protected $cacheEnabled; 32 | 33 | /** 34 | * @var array 35 | */ 36 | protected $configs = array(); 37 | 38 | /** 39 | * @var null|array 40 | */ 41 | protected $mergedConfig; 42 | 43 | /** 44 | * @var bool 45 | */ 46 | protected $skipConfig = false; 47 | 48 | /** 49 | * Constructor. 50 | * 51 | * @param string $cachePath 52 | * @param bool $cacheEnabled 53 | * @param string|array $paths A path or an array of paths where to look for resources 54 | */ 55 | public function __construct($cachePath, $cacheEnabled, $paths = array()) 56 | { 57 | $this->cachePath = $cachePath; 58 | $this->cacheEnabled = (bool) $cacheEnabled; 59 | 60 | if ((true === $this->cacheEnabled) && file_exists($this->cachePath)) { 61 | $this->skipConfig = true; 62 | $this->mergedConfig = require $this->cachePath; 63 | } 64 | 65 | parent::__construct($paths); 66 | } 67 | 68 | /** 69 | * @param mixed $resource The resource 70 | * @param string $type The resource type 71 | * 72 | * @return $this 73 | */ 74 | public function addConfig($resource, $type) 75 | { 76 | if (!$this->skipConfig) { 77 | $this->configs[] = array( 78 | 'resource' => $resource, 79 | 'type' => $type, 80 | ); 81 | } 82 | 83 | return $this; 84 | } 85 | 86 | public function getMergedConfig() 87 | { 88 | if (null === $this->mergedConfig) { 89 | $this->mergedConfig = array(); 90 | foreach ($this->configs as $config) { 91 | $this->mergedConfig = ArrayUtils::merge($this->mergedConfig, 92 | $this->load($config['resource'], $config['type'])); 93 | } 94 | 95 | if ($this->cacheEnabled) { 96 | $mode = 0666 & ~umask(); 97 | $content = "mergedConfig, 1) . ';'; 98 | $filesystem = new Filesystem(); 99 | $filesystem->dumpFile($this->cachePath, $content, $mode); 100 | } 101 | } 102 | 103 | return $this->mergedConfig; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/Config/ConfigurationProviderInterface.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Config; 12 | 13 | /** 14 | * Implemented by services that provide user-level configuration. 15 | * 16 | * @author Vítor Brandão 17 | */ 18 | interface ConfigurationProviderInterface 19 | { 20 | /** 21 | * Configuration defaults for a given service. 22 | * 23 | * @return array 24 | */ 25 | public function getConfigurationDefaults(); 26 | } 27 | -------------------------------------------------------------------------------- /src/Config/FileLocator.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Config; 12 | 13 | use Symfony\Component\Config\FileLocator as BaseFileLocator; 14 | 15 | /** 16 | * FileLocator uses an array of pre-defined paths to find files. 17 | * 18 | * @author Vítor Brandão 19 | */ 20 | class FileLocator extends BaseFileLocator 21 | { 22 | } 23 | -------------------------------------------------------------------------------- /src/Config/Loader/ArrayLoader.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Config\Loader; 12 | 13 | use Symfony\Component\Config\Loader\Loader; 14 | 15 | /** 16 | * ArrayLoader loads app configuration from a PHP array. 17 | * 18 | * @author Vítor Brandão 19 | */ 20 | class ArrayLoader extends Loader 21 | { 22 | /** 23 | * Loads a resource. 24 | * 25 | * @param mixed $resource The resource 26 | * @param string $type The resource type 27 | */ 28 | public function load($resource, $type = null) 29 | { 30 | return $resource; 31 | } 32 | 33 | /** 34 | * Returns true if this class supports the given resource. 35 | * 36 | * @param mixed $resource A resource 37 | * @param string $type The resource type 38 | * 39 | * @return bool true if this class supports the given resource, false otherwise 40 | */ 41 | public function supports($resource, $type = null) 42 | { 43 | return is_array($resource); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Config/Loader/DelegatingLoader.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Config\Loader; 12 | 13 | use Symfony\Component\Config\Loader\DelegatingLoader as BaseDelegatingLoader; 14 | 15 | /** 16 | * DelegatingLoader delegates loading to other loaders using a loader resolver. 17 | * 18 | * This loader acts as an array of LoaderInterface objects - each having 19 | * a chance to load a given resource (handled by the resolver) 20 | * 21 | * @author Vítor Brandão 22 | */ 23 | class DelegatingLoader extends BaseDelegatingLoader 24 | { 25 | } 26 | -------------------------------------------------------------------------------- /src/Config/Loader/IniFileLoader.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Config\Loader; 12 | 13 | use Symfony\Component\Config\Loader\FileLoader; 14 | 15 | /** 16 | * IniFileLoader loads parameters from INI files. 17 | * 18 | * @author Vítor Brandão 19 | */ 20 | class IniFileLoader extends FileLoader 21 | { 22 | /** 23 | * Loads a resource. 24 | * 25 | * @param mixed $file The resource 26 | * @param string $type The resource type 27 | * 28 | * @throws InvalidArgumentException When ini file is not valid 29 | */ 30 | public function load($file, $type = null) 31 | { 32 | $path = $this->locator->locate($file); 33 | $config = array(); 34 | 35 | $result = parse_ini_file($path, true); 36 | if (false === $result || array() === $result) { 37 | throw new InvalidArgumentException(sprintf('The "%s" file is not valid.', $file)); 38 | } 39 | 40 | if (isset($result['parameters']) && is_array($result['parameters'])) { 41 | $config['parameters'] = array(); 42 | foreach ($result['parameters'] as $key => $value) { 43 | $config['parameters'][$key] = $value; 44 | } 45 | } 46 | } 47 | 48 | /** 49 | * Returns true if this class supports the given resource. 50 | * 51 | * @param mixed $resource A resource 52 | * @param string $type The resource type 53 | * 54 | * @return bool true if this class supports the given resource, false otherwise 55 | */ 56 | public function supports($resource, $type = null) 57 | { 58 | return is_string($resource) && 'ini' === pathinfo($resource, PATHINFO_EXTENSION); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/Config/Loader/PhpFileLoader.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Config\Loader; 12 | 13 | use Symfony\Component\Config\Loader\FileLoader; 14 | 15 | /** 16 | * PhpFileLoader loads app configuration from a PHP file. 17 | * 18 | * @author Vítor Brandão 19 | */ 20 | class PhpFileLoader extends FileLoader 21 | { 22 | /** 23 | * Loads a PHP file. 24 | * 25 | * @param mixed $file The resource 26 | * @param string $type The resource type 27 | * 28 | * @throws \InvalidArgumentException 29 | * 30 | * @return array Array with configuration 31 | */ 32 | public function load($file, $type = null) 33 | { 34 | $path = $this->locator->locate($file); 35 | $this->setCurrentDir(dirname($path)); 36 | 37 | $config = require $path; 38 | 39 | // not an array 40 | if (!is_array($config)) { 41 | throw new \InvalidArgumentException(sprintf('The file "%s" must contain a PHP array.', $path)); 42 | } 43 | 44 | return $config; 45 | } 46 | 47 | /** 48 | * Returns true if this class supports the given resource. 49 | * 50 | * @param mixed $resource A resource 51 | * @param string $type The resource type 52 | * 53 | * @return bool true if this class supports the given resource, false otherwise 54 | */ 55 | public function supports($resource, $type = null) 56 | { 57 | return is_string($resource) && 'php' === pathinfo($resource, PATHINFO_EXTENSION); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/Config/README.md: -------------------------------------------------------------------------------- 1 | PPI Config 2 | ========== 3 | 4 | [@ppi]: http://ppi.io/ "PPI Framework - The PHP Meta Framework" 5 | 6 | The Config component for [PPI2][@ppi]. -------------------------------------------------------------------------------- /src/Console/Command/AbstractCommand.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Console\Command; 12 | 13 | use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; 14 | 15 | /** 16 | * Base class for all commands. 17 | * 18 | * @author Vítor Brandão 19 | */ 20 | abstract class AbstractCommand extends ContainerAwareCommand 21 | { 22 | /** 23 | * @return \Zend\ServiceManager\ServiceManagerInterface 24 | */ 25 | protected function getServiceManager() 26 | { 27 | return $this->getContainer(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Console/Command/CacheClearCommand.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Console\Command; 12 | 13 | use Symfony\Component\Console\Input\InputInterface; 14 | use Symfony\Component\Console\Output\OutputInterface; 15 | 16 | /** 17 | * Clear the cache. 18 | * 19 | * @author Vítor Brandão 20 | */ 21 | class CacheClearCommand extends AbstractCommand 22 | { 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | protected function configure() 27 | { 28 | $this 29 | ->setName('cache:clear') 30 | ->setDescription('Clears the cache') 31 | ->setHelp(<<%command.name% command clears the application cache for a given environment 33 | and debug mode: 34 | 35 | php %command.full_name% --env=dev 36 | php %command.full_name% --env=prod --no-debug 37 | EOF 38 | ); 39 | } 40 | 41 | /** 42 | * {@inheritdoc} 43 | */ 44 | protected function execute(InputInterface $input, OutputInterface $output) 45 | { 46 | $cacheDir = $this->getServiceManager()->getParameter('app.cache_dir'); 47 | $filesystem = $this->getServiceManager()->getService('filesystem'); 48 | 49 | if (!is_writable($cacheDir)) { 50 | throw new \RuntimeException(sprintf('Unable to write in the "%s" directory', $cacheDir)); 51 | } 52 | 53 | $app = $this->getServiceManager()->get('app'); 54 | $output->writeln(sprintf('Clearing the cache for the %s environment with debug %s', $app->getEnvironment(), var_export($app->isDebug(), true))); 55 | if (!$filesystem->exists($cacheDir)) { 56 | return; 57 | } 58 | 59 | $filesystem->remove(glob($cacheDir . '/*')); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/Console/Command/ConfigDebugCommand.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Console\Command; 12 | 13 | use Symfony\Component\Console\Input\InputInterface; 14 | use Symfony\Component\Console\Input\InputOption; 15 | use Symfony\Component\Console\Output\OutputInterface; 16 | use Symfony\Component\Yaml\Dumper; 17 | 18 | /** 19 | * Outputs all the configuration processed by the Framework, after merging. 20 | * 21 | * @author Vítor Brandão 22 | */ 23 | class ConfigDebugCommand extends AbstractCommand 24 | { 25 | /** 26 | * {@inheritdoc} 27 | */ 28 | protected function configure() 29 | { 30 | $this 31 | ->setName('config:debug') 32 | ->setDescription('Dumps the configuration in use') 33 | ->addOption('app-only', null, InputOption::VALUE_NONE, 'Show only the configuration set in the app/ directory') 34 | ->addOption('write-php', null, InputOption::VALUE_REQUIRED, 'Save the configuration in PHP format') 35 | ->addOption('write-yaml', null, InputOption::VALUE_REQUIRED, 'Save the configuration in YAML format') 36 | ->setHelp(<<%command.name% command dumps the configuration after being merged and processed 38 | by the framework: 39 | 40 | %command.full_name% 41 | 42 | If you only want to see the configuration defined in the app/ directory (excluding modules) 43 | use the --app-only option. This is the "raw" configuration, not processed by the framework. 44 | 45 | %command.full_name% --app-only 46 | EOF 47 | ); 48 | } 49 | 50 | /** 51 | * {@inheritdoc} 52 | */ 53 | protected function execute(InputInterface $input, OutputInterface $output) 54 | { 55 | $indentation = 4; 56 | 57 | if ($input->getOption('app-only')) { 58 | $message = "This is the configuration defined in the app/ directory (not processed):\n"; 59 | $config = $this->getServiceManager()->get('ApplicationConfig'); 60 | } else { 61 | $message = "This is the configuration in use for your current setup (merged and processed):\n"; 62 | $config = $this->getServiceManager()->get('Config'); 63 | } 64 | 65 | $files = array(); 66 | $contents = array(); 67 | 68 | if (($files['php'] = $input->getOption('write-php'))) { 69 | $contents['php'] = "\n"; 70 | } 71 | 72 | if (($files['yaml'] = $input->getOption('write-yaml'))) { 73 | $dumper = new Dumper(); 74 | $dumper->setIndentation($indentation); 75 | $contents['yaml'] = $dumper->dump($config, 6, 0, false, false); 76 | } 77 | 78 | if (empty($contents)) { 79 | $dumper = new Dumper(); 80 | $dumper->setIndentation($indentation); 81 | $output->writeln($message); 82 | 83 | foreach ($config as $rootKey => $subConfig) { 84 | $output->writeln('' . $rootKey . ':'); 85 | $output->writeln($dumper->dump($subConfig, 6, $indentation, false, false)); 86 | } 87 | 88 | return; 89 | } 90 | 91 | foreach ($files as $format => $file) { 92 | $output->write('Saving configuration in ' . strtoupper($format) . ' format...'); 93 | if ($fileExists = file_exists($file)) { 94 | if (!isset($dialog)) { 95 | $dialog = $this->getHelperSet()->get('dialog'); 96 | } 97 | if (!$dialog->askConfirmation($output, 98 | " File \"" . $file . "\" already exists. Proceed anyway? ", false)) { 99 | continue; 100 | } 101 | } 102 | 103 | file_put_contents($file, $contents[$format]); 104 | 105 | if (!$fileExists) { 106 | $output->writeln(' OK.'); 107 | } 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/Console/Command/ModuleDebugCommand.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Console\Command; 12 | 13 | use Symfony\Component\Console\Input\InputInterface; 14 | use Symfony\Component\Console\Output\OutputInterface; 15 | 16 | /** 17 | * ModuleDebug Command. 18 | * 19 | * @author Vítor Brandão 20 | */ 21 | class ModuleDebugCommand extends AbstractCommand 22 | { 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | protected function configure() 27 | { 28 | $this 29 | ->setName('module:list') 30 | ->setDescription('Displays information about the currently loaded modules') 31 | ->setHelp(<<%command.name% command dumps information about the currently loaded modules. 33 | 34 | php %command.full_name% 35 | 36 | EOF 37 | ); 38 | } 39 | 40 | /** 41 | * {@inheritdoc} 42 | */ 43 | protected function execute(InputInterface $input, OutputInterface $output) 44 | { 45 | $appName = 'PPI'; 46 | $mm = $this->getServiceManager()->get('ModuleManager'); 47 | $modules = $mm->getLoadedModules(true); 48 | 49 | $output->writeln(sprintf('%s is running with %d modules loaded.', $appName, count($modules))); 50 | 51 | foreach ($modules as $module) { 52 | $output->writeln(PHP_EOL . '' . $module->getName() . ''); 53 | $output->writeln(' - namespace: ' . $module->getNamespace()); 54 | $output->writeln(' - path: ' . $module->getPath()); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Console/Command/RouterDebugCommand.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Console\Command; 12 | 13 | use Symfony\Bundle\FrameworkBundle\Command\RouterDebugCommand as BaseRouterDebugCommand; 14 | 15 | /** 16 | * A console command for retrieving information about routes. 17 | * 18 | * @author Vítor Brandão 19 | */ 20 | class RouterDebugCommand extends BaseRouterDebugCommand 21 | { 22 | } 23 | -------------------------------------------------------------------------------- /src/Console/Command/RouterMatchCommand.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Console\Command; 12 | 13 | use Symfony\Bundle\FrameworkBundle\Command\RouterMatchCommand as BaseRouterMatchCommand; 14 | 15 | /** 16 | * A console command to test route matching. 17 | * 18 | * @author Vítor Brandão 19 | */ 20 | class RouterMatchCommand extends BaseRouterMatchCommand 21 | { 22 | } 23 | -------------------------------------------------------------------------------- /src/Console/README.md: -------------------------------------------------------------------------------- 1 | PPI Console 2 | =========== 3 | 4 | [@ppi]: http://ppi.io/ "PPI Framework - The PHP Meta Framework" 5 | 6 | The Console component for [PPI2][@ppi]. -------------------------------------------------------------------------------- /src/Console/Shell.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Console; 12 | 13 | use Symfony\Component\Console\Shell as BaseShell; 14 | 15 | /** 16 | * Shell. 17 | * 18 | * @author Vítor Brandão 19 | */ 20 | class Shell extends BaseShell 21 | { 22 | /** 23 | * Returns the shell header. 24 | * 25 | * @return string The header string 26 | */ 27 | protected function getHeader() 28 | { 29 | return << 31 | _____ _____ |_| 32 | / __ | / __ | /| 33 | | |__| || |__| || | 34 | | ___/ | ___/ | | 35 | | | | | |_| 36 | |/ |/ 37 | 38 | 39 | EOF 40 | . parent::getHeader(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Debug/README.md: -------------------------------------------------------------------------------- 1 | PPI Debug 2 | ========= 3 | 4 | [@ppi]: http://ppi.io/ "PPI Framework - The PHP Meta Framework" 5 | 6 | The Debug component for [PPI2][@ppi]. -------------------------------------------------------------------------------- /src/Exception/NotImplementedException.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Exception; 12 | 13 | /** 14 | * NotImplementedException. 15 | * 16 | * @author Vítor Brandão 17 | */ 18 | class NotImplementedException extends \BadMethodCallException 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /src/Exception/README.md: -------------------------------------------------------------------------------- 1 | PPI Exception 2 | ============= 3 | 4 | [@ppi]: http://ppi.io/ "PPI Framework - The PHP Meta Framework" 5 | 6 | The Exception component for [PPI2][@ppi]. -------------------------------------------------------------------------------- /src/Http/README.md: -------------------------------------------------------------------------------- 1 | PPI HTTP 2 | ======== 3 | 4 | [@ppi]: http://ppi.io/ "PPI Framework - The PHP Meta Framework" 5 | 6 | The HTTP component for [PPI2][@ppi]. -------------------------------------------------------------------------------- /src/Http/Request.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Http; 12 | 13 | use Symfony\Component\HttpFoundation\Request as SymfonyHttpRequest; 14 | 15 | /** 16 | * HTTP Request encapsulation. 17 | * 18 | * @author Paul Dragoonis 19 | * @author Vítor Brandão 20 | */ 21 | class Request extends SymfonyHttpRequest 22 | { 23 | } 24 | -------------------------------------------------------------------------------- /src/Http/Response.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Http; 12 | 13 | use Symfony\Component\HttpFoundation\Response as SymfonyHttpResponse; 14 | 15 | /** 16 | * @author Paul Dragoonis 17 | * @author Vítor Brandão 18 | */ 19 | class Response extends SymfonyHttpResponse 20 | { 21 | } 22 | -------------------------------------------------------------------------------- /src/MicroApp.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework; 12 | 13 | use PPI\Framework\App as BaseApp; 14 | use Symfony\Component\Routing\Matcher\UrlMatcher as UrlMatcher; 15 | use Symfony\Component\Routing\Route as Route; 16 | use Symfony\Component\Routing\RouteCollection; 17 | use Symfony\Component\Routing\Router; 18 | 19 | /** 20 | * The PPI MicroApp bootstrap class. 21 | * 22 | * This class sets various app settings, and allows you to override classes used in the bootup process. 23 | * 24 | * @author Paul Dragoonis 25 | */ 26 | class MicroApp extends BaseApp 27 | { 28 | protected $router; 29 | protected $routes = array(); 30 | protected $routeCollection; 31 | 32 | public function get($uri, $callback) 33 | { 34 | $this->add($uri, 'get', $callback); 35 | } 36 | 37 | public function post($uri, $callback) 38 | { 39 | $this->add($uri, 'post', $callback); 40 | } 41 | 42 | public function add($uri, $method, $callback) 43 | { 44 | $this->routes[md5($uri . $method)] = array( 45 | 'method' => $method, 46 | 'uri' => $uri, 47 | 'callback' => $callback, 48 | ); 49 | } 50 | 51 | public function boot() 52 | { 53 | parent::boot(); 54 | 55 | return $this; 56 | } 57 | 58 | public function dispatch() 59 | { 60 | 61 | // @todo - create the RouteCollection 62 | // @todo - run the matcher against this and get a route back 63 | 64 | $this->router = $this->serviceManager->get('MicroRouter'); 65 | 66 | $routeCollection = new RouteCollection(); 67 | foreach ($this->routes as $routeKey => $r) { 68 | $route = new Route($r['uri']); 69 | $route->setMethods($r['method']); 70 | 71 | $routeCollection->add($routeKey, $route); // @todo - dont md5() this. 72 | } 73 | 74 | $request = $this->getRequest(); 75 | 76 | $requestContext = $this->getServiceManager()->get('RouterRequestContext'); 77 | $requestContext->fromRequest($request); 78 | 79 | $matcher = new UrlMatcher($routeCollection, $requestContext); 80 | // @todo - try catch this 81 | $routeAttributes = $matcher->match($request->getPathInfo()); 82 | $matchedRouteKey = $routeAttributes['_route']; 83 | 84 | $this->routes[$matchedRouteKey]['callback']($this->getServiceManager()); 85 | 86 | // @todo - handle when the callback returns a Response object and send that to the client. 87 | return $this; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/Module/Controller/ControllerNameParser.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Module\Controller; 12 | 13 | use Zend\ModuleManager\ModuleManagerInterface; 14 | 15 | /** 16 | * ControllerNameParser converts controller from the short notation a:b:c 17 | * (BlogModule:Post:index) to a fully-qualified class::method string 18 | * (Module\BlogModule\Controller\PostController::indexAction). 19 | * 20 | * @author Fabien Potencier 21 | * @author Vítor Brandão 22 | * @author Paul Dragoonis 23 | */ 24 | class ControllerNameParser 25 | { 26 | protected $moduleManager; 27 | 28 | /** 29 | * Constructor. 30 | * 31 | * @param ModuleManagerInterface $moduleManager A ModuleManagerInterface instance 32 | */ 33 | public function __construct(ModuleManagerInterface $moduleManager) 34 | { 35 | $this->moduleManager = $moduleManager; 36 | } 37 | 38 | /** 39 | * Converts a short notation a:b:c to a class::method. 40 | * 41 | * @param string $controller A short notation controller (a:b:c) 42 | * 43 | * @throws \InvalidArgumentException when the specified module is not enabled 44 | * or the controller cannot be found 45 | * 46 | * @return string A string with class::method 47 | */ 48 | public function parse($controller) 49 | { 50 | list($module, $moduleName, $controller, $action) = $this->getPartsFromControllerName($controller); 51 | 52 | if (null === $module) { 53 | // this throws an exception if there is no such module 54 | $msg = sprintf('Unable to find controller "%s:%s" - module alias "%s" does not exist.', $moduleName, $controller, $moduleAlias); 55 | } else { 56 | $class = $module->getNamespace() . '\\Controller\\' . $controller; 57 | if (class_exists($class)) { 58 | return $class . '::' . $action . 'Action'; 59 | } 60 | 61 | $msg = sprintf('Unable to find controller "%s:%s" - class "%s" does not exist.', $moduleName, $controller, $class); 62 | } 63 | 64 | throw new \InvalidArgumentException($msg); 65 | } 66 | 67 | public function build($controller) 68 | { 69 | list($module, $moduleName, $controllerName, $actionName) = $this->getPartsFromControllerName($controller); 70 | 71 | return sprintf('%s:%s:%s', $moduleName, $controllerName, $actionName); 72 | } 73 | 74 | /** 75 | * @param string $controller 76 | * 77 | * @return array 78 | */ 79 | private function getPartsFromControllerName($controller) 80 | { 81 | if (3 != count($parts = explode(':', $controller))) { 82 | throw new \InvalidArgumentException(sprintf('The "%s" controller is not a valid a:b:c controller string.', $controller)); 83 | } 84 | 85 | list($moduleName, $controller, $action) = $parts; 86 | $controller = str_replace('/', '\\', $controller); 87 | $module = $this->moduleManager->getModule($moduleName); 88 | 89 | if (!is_object($module)) { 90 | throw new \RuntimeException(sprintf( 91 | 'Unable to locate module: %s, when parsing controller: %s', 92 | $moduleName, $controller 93 | )); 94 | } 95 | 96 | $moduleName = $module->getName(); 97 | 98 | return [$module, $moduleName, $controller, $action]; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/Module/Controller/ControllerResolver.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Module\Controller; 12 | 13 | use Psr\Log\LoggerInterface; 14 | use Symfony\Component\DependencyInjection\ContainerAwareInterface; 15 | use Symfony\Component\HttpKernel\Controller\ControllerResolver as BaseControllerResolver; 16 | use Zend\ServiceManager\ServiceLocatorAwareInterface; 17 | use Zend\ServiceManager\ServiceLocatorInterface; 18 | 19 | /** 20 | * ControllerResolver. 21 | * 22 | * @see Symfony\Bundle\FrameworkBundle\Controller\ControllerResolver 23 | * 24 | * @author Fabien Potencier 25 | * @author Vítor Brandão 26 | * @author Paul Dragoonis 27 | */ 28 | class ControllerResolver extends BaseControllerResolver 29 | { 30 | protected $request; 31 | 32 | /** 33 | * Constructor. 34 | * 35 | * @param ServiceLocatorInterface $serviceManager A ServiceLocatorInterface instance 36 | * @param ControllerNameParser $parser A ControllerNameParser instance 37 | * @param LoggerInterface $logger A LoggerInterface instance 38 | */ 39 | public function __construct(ServiceLocatorInterface $serviceManager, ControllerNameParser $parser, LoggerInterface $logger = null) 40 | { 41 | $this->serviceManager = $serviceManager; 42 | $this->parser = $parser; 43 | parent::__construct($logger); 44 | } 45 | 46 | /** 47 | * Returns a callable for the given controller. 48 | * 49 | * @param string $controller A Controller string 50 | * 51 | * @throws \LogicException When the name could not be parsed 52 | * @throws \InvalidArgumentException When the controller class does not exist 53 | * 54 | * @return mixed A PHP callable 55 | */ 56 | protected function createController($controller) 57 | { 58 | if (false === strpos($controller, '::')) { 59 | $count = substr_count($controller, ':'); 60 | if (2 == $count) { 61 | // controller in the a:b:c notation then 62 | $controller = $this->parser->parse($controller); 63 | } elseif (1 == $count) { 64 | // controller in the service:method notation 65 | list($service, $method) = explode(':', $controller, 2); 66 | 67 | return array($this->serviceManager->get($service), $method); 68 | } else { 69 | if ($this->serviceManager->has($controller) && method_exists($service = $this->serviceManager->get($controller), '__invoke')) { 70 | return $service; 71 | } else { 72 | throw new \LogicException(sprintf('Unable to parse the controller name "%s".', $controller)); 73 | } 74 | } 75 | } 76 | 77 | return parent::createController($controller); 78 | } 79 | 80 | /** 81 | * @param string $class 82 | * 83 | * @return object 84 | */ 85 | protected function instantiateController($class) 86 | { 87 | $controller = parent::instantiateController($class); 88 | 89 | if ($controller instanceof ServiceLocatorAwareInterface) { 90 | $controller->setServiceLocator($this->serviceManager); 91 | } 92 | 93 | if($controller instanceof ContainerAwareInterface) { 94 | $controller->setContainer($this->serviceManager->get('SymfonyContainer')); 95 | } 96 | 97 | return $controller; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/Module/Listener/ListenerOptions.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Module\Listener; 12 | 13 | use Zend\ModuleManager\Listener\ListenerOptions as BaseListenerOptions; 14 | 15 | /** 16 | * ListenerOptions class. 17 | * 18 | * @todo Add inline documentation. 19 | * 20 | * @author Paul Dragoonis 21 | */ 22 | class ListenerOptions extends BaseListenerOptions 23 | { 24 | /** 25 | * @todo Add inline documentation. 26 | * 27 | * @var type 28 | */ 29 | protected $routingEnabled; 30 | 31 | /** 32 | * @todo Add inline documentation. 33 | * 34 | * @param type $enabled 35 | */ 36 | public function setRoutingEnabled($enabled) 37 | { 38 | $this->routingEnabled = $enabled; 39 | } 40 | 41 | /** 42 | * @todo Add inline documentation. 43 | * 44 | * @return bool 45 | */ 46 | public function getRoutingEnabled() 47 | { 48 | return $this->routingEnabled; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Module/Module.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Module; 12 | 13 | /** 14 | * The base PPI module class. 15 | * 16 | * @note Kept for backwards compatibility. Module classes should inherit directly from AbstractModule. 17 | * 18 | * @deprecated since version 2.1, to be removed in 2.2. Inherit from AbstractModule instead. 19 | */ 20 | abstract class Module extends AbstractModule 21 | { 22 | } 23 | -------------------------------------------------------------------------------- /src/Module/ModuleInterface.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Module; 12 | 13 | /** 14 | * ModuleInterface. 15 | * 16 | * @author Paul Dragoonis 17 | * @author Vítor Brandão 18 | * 19 | * @api 20 | */ 21 | interface ModuleInterface 22 | { 23 | /** 24 | * Returns the module name. 25 | * 26 | * @return string The Module name 27 | */ 28 | public function getName(); 29 | 30 | /** 31 | * Gets the Module namespace. 32 | * 33 | * @return string The Module namespace 34 | * 35 | * @api 36 | */ 37 | public function getNamespace(); 38 | 39 | /** 40 | * Gets the Module directory path. 41 | * 42 | * The path should always be returned as a Unix path (with /). 43 | * 44 | * @return string The Module absolute path 45 | * 46 | * @api 47 | */ 48 | public function getPath(); 49 | } 50 | -------------------------------------------------------------------------------- /src/Module/README.md: -------------------------------------------------------------------------------- 1 | PPI Module 2 | ========== 3 | 4 | [@ppi]: http://ppi.io/ "PPI Framework - The PHP Meta Framework" 5 | 6 | The Module component for [PPI2][@ppi]. -------------------------------------------------------------------------------- /src/Module/RoutesProviderInterface.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Module; 12 | 13 | /** 14 | * RoutesProviderInterface interface. 15 | * 16 | * @todo Add inline documentation. 17 | */ 18 | interface RoutesProviderInterface 19 | { 20 | /** 21 | * @todo Add inline documentation. 22 | * 23 | * @return type 24 | */ 25 | public function getRoutes(); 26 | } 27 | -------------------------------------------------------------------------------- /src/Module/Routing/SymfonyTrait.php: -------------------------------------------------------------------------------- 1 | loadSymfonyRoutes($this->getRoutingFilePath()); 16 | } 17 | 18 | protected function getRoutingFilePath() 19 | { 20 | return $this->getPath() . '/resources/routes/symfony.yml'; 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /src/Module/Service.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Module; 12 | 13 | /** 14 | * The PPI Server class. These instances can be registered into the 15 | * ServiceLocator. 16 | * 17 | * @author Paul Dragoonis 18 | */ 19 | class Service 20 | { 21 | /** 22 | * The class name for this service. 23 | * 24 | * @var null|string 25 | */ 26 | protected $className = null; 27 | 28 | /** 29 | * Get the factory method name for this service. 30 | * 31 | * @var null|string 32 | */ 33 | protected $factoryMethod = null; 34 | 35 | /** 36 | * Constructor. 37 | * 38 | * @param type $className 39 | */ 40 | public function __construct($className = null) 41 | { 42 | $this->className = $className; 43 | } 44 | 45 | /** 46 | * Get the class name for this service. 47 | * 48 | * @return null|string 49 | */ 50 | public function getClassName() 51 | { 52 | return $this->className; 53 | } 54 | 55 | /** 56 | * Check if we have a class name for this service. 57 | * 58 | * @return bool 59 | */ 60 | public function hasClassName() 61 | { 62 | return $this->className !== null; 63 | } 64 | 65 | /** 66 | * Set the factory method name. 67 | * 68 | * @param string $method 69 | */ 70 | public function setFactoryMethod($method) 71 | { 72 | $this->factoryMethod = $method; 73 | } 74 | 75 | /** 76 | * Get the factory method name. 77 | * 78 | * @return null|string 79 | */ 80 | public function getFactoryMethod() 81 | { 82 | return $this->factoryMethod; 83 | } 84 | 85 | /** 86 | * Check if we have a factory method name. 87 | * 88 | * @return bool 89 | */ 90 | public function hasFactoryMethod() 91 | { 92 | return $this->factoryMethod !== null; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/Module/ServiceLocator.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Module; 12 | 13 | /** 14 | * The PPI Service Locator. 15 | * 16 | * @author Paul Dragoonis 17 | */ 18 | class ServiceLocator 19 | { 20 | /** 21 | * @todo Add inline documentation. 22 | * 23 | * @var array 24 | */ 25 | protected $loadedService = array(); 26 | 27 | /** 28 | * @todo Add inline documentation. 29 | * 30 | * @var array 31 | */ 32 | protected $services = array(); 33 | 34 | /** 35 | * @todo Add inline documentation. 36 | * 37 | * @param array $services 38 | */ 39 | public function __construct(array $services = array()) 40 | { 41 | if (!empty($services)) { 42 | foreach ($services as $key => $service) { 43 | $this->services[strtolower($key)] = $service; 44 | } 45 | } 46 | } 47 | 48 | /** 49 | * Get a registered service by its name. 50 | * 51 | * @param string $key 52 | * 53 | * @throws \Exception|\InvalidArgumentException 54 | * 55 | * @return mixed 56 | */ 57 | public function get($key) 58 | { 59 | $key = strtolower($key); 60 | 61 | if (!isset($this->services[$key])) { 62 | throw new \InvalidArgumentException('Service not found: ' . $key); 63 | } 64 | 65 | // Have we been here before? 66 | if (isset($this->loadedService[$key])) { 67 | return $this->loadedService[$key]; 68 | } 69 | 70 | if (!$this->services[$key] instanceof Service) { 71 | $this->loadedService[$key] = $this->services[$key]; 72 | 73 | return $this->loadedService[$key]; 74 | } 75 | 76 | // It's a Service instance, lets do some extra stuff. 77 | if (!$this->services[$key]->hasClassName()) { 78 | throw new \Exception('Unable to find class name from definition: ' . $key); 79 | } 80 | 81 | $className = $this->services[$key]->getClassName(); 82 | $instance = new $className(); 83 | 84 | if ($this->services[$key]->hasFactoryMethod()) { 85 | call_user_func($instance, $this->services[$key]->getFactoryMethod()); 86 | } 87 | 88 | $this->loadedService[$key] = $instance; 89 | 90 | return $this->loadedService[$key]; 91 | } 92 | 93 | /** 94 | * Set a service. 95 | * 96 | * @param string $key 97 | * @param mixed $service 98 | */ 99 | public function set($key, $service) 100 | { 101 | $this->services[strtolower($key)] = $service; 102 | } 103 | 104 | /** 105 | * Check if a service has been registered. 106 | * 107 | * @param string $key 108 | * 109 | * @return bool 110 | */ 111 | public function has($key) 112 | { 113 | return isset($this->services[strtolower($key)]); 114 | } 115 | 116 | /** 117 | * @todo Add inline documentation. 118 | * 119 | * @return array 120 | */ 121 | public function getKeys() 122 | { 123 | return array_keys($this->services); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/Router/ChainRouter.php: -------------------------------------------------------------------------------- 1 | 7 | * @license http://opensource.org/licenses/mit-license.php MIT 8 | * 9 | * @link http://www.ppi.io 10 | */ 11 | 12 | namespace PPI\Framework\Router; 13 | 14 | use Symfony\Cmf\Component\Routing\ChainRouter as BaseChainRouter; 15 | use Symfony\Component\HttpFoundation\Request; 16 | 17 | /** 18 | * Class ChainRouter. 19 | * 20 | * @author Paul Dragoonis 21 | */ 22 | class ChainRouter extends BaseChainRouter 23 | { 24 | /** 25 | * @var Request 26 | */ 27 | protected $matchedRouteRequest; 28 | 29 | private $routingCache; 30 | 31 | /** 32 | * @param array $parameters 33 | * 34 | * @return string 35 | */ 36 | public function parametersToString(array $parameters) 37 | { 38 | $pieces = array(); 39 | foreach ($parameters as $key => $val) { 40 | $pieces[] = sprintf('"%s": "%s"', $key, (is_string($val) ? $val : json_encode($val))); 41 | } 42 | 43 | return implode(', ', $pieces); 44 | } 45 | 46 | /** 47 | * @return bool 48 | */ 49 | public function hasRouters() 50 | { 51 | $routers = $this->sortRouters(); 52 | 53 | return !empty($routers); 54 | } 55 | 56 | /** 57 | * @todo - might not need this afterall 58 | * 59 | * @return Request 60 | */ 61 | public function getMatchedRouteRequest() 62 | { 63 | return $this->matchedRouteRequest; 64 | } 65 | 66 | /** 67 | * @param Request $request 68 | * 69 | * @throws \Exception 70 | */ 71 | public function matchRequest(Request $request) 72 | { 73 | try { 74 | $parameters = parent::matchRequest($request); 75 | $this->matchedRouteRequest = $request; 76 | return $parameters; 77 | } catch (\Exception $e) { 78 | throw $e; 79 | } 80 | 81 | 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /src/Router/LaravelRouter.php: -------------------------------------------------------------------------------- 1 | 7 | * @license http://opensource.org/licenses/mit-license.php MIT 8 | * 9 | * @link http://www.ppi.io 10 | */ 11 | 12 | namespace PPI\Framework\Router; 13 | 14 | use Illuminate\Http\Request as LaravelRequest; 15 | use Illuminate\Routing\Router as BaseRouter; 16 | use Symfony\Component\HttpFoundation\Request as SymfonyRequest; 17 | 18 | /** 19 | * Class LaravelRouter. 20 | * 21 | * @author Paul Dragoonis 22 | */ 23 | class LaravelRouter extends BaseRouter 24 | { 25 | /** 26 | * @var string 27 | */ 28 | protected $moduleName; 29 | 30 | /** 31 | * Given a request object, find the matching route. 32 | * 33 | * @param Request $request 34 | * 35 | * @return \Illuminate\Routing\Route 36 | */ 37 | public function matchRequest(SymfonyRequest $request) 38 | { 39 | $laravelRequest = LaravelRequest::createFromBase($request); 40 | $route = $this->findRoute($laravelRequest); 41 | $route->setParameter('_module', $this->moduleName); 42 | 43 | return $route; 44 | } 45 | 46 | public function generate(SymfonyRequest $path) 47 | { 48 | $route = $this->findRoute($request); 49 | 50 | // $parameters = $this->getUrlMatcher($request)->match($path); 51 | // $route = $this->routes->get($parameters['_route']); 52 | } 53 | 54 | /** 55 | * @param string $name 56 | */ 57 | public function setModuleName($name) 58 | { 59 | $this->moduleName = $name; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/Router/Loader/LaravelRoutesLoader.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Router\Loader; 12 | 13 | use Illuminate\Routing\Router; 14 | use Illuminate\Routing\Router as LaravelRouter; 15 | 16 | /** 17 | * LaravelRoutesLoader class. 18 | * 19 | * @author Paul Dragoonis 20 | */ 21 | class LaravelRoutesLoader 22 | { 23 | /** 24 | * @var LaravelRouter 25 | */ 26 | protected $router; 27 | 28 | public function __construct(LaravelRouter $router) 29 | { 30 | $this->router = $router; 31 | } 32 | 33 | /** 34 | * @param string $path 35 | * 36 | * @throws \Exception 37 | * 38 | * @return LaravelRouter 39 | */ 40 | public function load($path) 41 | { 42 | if (!is_readable($path)) { 43 | throw new \InvalidArgumentException('Invalid laravel routes path found: ' . $path); 44 | } 45 | 46 | // localising the object so the $path file can reference $router; 47 | $router = $this->router; 48 | 49 | // The included file must return the laravel router 50 | include $path; 51 | 52 | if (!($router instanceof LaravelRouter)) { 53 | throw new \Exception('Invalid return value from ' 54 | . pathinfo($path, PATHINFO_FILENAME) 55 | . ' expected instance of LaravelRouter' 56 | ); 57 | } 58 | 59 | return $router; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/Router/Loader/YamlFileLoader.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Router\Loader; 12 | 13 | use Symfony\Component\Routing\Loader\YamlFileLoader as BaseYamlFileLoader; 14 | use Symfony\Component\Routing\RouteCollection; 15 | 16 | /** 17 | * YamlFileLoader class. 18 | * 19 | * @author Paul Dragoonis 20 | * @author Vítor Brandão 21 | */ 22 | class YamlFileLoader extends BaseYamlFileLoader 23 | { 24 | /** 25 | * The loader defaults. 26 | * 27 | * @var array 28 | */ 29 | protected $defaults = array(); 30 | 31 | /** 32 | * Constructor. 33 | * 34 | * @param array $defaults 35 | */ 36 | public function setDefaults($defaults) 37 | { 38 | $this->defaults = $defaults; 39 | } 40 | 41 | /** 42 | * Parses a route and adds it to the RouteCollection. 43 | * 44 | * @param RouteCollection $collection A RouteCollection instance 45 | * @param string $name Route name 46 | * @param array $config Route definition 47 | * @param string $path Full path of the YAML file being processed 48 | */ 49 | protected function parseRoute(RouteCollection $collection, $name, array $config, $path) 50 | { 51 | if (!empty($this->defaults)) { 52 | $config['defaults'] = array_merge($config['defaults'], $this->defaults); 53 | } 54 | 55 | parent::parseRoute($collection, $name, $config, $path); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Router/README.md: -------------------------------------------------------------------------------- 1 | PPI Router 2 | ========== 3 | 4 | [@ppi]: http://ppi.io/ "PPI Framework - The PHP Meta Framework" 5 | 6 | The Router component for [PPI2][@ppi]. -------------------------------------------------------------------------------- /src/Router/RoutePluginManager.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Router; 12 | 13 | use Zend\ServiceManager\AbstractPluginManager; 14 | use Zend\ServiceManager\Exception\RuntimeException; 15 | 16 | /** 17 | * Plugin manager implementation for routes. 18 | * 19 | * Enforces that routes retrieved are instances of RouteInterface. It overrides 20 | * createFromInvokable() to call the route's factory method in order to get an 21 | * instance. The manager is marked to not share by default, in order to allow 22 | * multiple route instances of the same type. 23 | */ 24 | class RoutePluginManager extends AbstractPluginManager 25 | { 26 | /** 27 | * Do not share instances. 28 | * 29 | * @var bool 30 | */ 31 | protected $shareByDefault = false; 32 | 33 | /** 34 | * Override setInvokableClass(). 35 | * 36 | * Performs normal operation, but also auto-aliases the class name to the 37 | * service name. This ensures that providing the FQCN does not trigger an 38 | * abstract factory later. 39 | * 40 | * @param string $name 41 | * @param string $invokableClass 42 | * @param null|bool $shared 43 | * 44 | * @return RoutePluginManager 45 | */ 46 | public function setInvokableClass($name, $invokableClass, $shared = null) 47 | { 48 | parent::setInvokableClass($name, $invokableClass, $shared); 49 | if ($name != $invokableClass) { 50 | $this->setAlias($invokableClass, $name); 51 | } 52 | 53 | return $this; 54 | } 55 | 56 | /** 57 | * Validate the plugin. 58 | * 59 | * Checks that the filter loaded is either a valid callback or an instance 60 | * of FilterInterface. 61 | * 62 | * @param mixed $plugin 63 | * 64 | * @throws RuntimeException if invalid 65 | */ 66 | public function validatePlugin($plugin) 67 | { 68 | if ($plugin instanceof RouteInterface) { 69 | // we're okay 70 | return; 71 | } 72 | 73 | throw new RuntimeException(sprintf( 74 | 'Plugin of type %s is invalid; must implement %s\RouteInterface', 75 | (is_object($plugin) ? get_class($plugin) : gettype($plugin)), 76 | __NAMESPACE__ 77 | )); 78 | } 79 | 80 | /** 81 | * Attempt to create an instance via an invokable class. 82 | * 83 | * Overrides parent implementation by invoking the route factory, 84 | * passing $creationOptions as the argument. 85 | * 86 | * @param string $canonicalName 87 | * @param string $requestedName 88 | * 89 | * @throws Exception\RuntimeException If resolved class does not exist, or does not implement RouteInterface 90 | * 91 | * @return null|\stdClass 92 | */ 93 | protected function createFromInvokable($canonicalName, $requestedName) 94 | { 95 | $invokable = $this->invokableClasses[$canonicalName]; 96 | if (!class_exists($invokable)) { 97 | throw new RuntimeException(sprintf( 98 | '%s: failed retrieving "%s%s" via invokable class "%s"; class does not exist', 99 | __METHOD__, 100 | $canonicalName, 101 | ($requestedName ? '(alias: ' . $requestedName . ')' : ''), 102 | $invokable 103 | )); 104 | } 105 | 106 | if (!static::isSubclassOf($invokable, __NAMESPACE__ . '\RouteInterface')) { 107 | throw new RuntimeException(sprintf( 108 | '%s: failed retrieving "%s%s" via invokable class "%s"; class does not implement %s\RouteInterface', 109 | __METHOD__, 110 | $canonicalName, 111 | ($requestedName ? '(alias: ' . $requestedName . ')' : ''), 112 | $invokable, 113 | __NAMESPACE__ 114 | )); 115 | } 116 | 117 | return $invokable::factory($this->creationOptions); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/Router/Router.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Router; 12 | 13 | use Psr\Log\LoggerInterface; 14 | use Symfony\Component\Routing\RequestContext; 15 | use Symfony\Component\Routing\RouteCollection; 16 | use Symfony\Component\Routing\Router as BaseRouter; 17 | use Symfony\Component\Routing\RouterInterface; 18 | 19 | /** 20 | * The PPI Router. 21 | * 22 | * @author Paul Dragoonis 23 | * @author Vítor Brandão 24 | */ 25 | class Router extends BaseRouter implements RouterInterface 26 | { 27 | /** 28 | * Constructor. 29 | * 30 | * @param RequestContext $requestContext The context 31 | * @param RouteCollection|null $collection 32 | * @param array $options 33 | * @param LoggerInterface $logger A logger instance 34 | */ 35 | public function __construct(RequestContext $requestContext, RouteCollection $collection = null, 36 | array $options = array(), LoggerInterface $logger = null) 37 | { 38 | parent::setOptions($options); 39 | 40 | $this->context = $requestContext; 41 | $this->collection = $collection; 42 | $this->logger = $logger; 43 | } 44 | 45 | /** 46 | * Set the route collection. 47 | * 48 | * @param RouteCollection|null $collection 49 | */ 50 | public function setRouteCollection(RouteCollection $collection = null) 51 | { 52 | $this->collection = $collection; 53 | } 54 | 55 | /** 56 | * Has the cache matcher class been generated. 57 | * 58 | * @return bool 59 | */ 60 | public function isMatcherCached() 61 | { 62 | return file_exists( 63 | $this->options['cache_dir'] . 64 | DIRECTORY_SEPARATOR . 65 | $this->options['matcher_cache_class'] . 66 | '.php' 67 | ); 68 | } 69 | 70 | /** 71 | * Has the cache url generator class been generated. 72 | * 73 | * @return bool 74 | */ 75 | public function isGeneratorCached() 76 | { 77 | return file_exists( 78 | $this->options['cache_dir'] . 79 | DIRECTORY_SEPARATOR . 80 | $this->options['generator_cache_class'] . 81 | '.php' 82 | ); 83 | } 84 | 85 | /** 86 | * Warm up the matcher and generator parts of the router. 87 | */ 88 | public function warmUp() 89 | { 90 | $this->getMatcher(); 91 | $this->getGenerator(); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/Router/RoutingHelper.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Router; 12 | 13 | /** 14 | * A routing helper for the controller. 15 | * 16 | * @author Paul Dragoonis 17 | */ 18 | class RoutingHelper 19 | { 20 | /** 21 | * The routing params. 22 | * 23 | * @var array 24 | */ 25 | protected $params = array(); 26 | 27 | /** 28 | * @var string 29 | */ 30 | protected $activeRouteName; 31 | 32 | /** 33 | * Constructor. 34 | * 35 | * @param array $params 36 | */ 37 | public function __construct(array $params = array()) 38 | { 39 | if (!empty($params)) { 40 | $this->setParams($params); 41 | } 42 | } 43 | 44 | /** 45 | * Obtain a param's value. 46 | * 47 | * @param string $param The param name 48 | * 49 | * @throws \InvalidArgumentException When the param does not exist 50 | * 51 | * @return type 52 | */ 53 | public function getParam($param) 54 | { 55 | if (!isset($this->params[$param])) { 56 | throw new \InvalidArgumentException('Unable to find routing param: ' . $param); 57 | } 58 | 59 | return $this->params[$param]; 60 | } 61 | 62 | /** 63 | * Set a routing param's value. 64 | * 65 | * @param string $param 66 | * @param string $value 67 | * 68 | * @return $this 69 | */ 70 | public function setParam($param, $value) 71 | { 72 | $this->params[$param] = $value; 73 | 74 | return $this; 75 | } 76 | 77 | /** 78 | * Check if a routing param exists. 79 | * 80 | * @param string $param 81 | * 82 | * @return bool 83 | */ 84 | public function hasParam($param) 85 | { 86 | return array_key_exists($param, $this->params); 87 | } 88 | 89 | /** 90 | * Get all routing params. 91 | * 92 | * @return array 93 | */ 94 | public function getParams() 95 | { 96 | return $this->params; 97 | } 98 | 99 | /** 100 | * Set the routing params. 101 | * 102 | * @param array $params 103 | * 104 | * @return $this 105 | */ 106 | public function setParams(array $params) 107 | { 108 | $this->params = $params; 109 | 110 | return $this; 111 | } 112 | 113 | /** 114 | * Set the active route's name key. 115 | * 116 | * @param $name 117 | * 118 | * @return $this 119 | */ 120 | public function setActiveRouteName($name) 121 | { 122 | $this->activeRouteName = $name; 123 | 124 | return $this; 125 | } 126 | 127 | /** 128 | * Get the active route's name key. 129 | * 130 | * @return mixed 131 | */ 132 | public function getActiveRouteName() 133 | { 134 | return $this->activeRouteName; 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /src/Router/Wrapper/SymfonyRouterWrapper.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\Router\Wrapper; 12 | 13 | use Symfony\Component\Routing\RequestContext; 14 | use Symfony\Component\Routing\RouterInterface; 15 | 16 | /** 17 | * @author Paul Dragoonis 18 | */ 19 | class SymfonyRouterWrapper implements RouterInterface 20 | { 21 | /** 22 | * @var RouterInterface 23 | */ 24 | protected $router; 25 | 26 | /** 27 | * @param RouterInterface $router 28 | */ 29 | public function __construct(RouterInterface $router) 30 | { 31 | $this->setRouter($router); 32 | } 33 | 34 | /** 35 | * @param RouterInterface $router 36 | */ 37 | public function setRouter(RouterInterface $router) 38 | { 39 | $this->router = $router; 40 | } 41 | 42 | /** 43 | * {@inheritdoc} 44 | */ 45 | public function setContext(RequestContext $context) 46 | { 47 | $this->router->setContext($context); 48 | } 49 | 50 | /** 51 | * {@inheritdoc} 52 | */ 53 | public function getContext() 54 | { 55 | return $this->router->getContext(); 56 | } 57 | 58 | /** 59 | * {@inheritdoc} 60 | */ 61 | public function getRouteCollection() 62 | { 63 | return $this->router->getRouteCollection(); 64 | } 65 | 66 | /** 67 | * {@inheritdoc} 68 | */ 69 | public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH) 70 | { 71 | return $this->router->generate($name, $parameters, $referenceType); 72 | } 73 | 74 | /** 75 | * {@inheritdoc} 76 | */ 77 | public function match($pathinfo) 78 | { 79 | return $this->router->match($pathinfo); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/ServiceManager/Config/AbstractConfig.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\ServiceManager\Config; 12 | 13 | use PPI\Framework\Config\ConfigurationProviderInterface; 14 | use Zend\ServiceManager\Config; 15 | use Zend\ServiceManager\ServiceManager; 16 | use Zend\Stdlib\ArrayUtils; 17 | 18 | /** 19 | * AbstractConfig class. 20 | * 21 | * @author Vítor Brandão 22 | */ 23 | abstract class AbstractConfig extends Config implements ConfigurationProviderInterface 24 | { 25 | /** 26 | * Returns the mandatory prefix to use when using YAML. 27 | * 28 | * This convention is to remove the "Config" postfix from the class 29 | * name and then lowercase and underscore the result. So: 30 | * 31 | * AcmeHelloConfig 32 | * 33 | * becomes 34 | * 35 | * acme_hello 36 | * 37 | * This can be overridden in a sub-class to specify the alias manually. 38 | * 39 | * @throws \BadMethodCallException When the extension name does not follow conventions 40 | * 41 | * @return string The alias 42 | */ 43 | public function getAlias() 44 | { 45 | $className = get_class($this); 46 | if (substr($className, -6) != 'Config') { 47 | throw new \BadMethodCallException('This Config class does not follow the naming convention; you must overwrite the getAlias() method.'); 48 | } 49 | $classBaseName = substr(strrchr($className, '\\'), 1, -6); 50 | 51 | return strtolower($classBaseName); 52 | } 53 | 54 | /** 55 | * Returns the configuration reference for this component. 56 | * 57 | * @returns array 58 | */ 59 | public function getConfigurationReference() 60 | { 61 | return array($this->getAlias() => array()); 62 | } 63 | 64 | /** 65 | * @param ServiceManager $serviceManager 66 | * 67 | * @return array 68 | */ 69 | public function getParameters(ServiceManager $serviceManager) 70 | { 71 | $config = $serviceManager->get('Config'); 72 | 73 | return isset($config['parameters']) ? $config['parameters'] : array(); 74 | } 75 | 76 | /** 77 | * Process an array with the application configuration. 78 | * 79 | * @param array $config 80 | * @param \Zend\ServiceManager\ServiceManager $serviceManager 81 | * 82 | * @return array 83 | */ 84 | abstract protected function processConfiguration(array $config, ServiceManager $serviceManager = null); 85 | 86 | /** 87 | * Merges configuration. 88 | */ 89 | protected function mergeConfiguration(array $defaults, array $config) 90 | { 91 | return ArrayUtils::merge($defaults, $config); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/ServiceManager/Factory/AbstractFactory.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\ServiceManager\Factory; 12 | 13 | use PPI\Framework\Config\ConfigurationProviderInterface; 14 | use Zend\ServiceManager\FactoryInterface; 15 | use Zend\ServiceManager\ServiceLocatorInterface; 16 | use Zend\Stdlib\ArrayUtils; 17 | 18 | /** 19 | * AbstractFactory. 20 | * 21 | * @author Vítor Brandão 22 | */ 23 | abstract class AbstractFactory implements FactoryInterface, ConfigurationProviderInterface 24 | { 25 | /** 26 | * Process an array with the application configuration. 27 | * 28 | * @param array $config 29 | * @param \Zend\ServiceManager\ServiceLocatorInterface $serviceLocator 30 | * 31 | * @return array 32 | */ 33 | abstract protected function processConfiguration(array $config, ServiceLocatorInterface $serviceLocator = null); 34 | 35 | /** 36 | * Merges configuration. 37 | */ 38 | protected function mergeConfiguration(array $defaults, array $config) 39 | { 40 | return ArrayUtils::merge($defaults, $config); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/ServiceManager/Factory/AbstractPluginManagerFactory.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\ServiceManager\Factory; 12 | 13 | use Zend\ServiceManager\AbstractPluginManager; 14 | use Zend\ServiceManager\FactoryInterface; 15 | use Zend\ServiceManager\ServiceLocatorInterface; 16 | 17 | /** 18 | * AbstractPluginManagerFactory. 19 | * 20 | * @author Vítor Brandão 21 | */ 22 | abstract class AbstractPluginManagerFactory implements FactoryInterface 23 | { 24 | const PLUGIN_MANAGER_CLASS = 'AbstractPluginManager'; 25 | 26 | /** 27 | * Create and return a plugin manager. 28 | * Classes that extend this should provide a valid class for 29 | * the PLUGIN_MANGER_CLASS constant. 30 | * 31 | * @param ServiceLocatorInterface $serviceLocator 32 | * 33 | * @return \Zend\ServiceManager\AbstractPluginManager 34 | */ 35 | public function createService(ServiceLocatorInterface $serviceLocator) 36 | { 37 | $pluginManagerClass = static::PLUGIN_MANAGER_CLASS; 38 | /* @var $plugins \Zend\ServiceManager\AbstractPluginManager */ 39 | $plugins = new $pluginManagerClass(); 40 | $plugins->setServiceLocator($serviceLocator); 41 | 42 | return $plugins; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/ServiceManager/Factory/ConfigFactory.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\ServiceManager\Factory; 12 | 13 | use Zend\ServiceManager\FactoryInterface; 14 | use Zend\ServiceManager\ServiceLocatorInterface; 15 | use Zend\Stdlib\ArrayUtils; 16 | 17 | /** 18 | * Config Factory. 19 | * 20 | * @author Vítor Brandão 21 | */ 22 | class ConfigFactory implements FactoryInterface 23 | { 24 | /** 25 | * Create the application configuration service. 26 | * 27 | * Retrieves the Module Manager from the service locator, and executes 28 | * {@link Zend\ModuleManager\ModuleManager::loadModules()}. 29 | * 30 | * It then retrieves the config listener from the module manager, and from 31 | * that the merged configuration. 32 | * 33 | * @param ServiceLocatorInterface $serviceLocator 34 | * 35 | * @return array|\Traversable 36 | */ 37 | public function createService(ServiceLocatorInterface $serviceLocator) 38 | { 39 | $mm = $serviceLocator->get('ModuleManager'); 40 | $mm->loadModules(); 41 | $moduleParams = $mm->getEvent()->getParams(); 42 | 43 | $config = ArrayUtils::merge( 44 | $moduleParams['configListener']->getMergedConfig(false), 45 | $serviceLocator->get('ApplicationConfig') 46 | ); 47 | 48 | $parametersBag = $serviceLocator->get('ApplicationParameters'); 49 | 50 | $config['parameters'] = isset($config['parameters']) ? 51 | ArrayUtils::merge($parametersBag->all(), $config['parameters']) : 52 | $config['parameters'] = $parametersBag->all(); 53 | 54 | return $parametersBag->resolveArray($config); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/ServiceManager/Factory/ControllerNameParserFactory.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\ServiceManager\Factory; 12 | 13 | use PPI\Framework\Module\Controller\ControllerNameParser; 14 | use Zend\ServiceManager\FactoryInterface; 15 | use Zend\ServiceManager\ServiceLocatorInterface; 16 | 17 | /** 18 | * ControllerNameParserFactory. 19 | * 20 | * @author Vítor Brandão 21 | */ 22 | class ControllerNameParserFactory implements FactoryInterface 23 | { 24 | /** 25 | * Create and return a ControllerNameParser instance. 26 | * 27 | * @param ServiceLocatorInterface $serviceLocator 28 | * 29 | * @return \PPI\Framework\Module\Controller\ControllerNameParser 30 | */ 31 | public function createService(ServiceLocatorInterface $serviceLocator) 32 | { 33 | $moduleManager = $serviceLocator->get('ModuleManager'); 34 | 35 | return new ControllerNameParser($moduleManager); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/ServiceManager/Factory/ControllerResolverFactory.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\ServiceManager\Factory; 12 | 13 | use PPI\Framework\Module\Controller\ControllerResolver; 14 | use Zend\ServiceManager\FactoryInterface; 15 | use Zend\ServiceManager\ServiceLocatorInterface; 16 | 17 | /** 18 | * ControllerResolverFactory. 19 | * 20 | * @author Vítor Brandão 21 | */ 22 | class ControllerResolverFactory implements FactoryInterface 23 | { 24 | /** 25 | * Create and return a ControllerResolver instance. 26 | * 27 | * @param ServiceLocatorInterface $serviceLocator 28 | * 29 | * @return \PPI\Framework\Module\Controller\ControllerResolver 30 | */ 31 | public function createService(ServiceLocatorInterface $serviceLocator) 32 | { 33 | $parser = $serviceLocator->get('ControllerNameParser'); 34 | $logger = $serviceLocator->has('Logger') ? $serviceLocator->get('Logger') : null; 35 | 36 | return new ControllerResolver($serviceLocator, $parser, $logger); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/ServiceManager/Factory/DataSourceFactory.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\ServiceManager\Factory; 12 | 13 | use PPI\Framework\DataSource\ConnectionManager; 14 | use Zend\ServiceManager\FactoryInterface; 15 | use Zend\ServiceManager\ServiceLocatorInterface; 16 | 17 | /** 18 | * DataSource Factory. 19 | * 20 | * @author Vítor Brandão 21 | * @author Paul Dragoonis 22 | */ 23 | class DataSourceFactory implements FactoryInterface 24 | { 25 | protected $connectionClassMap = array( 26 | 'laravel' => 'PPI\Framework\DataSource\Connection\Laravel', 27 | 'doctrine_dbal' => 'PPI\Framework\DataSource\Connection\DoctrineDBAL', 28 | 'doctrine_mongdb' => 'PPI\Framework\DataSource\Connection\DoctrineMongoDB', 29 | 'fuelphp' => 'PPI\Framework\DataSource\Connection\FuelPHP', 30 | 'monga' => 'PPI\Framework\DataSource\Connection\Monga', 31 | 'zend_db' => 'PPI\Framework\DataSource\Connection\ZendDb', 32 | ); 33 | 34 | /** 35 | * Create and return the datasource service. 36 | * 37 | * @param ServiceLocatorInterface $serviceLocator 38 | * 39 | * @return \PPI\Framework\DataSource\DataSource; 40 | */ 41 | public function createService(ServiceLocatorInterface $serviceLocator) 42 | { 43 | $config = $serviceLocator->get('ApplicationConfig'); 44 | $allConnections = $libraryToConnMap = $configMap = array(); 45 | 46 | // Early return 47 | if (!isset($config['datasource']['connections'])) { 48 | return new ConnectionManager($allConnections, $this->connectionClassMap); 49 | } 50 | 51 | foreach ($config['datasource']['connections'] as $name => $config) { 52 | $allConnections[$name] = $config; 53 | $configMap[$config['library']][$name] = $config; 54 | } 55 | 56 | return new ConnectionManager($allConnections, $this->connectionClassMap); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/ServiceManager/Factory/EventManagerFactory.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\ServiceManager\Factory; 12 | 13 | use Zend\EventManager\EventManager; 14 | use Zend\ServiceManager\FactoryInterface; 15 | use Zend\ServiceManager\ServiceLocatorInterface; 16 | 17 | /** 18 | * EventManager Factory. 19 | * 20 | * @author Vítor Brandão 21 | */ 22 | class EventManagerFactory implements FactoryInterface 23 | { 24 | /** 25 | * Create an EventManager instance. 26 | * 27 | * Creates a new EventManager instance, seeding it with a shared instance 28 | * of SharedEventManager. 29 | * 30 | * @param ServiceLocatorInterface $serviceLocator 31 | * 32 | * @return EventManager 33 | */ 34 | public function createService(ServiceLocatorInterface $serviceLocator) 35 | { 36 | $em = new EventManager(); 37 | $em->setSharedManager($serviceLocator->get('SharedEventManager')); 38 | 39 | return $em; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/ServiceManager/Factory/FileLocatorFactory.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\ServiceManager\Factory; 12 | 13 | use PPI\Framework\Config\AppFileLocator as FileLocator; 14 | use Zend\ServiceManager\FactoryInterface; 15 | use Zend\ServiceManager\ServiceLocatorInterface; 16 | 17 | /** 18 | * FileLocator Factory. 19 | * 20 | * @author Vítor Brandão 21 | */ 22 | class FileLocatorFactory implements FactoryInterface 23 | { 24 | /** 25 | * Create and return the datasource service. 26 | * 27 | * @param ServiceLocatorInterface $serviceLocator 28 | * 29 | * @return \PPI\Framework\DataSource\DataSource; 30 | */ 31 | public function createService(ServiceLocatorInterface $serviceLocator) 32 | { 33 | $config = $serviceLocator->get('Config'); 34 | $appRootDir = $config['parameters']['app.root_dir']; 35 | 36 | return new FileLocator($serviceLocator->get('ModuleManager'), $appRootDir); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/ServiceManager/Factory/MicroRouterFactory.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\ServiceManager\Factory; 12 | 13 | use PPI\Framework\Router\Router; 14 | use Symfony\Component\Routing\RouteCollection; 15 | use Zend\ServiceManager\FactoryInterface; 16 | use Zend\ServiceManager\ServiceLocatorInterface; 17 | 18 | /** 19 | * Router Factory. 20 | * 21 | * @author Paul Dragoonis (paul@ppi.io) 22 | */ 23 | class MicroRouterFactory implements FactoryInterface 24 | { 25 | /** 26 | * Create and return the router. 27 | * 28 | * @param ServiceLocatorInterface $serviceLocator 29 | * 30 | * @return \PPI\Framework\Router\Router 31 | */ 32 | public function createService(ServiceLocatorInterface $serviceLocator) 33 | { 34 | $routeCollection = new RouteCollection(); 35 | $requestContext = $serviceLocator->get('RouterRequestContext'); 36 | $routerOptions = array(); 37 | 38 | $logger = $serviceLocator->has('logger') ? $serviceLocator->get('Logger') : null; 39 | 40 | $router = new Router($requestContext, $routeCollection, $routerOptions, $logger); 41 | 42 | // @todo - consider making a base router class, and then have a ModuleRouterFactory to pull module routes 43 | // @todo - find a way to set routes on this after we instantiate this factory 44 | 45 | // @todo - let you add new routes on demand and call $router->setRouteCollection() 46 | return $router; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/ServiceManager/Factory/MicroRouterListenerFactory.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\ServiceManager\Factory; 12 | 13 | use PPI\Framework\Router\RouterListener; 14 | use Zend\ServiceManager\FactoryInterface; 15 | use Zend\ServiceManager\ServiceLocatorInterface; 16 | 17 | /** 18 | * RouterListener Factory. 19 | * 20 | * @author Paul Dragoonis 21 | */ 22 | class MicroRouterListenerFactory implements FactoryInterface 23 | { 24 | /** 25 | * Create and return the router. 26 | * 27 | * @param ServiceLocatorInterface $serviceLocator 28 | * 29 | * @return \PPI\Framework\Router\RouterListener 30 | */ 31 | public function createService(ServiceLocatorInterface $serviceLocator) 32 | { 33 | $router = $serviceLocator->get('MicroRouter'); 34 | $requestContext = $serviceLocator->get('RouterRequestContext'); 35 | $logger = $serviceLocator->get('Logger'); 36 | 37 | return new RouterListener($router, $requestContext, $logger); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/ServiceManager/Factory/ModuleDefaultListenerFactory.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\ServiceManager\Factory; 12 | 13 | use PPI\Framework\Module\Listener\DefaultListenerAggregate; 14 | use PPI\Framework\Module\Listener\ListenerOptions; 15 | use Zend\ServiceManager\FactoryInterface; 16 | use Zend\ServiceManager\ServiceLocatorInterface; 17 | 18 | /** 19 | * ModuleDefaultListener Factory. 20 | * 21 | * @author Vítor Brandão 22 | */ 23 | class ModuleDefaultListenerFactory implements FactoryInterface 24 | { 25 | /** 26 | * Creates and returns the default module listeners, providing them configuration 27 | * from the "module_listener_options" key of the ApplicationConfig 28 | * service. Also sets the default config glob path. 29 | * 30 | * @param ServiceLocatorInterface $serviceLocator 31 | * 32 | * @return DefaultListenerAggregate 33 | * 34 | * @note If ListenerOptions becomes a service use "ModuleListenerOptions" or "module.listenerOptions" as the key. 35 | */ 36 | public function createService(ServiceLocatorInterface $serviceLocator) 37 | { 38 | $config = $serviceLocator->get('ApplicationConfig'); 39 | $config = isset($config['module_listener_options']) ? 40 | $config['module_listener_options'] : array(); 41 | 42 | /* 43 | * "module_listener_options": 44 | * 45 | * This should be an array of paths in which modules reside. 46 | * If a string key is provided, the listener will consider that a module 47 | * namespace, the value of that key the specific path to that module's 48 | * Module class. 49 | */ 50 | if (!isset($config['module_paths'])) { 51 | $paths = array(); 52 | $cwd = getcwd() . '/'; 53 | foreach (array('modules', 'vendor') as $dir) { 54 | if (is_dir($dir = $cwd . $dir)) { 55 | $paths[] = $dir; 56 | } 57 | } 58 | 59 | $config['module_paths'] = $paths; 60 | } 61 | 62 | // "extra_module_paths" is an invention of PPI (aka doesn't exist in ZF2). 63 | if (isset($config['extra_module_paths'])) { 64 | $config['module_paths'] = array_merge($config['module_paths'], $config['extra_module_paths']); 65 | } 66 | 67 | $listenerOptions = new ListenerOptions($config); 68 | 69 | $defaultListeners = new DefaultListenerAggregate($listenerOptions); 70 | 71 | return $defaultListeners; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/ServiceManager/Factory/ModuleManagerFactory.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\ServiceManager\Factory; 12 | 13 | use PPI\Framework\Module\ModuleManager; 14 | use Zend\ModuleManager\ModuleEvent; 15 | use Zend\ServiceManager\FactoryInterface; 16 | use Zend\ServiceManager\ServiceLocatorInterface; 17 | 18 | /** 19 | * ModuleManager Factory. 20 | * 21 | * @author Vítor Brandão 22 | */ 23 | class ModuleManagerFactory implements FactoryInterface 24 | { 25 | /** 26 | * Creates and returns the module manager. 27 | * 28 | * Instantiates the default module listeners, providing them configuration 29 | * from the "module_listener_options" key of the ApplicationConfig 30 | * service. Also sets the default config glob path. 31 | * 32 | * Module manager is instantiated and provided with an EventManager, to which 33 | * the default listener aggregate is attached. The ModuleEvent is also created 34 | * and attached to the module manager. 35 | * 36 | * @param ServiceLocatorInterface $serviceLocator 37 | * 38 | * @return ModuleManager 39 | */ 40 | public function createService(ServiceLocatorInterface $serviceLocator) 41 | { 42 | if (!$serviceLocator->has('ServiceListener')) { 43 | $serviceLocator->setFactory('ServiceListener', 'PPI\Framework\ServiceManager\Factory\ServiceListenerFactory'); 44 | } 45 | 46 | $config = $serviceLocator->get('ApplicationConfig'); 47 | $defaultListeners = $serviceLocator->get('ModuleDefaultListener'); 48 | $serviceListener = $serviceLocator->get('ServiceListener'); 49 | 50 | $serviceListener->addServiceManager( 51 | $serviceLocator, 52 | 'service_manager', 53 | 'Zend\ModuleManager\Feature\ServiceProviderInterface', 54 | 'getServiceConfig' 55 | ); 56 | $serviceListener->addServiceManager( 57 | 'RoutePluginManager', 58 | 'route_manager', 59 | 'Zend\ModuleManager\Feature\RouteProviderInterface', 60 | 'getRouteConfig' 61 | ); 62 | 63 | $modules = isset($config['modules']) ? $config['modules'] : array(); 64 | 65 | $events = $serviceLocator->get('EventManager'); 66 | $events->attach($defaultListeners); 67 | $events->attach($serviceListener); 68 | 69 | $moduleEvent = new ModuleEvent(); 70 | $moduleEvent->setParam('ServiceManager', $serviceLocator); 71 | 72 | $moduleManager = new ModuleManager($modules, $events); 73 | $moduleManager->setEvent($moduleEvent); 74 | 75 | return $moduleManager; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/ServiceManager/Factory/RequestFactory.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\ServiceManager\Factory; 12 | 13 | use PPI\Framework\Http\Request; 14 | use Zend\ServiceManager\FactoryInterface; 15 | use Zend\ServiceManager\ServiceLocatorInterface; 16 | 17 | /** 18 | * ServiceManager configuration for the Request component. 19 | * 20 | * @author Vítor Brandão 21 | */ 22 | class RequestFactory implements FactoryInterface 23 | { 24 | /** 25 | * Create and return a request instance. 26 | * 27 | * @param ServiceLocatorInterface $serviceLocator 28 | * 29 | * @return \PPI\Framework\Http\Request 30 | */ 31 | public function createService(ServiceLocatorInterface $serviceLocator) 32 | { 33 | return Request::createFromGlobals(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/ServiceManager/Factory/RequestStackFactory.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\ServiceManager\Factory; 12 | 13 | use Symfony\Component\HttpFoundation\RequestStack; 14 | use Zend\ServiceManager\FactoryInterface; 15 | use Zend\ServiceManager\ServiceLocatorInterface; 16 | 17 | /** 18 | * RequestStackFactory. 19 | * 20 | * @author Vítor Brandão 21 | */ 22 | class RequestStackFactory implements FactoryInterface 23 | { 24 | /** 25 | * Create and return a RequestStack instance. 26 | * 27 | * @param ServiceLocatorInterface $serviceLocator 28 | * 29 | * @return \Symfony\Component\HttpFoundation\RequestStack 30 | */ 31 | public function createService(ServiceLocatorInterface $serviceLocator) 32 | { 33 | return new RequestStack(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/ServiceManager/Factory/ResponseFactory.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\ServiceManager\Factory; 12 | 13 | use PPI\Framework\Http\Response; 14 | use Zend\ServiceManager\FactoryInterface; 15 | use Zend\ServiceManager\ServiceLocatorInterface; 16 | 17 | /** 18 | * ServiceManager configuration for the HttpResponse component. 19 | * 20 | * @author Vítor Brandão 21 | */ 22 | class ResponseFactory implements FactoryInterface 23 | { 24 | /** 25 | * Create and return a response instance. 26 | * 27 | * @param ServiceLocatorInterface $serviceLocator 28 | * 29 | * @return \PPI\Framework\Http\Response\Response 30 | */ 31 | public function createService(ServiceLocatorInterface $serviceLocator) 32 | { 33 | return new Response(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/ServiceManager/Factory/RoutePluginManagerFactory.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\ServiceManager\Factory; 12 | 13 | /** 14 | * RouterPluginManagerFactory. 15 | * 16 | * @author Vítor Brandão 17 | */ 18 | class RoutePluginManagerFactory extends AbstractPluginManagerFactory 19 | { 20 | const PLUGIN_MANAGER_CLASS = 'PPI\Framework\Router\RoutePluginManager'; 21 | } 22 | -------------------------------------------------------------------------------- /src/ServiceManager/Factory/RouterFactory.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\ServiceManager\Factory; 12 | 13 | use Aura\Router\Router as AuraRouter; 14 | use Illuminate\Http\Request as LaravelRequest; 15 | use Illuminate\Routing\Router as LaravelRouter; 16 | use Illuminate\Routing\UrlGenerator as LaravelUrlGenerator; 17 | use PPI\FastRoute\Wrapper\FastRouteWrapper; 18 | use PPI\Framework\Router\ChainRouter; 19 | use PPI\Framework\Router\Router as SymfonyRouter; 20 | use PPI\Framework\Router\Wrapper\AuraRouterWrapper; 21 | use PPI\Framework\Router\Wrapper\SymfonyRouterWrapper; 22 | use PPI\LaravelRouting\Wrapper\LaravelRouterWrapper; 23 | use Symfony\Component\Routing\RouteCollection as SymfonyRouteCollection; 24 | use Zend\ServiceManager\FactoryInterface; 25 | use Zend\ServiceManager\ServiceLocatorInterface; 26 | 27 | /** 28 | * Router Factory. 29 | * 30 | * @author Paul Dragoonis 31 | * @author Vítor Brandão 32 | */ 33 | class RouterFactory implements FactoryInterface 34 | { 35 | /** 36 | * @todo - move this to a separate method() - consider how to inject custom-defined arbitrary chain router entries 37 | * 38 | * @param ServiceLocatorInterface $serviceLocator 39 | * 40 | * @throws \Exception 41 | * 42 | * @return ChainRouter 43 | */ 44 | public function createService(ServiceLocatorInterface $serviceLocator) 45 | { 46 | $request = $serviceLocator->get('Request'); 47 | $requestContext = $serviceLocator->get('RouterRequestContext'); 48 | $routerOptions = array(); 49 | 50 | $logger = $serviceLocator->has('Logger') ? $serviceLocator->get('Logger') : null; 51 | 52 | $chainRouter = new ChainRouter($logger); 53 | if($serviceLocator->has('RoutingCache')) { 54 | $chainRouter->setCache($serviceLocator->get('RoutingCache')); 55 | } 56 | 57 | $chainRouter->setContext($requestContext); 58 | 59 | $allModuleRoutes = $serviceLocator->get('ModuleDefaultListener')->getRoutes(); 60 | 61 | // For each module, add a matching instance type to the chain router 62 | foreach ($allModuleRoutes as $moduleName => $moduleRoutingResponse) { 63 | switch (true) { 64 | // @todo - move this to a separate method() 65 | case $moduleRoutingResponse instanceof SymfonyRouteCollection: 66 | $sfRouter = new SymfonyRouter($requestContext, $moduleRoutingResponse, $routerOptions, $logger); 67 | $sfRouterWrapper = new SymfonyRouterWrapper($sfRouter); 68 | $chainRouter->add($sfRouterWrapper); 69 | break; 70 | 71 | // @todo - move this to a separate method() 72 | case $moduleRoutingResponse instanceof AuraRouter: 73 | $auraRouterWrapper = new AuraRouterWrapper($moduleRoutingResponse); 74 | $chainRouter->add($auraRouterWrapper); 75 | break; 76 | 77 | // @todo - move this to a separate method() 78 | case $moduleRoutingResponse instanceof LaravelRouter: 79 | $laravelRequest = new LaravelRequest(); 80 | $laravelUrlGenerator = new LaravelUrlGenerator($moduleRoutingResponse->getRoutes(), $laravelRequest); 81 | $laravelRouterWrapper = new LaravelRouterWrapper( 82 | $moduleRoutingResponse, $laravelRequest, $laravelUrlGenerator 83 | ); 84 | // @todo - solve this problem 85 | // $laravelRouterWrapper->setModuleName($this->getName()); 86 | $chainRouter->add($laravelRouterWrapper); 87 | break; 88 | 89 | case $moduleRoutingResponse instanceof FastRouteWrapper: 90 | $chainRouter->add($moduleRoutingResponse); 91 | break; 92 | 93 | default: 94 | throw new \Exception('Unexpected routes value return from module: ' . $moduleName . 95 | '. found value of type: ' . gettype($moduleRoutingResponse)); 96 | } 97 | } 98 | 99 | return $chainRouter; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/ServiceManager/Factory/RouterListenerFactory.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\ServiceManager\Factory; 12 | 13 | use PPI\Framework\Router\RouterListener; 14 | use Zend\ServiceManager\FactoryInterface; 15 | use Zend\ServiceManager\ServiceLocatorInterface; 16 | 17 | /** 18 | * RouterListener Factory. 19 | * 20 | * @author Paul Dragoonis 21 | * @author Vítor Brandão 22 | */ 23 | class RouterListenerFactory implements FactoryInterface 24 | { 25 | /** 26 | * Create and return the router. 27 | * 28 | * @param ServiceLocatorInterface $serviceLocator 29 | * 30 | * @return \PPI\Framework\Router\RouterListener 31 | */ 32 | public function createService(ServiceLocatorInterface $serviceLocator) 33 | { 34 | $router = $serviceLocator->get('Router'); 35 | $requestContext = $serviceLocator->get('RouterRequestContext'); 36 | $logger = $serviceLocator->has('Logger') ? $serviceLocator->get('Logger') : null; 37 | $requestStack = $serviceLocator->get('RequestStack'); 38 | 39 | return new RouterListener($router, $requestContext, $logger, $requestStack); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/ServiceManager/Factory/RouterRequestContextFactory.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\ServiceManager\Factory; 12 | 13 | use Symfony\Component\Routing\RequestContext; 14 | use Zend\ServiceManager\ServiceLocatorInterface; 15 | 16 | /** 17 | * RouterRequestContext Factory. 18 | * 19 | * @author Vítor Brandão 20 | */ 21 | class RouterRequestContextFactory extends AbstractFactory 22 | { 23 | /** 24 | * Create and return the router. 25 | * 26 | * @param ServiceLocatorInterface $serviceLocator 27 | * 28 | * @return \PPI\Framework\Router\RouterListener 29 | */ 30 | public function createService(ServiceLocatorInterface $serviceLocator) 31 | { 32 | $context = new RequestContext(); 33 | $context->fromRequest($serviceLocator->get('Request')); 34 | 35 | return $context; 36 | } 37 | 38 | /** 39 | * {@inheritDoc} 40 | */ 41 | public function getConfigurationDefaults() 42 | { 43 | return array('framework' => array( 44 | 'router' => array( 45 | // request_context 46 | 'host' => 'localhost', 47 | 'scheme' => 'http', 48 | // request_listener 49 | 'http_port' => '80', 50 | 'https_port' => '443', 51 | ), 52 | )); 53 | } 54 | 55 | /** 56 | * {@inheritDoc} 57 | */ 58 | protected function processConfiguration(array $config, ServiceLocatorInterface $serviceLocator = null) 59 | { 60 | $defaults = $this->getConfigurationDefaults(); 61 | $defaults = $defaults['framework']['router']; 62 | 63 | return isset($config['framework']['router']) ? 64 | $this->mergeConfiguration($defaults, $config['framework']['router']) : 65 | $defaults; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/ServiceManager/Factory/RoutingHelperFactory.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\ServiceManager\Factory; 12 | 13 | use PPI\Framework\Router\RoutingHelper; 14 | use Zend\ServiceManager\FactoryInterface; 15 | use Zend\ServiceManager\ServiceLocatorInterface; 16 | 17 | /** 18 | * RoutingHelper Factory. 19 | * 20 | * @author Vítor Brandão 21 | */ 22 | class RoutingHelperFactory implements FactoryInterface 23 | { 24 | /** 25 | * Create and return the routing helper. 26 | * 27 | * @param ServiceLocatorInterface $serviceLocator 28 | * 29 | * @return \PPI\Framework\Module\Routing\RoutingHelper 30 | */ 31 | public function createService(ServiceLocatorInterface $serviceLocator) 32 | { 33 | $params = array(); 34 | 35 | return new RoutingHelper($params); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/ServiceManager/ParameterBag.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\ServiceManager; 12 | 13 | use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag as BaseParameterBag; 14 | 15 | /** 16 | * Holds parameters. 17 | * 18 | * An alternative implementation, instead of Symfony's ParameterBag, is to use 19 | * Zend\Stdlib\AbstractOptions or Symfony\Component\OptionsResolver\Options. 20 | * 21 | * @author Vítor Brandão 22 | */ 23 | class ParameterBag extends BaseParameterBag implements \ArrayAccess, \IteratorAggregate, \Countable 24 | { 25 | /** 26 | * @see \ArrayAccess::offsetExists() 27 | */ 28 | public function offsetExists($option) 29 | { 30 | return $this->has($option); 31 | } 32 | 33 | /** 34 | * @see \ArrayAccess::offsetGet() 35 | */ 36 | public function offsetGet($option) 37 | { 38 | return $this->get($option); 39 | } 40 | 41 | /** 42 | * @see \ArrayAccess::offsetSet() 43 | */ 44 | public function offsetSet($option, $value) 45 | { 46 | $this->set($option, $value); 47 | } 48 | 49 | /** 50 | * @see \ArrayAccess::offsetUnset() 51 | */ 52 | public function offsetUnset($option) 53 | { 54 | $this->remove($option); 55 | } 56 | 57 | /** 58 | * @see \Traversable::getIterator() 59 | */ 60 | public function getIterator() 61 | { 62 | return new \ArrayIterator($this->all()); 63 | } 64 | 65 | /** 66 | * @see \Countable::count() 67 | */ 68 | public function count() 69 | { 70 | return count($this->all()); 71 | } 72 | 73 | /** 74 | * Replaces parameter placeholders (%name%) by their values in every string element of the $array. 75 | * 76 | * @param array $data 77 | * 78 | * @return array 79 | */ 80 | public function resolveArray(array $data) 81 | { 82 | $self = $this; 83 | array_walk_recursive($data, function (&$value, $key) use ($self) { 84 | if (is_string($value)) { 85 | $value = $self->resolveString($value); 86 | } 87 | }); 88 | 89 | return $data; 90 | } 91 | 92 | /** 93 | * Flattens an nested array of parameters. 94 | * 95 | * The scheme used is: 96 | * 'key' => array('key2' => array('key3' => 'value')) 97 | * Becomes: 98 | * 'key.key2.key3' => 'value' 99 | * 100 | * This function takes an array by reference and will modify it 101 | * 102 | * @param array &$parameters The array that will be flattened 103 | * @param array $subnode Current subnode being parsed, used internally for recursive calls 104 | * @param string $path Current path being parsed, used internally for recursive calls 105 | */ 106 | protected function flatten(array &$parameters, array $subnode = null, $path = null) 107 | { 108 | if (null === $subnode) { 109 | $subnode = & $parameters; 110 | } 111 | foreach ($subnode as $key => $value) { 112 | if (is_array($value)) { 113 | $nodePath = $path ? $path . '.' . $key : $key; 114 | $this->flatten($parameters, $value, $nodePath); 115 | if (null === $path) { 116 | unset($parameters[$key]); 117 | } 118 | } elseif (null !== $path) { 119 | $parameters[$path . '.' . $key] = $value; 120 | } 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/ServiceManager/README.md: -------------------------------------------------------------------------------- 1 | PPI ServiceManager 2 | ================== 3 | 4 | [@ppi]: http://ppi.io/ "PPI Framework - The PHP Meta Framework" 5 | 6 | The ServiceManager component for [PPI2][@ppi]. -------------------------------------------------------------------------------- /src/ServiceManager/ServiceManagerBuilder.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\ServiceManager; 12 | 13 | use Psr\Log\NullLogger; 14 | 15 | /** 16 | * ServiceManager builder. 17 | * 18 | * @author Vítor Brandão 19 | */ 20 | class ServiceManagerBuilder extends ServiceManager 21 | { 22 | /** 23 | * @var array 24 | */ 25 | protected $config; 26 | 27 | /** 28 | * @param array $config 29 | */ 30 | public function __construct(array $config = array()) 31 | { 32 | $this->config = $config; 33 | 34 | $smConfig = isset($this->config['service_manager']) ? $this->config['service_manager'] : array(); 35 | parent::__construct(new Config\ServiceManagerConfig($smConfig)); 36 | } 37 | 38 | /** 39 | * @param array $parameters 40 | * 41 | * @return $this 42 | */ 43 | public function build(array $parameters = array()) 44 | { 45 | if (!isset($this->config['framework'])) { 46 | $this->config['framework'] = array(); 47 | } 48 | 49 | // Core parameters set by PPI\Framework\App 50 | $parametersBag = new ParameterBag($parameters); 51 | $parametersBag->resolve(); 52 | $this->setService('ApplicationParameters', $parametersBag); 53 | 54 | // Settings provided by the application itself on App boot, config provided by modules is not included 55 | $this->setService('ApplicationConfig', $parametersBag->resolveArray($this->config)); 56 | 57 | if (false === $this->has('Logger')) { 58 | $this->setService('Logger', new NullLogger()); 59 | } 60 | 61 | foreach (array( 62 | new Config\SessionConfig(), 63 | new Config\TemplatingConfig(), 64 | ) as $serviceConfig) { 65 | $serviceConfig->configureServiceManager($this); 66 | } 67 | 68 | return $this; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/View/DelegatingEngine.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\View; 12 | 13 | use Symfony\Component\Templating\DelegatingEngine as BaseDelegatingEngine; 14 | 15 | /** 16 | * DelegatingEngine selects an engine for a given template. 17 | * 18 | * @author Vítor Brandão 19 | */ 20 | class DelegatingEngine extends BaseDelegatingEngine 21 | { 22 | /** 23 | * @todo Add inline documentation. 24 | * 25 | * @var array 26 | */ 27 | protected $globals = array(); 28 | 29 | /** 30 | * Any templating helpers to be registered upon render. 31 | * 32 | * @var array 33 | */ 34 | protected $helpers = array(); 35 | 36 | /** 37 | * Renders a template. 38 | * 39 | * @param mixed $name A template name or a TemplateReferenceInterface 40 | * instance 41 | * @param array $parameters An array of parameters to pass to the template 42 | * 43 | * @throws \InvalidArgumentException If the template does not exist 44 | * @throws \RuntimeException If the template cannot be rendered 45 | * 46 | * @return string The evaluated template as a string 47 | * 48 | * @api 49 | */ 50 | public function render($name, array $parameters = array()) 51 | { 52 | $engine = $this->getEngine($name); 53 | 54 | if (!empty($this->globals)) { 55 | foreach ($this->globals as $key => $val) { 56 | $engine->addGlobal($key, $val); 57 | } 58 | } 59 | 60 | // @todo - This only supports addHelper(), which is on PhpEngine, we should allow addExtension() on SmartyEngine and TwigEngine too. 61 | if (!empty($this->helpers) && is_callable(array($engine, 'addHelpers'))) { 62 | $engine->addHelpers($this->helpers); 63 | } 64 | 65 | return $engine->render($name, $parameters); 66 | } 67 | 68 | /** 69 | * Add a global parameter to the sub-engine selected. 70 | * 71 | * @param string $name 72 | * @param mixed $value 73 | * 74 | * @api 75 | */ 76 | public function addGlobal($name, $value) 77 | { 78 | $this->globals[$name] = $value; 79 | } 80 | 81 | public function addHelper($helper) 82 | { 83 | $this->helpers[$helper->getName()] = $helper; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/View/EngineInterface.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\View; 12 | 13 | use Symfony\Component\HttpFoundation\Response; 14 | use Symfony\Component\Templating\EngineInterface as BaseEngineInterface; 15 | 16 | /** 17 | * EngineInterface is the interface each engine must implement. 18 | * 19 | * @author Fabien Potencier 20 | */ 21 | interface EngineInterface extends BaseEngineInterface 22 | { 23 | /** 24 | * Renders a view and returns a Response. 25 | * 26 | * @param string $view The view name 27 | * @param array $parameters An array of parameters to pass to the view 28 | * @param Response $response A Response instance 29 | * 30 | * @return Response A Response instance 31 | */ 32 | public function renderResponse($view, array $parameters = array(), Response $response = null); 33 | } 34 | -------------------------------------------------------------------------------- /src/View/GlobalVariables.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\View; 12 | 13 | use Zend\ServiceManager\ServiceLocatorInterface; 14 | 15 | /** 16 | * GlobalVariables is the entry point for PPI global variables in PHP/Smarty/Twig 17 | * templates. 18 | * 19 | * @author Vítor Brandão 20 | */ 21 | class GlobalVariables implements \ArrayAccess 22 | { 23 | /** 24 | * @todo Add inline documentation. 25 | * 26 | * @var ServiceLocatorInterface 27 | */ 28 | protected $serviceManager; 29 | 30 | /** 31 | * Constructor. 32 | * 33 | * @param ServiceLocatorInterface $serviceManager 34 | */ 35 | public function __construct(ServiceLocatorInterface $serviceManager) 36 | { 37 | $this->serviceManager = $serviceManager; 38 | } 39 | 40 | /** 41 | * Returns the current request. 42 | * 43 | * @return \Symfony\Component\HttpFoundation\Request|void Http request object 44 | */ 45 | public function getRequest() 46 | { 47 | if ($this->serviceManager->has('request') && $request = $this->serviceManager->get('request')) { 48 | return $request; 49 | } 50 | } 51 | 52 | /** 53 | * Returns the current session. 54 | * 55 | * @return \Symfony\Component\HttpFoundation\Session\Session|void The session 56 | */ 57 | public function getSession() 58 | { 59 | if (($request = $this->getRequest()) != false) { 60 | return $request->getSession(); 61 | } 62 | } 63 | 64 | /** 65 | * Returns the current app environment. 66 | * 67 | * @return string The current environment string (e.g 'dev') 68 | */ 69 | public function getEnvironment() 70 | { 71 | return $this->serviceManager->getOption('app.environment'); 72 | } 73 | 74 | /** 75 | * Returns the current app debug mode. 76 | * 77 | * @return bool The current debug mode 78 | */ 79 | public function getDebug() 80 | { 81 | return (boolean) $this->serviceManager->getOption('app.debug'); 82 | } 83 | 84 | /** 85 | * @see \ArrayAccess::offsetExists() 86 | */ 87 | public function offsetExists($property) 88 | { 89 | return method_exists($this, 'get' . ucfirst($property)); 90 | } 91 | 92 | /** 93 | * @see \ArrayAccess::offsetGet() 94 | */ 95 | public function offsetGet($property) 96 | { 97 | return call_user_func(array($this, 'get' . ucfirst($property))); 98 | } 99 | 100 | /** 101 | * @see \ArrayAccess::offsetSet() 102 | */ 103 | public function offsetSet($property, $value) 104 | { 105 | throw new \RuntimeException('Usage of ' . __METHOD__ . ' is not allowed'); 106 | } 107 | 108 | /** 109 | * @see \ArrayAccess::offsetUnset() 110 | */ 111 | public function offsetUnset($property) 112 | { 113 | throw new \RuntimeException('Usage of ' . __METHOD__ . ' is not allowed'); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/View/Helper/RouterHelper.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\View\Helper; 12 | 13 | use Symfony\Component\Routing\Generator\UrlGeneratorInterface; 14 | use Symfony\Component\Templating\Helper\Helper; 15 | 16 | /** 17 | * RouterHelper manages links between pages in a template context. 18 | * 19 | * @author Fabien Potencier 20 | */ 21 | class RouterHelper extends Helper 22 | { 23 | /** 24 | * @todo Add inline documentation. 25 | * 26 | * @var UrlGeneratorInterface 27 | */ 28 | protected $generator; 29 | 30 | /** 31 | * Constructor. 32 | * 33 | * @param UrlGeneratorInterface $router A Router instance 34 | */ 35 | public function __construct(UrlGeneratorInterface $router) 36 | { 37 | $this->generator = $router; 38 | } 39 | 40 | /** 41 | * Generates a URL from the given parameters. 42 | * 43 | * @param string $name The name of the route 44 | * @param mixed $parameters An array of parameters 45 | * @param bool $absolute Whether to generate an absolute URL 46 | * 47 | * @return string The generated URL 48 | */ 49 | public function generate($name, $parameters = array(), $absolute = false) 50 | { 51 | return $this->generator->generate($name, $parameters, $absolute); 52 | } 53 | 54 | /** 55 | * Returns the canonical name of this helper. 56 | * 57 | * @return string The canonical name 58 | */ 59 | public function getName() 60 | { 61 | return 'router'; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/View/Helper/SessionHelper.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\View\Helper; 12 | 13 | use Symfony\Component\HttpFoundation\Session\SessionInterface; 14 | use Symfony\Component\Templating\Helper\Helper; 15 | 16 | /** 17 | * SessionHelper provides read-only access to the session attributes. 18 | * 19 | * @author Fabien Potencier 20 | * @author Paul Dragoonis 21 | */ 22 | class SessionHelper extends Helper 23 | { 24 | /** 25 | * @todo Add inline documentation. 26 | * 27 | * @var SessionInterface 28 | */ 29 | protected $session; 30 | 31 | /** 32 | * Constructor. 33 | * 34 | * @param SessionInterface $session 35 | */ 36 | public function __construct(SessionInterface $session) 37 | { 38 | $this->session = $session; 39 | } 40 | 41 | /** 42 | * Returns an attribute. 43 | * 44 | * @param string $name The attribute name 45 | * @param mixed $default The default value 46 | * 47 | * @return mixed 48 | */ 49 | public function get($name, $default = null) 50 | { 51 | return $this->session->get($name, $default); 52 | } 53 | 54 | /** 55 | * @todo Add inline documentation. 56 | * 57 | * @param type $name 58 | * @param array $default 59 | * 60 | * @return type 61 | */ 62 | public function getFlash($name, array $default = array()) 63 | { 64 | return $this->session->getFlashBag()->get($name, $default); 65 | } 66 | 67 | /** 68 | * @todo Add inline documentation. 69 | * 70 | * @return type 71 | */ 72 | public function getFlashes() 73 | { 74 | return $this->session->getFlashBag()->all(); 75 | } 76 | 77 | /** 78 | * @todo Add inline documentation. 79 | * 80 | * @param type $name 81 | * 82 | * @return type 83 | */ 84 | public function hasFlash($name) 85 | { 86 | return $this->session->getFlashBag()->has($name); 87 | } 88 | 89 | /** 90 | * @todo Add inline documentation. 91 | * 92 | * @return type 93 | */ 94 | public function hasFlashes() 95 | { 96 | return count($this->session->getFlashBag()->peekAll()) > 0; 97 | } 98 | 99 | /** 100 | * @todo Add inline documentation. 101 | * 102 | * @return string 103 | */ 104 | public function getName() 105 | { 106 | return 'session'; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/View/Mustache/Loader/FileSystemLoader.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\View\Mustache\Loader; 12 | 13 | use Symfony\Component\Config\FileLocatorInterface; 14 | use Symfony\Component\Templating\TemplateNameParserInterface; 15 | 16 | /** 17 | * This engine knows how to render Mustache templates. 18 | * 19 | * @author Justin Hileman 20 | */ 21 | class FileSystemLoader extends \Mustache_Loader_FilesystemLoader 22 | { 23 | protected $locator; 24 | protected $parser; 25 | 26 | /** 27 | * Constructor. 28 | * 29 | * @param FileLocatorInterface $locator A FileLocatorInterface instance 30 | * @param TemplateNameParserInterface $parser A TemplateNameParserInterface instance 31 | */ 32 | public function __construct(FileLocatorInterface $locator, TemplateNameParserInterface $parser) 33 | { 34 | $this->locator = $locator; 35 | $this->parser = $parser; 36 | $this->cache = array(); 37 | } 38 | 39 | /** 40 | * Helper function for getting a Mustache template file name. 41 | * 42 | * @param string $name 43 | * 44 | * @return string Template file name 45 | */ 46 | protected function getFileName($name) 47 | { 48 | $name = (string) $name; 49 | 50 | try { 51 | $template = $this->parser->parse($name); 52 | $file = $this->locator->locate($template); 53 | } catch (\Exception $e) { 54 | throw new \InvalidArgumentException(sprintf('Unable to find template "%s".', $name)); 55 | } 56 | 57 | return $file; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/View/Mustache/MustacheEngine.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\View\Mustache; 12 | 13 | use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface; 14 | use Symfony\Component\HttpFoundation\Response; 15 | use Symfony\Component\Templating\TemplateNameParserInterface; 16 | 17 | /** 18 | * This engine knows how to render Mustache templates. 19 | * 20 | * @author Justin Hileman 21 | */ 22 | class MustacheEngine implements EngineInterface 23 | { 24 | protected $mustache; 25 | protected $parser; 26 | 27 | /** 28 | * Constructor. 29 | * 30 | * @param Mustache_Engine $mustache A \Mustache_Engine instance 31 | * @param TemplateNameParserInterface $parser A TemplateNameParserInterface instance 32 | */ 33 | public function __construct(\Mustache_Engine $mustache, TemplateNameParserInterface $parser) 34 | { 35 | $this->mustache = $mustache; 36 | $this->parser = $parser; 37 | } 38 | 39 | /** 40 | * Renders a template. 41 | * 42 | * @param mixed $name A template name 43 | * @param array $parameters An array of parameters to pass to the template 44 | * 45 | * @throws \InvalidArgumentException if the template does not exist 46 | * @throws \RuntimeException if the template cannot be rendered 47 | * 48 | * @return string The evaluated template as a string 49 | */ 50 | public function render($name, array $parameters = array()) 51 | { 52 | return $this->load($name)->render($parameters); 53 | } 54 | 55 | /** 56 | * Returns true if the template exists. 57 | * 58 | * @param mixed $name A template name 59 | * 60 | * @return bool true if the template exists, false otherwise 61 | */ 62 | public function exists($name) 63 | { 64 | try { 65 | $this->load($name); 66 | } catch (\InvalidArgumentException $e) { 67 | return false; 68 | } 69 | 70 | return true; 71 | } 72 | 73 | /** 74 | * Returns true if this class is able to render the given template. 75 | * 76 | * @param string $name A template name 77 | * 78 | * @return bool True if this class supports the given resource, false otherwise 79 | */ 80 | public function supports($name) 81 | { 82 | if ($name instanceof \Mustache_Template) { 83 | return true; 84 | } 85 | 86 | $template = $this->parser->parse($name); 87 | 88 | return 'mustache' === $template->get('engine'); 89 | } 90 | 91 | /** 92 | * Renders a view and returns a Response. 93 | * 94 | * @param string $view The view name 95 | * @param array $parameters An array of parameters to pass to the view 96 | * @param Response $response A Response instance 97 | * 98 | * @return Response A Response instance 99 | */ 100 | public function renderResponse($view, array $parameters = array(), Response $response = null) 101 | { 102 | if (null === $response) { 103 | $response = new Response(); 104 | } 105 | 106 | $response->setContent($this->render($view, $parameters)); 107 | 108 | return $response; 109 | } 110 | 111 | /** 112 | * Loads the given template. 113 | * 114 | * @param mixed $name A template name or an instance of Mustache_Template 115 | * 116 | * @throws \InvalidArgumentException if the template does not exist 117 | * 118 | * @return \Mustache_Template A \Mustache_Template instance 119 | */ 120 | protected function load($name) 121 | { 122 | if ($name instanceof \Mustache_Template) { 123 | return $name; 124 | } 125 | 126 | return $this->mustache->loadTemplate($name); 127 | } 128 | 129 | /** 130 | * Adding the addGlobal() call to keep things compliant with the existing systems relying on global vars. 131 | * This method will be removed as of PPI 2.1. 132 | * 133 | * @param string $key 134 | * @param mixed $val 135 | * 136 | * @return bool 137 | */ 138 | public function addGlobal($key, $val) 139 | { 140 | return false; 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/View/README.md: -------------------------------------------------------------------------------- 1 | PPI View 2 | ======== 3 | 4 | [@ppi]: http://ppi.io/ "PPI Framework - The PHP Meta Framework" 5 | 6 | The View component for [PPI2][@ppi]. -------------------------------------------------------------------------------- /src/View/Smarty/Extension/AssetsExtension.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\View\Smarty\Extension; 12 | 13 | use NoiseLabs\Bundle\SmartyBundle\Extension\AssetsExtension as BaseAssetsExtension; 14 | use Symfony\Component\Templating\Helper\AssetsHelper; 15 | 16 | /** 17 | * Provides helper functions to link to assets (images, Javascript, 18 | * stylesheets, etc.). 19 | * 20 | * @author Vítor Brandão 21 | */ 22 | class AssetsExtension extends BaseAssetsExtension 23 | { 24 | /** 25 | * A key/value pair of functions to remap to help comply with PSR standards. 26 | * 27 | * @var array 28 | */ 29 | protected $funRemap = array( 30 | 'getAssetUrl_block' => 'getAssetUrlBlock', 31 | 'getAssetUrl_modifier' => 'getAssetUrlModifier', 32 | ); 33 | 34 | /** 35 | * Constructor. 36 | * 37 | * @param AssetsHelper $assetsHelper 38 | */ 39 | public function __construct(AssetsHelper $assetsHelper) 40 | { 41 | $this->helper = $assetsHelper; 42 | } 43 | 44 | public function getHelper() 45 | { 46 | return $this->assetsHelper; 47 | } 48 | 49 | /** 50 | * The magic call method triggers before throwing an exception. 51 | * 52 | * @param string $method The method you are looking for 53 | * @param array $params The params you wish to pass to your method 54 | * 55 | * @return mixed 56 | */ 57 | public function __call($method, array $params = array()) 58 | { 59 | if (isset($this->funRemap[$method])) { 60 | return call_user_func_array(array($this, $this->funRemap[$method]), $params); 61 | } 62 | throw new \BadMethodCallException('Method ' . $method . ' does not exist'); 63 | } 64 | 65 | /** 66 | * Returns the public path of an asset. 67 | * 68 | * Absolute paths (i.e. http://...) are returned unmodified. 69 | * 70 | * @param string $path A public path 71 | * @param string $packageName The name of the asset package to use 72 | * 73 | * @return string A public path which takes into account the base path and URL path 74 | */ 75 | public function getAssetUrl($path, $packageName = null) 76 | { 77 | return $this->helper->getUrl($path, $packageName); 78 | } 79 | 80 | /** 81 | * Returns the public path of an asset. Absolute paths (i.e. http://...) are 82 | * returned unmodified. 83 | * 84 | * @param array $parameters 85 | * @param type $path 86 | * @param type $template 87 | * @param type $repeat 88 | * 89 | * @return string A public path which takes into account the base path and URL path 90 | */ 91 | public function getAssetUrlBlock(array $parameters = array(), $path = null, $template, &$repeat) 92 | { 93 | // only output on the closing tag 94 | if (!$repeat) { 95 | $parameters = array_merge(array( 96 | 'package' => null, 97 | ), $parameters); 98 | 99 | return $this->helper->getUrl($path, $parameters['package']); 100 | } 101 | } 102 | 103 | /** 104 | * Returns the public path of an asset. 105 | * 106 | * Absolute paths (i.e. http://...) are returned unmodified. 107 | * 108 | * @param string $path A public path 109 | * @param type $package 110 | * 111 | * @return string A public path which takes into account the base path 112 | * and URL path 113 | */ 114 | public function getAssetUrlModifier($path, $package = null) 115 | { 116 | return $this->helper->getUrl($path, $package); 117 | } 118 | 119 | /** 120 | * Returns the version of the assets in a package. 121 | * 122 | * @param array $parameters 123 | * @param \Smarty_Internal_Template $template 124 | * 125 | * @return int 126 | */ 127 | public function getAssetsVersion(array $parameters = array(), \Smarty_Internal_Template $template) 128 | { 129 | $parameters = array_merge(array( 130 | 'package' => null, 131 | ), $parameters); 132 | 133 | return $this->helper->getVersion($parameters['package']); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/View/Smarty/Extension/RouterExtension.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\View\Smarty\Extension; 12 | 13 | use NoiseLabs\Bundle\SmartyBundle\Extension\RoutingExtension as BaseRoutingExtension; 14 | 15 | /** 16 | * Provides integration of the Routing component with Smarty[Bundle]. 17 | * 18 | * @author Vítor Brandão 19 | */ 20 | class RouterExtension extends BaseRoutingExtension 21 | { 22 | } 23 | -------------------------------------------------------------------------------- /src/View/Smarty/SmartyEngine.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\View\Smarty; 12 | 13 | use NoiseLabs\Bundle\SmartyBundle\SmartyEngine as BaseSmartyEngine; 14 | use PPI\Framework\View\GlobalVariables; 15 | use PPI\Framework\View\TemplateLocator; 16 | use Psr\Log\LoggerInterface; 17 | use Symfony\Component\Templating\Loader\LoaderInterface; 18 | use Symfony\Component\Templating\TemplateNameParserInterface; 19 | 20 | /** 21 | * SmartyEngine is an engine able to render Smarty templates. 22 | * 23 | * @author Paul Dragoonis 24 | * @author Vítor Brandão 25 | */ 26 | class SmartyEngine extends BaseSmartyEngine 27 | { 28 | /** 29 | * @var \PPI\Framework\View\TemplateLocator 30 | */ 31 | protected $locator; 32 | 33 | /** 34 | * Constructor. 35 | * 36 | * @param \Smarty $smarty A \Smarty instance 37 | * @param TemplateLocator $locator A TemplateLocator instance 38 | * @param TemplateNameParserInterface $parser A TemplateNameParserInterface instance 39 | * @param LoaderInterface $loader A LoaderInterface instance 40 | * @param array $options An array of \Smarty properties 41 | * @param GlobalVariables|null $globals A GlobalVariables instance or null 42 | * @param LoggerInterface|null $logger A LoggerInterface instance or null 43 | */ 44 | public function __construct(\Smarty $smarty, TemplateLocator $locator, TemplateNameParserInterface $parser, 45 | LoaderInterface $loader, array $options = array(), GlobalVariables $globals = null, 46 | LoggerInterface $logger = null) 47 | { 48 | $this->smarty = $smarty; 49 | $this->locator = $locator; 50 | $this->parser = $parser; 51 | $this->loader = $loader; 52 | $this->globals = array(); 53 | $this->logger = null; 54 | 55 | // There are no default extensions. 56 | $this->extensions = array(); 57 | 58 | /* 59 | * Register an handler for 'logical' filenames of the type: 60 | * file:Application:index:index.html.smarty 61 | */ 62 | $this->smarty->default_template_handler_func = array($this, 'smartyDefaultTemplateHandler'); 63 | 64 | /* 65 | * Define a set of template dirs to look for. This will allow the 66 | * usage of the following syntax: 67 | * file:[Application]/index/index.html.tpl 68 | * 69 | * See {@link http://www.smarty.net/docs/en/resources.tpl} for details 70 | */ 71 | $this->smarty->setTemplateDir($this->locator->getAppPath()); 72 | $this->smarty->addTemplateDir($this->locator->getModulesPath()); 73 | 74 | foreach ($options as $property => $value) { 75 | $this->smarty->{$this->smartyPropertyToSetter($property)}($value); 76 | } 77 | 78 | if (null !== $globals) { 79 | $this->addGlobal('app', $globals); 80 | } 81 | 82 | /* 83 | * @note muteExpectedErrors() was activated to workaround the following issue: 84 | * 85 | * Warning: filemtime(): stat failed for /path/to/smarty/cache/3ab50a623e65185c49bf17c63c90cc56070ea85c.one.tpl.php 86 | * in /path/to/smarty/libs/sysplugins/smarty_resource.php 87 | * 88 | * This means that your application registered a custom error hander 89 | * (using set_error_handler()) which is not respecting the given $errno 90 | * as it should. If, for whatever reason, this is the desired behaviour 91 | * of your custom error handler, please call muteExpectedErrors() after 92 | * you've registered your custom error handler. 93 | * 94 | * muteExpectedErrors() registers a custom error handler using 95 | * set_error_handler(). The error handler merely inspects $errno and 96 | * $errfile to determine if the given error was produced deliberately 97 | * and must be ignored, or should be passed on to the next error handler. 98 | */ 99 | $smarty->muteExpectedErrors(); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/View/TemplateLocator.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\View; 12 | 13 | use Symfony\Bundle\FrameworkBundle\Templating\Loader\TemplateLocator as BaseTemplateLocator; 14 | 15 | /** 16 | * The PPI Template Locator. 17 | * 18 | * @author Vítor Brandão 19 | */ 20 | class TemplateLocator extends BaseTemplateLocator 21 | { 22 | /** 23 | * Returns the path to the views directory in the app dir. 24 | * 25 | * @return string The path to the app directory. 26 | */ 27 | public function getAppPath() 28 | { 29 | return $this->locator->getAppPath() . DIRECTORY_SEPARATOR . TemplateReference::APP_VIEWS_DIRECTORY; 30 | } 31 | 32 | /** 33 | * Returns an array of paths to modules views dir. 34 | * 35 | * @return array An array of paths to each loaded module 36 | */ 37 | public function getModulesPath() 38 | { 39 | $paths = $this->locator->getModulesPath(); 40 | foreach (array_keys($paths) as $module) { 41 | $paths[$module] .= DIRECTORY_SEPARATOR . TemplateReference::MODULE_VIEWS_DIRECTORY; 42 | } 43 | 44 | return $paths; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/View/TemplateNameParser.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\View; 12 | 13 | use PPI\Framework\Module\ModuleManager; 14 | use Symfony\Bundle\FrameworkBundle\Templating\TemplateNameParser as BaseTemplateNameParser; 15 | use Symfony\Component\Templating\TemplateReferenceInterface; 16 | 17 | /** 18 | * TemplateNameParser converts template names from the short notation 19 | * "bundle:section:template.format.engine" to TemplateReferenceInterface 20 | * instances. 21 | * 22 | * @author Fabien Potencier 23 | * @author Paul Dragoonis 24 | */ 25 | class TemplateNameParser extends BaseTemplateNameParser 26 | { 27 | /** 28 | * @var ModuleManager 29 | */ 30 | protected $moduleManager; 31 | 32 | /** 33 | * Constructor. 34 | * 35 | * @param ModuleManager $moduleManager A ModuleManager instance 36 | */ 37 | public function __construct(ModuleManager $moduleManager) 38 | { 39 | $this->moduleManager = $moduleManager; 40 | $this->cache = array(); 41 | } 42 | 43 | /** 44 | * {@inheritdoc} 45 | */ 46 | public function parse($name) 47 | { 48 | if ($name instanceof TemplateReferenceInterface) { 49 | return $name; 50 | } elseif (isset($this->cache[$name])) { 51 | return $this->cache[$name]; 52 | } 53 | 54 | // normalize name 55 | $name = str_replace(':/', ':', preg_replace('#/{2,}#', '/', strtr($name, '\\', '/'))); 56 | 57 | if (false !== strpos($name, '..')) { 58 | throw new \RuntimeException(sprintf('Template name "%s" contains invalid characters.', $name)); 59 | } 60 | 61 | $parts = explode(':', $name); 62 | if (3 !== count($parts)) { 63 | throw new \InvalidArgumentException(sprintf('Template name "%s" is not valid (format is "bundle:section:template.format.engine").', $name)); 64 | } 65 | 66 | $elements = explode('.', $parts[2]); 67 | if (3 > count($elements)) { 68 | throw new \InvalidArgumentException(sprintf('Template name "%s" is not valid (format is "bundle:section:template.format.engine").', $name)); 69 | } 70 | $engine = array_pop($elements); 71 | $format = array_pop($elements); 72 | 73 | $template = new TemplateReference($parts[0], $parts[1], implode('.', $elements), $format, $engine); 74 | 75 | if ($template->get('module')) { 76 | try { 77 | $this->moduleManager->getModule($template->get('module')); 78 | } catch (\Exception $e) { 79 | throw new \InvalidArgumentException(sprintf('Template name "%s" is not valid.', $name), 0, $e); 80 | } 81 | } 82 | 83 | return $this->cache[$name] = $template; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/View/TemplateReference.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\View; 12 | 13 | use Symfony\Component\Templating\TemplateReference as BaseTemplateReference; 14 | 15 | /** 16 | * Internal representation of a template. 17 | * 18 | * @author Victor Berchet 19 | * @author Paul Dragoonis 20 | * @author Vítor Brandão 21 | */ 22 | class TemplateReference extends BaseTemplateReference 23 | { 24 | /** 25 | * @var string 26 | */ 27 | const APP_VIEWS_DIRECTORY = 'views'; 28 | 29 | /** 30 | * @var string 31 | */ 32 | const MODULE_VIEWS_DIRECTORY = 'resources/views'; 33 | 34 | /** 35 | * Constructor. 36 | * 37 | * @param null $module 38 | * @param null $controller 39 | * @param null $name 40 | * @param null $format 41 | * @param null $engine 42 | */ 43 | public function __construct($module = null, $controller = null, $name = null, $format = null, $engine = null) 44 | { 45 | $this->parameters = array( 46 | 'module' => $module, 47 | 'controller' => $controller, 48 | 'name' => $name, 49 | 'format' => $format, 50 | 'engine' => $engine, 51 | ); 52 | } 53 | 54 | /** 55 | * Returns the path to the template 56 | * - as a path when the template is not part of a module 57 | * - as a resource when the template is part of a module. 58 | * 59 | * @return string A path to the template or a resource 60 | */ 61 | public function getPath() 62 | { 63 | $controller = str_replace('\\', '/', $this->get('controller')); 64 | 65 | $path = (empty($controller) ? '' : $controller . '/') . $this->get('name') . '.' . $this->get('format') . '.' . $this->get('engine'); 66 | 67 | return empty($this->parameters['module']) ? 68 | self::APP_VIEWS_DIRECTORY . '/' . $path : '@' . $this->get('module') . '/' . self::MODULE_VIEWS_DIRECTORY . '/' . $path; 69 | } 70 | 71 | /** 72 | * {@inheritdoc} 73 | */ 74 | public function getLogicalName() 75 | { 76 | return sprintf('%s:%s:%s.%s.%s', $this->parameters['module'], $this->parameters['controller'], 77 | $this->parameters['name'], $this->parameters['format'], $this->parameters['engine']); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/View/Twig/Extension/AssetsExtension.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\View\Twig\Extension; 12 | 13 | use Symfony\Component\Templating\Helper\AssetsHelper; 14 | 15 | /** 16 | * The PPI Twig AssetsExtension. 17 | */ 18 | class AssetsExtension extends \Twig_Extension 19 | { 20 | /** 21 | * @todo Add inline documentation. 22 | * 23 | * @var type 24 | */ 25 | protected $assetsHelper = null; 26 | 27 | /** 28 | * @todo Add inline documentation. 29 | * 30 | * @param AssetsHelper $assetsHelper 31 | */ 32 | public function __construct(AssetsHelper $assetsHelper) 33 | { 34 | $this->assetsHelper = $assetsHelper; 35 | } 36 | 37 | /** 38 | * Returns a list of functions to add to the existing list. 39 | * 40 | * @return array An array of functions 41 | */ 42 | public function getFunctions() 43 | { 44 | return array( 45 | 'asset' => new \Twig_Function_Method($this, 'getAssetUrl'), 46 | 'assets_version' => new \Twig_Function_Method($this, 'getAssetsVersion'), 47 | ); 48 | } 49 | 50 | /** 51 | * Returns the public path of an asset. 52 | * 53 | * Absolute paths (i.e. http://...) are returned unmodified. 54 | * 55 | * @param string $path A public path 56 | * @param string $packageName The name of the asset package to use 57 | * 58 | * @return string A public path which takes into account the base path and URL path 59 | */ 60 | public function getAssetUrl($path, $packageName = null) 61 | { 62 | return $this->assetsHelper->getUrl($path, $packageName); 63 | } 64 | 65 | /** 66 | * Returns the version of the assets in a package. 67 | * 68 | * @param string $packageName 69 | * 70 | * @return int 71 | */ 72 | public function getAssetsVersion($packageName = null) 73 | { 74 | return $this->assetsHelper->getVersion($packageName); 75 | } 76 | 77 | /** 78 | * Returns the name of the extension. 79 | * 80 | * @return string The extension name 81 | */ 82 | public function getName() 83 | { 84 | return 'assets'; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/View/Twig/Extension/RouterExtension.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\View\Twig\Extension; 12 | 13 | use Symfony\Component\Routing\Generator\UrlGeneratorInterface; 14 | 15 | /** 16 | * Provides integration of the Routing component with Twig. 17 | * 18 | * @author Fabien Potencier 19 | */ 20 | class RouterExtension extends \Twig_Extension 21 | { 22 | /** 23 | * @todo Add inline documentation. 24 | * 25 | * @var type 26 | */ 27 | private $generator; 28 | 29 | /** 30 | * @todo Add inline documentation. 31 | * 32 | * @param UrlGeneratorInterface $generator 33 | */ 34 | public function __construct(UrlGeneratorInterface $generator) 35 | { 36 | $this->generator = $generator; 37 | } 38 | 39 | /** 40 | * Returns a list of functions to add to the existing list. 41 | * 42 | * @return array An array of functions 43 | */ 44 | public function getFunctions() 45 | { 46 | return array( 47 | 'url' => new \Twig_Function_Method($this, 'getUrl'), 48 | 'path' => new \Twig_Function_Method($this, 'getPath'), 49 | ); 50 | } 51 | 52 | /** 53 | * @todo Add inline documentation. 54 | * 55 | * @param type $name 56 | * @param type $parameters 57 | * 58 | * @return type 59 | */ 60 | public function getPath($name, $parameters = array()) 61 | { 62 | return $this->generator->generate($name, $parameters, false); 63 | } 64 | 65 | /** 66 | * @todo Add inline documentation. 67 | * 68 | * @param type $name 69 | * @param type $parameters 70 | * 71 | * @return type 72 | */ 73 | public function getUrl($name, $parameters = array()) 74 | { 75 | return $this->generator->generate($name, $parameters, true); 76 | } 77 | 78 | /** 79 | * Returns the name of the extension. 80 | * 81 | * @return string The extension name 82 | */ 83 | public function getName() 84 | { 85 | return 'routing'; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/View/Twig/Loader/FileSystemLoader.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\Framework\View\Twig\Loader; 12 | 13 | use Symfony\Component\Config\FileLocatorInterface; 14 | use Symfony\Component\Templating\TemplateNameParserInterface; 15 | 16 | /** 17 | * FilesystemLoader extends the default Twig filesystem loader 18 | * to work with the Symfony2 paths. 19 | * 20 | * @author Fabien Potencier 21 | */ 22 | class FileSystemLoader extends \Twig_Loader_Filesystem 23 | { 24 | /** 25 | * @todo Add inline documentation. 26 | * 27 | * @var type 28 | */ 29 | protected $locator; 30 | 31 | /** 32 | * @todo Add inline documentation. 33 | * 34 | * @var type 35 | */ 36 | protected $parser; 37 | 38 | /** 39 | * Constructor. 40 | * 41 | * @param FileLocatorInterface $locator A FileLocatorInterface instance 42 | * @param TemplateNameParserInterface $parser A TemplateNameParserInterface instance 43 | */ 44 | public function __construct(FileLocatorInterface $locator, TemplateNameParserInterface $parser) 45 | { 46 | parent::__construct(array()); 47 | 48 | $this->locator = $locator; 49 | $this->parser = $parser; 50 | $this->cache = array(); 51 | } 52 | 53 | /** 54 | * Returns the path to the template file. 55 | * 56 | * The file locator is used to locate the template when the naming convention 57 | * is the symfony one (i.e. the name can be parsed). 58 | * Otherwise the template is located using the locator from the twig library. 59 | * 60 | * @param string|TemplateReferenceInterface $template The template 61 | * 62 | * @throws \Twig_Error_Loader if the template could not be found 63 | * 64 | * @return string The path to the template file 65 | */ 66 | protected function findTemplate($template) 67 | { 68 | $logicalName = (string) $template; 69 | 70 | if (isset($this->cache[$logicalName])) { 71 | return $this->cache[$logicalName]; 72 | } 73 | 74 | $file = null; 75 | $previous = null; 76 | try { 77 | $template = $this->parser->parse($template); 78 | try { 79 | $file = $this->locator->locate($template); 80 | } catch (\InvalidArgumentException $e) { 81 | $previous = $e; 82 | } 83 | } catch (\Exception $e) { 84 | try { 85 | $file = parent::findTemplate($template); 86 | } catch (\Twig_Error_Loader $e) { 87 | $previous = $e; 88 | } 89 | } 90 | 91 | if (false === $file || null === $file) { 92 | throw new \Twig_Error_Loader(sprintf('Unable to find template "%s".', $logicalName), -1, null, $previous); 93 | } 94 | 95 | return $this->cache[$logicalName] = $file; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /tests/Fixtures/AppForDispatchTest.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\FrameworkTest\Fixtures; 12 | 13 | use PPI\Framework\App; 14 | 15 | /** 16 | * Class AppForDispatchTest. 17 | * 18 | * @author Paul Dragoonis 19 | */ 20 | class AppForDispatchTest extends App 21 | { 22 | public function __construct(array $options = array()) 23 | { 24 | parent::__construct($options); 25 | $this->booted = true; // Force it to not boot 26 | } 27 | 28 | public function setServiceManager($sm) 29 | { 30 | $this->serviceManager = $sm; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/Fixtures/AppForTest.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\FrameworkTest\Fixtures; 12 | 13 | use PPI\Framework\App; 14 | 15 | /** 16 | * Class AppForTest. 17 | * 18 | * @author Vítor Brandão 19 | */ 20 | class AppForTest extends App 21 | { 22 | public function isBooted() 23 | { 24 | return $this->booted; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/Fixtures/ControllerForAppTest.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\FrameworkTest\Fixtures; 12 | 13 | use PPI\Framework\Module\Controller as BaseController; 14 | 15 | /** 16 | * @author Paul Dragoonis 17 | */ 18 | class ControllerForAppTest extends BaseController 19 | { 20 | public function indexAction() 21 | { 22 | return 'Working Response From Controller Index Action'; 23 | } 24 | 25 | public function __invoke() 26 | { 27 | return 'Working Response From Controller Invoke Action'; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/Router/ChainRouterTest.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\FrameworkTest\Router; 12 | 13 | use PPI\Framework\Router\ChainRouter; 14 | 15 | /** 16 | * Class ChainRouterTest. 17 | * 18 | * @author Paul Dragoonis 19 | */ 20 | class ChainRouterTest extends \PHPUnit_Framework_TestCase 21 | { 22 | private $router = null; 23 | 24 | protected function setUp() 25 | { 26 | $this->router = new ChainRouter(); 27 | } 28 | 29 | /** 30 | * @dataProvider parametersToStringData 31 | */ 32 | public function testParametersToString($parameters, $expected) 33 | { 34 | $this->assertEquals($expected, $this->router->parametersToString($parameters)); 35 | } 36 | 37 | /** 38 | * @return array 39 | */ 40 | public function parametersToStringData() 41 | { 42 | return array( 43 | array(array('_controller' => 'index'), '"_controller": "index"'), 44 | array(array('_controller' => 'index'), '"_controller": "index"'), 45 | array(array('_module' => 'Application'), '"_module": "Application"'), 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /tests/Router/Fixtures/RoutePluginManagerForTest.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\FrameworkTest\Router\Fixtures; 12 | 13 | use PPI\Framework\Router\RoutePluginManager; 14 | 15 | /** 16 | * Class RoutePluginManagerForTest. 17 | * 18 | * @author Vítor Brandão 19 | */ 20 | class RoutePluginManagerForTest extends RoutePluginManager 21 | { 22 | /** 23 | * {@inheritDoc} 24 | */ 25 | public function validatePlugin($plugin) 26 | { 27 | return; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/Router/Fixtures/empty.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ppi/framework/9dec3ce10e3fffbf31f44b2957472ae9c7243d7c/tests/Router/Fixtures/empty.yml -------------------------------------------------------------------------------- /tests/Router/Fixtures/nonesense_resource_plus_path.yml: -------------------------------------------------------------------------------- 1 | blog_show: 2 | resource: validpattern.yml 3 | path: /test 4 | -------------------------------------------------------------------------------- /tests/Router/Fixtures/nonesense_type_without_resource.yml: -------------------------------------------------------------------------------- 1 | blog_show: 2 | path: /blog/{slug} 3 | type: custom 4 | -------------------------------------------------------------------------------- /tests/Router/Fixtures/nonvalid.yml: -------------------------------------------------------------------------------- 1 | foo 2 | -------------------------------------------------------------------------------- /tests/Router/Fixtures/nonvalid2.yml: -------------------------------------------------------------------------------- 1 | route: string 2 | -------------------------------------------------------------------------------- /tests/Router/Fixtures/nonvalidkeys.yml: -------------------------------------------------------------------------------- 1 | someroute: 2 | resource: path/to/some.yml 3 | name_prefix: test_ 4 | -------------------------------------------------------------------------------- /tests/Router/Fixtures/special_route_name.yml: -------------------------------------------------------------------------------- 1 | "#$péß^a|": 2 | path: "true" 3 | -------------------------------------------------------------------------------- /tests/Router/Fixtures/validpattern.yml: -------------------------------------------------------------------------------- 1 | blog_show: 2 | path: /blog/{slug} 3 | defaults: { _controller: "MyBundle:Blog:show" } 4 | host: "{locale}.example.com" 5 | requirements: { 'locale': '\w+' } 6 | methods: ['GET','POST','put','OpTiOnS'] 7 | schemes: ['https'] 8 | condition: 'context.getMethod() == "GET"' 9 | options: 10 | compiler_class: RouteCompiler 11 | 12 | blog_show_legacy: 13 | pattern: /blog/{slug} 14 | defaults: { _controller: "MyBundle:Blog:show" } 15 | host: "{locale}.example.com" 16 | requirements: { '_method': 'GET|POST|put|OpTiOnS', _scheme: https, 'locale': '\w+' } 17 | condition: 'context.getMethod() == "GET"' 18 | options: 19 | compiler_class: RouteCompiler 20 | 21 | blog_show_inherited: 22 | path: /blog/{slug} 23 | -------------------------------------------------------------------------------- /tests/Router/Fixtures/validresource.yml: -------------------------------------------------------------------------------- 1 | _blog: 2 | resource: validpattern.yml 3 | prefix: /{foo} 4 | defaults: { 'foo': '123' } 5 | requirements: { 'foo': '\d+' } 6 | options: { 'foo': 'bar' } 7 | host: "" 8 | condition: 'context.getMethod() == "POST"' 9 | -------------------------------------------------------------------------------- /tests/Router/RouterListenerTest.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\FrameworkTest\Router; 12 | 13 | use PPI\Framework\Router\RouterListener; 14 | use Symfony\Component\HttpFoundation\Request; 15 | use Symfony\Component\HttpFoundation\RequestStack; 16 | use Symfony\Component\Routing\RequestContext; 17 | 18 | /** 19 | * Class RouterListenerTest. 20 | * 21 | * @author Vítor Brandão 22 | */ 23 | class RouterListenerTest extends \PHPUnit_Framework_TestCase 24 | { 25 | private $requestStack; 26 | 27 | protected function setUp() 28 | { 29 | $this->requestStack = $this->getMock('Symfony\Component\HttpFoundation\RequestStack', array(), array(), '', 30 | false); 31 | } 32 | 33 | /** 34 | * @dataProvider getPortData 35 | */ 36 | public function testPort($defaultHttpPort, $defaultHttpsPort, $uri, $expectedHttpPort, $expectedHttpsPort) 37 | { 38 | $urlMatcher = $this->getMockBuilder('Symfony\Component\Routing\Matcher\UrlMatcherInterface') 39 | ->disableOriginalConstructor() 40 | ->getMock(); 41 | $context = new RequestContext(); 42 | $context->setHttpPort($defaultHttpPort); 43 | $context->setHttpsPort($defaultHttpsPort); 44 | $urlMatcher->expects($this->any()) 45 | ->method('getContext') 46 | ->will($this->returnValue($context)); 47 | $routerListener = new RouterListener($urlMatcher, null, null, $this->requestStack); 48 | $request = $this->createRequestForUri($uri); 49 | $routerListener->match($request); 50 | $this->assertEquals($expectedHttpPort, $context->getHttpPort()); 51 | $this->assertEquals($expectedHttpsPort, $context->getHttpsPort()); 52 | $this->assertEquals(0 === strpos($uri, 'https') ? 'https' : 'http', $context->getScheme()); 53 | } 54 | public function getPortData() 55 | { 56 | return array( 57 | array(80, 443, 'http://localhost/', 80, 443), 58 | array(80, 443, 'http://localhost:90/', 90, 443), 59 | array(80, 443, 'https://localhost/', 80, 443), 60 | array(80, 443, 'https://localhost:90/', 80, 90), 61 | ); 62 | } 63 | /** 64 | * @param string $uri 65 | * 66 | * @return Request 67 | */ 68 | private function createRequestForUri($uri) 69 | { 70 | $request = Request::create($uri); 71 | $request->attributes->set('_controller', null); // Prevents going in to routing process 72 | 73 | return $request; 74 | } 75 | /** 76 | * @expectedException \InvalidArgumentException 77 | */ 78 | public function testInvalidMatcher() 79 | { 80 | new RouterListener(new \stdClass(), null, null, $this->requestStack); 81 | } 82 | public function testRequestMatcher() 83 | { 84 | $request = Request::create('http://localhost/'); 85 | $requestMatcher = $this->getMock('Symfony\Component\Routing\Matcher\RequestMatcherInterface'); 86 | $requestMatcher->expects($this->once()) 87 | ->method('matchRequest') 88 | ->with($this->isInstanceOf('Symfony\Component\HttpFoundation\Request')) 89 | ->will($this->returnValue(array())); 90 | $routerListener = new RouterListener($requestMatcher, new RequestContext(), null, $this->requestStack); 91 | $routerListener->match($request); 92 | } 93 | public function testSubRequestWithDifferentMethod() 94 | { 95 | $request = Request::create('http://localhost/', 'post'); 96 | $requestMatcher = $this->getMock('Symfony\Component\Routing\Matcher\RequestMatcherInterface'); 97 | $requestMatcher->expects($this->any()) 98 | ->method('matchRequest') 99 | ->with($this->isInstanceOf('Symfony\Component\HttpFoundation\Request')) 100 | ->will($this->returnValue(array())); 101 | $context = new RequestContext(); 102 | $requestMatcher->expects($this->any()) 103 | ->method('getContext') 104 | ->will($this->returnValue($context)); 105 | $routerListener = new RouterListener($requestMatcher, new RequestContext(), null, $this->requestStack); 106 | $routerListener->match($request); 107 | 108 | // sub-request with another HTTP method 109 | $request = Request::create('http://localhost/', 'get'); 110 | $routerListener->match($request); 111 | $this->assertEquals('GET', $context->getMethod()); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /tests/Router/RouterTest.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\FrameworkTest\Router; 12 | 13 | use PPI\Framework\Router\Router; 14 | use Symfony\Component\HttpFoundation\Request; 15 | 16 | /** 17 | * Class RouterTest. 18 | * 19 | * @author Vítor Brandão 20 | */ 21 | class RouterTest extends \PHPUnit_Framework_TestCase 22 | { 23 | private $router = null; 24 | 25 | protected function setUp() 26 | { 27 | $requestContext = $this->getMock('Symfony\Component\Routing\RequestContext'); 28 | $collection = $this->getMock('Symfony\Component\Routing\RouteCollection'); 29 | $options = array(); 30 | $logger = null; 31 | 32 | $this->router = new Router($requestContext, $collection, $options, $logger); 33 | } 34 | 35 | public function testSetOptionsWithSupportedOptions() 36 | { 37 | $this->router->setOptions(array( 38 | 'cache_dir' => './cache', 39 | 'debug' => true, 40 | 'resource_type' => 'ResourceType', 41 | )); 42 | $this->assertSame('./cache', $this->router->getOption('cache_dir')); 43 | $this->assertTrue($this->router->getOption('debug')); 44 | $this->assertSame('ResourceType', $this->router->getOption('resource_type')); 45 | } 46 | 47 | /** 48 | * @expectedException \InvalidArgumentException 49 | * @expectedExceptionMessage The Router does not support the following options: "option_foo", "option_bar" 50 | */ 51 | public function testSetOptionsWithUnsupportedOptions() 52 | { 53 | $this->router->setOptions(array( 54 | 'cache_dir' => './cache', 55 | 'option_foo' => true, 56 | 'option_bar' => 'baz', 57 | 'resource_type' => 'ResourceType', 58 | )); 59 | } 60 | 61 | public function testSetOptionWithSupportedOption() 62 | { 63 | $this->router->setOption('cache_dir', './cache'); 64 | $this->assertSame('./cache', $this->router->getOption('cache_dir')); 65 | } 66 | 67 | /** 68 | * @expectedException \InvalidArgumentException 69 | * @expectedExceptionMessage The Router does not support the "option_foo" option 70 | */ 71 | public function testSetOptionWithUnsupportedOption() 72 | { 73 | $this->router->setOption('option_foo', true); 74 | } 75 | 76 | /** 77 | * @expectedException \InvalidArgumentException 78 | * @expectedExceptionMessage The Router does not support the "option_foo" option 79 | */ 80 | public function testGetOptionWithUnsupportedOption() 81 | { 82 | $this->router->getOption('option_foo', true); 83 | } 84 | 85 | /** 86 | * @return array 87 | */ 88 | public function provideMatcherOptionsPreventingCaching() 89 | { 90 | return array( 91 | array('cache_dir'), 92 | array('matcher_cache_class'), 93 | ); 94 | } 95 | 96 | /** 97 | * @return array 98 | */ 99 | public function provideGeneratorOptionsPreventingCaching() 100 | { 101 | return array( 102 | array('cache_dir'), 103 | array('generator_cache_class'), 104 | ); 105 | } 106 | 107 | public function testMatchRequestWithUrlMatcherInterface() 108 | { 109 | $matcher = $this->getMock('Symfony\Component\Routing\Matcher\UrlMatcherInterface'); 110 | $matcher->expects($this->once())->method('match'); 111 | $p = new \ReflectionProperty($this->router, 'matcher'); 112 | $p->setAccessible(true); 113 | $p->setValue($this->router, $matcher); 114 | $this->router->matchRequest(Request::create('/')); 115 | } 116 | 117 | public function testMatchRequestWithRequestMatcherInterface() 118 | { 119 | $matcher = $this->getMock('Symfony\Component\Routing\Matcher\RequestMatcherInterface'); 120 | $matcher->expects($this->once())->method('matchRequest'); 121 | $p = new \ReflectionProperty($this->router, 'matcher'); 122 | $p->setAccessible(true); 123 | $p->setValue($this->router, $matcher); 124 | $this->router->matchRequest(Request::create('/')); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /tests/Router/RoutingHelperTest.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\FrameworkTest\Router; 12 | 13 | use PPI\Framework\Router\RoutingHelper; 14 | 15 | /** 16 | * Class RoutingHelperTest. 17 | * 18 | * @author Vítor Brandão 19 | */ 20 | class RoutingHelperTest extends \PHPUnit_Framework_TestCase 21 | { 22 | /** 23 | * @var array 24 | */ 25 | private $params; 26 | 27 | public function setUp() 28 | { 29 | $this->params = array( 30 | '_controller' => 'BlogModule\Controller\BlogController::showAction', 31 | ); 32 | } 33 | 34 | public function testParamsAreReturned() 35 | { 36 | $k = '_controller'; 37 | 38 | // Via constructor 39 | $routingHelper = new RoutingHelper($this->params); 40 | $this->assertEquals($this->params[$k], $routingHelper->getParam($k)); 41 | 42 | // Via setParams() 43 | $routingHelper = new RoutingHelper(); 44 | $routingHelper->setParams($this->params); 45 | $this->assertEquals($this->params[$k], $routingHelper->getParam($k)); 46 | 47 | // Via setParam() 48 | $routingHelper = new RoutingHelper(); 49 | $routingHelper->setParam($k, $this->params[$k]); 50 | $this->assertEquals($this->params[$k], $routingHelper->getParam($k)); 51 | } 52 | 53 | public function testUnsetParamThrowsInvalidArgumentException() 54 | { 55 | $routingHelper = new RoutingHelper(); 56 | $this->setExpectedException('\InvalidArgumentException'); 57 | $routingHelper->getParam('_controller'); 58 | } 59 | 60 | public function testActiveRouteNameIsSaved() 61 | { 62 | $routingHelper = new RoutingHelper(); 63 | $routingHelper->setActiveRouteName('test'); 64 | $this->assertEquals('test', $routingHelper->getActiveRouteName()); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /tests/ServiceManager/Fixtures/AbstractFactoryWithMutableCreationOptions.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\FrameworkTest\ServiceManager\Fixtures; 12 | 13 | use stdClass; 14 | use Zend\ServiceManager\AbstractFactoryInterface; 15 | use Zend\ServiceManager\MutableCreationOptionsInterface; 16 | use Zend\ServiceManager\ServiceLocatorInterface; 17 | 18 | /** 19 | * Class AbstractFactoryWithMutableCreationOptions. 20 | * 21 | * @author Vítor Brandão 22 | */ 23 | class AbstractFactoryWithMutableCreationOptions implements AbstractFactoryInterface, MutableCreationOptionsInterface 24 | { 25 | /** 26 | * @param \Zend\ServiceManager\ServiceLocatorInterface $serviceLocator 27 | * @param $name 28 | * @param $requestedName 29 | * 30 | * @return bool 31 | */ 32 | public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) 33 | { 34 | return true; 35 | } 36 | 37 | /** 38 | * @param \Zend\ServiceManager\ServiceLocatorInterface $serviceLocator 39 | * @param $name 40 | * @param $requestedName 41 | * 42 | * @return \stdClass 43 | */ 44 | public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) 45 | { 46 | return new stdClass(); 47 | } 48 | 49 | public function setCreationOptions(array $options) 50 | { 51 | $this->options = $options; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /tests/ServiceManager/Fixtures/Bar.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\FrameworkTest\ServiceManager\Fixtures; 12 | 13 | /** 14 | * Class Bar. 15 | * 16 | * @author Vítor Brandão 17 | */ 18 | class Bar 19 | { 20 | /** 21 | * @param array $foo 22 | */ 23 | public function __construct(array $foo = null) 24 | { 25 | if (null === $foo) { 26 | throw new \RuntimeException(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/ServiceManager/Fixtures/BarAbstractFactory.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\FrameworkTest\ServiceManager\Fixtures; 12 | 13 | use Zend\ServiceManager\AbstractFactoryInterface; 14 | use Zend\ServiceManager\ServiceLocatorInterface; 15 | 16 | class BarAbstractFactory implements AbstractFactoryInterface 17 | { 18 | public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) 19 | { 20 | if ($name != 'bar') { 21 | return false; 22 | } 23 | 24 | return true; 25 | } 26 | 27 | public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) 28 | { 29 | return new Bar(array()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/ServiceManager/Fixtures/CallableWithMutableCreationOptions.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\FrameworkTest\ServiceManager\Fixtures; 12 | 13 | use stdClass; 14 | use Zend\ServiceManager\MutableCreationOptionsInterface; 15 | use Zend\ServiceManager\ServiceLocatorInterface; 16 | 17 | /** 18 | * Implements multiple interface invokable object mock. 19 | */ 20 | class CallableWithMutableCreationOptions implements MutableCreationOptionsInterface 21 | { 22 | /** 23 | * @param array $options 24 | */ 25 | public function setCreationOptions(array $options) 26 | { 27 | $this->options = $options; 28 | } 29 | 30 | /** 31 | * @param \Zend\ServiceManager\ServiceLocatorInterface $serviceLocator 32 | * @param $cName 33 | * @param $rName 34 | * 35 | * @return \stdClass 36 | */ 37 | public function __invoke(ServiceLocatorInterface $serviceLocator, $cName, $rName) 38 | { 39 | return new stdClass(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tests/ServiceManager/Fixtures/CircularDependencyAbstractFactory.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\FrameworkTest\ServiceManager\Fixtures; 12 | 13 | use Zend\ServiceManager\AbstractFactoryInterface; 14 | use Zend\ServiceManager\ServiceLocatorInterface; 15 | 16 | /** 17 | * Class used to try to simulate a cyclic dependency in ServiceManager. 18 | */ 19 | class CircularDependencyAbstractFactory implements AbstractFactoryInterface 20 | { 21 | public $expectedInstance = 'a retrieved value'; 22 | 23 | /** 24 | * {@inheritDoc} 25 | */ 26 | public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) 27 | { 28 | return true; 29 | } 30 | 31 | /** 32 | * {@inheritDoc} 33 | */ 34 | public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) 35 | { 36 | if ($serviceLocator->has($name)) { 37 | return $serviceLocator->get($name); 38 | } 39 | 40 | return $this->expectedInstance; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/ServiceManager/Fixtures/Foo.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\FrameworkTest\ServiceManager\Fixtures; 12 | 13 | /** 14 | * Class Foo. 15 | * 16 | * @author Vítor Brandão 17 | */ 18 | class Foo 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /tests/ServiceManager/Fixtures/FooAbstractFactory.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\FrameworkTest\ServiceManager\Fixtures; 12 | 13 | use Zend\ServiceManager\AbstractFactoryInterface; 14 | use Zend\ServiceManager\ServiceLocatorInterface; 15 | 16 | class FooAbstractFactory implements AbstractFactoryInterface 17 | { 18 | public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) 19 | { 20 | if ($name == 'foo') { 21 | return true; 22 | } 23 | } 24 | public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) 25 | { 26 | return new Foo(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /tests/ServiceManager/Fixtures/FooCounterAbstractFactory.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\FrameworkTest\ServiceManager\Fixtures; 12 | 13 | use Zend\ServiceManager\AbstractFactoryInterface; 14 | use Zend\ServiceManager\ServiceLocatorInterface; 15 | 16 | /** 17 | * Abstract factory that keeps track of the number of times it is instantiated. 18 | */ 19 | class FooCounterAbstractFactory implements AbstractFactoryInterface 20 | { 21 | /** 22 | * @var int 23 | */ 24 | public static $instantiationCount = 0; 25 | 26 | /** 27 | * Increments instantiation count. 28 | */ 29 | public function __construct() 30 | { 31 | static::$instantiationCount += 1; 32 | } 33 | 34 | /** 35 | * {@inheritDoc} 36 | */ 37 | public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) 38 | { 39 | if ($name == 'foo') { 40 | return true; 41 | } 42 | } 43 | 44 | /** 45 | * {@inheritDoc} 46 | */ 47 | public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) 48 | { 49 | return new Foo(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tests/ServiceManager/Fixtures/FooException.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\FrameworkTest\ServiceManager\Fixtures; 12 | 13 | class FooException extends \Exception 14 | { 15 | } 16 | -------------------------------------------------------------------------------- /tests/ServiceManager/Fixtures/FooFactory.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\FrameworkTest\ServiceManager\Fixtures; 12 | 13 | use Zend\ServiceManager\FactoryInterface; 14 | use Zend\ServiceManager\MutableCreationOptionsInterface; 15 | use Zend\ServiceManager\ServiceLocatorInterface; 16 | 17 | /** 18 | * Class FooFactory. 19 | * 20 | * @author Vítor Brandão 21 | */ 22 | class FooFactory implements FactoryInterface, MutableCreationOptionsInterface 23 | { 24 | /** 25 | * @var array 26 | */ 27 | protected $creationOptions; 28 | 29 | /** 30 | * @param array $creationOptions 31 | */ 32 | public function __construct(array $creationOptions = array()) 33 | { 34 | $this->creationOptions = $creationOptions; 35 | } 36 | 37 | /** 38 | * @param array $creationOptions 39 | */ 40 | public function setCreationOptions(array $creationOptions) 41 | { 42 | $this->creationOptions = $creationOptions; 43 | } 44 | 45 | /** 46 | * @return array 47 | */ 48 | public function getCreationOptions() 49 | { 50 | return $this->creationOptions; 51 | } 52 | 53 | public function createService(ServiceLocatorInterface $serviceLocator) 54 | { 55 | return new Foo(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /tests/ServiceManager/Fixtures/FooFake.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\FrameworkTest\ServiceManager\Fixtures; 12 | 13 | class FooFake 14 | { 15 | } 16 | -------------------------------------------------------------------------------- /tests/ServiceManager/Fixtures/FooFakeAbstractFactory.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\FrameworkTest\ServiceManager\Fixtures; 12 | 13 | use Zend\ServiceManager\AbstractFactoryInterface; 14 | use Zend\ServiceManager\ServiceLocatorInterface; 15 | 16 | class FooFakeAbstractFactory implements AbstractFactoryInterface 17 | { 18 | public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) 19 | { 20 | if ($name == 'foo') { 21 | return true; 22 | } 23 | } 24 | public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) 25 | { 26 | return new FooFake(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /tests/ServiceManager/Fixtures/FooInitializer.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\FrameworkTest\ServiceManager\Fixtures; 12 | 13 | use Zend\ServiceManager\InitializerInterface; 14 | use Zend\ServiceManager\ServiceLocatorInterface; 15 | 16 | class FooInitializer implements InitializerInterface 17 | { 18 | public $sm; 19 | 20 | protected $var; 21 | 22 | public function __construct($var = null) 23 | { 24 | if ($var) { 25 | $this->var = $var; 26 | } 27 | } 28 | 29 | public function initialize($instance, ServiceLocatorInterface $serviceLocator) 30 | { 31 | $this->sm = $serviceLocator; 32 | if ($this->var) { 33 | list($key, $value) = each($this->var); 34 | $instance->{$key} = $value; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/ServiceManager/Fixtures/GlobIteratorService.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\FrameworkTest\ServiceManager\Fixtures; 12 | 13 | class GlobIteratorService extends \GlobIterator 14 | { 15 | public function __construct() 16 | { 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/ServiceManager/Fixtures/MockSelfReturningDelegatorFactory.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\FrameworkTest\ServiceManager\Fixtures; 12 | 13 | use Zend\ServiceManager\DelegatorFactoryInterface; 14 | use Zend\ServiceManager\ServiceLocatorInterface; 15 | 16 | /** 17 | * Mock factory that logs delegated service instances and returns itself instead of the original service. 18 | * 19 | * @author Vítor Brandão 20 | */ 21 | class MockSelfReturningDelegatorFactory implements DelegatorFactoryInterface 22 | { 23 | /** 24 | * @var mixed[] 25 | */ 26 | public $instances = array(); 27 | 28 | /** 29 | * {@inheritDoc} 30 | */ 31 | public function createDelegatorWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName, $callback) 32 | { 33 | $this->instances[] = call_user_func($callback); 34 | 35 | return $this; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/ServiceManager/Fixtures/TrollAbstractFactory.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\FrameworkTest\ServiceManager\Fixtures; 12 | 13 | use stdClass; 14 | use Zend\ServiceManager\AbstractFactoryInterface; 15 | use Zend\ServiceManager\ServiceLocatorInterface; 16 | 17 | class TrollAbstractFactory implements AbstractFactoryInterface 18 | { 19 | public $inexistingServiceCheckResult = null; 20 | 21 | public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) 22 | { 23 | // Check if a non-existing service exists 24 | $this->inexistingServiceCheckResult = $serviceLocator->has('NonExistingService'); 25 | 26 | if ($requestedName === 'SomethingThatCanBeCreated') { 27 | return true; 28 | } 29 | 30 | return false; 31 | } 32 | 33 | public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) 34 | { 35 | return new stdClass(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/ServiceManager/Fixtures/WaitingAbstractFactory.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\FrameworkTest\ServiceManager\Fixtures; 12 | 13 | use stdClass; 14 | use Zend\ServiceManager\AbstractFactoryInterface; 15 | use Zend\ServiceManager\ServiceLocatorInterface; 16 | 17 | class WaitingAbstractFactory implements AbstractFactoryInterface 18 | { 19 | public $waitingService = null; 20 | 21 | public $canCreateCallCount = 0; 22 | 23 | public $createNullService = false; 24 | 25 | public $throwExceptionWhenCreate = false; 26 | 27 | public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) 28 | { 29 | $this->canCreateCallCount++; 30 | 31 | return $requestedName === $this->waitingService; 32 | } 33 | 34 | public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) 35 | { 36 | if ($this->throwExceptionWhenCreate) { 37 | throw new FooException('E'); 38 | } 39 | if ($this->createNullService) { 40 | return; 41 | } 42 | 43 | return new stdClass(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/ServiceManager/ServiceManagerBuilderTest.php: -------------------------------------------------------------------------------- 1 | 6 | * @license http://opensource.org/licenses/mit-license.php MIT 7 | * 8 | * @link http://www.ppi.io 9 | */ 10 | 11 | namespace PPI\FrameworkTest\ServiceManager; 12 | 13 | use PPI\Framework\ServiceManager\ServiceManagerBuilder; 14 | use Psr\Log\NullLogger; 15 | 16 | class ServiceManagerBuilderTest extends \PHPUnit_Framework_TestCase 17 | { 18 | public function testNullLoggerIsUsedIfNoneProvided() 19 | { 20 | $builder = new ServiceManagerBuilder(array()); 21 | $serviceManager = $builder->build($this->getAppParameters()); 22 | 23 | $this->assertTrue($serviceManager->has('logger')); 24 | $this->assertInstanceOf('Psr\Log\NullLogger', $serviceManager->get('logger')); 25 | } 26 | 27 | public function testNullLoggerIsNotUsedIfAnotherLoggerProvided() 28 | { 29 | $builder = new ServiceManagerBuilder(array( 30 | 'service_manager' => array( 31 | 'invokables' => array( 32 | 'Logger' => 'PPI\FrameworkTest\ServiceManager\MyLogger', 33 | ), 34 | ), 35 | )); 36 | $serviceManager = $builder->build($this->getAppParameters()); 37 | 38 | $this->assertTrue($serviceManager->has('logger')); 39 | $this->assertInstanceOf('Psr\Log\NullLogger', $serviceManager->get('logger')); 40 | } 41 | 42 | /** 43 | * @return array 44 | * 45 | * NOTE: the following app.* parameters are required by the TemplatingConfig. 46 | */ 47 | private function getAppParameters() 48 | { 49 | return array( 50 | 'app.root_dir' => 'foo', 51 | 'app.cache_dir' => 'bar', 52 | 'app.charset' => 'baz', 53 | ); 54 | } 55 | } 56 | 57 | class MyLogger extends NullLogger 58 | { 59 | } 60 | --------------------------------------------------------------------------------