├── .gitignore ├── .php_cs ├── Module.php ├── README.md ├── bin ├── .gitignore └── create-phar ├── composer.json ├── config ├── module.config.php └── zftool.global.php.dist ├── docs ├── DIAGNOSTICS.md └── img │ ├── browser-run.png │ ├── simple-run.png │ └── verbose-run.png ├── src └── ZFTool │ ├── Controller │ ├── ClassmapController.php │ ├── ConfigController.php │ ├── CreateController.php │ ├── DiagnosticsController.php │ ├── InfoController.php │ ├── InstallController.php │ └── ModuleController.php │ ├── Diagnostics │ ├── Config.php │ ├── ConfigInterface.php │ ├── Exception │ │ ├── ExceptionInterface.php │ │ ├── InvalidArgumentException.php │ │ └── RuntimeException.php │ ├── Reporter │ │ ├── BasicConsole.php │ │ └── VerboseConsole.php │ └── Runner.php │ ├── Model │ ├── Config.php │ ├── Skeleton.php │ ├── Utility.php │ └── Zf.php │ └── Module.php ├── tests ├── Bootstrap.php ├── ZFToolTest │ ├── Diagnostics │ │ ├── DiagnosticsControllerTest.php │ │ ├── Reporter │ │ │ ├── BasicConsoleTest.php │ │ │ ├── ReporterTest.php │ │ │ └── VerboseConsoleTest.php │ │ ├── RunnerTest.php │ │ └── TestAsset │ │ │ ├── AlwaysFailCheck.php │ │ │ ├── AlwaysSuccessCheck.php │ │ │ ├── ConsoleAdapter.php │ │ │ ├── DummyModule.php │ │ │ ├── DummyReporter.php │ │ │ ├── InjectableModuleManager.php │ │ │ ├── ReturnThisCheck.php │ │ │ └── UnknownResult.php │ └── Model │ │ ├── SkeletonTest.php │ │ └── UtilityTest.php └── phpunit.xml ├── view └── diagnostics │ └── run.phtml ├── zf.php └── zf2.bat /.gitignore: -------------------------------------------------------------------------------- 1 | nbproject 2 | .idea 3 | .buildpath 4 | .project 5 | .settings/ 6 | tmp/ 7 | .DS_Store 8 | composer.lock 9 | composer.phar 10 | .*.sw* 11 | .*.un~ 12 | vendor/ 13 | -------------------------------------------------------------------------------- /.php_cs: -------------------------------------------------------------------------------- 1 | in('src') 4 | ->in('tests'); 5 | $config = Symfony\CS\Config\Config::create(); 6 | $config->level(null); 7 | $config->fixers( 8 | array( 9 | 'braces', 10 | 'duplicate_semicolon', 11 | 'elseif', 12 | 'empty_return', 13 | 'encoding', 14 | 'eof_ending', 15 | 'function_call_space', 16 | 'function_declaration', 17 | 'indentation', 18 | 'join_function', 19 | 'line_after_namespace', 20 | 'linefeed', 21 | 'lowercase_keywords', 22 | 'parenthesis', 23 | 'multiple_use', 24 | 'method_argument_space', 25 | 'object_operator', 26 | 'php_closing_tag', 27 | 'remove_lines_between_uses', 28 | 'short_tag', 29 | 'standardize_not_equal', 30 | 'trailing_spaces', 31 | 'unused_use', 32 | 'visibility', 33 | 'whitespacy_lines', 34 | ) 35 | ); 36 | $config->finder($finder); 37 | return $config; 38 | -------------------------------------------------------------------------------- /Module.php: -------------------------------------------------------------------------------- 1 | ## Repository abandoned 2019-12-05 5 | > 6 | > This repository is no longer maintained. Tooling was not updated to work with ZF3, and with the transition to Laminas, we will be deciding what, if any, new tooling we want to provide for the MVC framework. 7 | 8 | **ZFTool** is an utility module for maintaining modular Zend Framework 2 applications. 9 | It runs from the command line and can be installed as ZF2 module or as PHAR (see below). 10 | 11 | ## Features 12 | * Class-map generator 13 | * Listing of loaded modules 14 | * Create a new project (install the ZF2 skeleton application) 15 | * Create a new module 16 | * Create a new controller 17 | * Create a new action in a controller 18 | * [Application diagnostics](docs/DIAGNOSTICS.md) 19 | 20 | ## Requirements 21 | * Zend Framework 2.0.0 or later. 22 | * PHP 5.3.3 or later. 23 | * Console access to the application being maintained (shell, command prompt) 24 | 25 | ## Installation using [Composer](http://getcomposer.org) 26 | 1. Open console (command prompt) 27 | 2. Go to your application's directory. 28 | 3. Run `composer require zendframework/zftool:dev-master` 29 | 4. Execute the `vendor/bin/zf.php` as reported below 30 | 31 | ## Using the PHAR file (zftool.phar) 32 | 33 | 1. Download the [zftool.phar from packages.zendframework.com](http://packages.zendframework.com/zftool.phar) 34 | 2. Execute the `zftool.phar` with one of the options reported below (`zftool.phar` replace the `zf.php`) 35 | 36 | You can also generate the zftool.phar using the `bin/create-phar` command as reported below 37 | 38 | ## Usage 39 | 40 | ### Basic information 41 | 42 | zf.php modules [list] show loaded modules 43 | zf.php version | --version display current Zend Framework version 44 | 45 | ### Diagnostics 46 | 47 | zf.php diag [options] [module name] 48 | 49 | [module name] (Optional) name of module to test 50 | -v --verbose Display detailed information. 51 | -b --break Stop testing on first failure. 52 | -q --quiet Do not display any output unless an error occurs. 53 | --debug Display raw debug info from tests. 54 | 55 | ### Project creation 56 | 57 | zf.php create project 58 | 59 | The path of the project to be created 60 | 61 | ### Module creation 62 | 63 | zf.php create module [] 64 | 65 | The name of the module to be created 66 | The path to the root folder of the ZF2 application (optional) 67 | 68 | ### Controller creation: 69 | zf.php create controller [] 70 | 71 | The name of the controller to be created 72 | The module in which the controller should be created 73 | The root path of a ZF2 application where to create the controller 74 | 75 | ### Action creation: 76 | zf.php create action [] 77 | 78 | The name of the action to be created 79 | The name of the controller in which the action should be created 80 | The module containing the controller 81 | The root path of a ZF2 application where to create the action 82 | 83 | ### Application configuration 84 | 85 | zf.php config list list all configuration option 86 | zf.php config get display a single config value, i.e. "config get db.host" 87 | zf.php config set set a single config value (use only to change scalar values) 88 | 89 | ### Classmap generator 90 | 91 | zf.php classmap generate [--append|-a] [--overwrite|-w] 92 | 93 | The directory to scan for PHP classes (use "." to use current directory) 94 | File name for generated class map file or - for standard output. If not supplied, defaults to 95 | autoload_classmap.php inside . 96 | --append | -a Append to classmap file if it exists 97 | --overwrite | -w Whether or not to overwrite existing classmap file 98 | 99 | ### ZF library installation 100 | 101 | zf.php install zf [] 102 | 103 | The directory where to install the ZF2 library 104 | The version to install, if not specified uses the last available 105 | 106 | ### Compile the PHAR file 107 | 108 | You can create a .phar file containing the ZFTool project. In order to compile ZFTool in a .phar file you need 109 | to execute the following command: 110 | 111 | bin/create-phar 112 | 113 | This command will create a *zftool.phar* file in the bin folder. 114 | You can use and ship only this file to execute all the ZFTool functionalities. 115 | After the *zftool.phar* creation, we suggest to add the folder bin of ZFTool in your PATH environment. In this 116 | way you can execute the *zftool.phar* script wherever you are, for instance executing the command: 117 | 118 | mv zftool.phar /usr/local/bin/zftool.phar 119 | 120 | Note: If the above fails due to permissions, run the mv line again with sudo. 121 | 122 | 123 | ## Todo 124 | * Module maintenance (installation, configuration, removal etc.) [installation DONE] 125 | * Inspection of application configuration. [DONE] 126 | * Deploying zf2 skeleton applications. [DONE] 127 | * Reading and writing app configuration. [DONE] -------------------------------------------------------------------------------- /bin/.gitignore: -------------------------------------------------------------------------------- 1 | *.phar 2 | -------------------------------------------------------------------------------- /bin/create-phar: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | startBuffering(); 27 | 28 | // remove the first line in zf.php 29 | $phar->addFromString('zf.php', substr(php_strip_whitespace("$srcRoot/zf.php"), 19)); 30 | $phar->addFromString('Module.php', php_strip_whitespace("$srcRoot/Module.php")); 31 | 32 | addDir($phar, "$srcRoot/vendor", $srcRoot); 33 | addDir($phar, "$srcRoot/config", $srcRoot); 34 | addDir($phar, "$srcRoot/src", $srcRoot); 35 | addDir($phar, "$srcRoot/view", $srcRoot); 36 | 37 | $stub = <<setStub($stub); 54 | $phar->stopBuffering(); 55 | 56 | if (file_exists($pharPath)) { 57 | echo "Phar created successfully in $pharPath\n"; 58 | chmod($pharPath, 0755); 59 | } else { 60 | echo "Error during the compile of the Phar file $pharPath\n"; 61 | exit(2); 62 | } 63 | 64 | /** 65 | * Add a directory in phar removing whitespaces from PHP source code 66 | * 67 | * @param Phar $phar 68 | * @param string $sDir 69 | */ 70 | function addDir($phar, $sDir, $baseDir = null) { 71 | $oDir = new RecursiveIteratorIterator ( 72 | new RecursiveDirectoryIterator ($sDir), 73 | RecursiveIteratorIterator::SELF_FIRST 74 | ); 75 | 76 | foreach ($oDir as $sFile) { 77 | if (preg_match ('/\\.php$/i', $sFile)) { 78 | addFile($phar, $sFile, $baseDir); 79 | } 80 | } 81 | } 82 | 83 | /** 84 | * Add a file in phar removing whitespaces from the file 85 | * 86 | * @param Phar $phar 87 | * @param string $sFile 88 | */ 89 | function addFile($phar, $sFile, $baseDir = null) { 90 | if (null !== $baseDir) { 91 | $phar->addFromString(substr($sFile, strlen($baseDir) + 1), php_strip_whitespace($sFile)); 92 | } else { 93 | $phar->addFromString($sFile, php_strip_whitespace($sFile)); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "zendframework/zftool", 3 | "description": "Utility module for Zend Framework 2 applications.", 4 | "keywords": [ 5 | "zf2", 6 | "tool" 7 | ], 8 | "homepage": "http://framework.zend.com/", 9 | "license": "BSD-3-Clause", 10 | "repositories": [ 11 | { 12 | "type": "composer", 13 | "url": "https://packages.zendframework.com/" 14 | } 15 | ], 16 | "autoload": { 17 | "psr-0": { 18 | "ZFTool\\": "src/" 19 | } 20 | }, 21 | "require": { 22 | "php": ">=5.3.3", 23 | "zendframework/zenddiagnostics" : ">=1.0.0", 24 | "zendframework/zend-code": ">=2.2.2", 25 | "zendframework/zend-config": ">=2.2.2", 26 | "zendframework/zend-console": ">=2.2.2", 27 | "zendframework/zend-file": ">=2.2.2", 28 | "zendframework/zend-form": ">=2.2.2", 29 | "zendframework/zend-i18n": ">=2.2.2", 30 | "zendframework/zend-loader": ">=2.2.2", 31 | "zendframework/zend-log": ">=2.2.2", 32 | "zendframework/zend-modulemanager": ">=2.2.2", 33 | "zendframework/zend-mvc": ">=2.2.2", 34 | "zendframework/zend-serializer": ">=2.2.2", 35 | "zendframework/zend-servicemanager": ">=2.2.2", 36 | "zendframework/zend-stdlib": ">=2.2.2", 37 | "zendframework/zend-text": ">=2.2.2", 38 | "zendframework/zend-version": ">=2.2.2 ", 39 | "zendframework/zend-view": ">=2.2.2", 40 | "zendframework/zend-http": ">=2.2.2" 41 | }, 42 | "require-dev": { 43 | "fabpot/php-cs-fixer": "1.7.*", 44 | "phpunit/phpunit": "4.*" 45 | }, 46 | "bin": ["zf.php"] 47 | } 48 | -------------------------------------------------------------------------------- /config/module.config.php: -------------------------------------------------------------------------------- 1 | array( 4 | 'disable_usage' => false, // set to true to disable showing available ZFTool commands in Console. 5 | ), 6 | 7 | // -----=-----=-----=-----=-----=-----=-----=-----=-----=-----=-----=-----=-----=-----=-----=-----= 8 | 9 | 'controllers' => array( 10 | 'invokables' => array( 11 | 'ZFTool\Controller\Info' => 'ZFTool\Controller\InfoController', 12 | 'ZFTool\Controller\Config' => 'ZFTool\Controller\ConfigController', 13 | 'ZFTool\Controller\Module' => 'ZFTool\Controller\ModuleController', 14 | 'ZFTool\Controller\Classmap' => 'ZFTool\Controller\ClassmapController', 15 | 'ZFTool\Controller\Create' => 'ZFTool\Controller\CreateController', 16 | 'ZFTool\Controller\Install' => 'ZFTool\Controller\InstallController', 17 | 'ZFTool\Controller\Diagnostics' => 'ZFTool\Controller\DiagnosticsController', 18 | ), 19 | ), 20 | 21 | 'view_manager' => array( 22 | 'template_map' => array( 23 | 'zf-tool/diagnostics/run' => __DIR__ . '/../view/diagnostics/run.phtml', 24 | ) 25 | ), 26 | 27 | 'console' => array( 28 | 'router' => array( 29 | 'routes' => array( 30 | 'zftool-version' => array( 31 | 'options' => array( 32 | 'route' => 'version', 33 | 'defaults' => array( 34 | 'controller' => 'ZFTool\Controller\Info', 35 | 'action' => 'version', 36 | ), 37 | ), 38 | ), 39 | 'zftool-version2' => array( 40 | 'options' => array( 41 | 'route' => '--version', 42 | 'defaults' => array( 43 | 'controller' => 'ZFTool\Controller\Info', 44 | 'action' => 'version', 45 | ), 46 | ), 47 | ), 48 | 'zftool-config-list' => array( 49 | 'options' => array( 50 | 'route' => 'config list [--local|-l]:local', 51 | 'defaults' => array( 52 | 'controller' => 'ZFTool\Controller\Config', 53 | 'action' => 'list', 54 | ), 55 | ), 56 | ), 57 | 'zftool-config' => array( 58 | 'options' => array( 59 | 'route' => 'config [] []', 60 | 'defaults' => array( 61 | 'controller' => 'ZFTool\Controller\Config', 62 | 'action' => 'get', 63 | ), 64 | ), 65 | ), 66 | 'zftool-classmap-generate' => array( 67 | 'options' => array( 68 | 'route' => 'classmap generate [] [--append|-a] [--overwrite|-w]', 69 | 'defaults' => array( 70 | 'controller' => 'ZFTool\Controller\Classmap', 71 | 'action' => 'generate', 72 | ), 73 | ), 74 | ), 75 | 'zftool-modules-list' => array( 76 | 'options' => array( 77 | 'route' => 'modules [list]', 78 | 'defaults' => array( 79 | 'controller' => 'ZFTool\Controller\Module', 80 | 'action' => 'list', 81 | ), 82 | ), 83 | ), 84 | 'zftool-create-project' => array( 85 | 'options' => array( 86 | 'route' => 'create project ', 87 | 'defaults' => array( 88 | 'controller' => 'ZFTool\Controller\Create', 89 | 'action' => 'project', 90 | ), 91 | ), 92 | ), 93 | 'zftool-create-module' => array( 94 | 'options' => array( 95 | 'route' => 'create module []', 96 | 'defaults' => array( 97 | 'controller' => 'ZFTool\Controller\Create', 98 | 'action' => 'module', 99 | ), 100 | ), 101 | ), 102 | 'zftool-create-controller' => array( 103 | 'options' => array( 104 | 'route' => 'create controller []', 105 | 'defaults' => array( 106 | 'controller' => 'ZFTool\Controller\Create', 107 | 'action' => 'controller', 108 | ), 109 | ), 110 | ), 111 | 'zftool-create-action' => array( 112 | 'options' => array( 113 | 'route' => 'create action ', 114 | 'defaults' => array( 115 | 'controller' => 'ZFTool\Controller\Create', 116 | 'action' => 'method', 117 | ), 118 | ), 119 | ), 120 | 'zftool-install-zf' => array( 121 | 'options' => array( 122 | 'route' => 'install zf []', 123 | 'defaults' => array( 124 | 'controller' => 'ZFTool\Controller\Install', 125 | 'action' => 'zf', 126 | ), 127 | ), 128 | ), 129 | 'zftool-diagnostics' => array( 130 | 'options' => array( 131 | 'route' => '(diagnostics|diag) [-v|--verbose]:verbose [--debug] [-q|--quiet]:quiet [-b|--break]:break []', 132 | 'defaults' => array( 133 | 'controller' => 'ZFTool\Controller\Diagnostics', 134 | 'action' => 'run', 135 | ), 136 | ), 137 | ), 138 | ), 139 | ), 140 | ), 141 | 142 | 'diagnostics' => array( 143 | 'ZF' => array( 144 | 'PHP Version' => array('PhpVersion', '5.3.3'), 145 | ) 146 | ) 147 | ); 148 | -------------------------------------------------------------------------------- /config/zftool.global.php.dist: -------------------------------------------------------------------------------- 1 | array( 6 | 'routes' => array( 7 | 'zftool-diagnostics' => array( 8 | 'type' => 'Zend\Mvc\Router\Http\Literal', 9 | 'options' => array( 10 | 'route' => '/diagnostics', 11 | 'defaults' => array( 12 | 'controller' => 'ZFTool\Controller\Diagnostics', 13 | 'action' => 'run' 14 | ) 15 | ) 16 | ) 17 | ) 18 | ), 19 | */ 20 | 21 | ); -------------------------------------------------------------------------------- /docs/DIAGNOSTICS.md: -------------------------------------------------------------------------------- 1 | ZF2 Tool Diagnostics 2 | ========================== 3 | 4 | 1. [Available checks](#available-checks) 5 | 2. [Running diagnostics in console](#running-diagnostics-in-console) 6 | 3. [Running diagnostics in web browser](#running-diagnostics-in-web-browser) 7 | 4. [What is a check?](#what-is-a-check) 8 | 5. [Adding checks to your module](#adding-checks-to-your-module) 9 | 6. [Checks in config files](#checks-in-config-files) 10 | 7. [Using built-in diagnostics checks](#using-built-in-diagnostics-checks) 11 | 8. [Providing debug information in checks](#providing-debug-information-in-checks) 12 | 13 | ## Available checks 14 | 15 | * All checks from [ZendDiagnostics](https://github.com/zendframework/ZendDiagnostics#zenddiagnostics) 16 | 17 | ## Running diagnostics in console 18 | 19 | After installing ZF2 tool, you can run application diagnostics with the following console command: 20 | 21 | php public/index.php diag 22 | 23 | This will run the default set of diag checks and in case of trouble, display any errors or warnings. 24 | ![Running diag in console](img/simple-run.png) 25 | 26 | To display additional information on the checks performed, you can run diagnostics in verbose mode using 27 | `--verbose` or `-v` switches: 28 | 29 | php public/index.php diag -v 30 | 31 | ![Verbose mode diagnostics](img/verbose-run.png) 32 | 33 | Some checks will also produce debug information, which you can display with `--debug` switch: 34 | 35 | # Run diagnostics in "debug" mode 36 | php public/index.php diag --debug 37 | 38 | You could also specify which checks you want to run (which module to check): 39 | 40 | # Run only checks included in Application module 41 | php public/index.php diag Application 42 | 43 | 44 | ## Running diagnostics in web browser 45 | 46 | In order to enable diagnostics in browser, copy the included `config/zftool.global.php.dist` file to 47 | your `config/autoload/` directory and rename it to `zftool.global.php`. Now open the file and uncomment 48 | the `router => array()` section. The default URL for diagnostics is simply: 49 | 50 | http://yourwebsite/diagnostics 51 | 52 | You can always change it to anything you like by editing the above config file. 53 | 54 | ![Browser-based diagnostics](img/browser-run.png) 55 | 56 | 57 | 58 | ## What is a check? 59 | 60 | A check is simply: 61 | 62 | * Any function (anonymous, named, method), or 63 | * Any class implementing `ZFTool\Diagnostics\Check\CheckInterface` 64 | 65 | A check returns: 66 | 67 | * `true` which means check passed OK, 68 | * `false` which means check failed, 69 | * a `string` with warning message, 70 | * or instance of `ZFTool\Diagnostics\Result`, including Success, Failure, Warning. 71 | 72 | 73 | ## Adding checks to your module 74 | 75 | The simplest way to add checks is to write `getDiagnostics()` method in your module main class. For example, we could 76 | add the following checks to our `modules/Application/Module.php` file: 77 | 78 | ````php 79 | function(){ 92 | return function_exists('memcache_add'); 93 | }, 94 | 'Cache directory exists' => function() { 95 | return file_exists('data/cache') && is_dir('data/cache'); 96 | } 97 | ); 98 | } 99 | } 100 | ```` 101 | 102 | The returned array should contain pairs of a `label => check`. The label can be any string and will only be 103 | used as a description of the tested requirement. The `check` can be a callable, a function or a string, which 104 | will automatically be expanded. The following chapter describes all available methods of declaring checks. 105 | 106 | 107 | ## Checks in config files 108 | 109 | 110 | The second method is to define checks in config files which will be lazy-loaded as needed. Diagnostic 111 | component can understand the following types of definitions: 112 | 113 | ### Check function name 114 | 115 | The simplest form of a check is a "callable", a function or a method. Here are a few examples: 116 | 117 | ````php 118 | array( 122 | 123 | // "application" check group 124 | 'application' => array( 125 | // invoke static method Application\Module::checkEnvironment() 126 | 'Check environment' => array('Application\Module', 'checkEnvironment'), 127 | 128 | // invoke php built-in function with a parameter 129 | 'Check if public dir exists' => array('file_exists', 'public/'), 130 | 131 | // invoke a static method with 2 parameters 132 | 'Check paths' => array( 133 | array('Application\Module', 'checkPaths'), 134 | 'foo/', 135 | 'bar/' 136 | ) 137 | ) 138 | ) 139 | ); 140 | ```` 141 | 142 | ### Check class name 143 | 144 | Assuming we have written following check class: 145 | 146 | ````php 147 | array( 166 | 'application' => array( 167 | 'Verify that this system is 64bit' => 'Application\Check\is64bit' 168 | ) 169 | ) 170 | ); 171 | ```` 172 | 173 | It is also possible to provide constructor parameters for check instances, like so: 174 | 175 | ````php 176 | array( 190 | 'application' => array( 191 | // equivalent of constructing new EnvironmentTest("production", 15); 192 | 'Verify environment' => array( 193 | 'Application\Check\is64bit', 194 | 'production', 195 | 15 196 | ) 197 | ) 198 | ) 199 | ); 200 | ```` 201 | 202 | ### Check instance fetched from Service Manager 203 | 204 | If we define the check as a string, the diag component will attempt to fetch the check from 205 | Application Service Manager. For example, we could have the following check class: 206 | 207 | ````php 208 | getServiceLocator()->has('zfcuser'); 222 | } 223 | 224 | public function setServiceLocator(ServiceLocatorInterface $sl) 225 | { 226 | $this->sl = $sl; 227 | } 228 | 229 | public function getServiceLocator() 230 | { 231 | return $this->sl; 232 | } 233 | } 234 | ```` 235 | 236 | Now we just have to add proper definition to Service Manager and then diagnostics. 237 | 238 | 239 | ````php 240 | array( 244 | invokables' => array( 245 | 'CheckUserModuleTest' => 'Application\check\CheckUserModule', 246 | ), 247 | ), 248 | 249 | 'diagnostics' => array( 250 | 'application' => array( 251 | 'Check if user module is loaded' => 'CheckUserModuleTest' 252 | ) 253 | ) 254 | ); 255 | ```` 256 | 257 | 258 | ## Using built-in diagnostics checks 259 | 260 | ZFTool uses a bundle of general-purpose checks from 261 | [ZendDiagnostics](https://github.com/zendframework/ZendDiagnostics#zenddiagnostics) but also provides ZF2-specific 262 | classes. 263 | 264 | 265 | ## Providing debug information in checks 266 | 267 | A check function or class can return an instance of `Success`, `Failure` or `Warning` providing detailed information 268 | on the check performed and its result: 269 | 270 | ````php 271 | $success = new ZFTool\Diagnostics\Result\Success( $message, $debugData ) 272 | $failure = new ZFTool\Diagnostics\Result\Failure( $message, $debugData ) 273 | $warning = new ZFTool\Diagnostics\Result\Warning( $message, $debugData ) 274 | ```` 275 | 276 | Below is an example of a module-defined checks that return various responses: 277 | 278 | ````php 279 | function(){ 295 | if (!extension_loaded('mbstring')) { 296 | return new Failure( 297 | 'MB string is required for this module to work', 298 | get_loaded_extensions() 299 | ); 300 | } 301 | 302 | if (!extension_loaded('apc')) { 303 | return new Warning( 304 | 'APC extension is not loaded. It is highly recommended for performance.', 305 | get_loaded_extensions() 306 | ); 307 | } 308 | 309 | return new Success('Everything in order...'); 310 | } 311 | ); 312 | } 313 | } 314 | ```` 315 | 316 | -------------------------------------------------------------------------------- /docs/img/browser-run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zendframework/ZFTool/ecdae4929b3e60cd07b67d22901ec096d4fb7c12/docs/img/browser-run.png -------------------------------------------------------------------------------- /docs/img/simple-run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zendframework/ZFTool/ecdae4929b3e60cd07b67d22901ec096d4fb7c12/docs/img/simple-run.png -------------------------------------------------------------------------------- /docs/img/verbose-run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zendframework/ZFTool/ecdae4929b3e60cd07b67d22901ec096d4fb7c12/docs/img/verbose-run.png -------------------------------------------------------------------------------- /src/ZFTool/Controller/ClassmapController.php: -------------------------------------------------------------------------------- 1 | getRequest(); 18 | $console = $this->getServiceLocator()->get('console'); 19 | $relativePath = ''; 20 | $usingStdout = false; 21 | $directory = $request->getParam('directory'); 22 | $appending = $request->getParam('append', false) || $request->getParam('a', false); 23 | $overwrite = $request->getParam('overwrite', false) || $request->getParam('w', false); 24 | 25 | // Validate directory 26 | if (!is_dir($directory)) { 27 | $m = new ConsoleModel(); 28 | $m->setErrorLevel(2); 29 | $m->setResult('Invalid library directory provided "' . $directory . '"' . PHP_EOL); 30 | return $m; 31 | } 32 | 33 | $directory = realpath($directory); 34 | 35 | // Determine output file name 36 | $output = $request->getParam('destination', $directory . '/autoload_classmap.php'); 37 | if ('-' == $output) { 38 | $output = STDOUT; 39 | $usingStdout = true; 40 | } elseif (is_dir($output)) { 41 | $m = new ConsoleModel(); 42 | $m->setErrorLevel(2); 43 | $m->setResult('Invalid output file provided' . PHP_EOL); 44 | return $m; 45 | } elseif (!is_writeable(dirname($output))) { 46 | $m = new ConsoleModel(); 47 | $m->setErrorLevel(2); 48 | $m->setResult("Cannot write to '$output'; aborting." . PHP_EOL); 49 | return $m; 50 | } elseif (file_exists($output) && !$overwrite && !$appending) { 51 | $m = new ConsoleModel(); 52 | $m->setErrorLevel(2); 53 | $m->setResult( 54 | "Autoload file already exists at '$output'," . PHP_EOL 55 | . "but 'overwrite' or 'appending' flag was not specified; aborting." . PHP_EOL 56 | ); 57 | return $m; 58 | } else { 59 | // We need to add the $libraryPath into the relative path that is created in the classmap file. 60 | $classmapPath = str_replace(DIRECTORY_SEPARATOR, '/', realpath(dirname($output))); 61 | 62 | // Simple case: $libraryPathCompare is in $classmapPathCompare 63 | if (strpos($directory, $classmapPath) === 0) { 64 | if ($directory !== $classmapPath) { // prevent double dash in filepaths when using "." as directory 65 | $relativePath = substr($directory, strlen($classmapPath) + 1) . '/'; 66 | } 67 | } else { 68 | $libraryPathParts = explode('/', $directory); 69 | $classmapPathParts = explode('/', $classmapPath); 70 | 71 | // Find the common part 72 | $count = count($classmapPathParts); 73 | for ($i = 0; $i < $count; $i++) { 74 | if (!isset($libraryPathParts[$i]) || $libraryPathParts[$i] != $classmapPathParts[$i]) { 75 | // Common part end 76 | break; 77 | } 78 | } 79 | 80 | // Add parent dirs for the subdirs of classmap 81 | $relativePath = str_repeat('../', $count - $i); 82 | 83 | // Add library subdirs 84 | $count = count($libraryPathParts); 85 | for (; $i < $count; $i++) { 86 | $relativePath .= $libraryPathParts[$i] . '/'; 87 | } 88 | } 89 | } 90 | 91 | if (!$usingStdout) { 92 | if ($appending) { 93 | $console->write('Appending to class file map '); 94 | $console->write($output, Color::LIGHT_WHITE); 95 | $console->write(' for library in '); 96 | $console->writeLine($directory, Color::LIGHT_WHITE); 97 | } else { 98 | $console->write('Creating classmap file for library in '); 99 | $console->writeLine($directory, Color::LIGHT_WHITE); 100 | } 101 | $console->write('Scanning for files containing PHP classes '); 102 | } 103 | 104 | 105 | // Get the ClassFileLocator, and pass it the library path 106 | $l = new ClassFileLocator($directory); 107 | 108 | // Iterate over each element in the path, and create a map of 109 | // classname => filename, where the filename is relative to the library path 110 | $map = new \stdClass; 111 | $count = 0; 112 | foreach ($l as $file) { 113 | $filename = str_replace($directory . '/', '', str_replace(DIRECTORY_SEPARATOR, '/', $file->getPath()) . '/' . $file->getFilename()); 114 | 115 | // Add in relative path to library 116 | $filename = $relativePath . $filename; 117 | 118 | foreach ($file->getClasses() as $class) { 119 | $map->{$class} = $filename; 120 | } 121 | 122 | $count++; 123 | $console->write('.'); 124 | } 125 | 126 | if (!$usingStdout) { 127 | $console->writeLine(" DONE", Color::GREEN); 128 | $console->write('Found '); 129 | $console->write((int)$count, Color::LIGHT_WHITE); 130 | $console->writeLine(' PHP classes'); 131 | $console->write('Creating classmap code ...'); 132 | } 133 | 134 | // Check if we have found any PHP classes. 135 | if (!$count) { 136 | $console->writeLine('Cannot find any PHP classes in ' . $directory . '. Aborting!', Color::YELLOW); 137 | exit(1); 138 | } 139 | 140 | if ($appending) { 141 | $content = var_export((array)$map, true) . ';'; 142 | 143 | // Prefix with __DIR__; modify the generated content 144 | $content = preg_replace("#(=> ')#", "=> __DIR__ . '/", $content); 145 | 146 | // Fix \' strings from injected DIRECTORY_SEPARATOR usage in iterator_apply op 147 | $content = str_replace("\\'", "'", $content); 148 | 149 | // Convert to an array and remove the first "array(" 150 | $content = explode(PHP_EOL, $content); 151 | array_shift($content); 152 | 153 | // Load existing class map file and remove the closing "bracket ");" from it 154 | $existing = file($output, FILE_IGNORE_NEW_LINES); 155 | array_pop($existing); 156 | 157 | // Merge 158 | $content = implode(PHP_EOL, array_merge($existing, $content)); 159 | } else { 160 | // Create a file with the class/file map. 161 | // Stupid syntax highlighters make separating < from PHP declaration necessary 162 | $content = '<' . "?php\n" 163 | . "// Generated by Zend Framework 2\n" 164 | . 'return ' . var_export((array)$map, true) . ';'; 165 | 166 | // Prefix with __DIR__; modify the generated content 167 | $content = preg_replace("#(=> ')#", "=> __DIR__ . '/", $content); 168 | 169 | // Fix \' strings from injected DIRECTORY_SEPARATOR usage in iterator_apply op 170 | $content = str_replace("\\'", "'", $content); 171 | } 172 | 173 | // Remove unnecessary double-backslashes 174 | $content = str_replace('\\\\', '\\', $content); 175 | 176 | // Exchange "array (" width "array(" 177 | $content = str_replace('array (', 'array(', $content); 178 | 179 | // Align "=>" operators to match coding standard 180 | preg_match_all('(\n\s+([^=]+)=>)', $content, $matches, PREG_SET_ORDER); 181 | $maxWidth = 0; 182 | 183 | foreach ($matches as $match) { 184 | $maxWidth = max($maxWidth, strlen($match[1])); 185 | } 186 | 187 | $content = preg_replace_callback('(\n\s+([^=]+)=>)', function ($match) use ($maxWidth) { 188 | return "\n " . $match[1] . str_repeat(' ', $maxWidth - strlen($match[1])) . '=>'; 189 | }, $content); 190 | 191 | if (!$usingStdout) { 192 | $console->writeLine(" DONE" . PHP_EOL, Color::GREEN); 193 | $console->write('Writing classmap to '); 194 | $console->write($output, Color::LIGHT_WHITE); 195 | $console->write('... '); 196 | } 197 | 198 | // Write the contents to disk 199 | file_put_contents($output, $content); 200 | 201 | if (!$usingStdout) { 202 | $console->writeLine(" DONE", Color::GREEN); 203 | $console->writeLine('Wrote classmap to ' . realpath($output), Color::LIGHT_WHITE); 204 | } 205 | } 206 | } 207 | -------------------------------------------------------------------------------- /src/ZFTool/Controller/ConfigController.php: -------------------------------------------------------------------------------- 1 | getServiceLocator()->get('console'); 18 | $sm = $this->getServiceLocator(); 19 | 20 | $isLocal = $this->params()->fromRoute('local'); 21 | 22 | if ($isLocal) { 23 | $appdir = getcwd(); 24 | echo $appdir; 25 | if (file_exists($appdir . '/config/autoload/local.php')) { 26 | $config = include $appdir . '/config/autoload/local.php'; 27 | } else { 28 | echo 'FILE NO EXIST' . PHP_EOL; 29 | $config = array(); 30 | } 31 | } else { 32 | $config = $sm->get('Configuration'); 33 | } 34 | 35 | if (!is_array($config)) { 36 | $config = ArrayUtils::iteratorToArray($config, true); 37 | } 38 | 39 | $console->writeLine('Configuration:', Color::GREEN); 40 | // print_r($config); 41 | $ini = new IniWriter; 42 | echo $ini->toString($config); 43 | } 44 | 45 | public function getAction() 46 | { 47 | $console = $this->getServiceLocator()->get('console'); 48 | $sm = $this->getServiceLocator(); 49 | 50 | $name = $this->params()->fromRoute('arg1'); 51 | 52 | if (!$name) { 53 | $console->writeLine('config get was not provided', Color::RED); 54 | return; 55 | } 56 | 57 | $isLocal = $this->params()->fromRoute('local'); 58 | 59 | if ($isLocal) { 60 | $appdir = getcwd(); 61 | $configFile = new Config($appdir . '/config/autoload/local.php'); 62 | $configFile->read($name); 63 | } else { 64 | $config = $sm->get('Configuration'); 65 | echo $name; 66 | $value = Config::findValueInArray($name, $config); 67 | if (is_scalar($value)) { 68 | echo ' = ' . $value; 69 | } else { 70 | echo ':' . PHP_EOL; 71 | var_export($value); 72 | } 73 | echo PHP_EOL; 74 | } 75 | } 76 | 77 | public function setAction() 78 | { 79 | $console = $this->getServiceLocator()->get('console'); 80 | $sm = $this->getServiceLocator(); 81 | 82 | $name = $this->params()->fromRoute('arg1'); 83 | $value = $this->params()->fromRoute('arg2'); 84 | 85 | if ($value === 'null') { 86 | $value = null; 87 | } 88 | 89 | $appdir = getcwd(); 90 | $configPath = $appdir . '/config/autoload/local.php'; 91 | $configFile = new Config($configPath); 92 | $configFile->write($name, $value); 93 | 94 | echo 'Config file written at: ' . $configPath . PHP_EOL; 95 | } 96 | 97 | protected function getZF2Path() 98 | { 99 | if (getenv('ZF2_PATH')) { 100 | return getenv('ZF2_PATH'); 101 | } elseif (get_cfg_var('zf2_path')) { 102 | return get_cfg_var('zf2_path'); 103 | } elseif (is_dir('vendor/ZF2/library')) { 104 | return 'vendor/ZF2/library'; 105 | } elseif (is_dir('vendor/zendframework/zendframework/library')) { 106 | return 'vendor/zendframework/zendframework/library'; 107 | } elseif (is_dir('vendor/zendframework/zend-version')) { 108 | return 'vendor/zendframework/zend-version'; 109 | } 110 | return false; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/ZFTool/Controller/CreateController.php: -------------------------------------------------------------------------------- 1 | sendError('You need to install the ZIP extension of PHP'); 22 | } 23 | if (!extension_loaded('openssl')) { 24 | return $this->sendError('You need to install the OpenSSL extension of PHP'); 25 | } 26 | $console = $this->getServiceLocator()->get('console'); 27 | $tmpDir = sys_get_temp_dir(); 28 | $request = $this->getRequest(); 29 | $path = rtrim($request->getParam('path'), '/'); 30 | 31 | if (file_exists($path)) { 32 | return $this->sendError( 33 | "The directory $path already exists. You cannot create a ZF2 project here." 34 | ); 35 | } 36 | 37 | $commit = Skeleton::getLastCommit(); 38 | if (false === $commit) { // error on github connection 39 | $tmpFile = Skeleton::getLastZip($tmpDir); 40 | if (empty($tmpFile)) { 41 | return $this->sendError('I cannot access the API of github.'); 42 | } 43 | $console->writeLine( 44 | "Warning: I cannot connect to github, I will use the last download of ZF2 Skeleton.", 45 | Color::GRAY 46 | ); 47 | } else { 48 | $tmpFile = Skeleton::getTmpFileName($tmpDir, $commit); 49 | } 50 | 51 | if (!file_exists($tmpFile)) { 52 | if (!Skeleton::getSkeletonApp($tmpFile)) { 53 | return $this->sendError('I cannot access the ZF2 skeleton application in github.'); 54 | } 55 | } 56 | 57 | $zip = new \ZipArchive; 58 | if ($zip->open($tmpFile)) { 59 | $stateIndex0 = $zip->statIndex(0); 60 | $tmpSkeleton = $tmpDir . '/' . rtrim($stateIndex0['name'], "/"); 61 | if (!$zip->extractTo($tmpDir)) { 62 | return $this->sendError("Error during the unzip of $tmpFile."); 63 | } 64 | $result = Utility::copyFiles($tmpSkeleton, $path); 65 | if (file_exists($tmpSkeleton)) { 66 | Utility::deleteFolder($tmpSkeleton); 67 | } 68 | $zip->close(); 69 | if (false === $result) { 70 | return $this->sendError("Error during the copy of the files in $path."); 71 | } 72 | } 73 | if (file_exists("$path/composer.phar")) { 74 | exec("php $path/composer.phar self-update"); 75 | } else { 76 | if (!file_exists("$tmpDir/composer.phar")) { 77 | if (!file_exists("$tmpDir/composer_installer.php")) { 78 | file_put_contents( 79 | "$tmpDir/composer_installer.php", 80 | '?>' . file_get_contents('https://getcomposer.org/installer') 81 | ); 82 | } 83 | exec("php $tmpDir/composer_installer.php --install-dir $tmpDir"); 84 | } 85 | copy("$tmpDir/composer.phar", "$path/composer.phar"); 86 | } 87 | chmod("$path/composer.phar", 0755); 88 | $console->writeLine("ZF2 skeleton application installed in $path.", Color::GREEN); 89 | $console->writeLine("In order to execute the skeleton application you need to install the ZF2 library."); 90 | $console->writeLine("Execute: \"composer.phar install\" in $path"); 91 | $console->writeLine("For more info in $path/README.md"); 92 | } 93 | 94 | public function controllerAction() 95 | { 96 | $console = $this->getServiceLocator()->get('console'); 97 | $tmpDir = sys_get_temp_dir(); 98 | $request = $this->getRequest(); 99 | $name = $request->getParam('name'); 100 | $module = $request->getParam('module'); 101 | $path = $request->getParam('path', '.'); 102 | 103 | if (!file_exists("$path/module") || !file_exists("$path/config/application.config.php")) { 104 | return $this->sendError( 105 | "The path $path doesn't contain a ZF2 application. I cannot create a module here." 106 | ); 107 | } 108 | if (file_exists("$path/module/$module/src/$module/Controller/$name")) { 109 | return $this->sendError( 110 | "The controller $name already exists in module $module." 111 | ); 112 | } 113 | 114 | $ucName = ucfirst($name); 115 | $ctrlPath = $path . '/module/' . $module . '/src/' . $module . '/Controller/' . $ucName.'Controller.php'; 116 | $controller = $ucName . 'Controller'; 117 | 118 | $code = new Generator\ClassGenerator(); 119 | $code->setNamespaceName(ucfirst($module) . '\Controller') 120 | ->addUse('Zend\Mvc\Controller\AbstractActionController') 121 | ->addUse('Zend\View\Model\ViewModel'); 122 | 123 | $code->setName($controller) 124 | ->addMethods(array( 125 | new Generator\MethodGenerator( 126 | 'indexAction', 127 | array(), 128 | Generator\MethodGenerator::FLAG_PUBLIC, 129 | 'return new ViewModel();' 130 | ), 131 | )) 132 | ->setExtendedClass('AbstractActionController'); 133 | 134 | $file = new Generator\FileGenerator( 135 | array( 136 | 'classes' => array($code), 137 | ) 138 | ); 139 | 140 | $filter = new CamelCaseToDashFilter(); 141 | $viewfolder = strtolower($filter->filter($module)); 142 | 143 | $dir = $path . "/module/$module/view/$viewfolder/" . strtolower($filter->filter($name)); 144 | if (!file_exists($dir)) { 145 | mkdir($dir, 0777, true); 146 | } 147 | 148 | $phtml = false; 149 | $phtmlPath = $dir . "/index.phtml"; 150 | if (file_put_contents($phtmlPath, 'Action "index", controller "'.$ucName.'", module "'.$module.'".')) { 151 | $phtml = true; 152 | } 153 | 154 | if (file_put_contents($ctrlPath, $file->generate()) && $phtml == true) { 155 | $console->writeLine("The controller $name has been created in module $module.", Color::GREEN); 156 | } else { 157 | $console->writeLine("There was an error during controller creation.", Color::RED); 158 | } 159 | } 160 | 161 | public function methodAction() 162 | { 163 | $console = $this->getServiceLocator()->get('console'); 164 | $request = $this->getRequest(); 165 | $action = $request->getParam('name'); 166 | $controller = $request->getParam('controllerName'); 167 | $module = $request->getParam('module'); 168 | $path = $request->getParam('path', '.'); 169 | $ucController = ucfirst($controller); 170 | $controllerPath = sprintf('%s/module/%s/src/%s/Controller/%sController.php', $path, $module, $module, $ucController); 171 | $class = sprintf('%s\\Controller\\%sController', $module, $ucController); 172 | 173 | 174 | $console->writeLine("Creating action '$action' in controller '$module\\Controller\\$controller'.", Color::YELLOW); 175 | 176 | if (!file_exists("$path/module") || !file_exists("$path/config/application.config.php")) { 177 | return $this->sendError( 178 | "The path $path doesn't contain a ZF2 application. I cannot create a controller action." 179 | ); 180 | } 181 | if (!file_exists($controllerPath)) { 182 | return $this->sendError( 183 | "The controller $controller does not exists in module $module. I cannot create a controller action." 184 | ); 185 | } 186 | 187 | $fileReflection = new Reflection\FileReflection($controllerPath, true); 188 | $classReflection = $fileReflection->getClass($class); 189 | 190 | $classGenerator = Generator\ClassGenerator::fromReflection($classReflection); 191 | $classGenerator->addUse('Zend\Mvc\Controller\AbstractActionController') 192 | ->addUse('Zend\View\Model\ViewModel') 193 | ->setExtendedClass('AbstractActionController'); 194 | 195 | if ($classGenerator->hasMethod($action . 'Action')) { 196 | return $this->sendError( 197 | "The action $action already exists in controller $controller of module $module." 198 | ); 199 | } 200 | 201 | $classGenerator->addMethods(array( 202 | new Generator\MethodGenerator( 203 | $action . 'Action', 204 | array(), 205 | Generator\MethodGenerator::FLAG_PUBLIC, 206 | 'return new ViewModel();' 207 | ), 208 | )); 209 | 210 | $fileGenerator = new Generator\FileGenerator( 211 | array( 212 | 'classes' => array($classGenerator), 213 | ) 214 | ); 215 | 216 | $filter = new CamelCaseToDashFilter(); 217 | $phtmlPath = sprintf( 218 | '%s/module/%s/view/%s/%s/%s.phtml', 219 | $path, 220 | $module, 221 | strtolower($filter->filter($module)), 222 | strtolower($filter->filter($controller)), 223 | strtolower($filter->filter($action)) 224 | ); 225 | if (!file_exists($phtmlPath)) { 226 | $contents = sprintf("Module: %s\nController: %s\nAction: %s", $module, $controller, $action); 227 | if (file_put_contents($phtmlPath, $contents)) { 228 | $console->writeLine(sprintf("Created view script at %s", $phtmlPath), Color::GREEN); 229 | } else { 230 | $console->writeLine(sprintf("An error occurred when attempting to create view script at location %s", $phtmlPath), Color::RED); 231 | } 232 | } 233 | 234 | if (file_put_contents($controllerPath, $fileGenerator->generate())) { 235 | $console->writeLine(sprintf('The action %s has been created in controller %s\\Controller\\%s.', $action, $module, $controller), Color::GREEN); 236 | } else { 237 | $console->writeLine("There was an error during action creation.", Color::RED); 238 | } 239 | } 240 | 241 | public function moduleAction() 242 | { 243 | $console = $this->getServiceLocator()->get('console'); 244 | $tmpDir = sys_get_temp_dir(); 245 | $request = $this->getRequest(); 246 | $name = $request->getParam('name'); 247 | $path = rtrim($request->getParam('path'), '/'); 248 | 249 | if (empty($path)) { 250 | $path = '.'; 251 | } 252 | 253 | if (!file_exists("$path/module") || !file_exists("$path/config/application.config.php")) { 254 | return $this->sendError( 255 | "The path $path doesn't contain a ZF2 application. I cannot create a module here." 256 | ); 257 | } 258 | if (file_exists("$path/module/$name")) { 259 | return $this->sendError( 260 | "The module $name already exists." 261 | ); 262 | } 263 | 264 | $filter = new CamelCaseToDashFilter(); 265 | $viewfolder = strtolower($filter->filter($name)); 266 | 267 | $name = ucfirst($name); 268 | mkdir("$path/module/$name/config", 0777, true); 269 | mkdir("$path/module/$name/src/$name/Controller", 0777, true); 270 | mkdir("$path/module/$name/view/$viewfolder", 0777, true); 271 | 272 | // Create the Module.php 273 | file_put_contents("$path/module/$name/Module.php", Skeleton::getModule($name)); 274 | 275 | // Create the module.config.php 276 | file_put_contents("$path/module/$name/config/module.config.php", Skeleton::getModuleConfig($name)); 277 | 278 | // Add the module in application.config.php 279 | $application = require "$path/config/application.config.php"; 280 | if (!in_array($name, $application['modules'])) { 281 | $application['modules'][] = $name; 282 | copy("$path/config/application.config.php", "$path/config/application.config.old"); 283 | $content = <<writeLine("The module $name has been created", Color::GREEN); 299 | } else { 300 | $console->writeLine("The module $name has been created in $path", Color::GREEN); 301 | } 302 | } 303 | 304 | /** 305 | * Send an error message to the console 306 | * 307 | * @param string $msg 308 | * @return ConsoleModel 309 | */ 310 | protected function sendError($msg) 311 | { 312 | $m = new ConsoleModel(); 313 | $m->setErrorLevel(2); 314 | $m->setResult($msg . PHP_EOL); 315 | return $m; 316 | } 317 | } 318 | -------------------------------------------------------------------------------- /src/ZFTool/Controller/DiagnosticsController.php: -------------------------------------------------------------------------------- 1 | getServiceLocator(); 42 | /* @var $console AdapterInterface */ 43 | /* @var $config array */ 44 | /* @var $mm ModuleManager */ 45 | $console = $sm->get('console'); 46 | $config = $sm->get('Configuration'); 47 | $mm = $sm->get('ModuleManager'); 48 | 49 | $verbose = $this->params()->fromRoute('verbose', false); 50 | $debug = $this->params()->fromRoute('debug', false); 51 | $quiet = !$verbose && !$debug && $this->params()->fromRoute('quiet', false); 52 | $breakOnFailure = $this->params()->fromRoute('break', false); 53 | $checkGroupName = $this->params()->fromRoute('filter', false); 54 | 55 | // Get basic diag configuration 56 | $config = isset($config['diagnostics']) ? $config['diagnostics'] : array(); 57 | 58 | // Collect diag tests from modules 59 | $modules = $mm->getLoadedModules(false); 60 | foreach ($modules as $moduleName => $module) { 61 | if (is_callable(array($module, 'getDiagnostics'))) { 62 | $checks = $module->getDiagnostics(); 63 | if (is_array($checks)) { 64 | $config[$moduleName] = $checks; 65 | } 66 | 67 | // Exit the loop early if we found check definitions for 68 | // the only check group that we want to run. 69 | if ($checkGroupName && $moduleName == $checkGroupName) { 70 | break; 71 | } 72 | } 73 | } 74 | 75 | // Filter array if a check group name has been provided 76 | if ($checkGroupName) { 77 | $config = array_intersect_ukey($config, array($checkGroupName => 1), 'strcasecmp'); 78 | 79 | if (empty($config)) { 80 | $m = new ConsoleModel(); 81 | $m->setResult($console->colorize(sprintf( 82 | "Unable to find a group of diagnostic checks called \"%s\". Try to use module name (i.e. \"%s\").\n", 83 | $checkGroupName, 84 | 'Application' 85 | ), ColorInterface::YELLOW)); 86 | $m->setErrorLevel(1); 87 | 88 | return $m; 89 | } 90 | } 91 | 92 | // Check if there are any diagnostic checks defined 93 | if (empty($config)) { 94 | $m = new ConsoleModel(); 95 | $m->setResult( 96 | $console->colorize( 97 | "There are no diagnostic checks currently enabled for this application - please add one or more " . 98 | "entries into config \"diagnostics\" array or add getDiagnostics() method to your Module class. " . 99 | "\n\nMore info: https://github.com/zendframework/ZFTool/blob/master/docs/" . 100 | "DIAGNOSTICS.md#adding-checks-to-your-module\n", ColorInterface::YELLOW) 101 | ); 102 | $m->setErrorLevel(1); 103 | 104 | return $m; 105 | } 106 | 107 | // Analyze check definitions and construct check instances 108 | $checkCollection = array(); 109 | foreach ($config as $checkGroupName => $checks) { 110 | foreach ($checks as $checkLabel => $check) { 111 | // Do not use numeric labels. 112 | if (!$checkLabel || is_numeric($checkLabel)) { 113 | $checkLabel = false; 114 | } 115 | 116 | // Handle a callable. 117 | if (is_callable($check)) { 118 | $check = new Callback($check); 119 | if ($checkLabel) { 120 | $check->setLabel($checkGroupName . ': ' . $checkLabel); 121 | } 122 | 123 | $checkCollection[] = $check; 124 | continue; 125 | } 126 | 127 | // Handle check object instance. 128 | if (is_object($check)) { 129 | if (!$check instanceof CheckInterface) { 130 | throw new RuntimeException( 131 | 'Cannot use object of class "' . get_class($check). '" as check. '. 132 | 'Expected instance of ZendDiagnostics\Check\CheckInterface' 133 | ); 134 | } 135 | 136 | // Use duck-typing for determining if the check allows for setting custom label 137 | if ($checkLabel && is_callable(array($check, 'setLabel'))) { 138 | $check->setLabel($checkGroupName . ': ' . $checkLabel); 139 | } 140 | $checkCollection[] = $check; 141 | continue; 142 | } 143 | 144 | // Handle an array containing callback or identifier with optional parameters. 145 | if (is_array($check)) { 146 | if (!count($check)) { 147 | throw new RuntimeException( 148 | 'Cannot use an empty array() as check definition in "'.$checkGroupName.'"' 149 | ); 150 | } 151 | 152 | // extract check identifier and store the remainder of array as parameters 153 | $testName = array_shift($check); 154 | $params = $check; 155 | } elseif (is_scalar($check)) { 156 | $testName = $check; 157 | $params = array(); 158 | } else { 159 | throw new RuntimeException( 160 | 'Cannot understand diagnostic check definition "' . gettype($check). '" in "'.$checkGroupName.'"' 161 | ); 162 | } 163 | 164 | // Try to expand check identifier using Service Locator 165 | if (is_string($testName) && $sm->has($testName)) { 166 | $check = $sm->get($testName); 167 | 168 | // Try to use the ZendDiagnostics namespace 169 | } elseif (is_string($testName) && class_exists('ZendDiagnostics\\Check\\' . $testName)) { 170 | $class = new \ReflectionClass('ZendDiagnostics\\Check\\' . $testName); 171 | $check = $class->newInstanceArgs($params); 172 | 173 | // Try to use the ZFTool namespace 174 | } elseif (is_string($testName) && class_exists('ZFTool\\Diagnostics\\Check\\' . $testName)) { 175 | $class = new \ReflectionClass('ZFTool\\Diagnostics\\Check\\' . $testName); 176 | $check = $class->newInstanceArgs($params); 177 | 178 | // Check if provided with a callable inside an array 179 | } elseif (is_callable($testName)) { 180 | $check = new Callback($testName, $params); 181 | if ($checkLabel) { 182 | $check->setLabel($checkGroupName . ': ' . $checkLabel); 183 | } 184 | 185 | $checkCollection[] = $check; 186 | continue; 187 | 188 | // Try to expand check using class name 189 | } elseif (is_string($testName) && class_exists($testName)) { 190 | $class = new \ReflectionClass($testName); 191 | $check = $class->newInstanceArgs($params); 192 | } else { 193 | throw new RuntimeException( 194 | 'Cannot find check class or service with the name of "' . $testName . '" ('.$checkGroupName.')' 195 | ); 196 | } 197 | 198 | if (!$check instanceof CheckInterface) { 199 | // not a real check 200 | throw new RuntimeException( 201 | 'The check object of class '.get_class($check).' does not implement '. 202 | 'ZendDiagnostics\Check\CheckInterface' 203 | ); 204 | } 205 | 206 | // Use duck-typing for determining if the check allows for setting custom label 207 | if ($checkLabel && is_callable(array($check, 'setLabel'))) { 208 | $check->setLabel($checkGroupName . ': ' . $checkLabel); 209 | } 210 | 211 | $checkCollection[] = $check; 212 | } 213 | } 214 | 215 | // Configure check runner 216 | $runner = new Runner(); 217 | $runner->addChecks($checkCollection); 218 | $runner->getConfig()->setBreakOnFailure($breakOnFailure); 219 | 220 | if (!$quiet && $this->getRequest() instanceof ConsoleRequest) { 221 | if ($verbose || $debug) { 222 | $runner->addReporter(new VerboseConsole($console, $debug)); 223 | } else { 224 | $runner->addReporter(new BasicConsole($console)); 225 | } 226 | } 227 | 228 | // Run tests 229 | $results = $runner->run(); 230 | 231 | $request = $this->getRequest(); 232 | 233 | // Return result 234 | if ($request instanceof ConsoleRequest) { 235 | return $this->processConsoleRequest($results); 236 | } 237 | 238 | if ($request instanceof Request) { 239 | return $this->processHttpRequest($request, $results); 240 | } 241 | } 242 | 243 | private function processConsoleRequest(Collection $results) 244 | { 245 | // Return appropriate error code in console 246 | $model = new ConsoleModel(array('results' => $results)); 247 | 248 | if ($results->getFailureCount() > 0) { 249 | $model->setErrorLevel(1); 250 | } else { 251 | $model->setErrorLevel(0); 252 | } 253 | return $model; 254 | } 255 | 256 | private function processHttpRequest(Request $request, Collection $results) 257 | { 258 | $defaultAccept = new Accept(); 259 | $defaultAccept->addMediaType(self::CONTENT_TYPE_HTML); 260 | 261 | $acceptHeader = $request->getHeader('Accept', $defaultAccept); 262 | 263 | if ($acceptHeader->match(self::CONTENT_TYPE_HTML) || !$acceptHeader->match(self::CONTENT_TYPE_JSON)) { 264 | // Display results as a web page 265 | return new ViewModel(array('results' => $results)); 266 | } 267 | return new JsonModel($this->getResultCollectionToArray($results)); 268 | } 269 | 270 | /** 271 | * @param ResultInterface $result 272 | * @return string 273 | */ 274 | protected function getResultName(ResultInterface $result) 275 | { 276 | switch (true) { 277 | case $result instanceof SuccessInterface: 278 | return self::RESULT_SUCCESS; 279 | case $result instanceof WarningInterface: 280 | return self::RESULT_WARNING; 281 | case $result instanceof FailureInterface: 282 | return self::RESULT_FAILURE; 283 | case $result instanceof SkipInterface: 284 | return self::RESULT_SKIP; 285 | default: 286 | return self::RESULT_UNKNOWN; 287 | } 288 | } 289 | 290 | /** 291 | * @param Collection $results 292 | * @return array 293 | */ 294 | protected function getResultCollectionToArray(Collection $results) 295 | { 296 | foreach ($results as $item) { 297 | $result = $results[$item]; 298 | $data[$item->getLabel()] = array( 299 | 'result' => $this->getResultName($result), 300 | 'message' => $result->getMessage(), 301 | 'data' => $result->getData(), 302 | ); 303 | } 304 | 305 | return array( 306 | 'details' => $data, 307 | 'success' => $results->getSuccessCount(), 308 | 'warning' => $results->getWarningCount(), 309 | 'failure' => $results->getFailureCount(), 310 | 'skip' => $results->getSkipCount(), 311 | 'unknown' => $results->getUnknownCount(), 312 | 'passed' => $results->getFailureCount() === 0, 313 | ); 314 | } 315 | } 316 | -------------------------------------------------------------------------------- /src/ZFTool/Controller/InfoController.php: -------------------------------------------------------------------------------- 1 | getServiceLocator()->get('console'); 17 | 18 | $zf2Path = $this->getZF2Path(); 19 | if (file_exists($zf2Path . '/Zend/Version/Version.php')) { 20 | require_once $zf2Path . '/Zend/Version/Version.php'; 21 | $msg = 'The application in this folder is using Zend Framework '; 22 | } else { 23 | $msg = 'The ZFTool is using Zend Framework '; 24 | } 25 | 26 | $console->writeLine(Module::NAME, Color::GREEN); 27 | $console->writeLine($msg . Version::VERSION); 28 | } 29 | 30 | public function configAction() 31 | { 32 | $console = $this->getServiceLocator()->get('console'); 33 | 34 | $sm = $this->getServiceLocator(); 35 | $config = $sm->get('Configuration'); 36 | 37 | if (!is_array($config)) { 38 | $config = ArrayUtils::iteratorToArray($config, true); 39 | } 40 | $console->writeLine('Configuration:', Color::GREEN); 41 | print_r($config); 42 | } 43 | 44 | protected function getZF2Path() 45 | { 46 | if (getenv('ZF2_PATH')) { 47 | return getenv('ZF2_PATH'); 48 | } elseif (get_cfg_var('zf2_path')) { 49 | return get_cfg_var('zf2_path'); 50 | } elseif (is_dir('vendor/ZF2/library')) { 51 | return 'vendor/ZF2/library'; 52 | } elseif (is_dir('vendor/zendframework/zendframework/library')) { 53 | return 'vendor/zendframework/zendframework/library'; 54 | } elseif (is_dir('vendor/zendframework/zend-version')) { 55 | return 'vendor/zendframework/zend-version'; 56 | } 57 | return false; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/ZFTool/Controller/InstallController.php: -------------------------------------------------------------------------------- 1 | sendError('You need to install the ZIP extension of PHP'); 18 | } 19 | $console = $this->getServiceLocator()->get('console'); 20 | $tmpDir = sys_get_temp_dir(); 21 | $request = $this->getRequest(); 22 | $version = $request->getParam('version'); 23 | $path = rtrim($request->getParam('path'), '/'); 24 | 25 | if (file_exists($path)) { 26 | return $this->sendError( 27 | "The directory $path already exists. You cannot install the ZF2 library here." 28 | ); 29 | } 30 | 31 | if (empty($version)) { 32 | $version = Zf::getLastVersion(); 33 | if (false === $version) { 34 | return $this->sendError( 35 | "I cannot connect to the Zend Framework website." 36 | ); 37 | } 38 | } else { 39 | if (!Zf::checkVersion($version)) { 40 | return $this->sendError( 41 | "The specified ZF version, $version, doesn't exist." 42 | ); 43 | } 44 | } 45 | 46 | $tmpFile = ZF::getTmpFileName($tmpDir, $version); 47 | if (!file_exists($tmpFile)) { 48 | if (!Zf::downloadZip($tmpFile, $version)) { 49 | return $this->sendError( 50 | "I cannot download the ZF2 library from github." 51 | ); 52 | } 53 | } 54 | 55 | $zip = new \ZipArchive; 56 | if ($zip->open($tmpFile)) { 57 | $zipFolders = $zip->statIndex(0); 58 | $zipFolder = $tmpDir . '/' . rtrim($zipFolders['name'], "/"); 59 | if (!$zip->extractTo($tmpDir)) { 60 | return $this->sendError("Error during the unzip of $tmpFile."); 61 | } 62 | 63 | $result = Utility::copyFiles($zipFolder, $path); 64 | if (file_exists($zipFolder)) { 65 | Utility::deleteFolder($zipFolder); 66 | } 67 | $zip->close(); 68 | if (false === $result) { 69 | return $this->sendError("Error during the copy of the files in $path."); 70 | } 71 | } 72 | 73 | $console->writeLine("The ZF library $version has been installed in $path.", Color::GREEN); 74 | } 75 | 76 | /** 77 | * Send an error message to the console 78 | * 79 | * @param string $msg 80 | * @return ConsoleModel 81 | */ 82 | protected function sendError($msg) 83 | { 84 | $m = new ConsoleModel(); 85 | $m->setErrorLevel(2); 86 | $m->setResult($msg . PHP_EOL); 87 | return $m; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/ZFTool/Controller/ModuleController.php: -------------------------------------------------------------------------------- 1 | getServiceLocator()->get('console'); 14 | $modules = $this->getModulesFromService(); 15 | if (empty($modules)) { 16 | $console->writeLine('No modules installed. Are you in the root folder of a ZF2 app?'); 17 | return; 18 | } 19 | $modules = array_diff($modules, array('ZFTool')); 20 | 21 | $console->writeLine("Modules installed:"); 22 | foreach ($modules as $module) { 23 | $console->writeLine($module, Color::GREEN); 24 | } 25 | } 26 | 27 | private function sendError($msg) 28 | { 29 | $m = new ConsoleModel(); 30 | $m->setErrorLevel(2); 31 | $m->setResult($msg . PHP_EOL); 32 | return $m; 33 | } 34 | 35 | protected function getModulesFromService() 36 | { 37 | $sm = $this->getServiceLocator(); 38 | try { 39 | /* @var $mm \Zend\ModuleManager\ModuleManager */ 40 | $mm = $sm->get('modulemanager'); 41 | } catch (ServiceNotFoundException $e) { 42 | return $this->sendError( 43 | 'Cannot get Zend\ModuleManager\ModuleManager instance. Is your application using it?' 44 | ); 45 | } 46 | $modules = array_keys($mm->getLoadedModules(false)); 47 | 48 | return $modules; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/ZFTool/Diagnostics/Config.php: -------------------------------------------------------------------------------- 1 | breakOnFailure = $breakOnFailure; 29 | } 30 | 31 | /** 32 | * @return boolean 33 | */ 34 | public function getBreakOnFailure() 35 | { 36 | return $this->breakOnFailure; 37 | } 38 | 39 | /** 40 | * Set severity of error that will result in a check failing. Defaults to: 41 | * E_WARNING|E_PARSE|E_USER_ERROR|E_USER_WARNING|E_RECOVERABLE_ERROR 42 | * 43 | * @param int $catchErrorSeverity 44 | */ 45 | public function setCatchErrorSeverity($catchErrorSeverity) 46 | { 47 | $this->catchErrorSeverity = (int) $catchErrorSeverity; 48 | } 49 | 50 | /** 51 | * Get current severity of error that will result in a check failing. 52 | * 53 | * @return int 54 | */ 55 | public function getCatchErrorSeverity() 56 | { 57 | return $this->catchErrorSeverity; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/ZFTool/Diagnostics/ConfigInterface.php: -------------------------------------------------------------------------------- 1 | console = $console; 39 | } 40 | 41 | /** 42 | * This method is called right after Reporter starts running, via Runner::run() 43 | * 44 | * @param ArrayObject $checks 45 | * @param array $runnerConfig 46 | * @return void 47 | */ 48 | public function onStart(ArrayObject $checks, $runnerConfig) 49 | { 50 | $this->stopped = false; 51 | $this->width = $this->console->getWidth(); 52 | $this->total = $checks->count(); 53 | 54 | // Calculate gutter width to accommodate number of checks passed 55 | if ($this->total <= $this->width) { 56 | $this->gutter = 0; // everything fits well 57 | } else { 58 | $this->countLength = floor(log10($this->total)) + 1; 59 | $this->gutter = ($this->countLength * 2) + 11; 60 | } 61 | 62 | $this->console->writeLine('Starting diagnostics:'); 63 | $this->console->writeLine(''); 64 | } 65 | 66 | /** 67 | * This method is called before each individual Check is performed. If this 68 | * method returns false, the Check will not be performed (will be skipped). 69 | * 70 | * @param CheckInterface $check Check instance that is about to be performed. 71 | * @param bool $alias The alias being targeted by the check 72 | * @return bool|void Return false to prevent check from happening 73 | */ 74 | public function onBeforeRun(CheckInterface $check, $alias = null) 75 | { 76 | } 77 | 78 | /** 79 | * This method is called every time a Check has been performed. 80 | * 81 | * @param CheckInterface $check A Check instance that has just finished running 82 | * @param ResultInterface $result Result for that particular check instance 83 | * @param bool $alias The alias being targeted by the check 84 | * @return bool|void Return false to prevent from running additional Checks 85 | */ 86 | public function onAfterRun(CheckInterface $check, ResultInterface $result, $alias = null) 87 | { 88 | // Draw a symbol 89 | if ($result instanceof Success) { 90 | $this->console->write('.', Color::GREEN); 91 | } elseif ($result instanceof Failure) { 92 | $this->console->write('F', Color::WHITE, Color::RED); 93 | } elseif ($result instanceof Warning) { 94 | $this->console->write('!', Color::YELLOW); 95 | } elseif ($result instanceof Skip) { 96 | $this->console->write('S', Color::YELLOW); 97 | } else { 98 | $this->console->write('?', Color::YELLOW); 99 | } 100 | 101 | $this->pos++; 102 | 103 | // Check if we need to move to the next line 104 | if ($this->gutter > 0 && $this->pos > $this->width - $this->gutter) { 105 | $this->console->write( 106 | str_pad( 107 | str_pad($this->iter, $this->countLength, ' ', STR_PAD_LEFT) . ' / ' . $this->total . 108 | ' (' . str_pad(round($this->iter / $this->total * 100), 3, ' ', STR_PAD_LEFT) . '%)', $this->gutter, ' ', STR_PAD_LEFT 109 | ) 110 | ); 111 | $this->pos = 1; 112 | } 113 | 114 | $this->iter++; 115 | } 116 | 117 | /** 118 | * This method is called when Runner has been aborted and could not finish the 119 | * whole run(). 120 | * 121 | * @param ResultsCollection $results Collection of Results for performed Checks. 122 | * @return void 123 | */ 124 | public function onStop(ResultsCollection $results) 125 | { 126 | $this->stopped = true; 127 | } 128 | 129 | /** 130 | * This method is called when Runner has finished its run. 131 | * 132 | * @param ResultsCollection $results Collection of Results for performed Checks. 133 | * @return void 134 | */ 135 | public function onFinish(ResultsCollection $results) 136 | { 137 | /* @var $results \ZendDiagnostics\Result\Collection */ 138 | $this->console->writeLine(); 139 | $this->console->writeLine(); 140 | 141 | // Display a summary line 142 | if ( 143 | $results->getFailureCount() == 0 && 144 | $results->getWarningCount() == 0 && 145 | $results->getUnknownCount() == 0 && 146 | $results->getSkipCount() == 0 147 | ) { 148 | $line = 'OK (' . $this->total . ' diagnostic checks)'; 149 | $this->console->writeLine( 150 | str_pad($line, $this->width-1, ' ', STR_PAD_RIGHT), 151 | Color::NORMAL, Color::GREEN 152 | ); 153 | } elseif ($results->getFailureCount() == 0) { 154 | $line = $results->getWarningCount() . ' warnings'; 155 | 156 | if ($results->getSkipCount() > 0) { 157 | $line .= ', ' . $results->getSkipCount() . ' skipped checks'; 158 | } 159 | 160 | if ($results->getUnknownCount() > 0) { 161 | $line .= ', ' . $results->getUnknownCount() . ' unknown check results'; 162 | } 163 | 164 | $line .= ', ' . $results->getSuccessCount() . ' successful checks'; 165 | 166 | $line .= '.'; 167 | 168 | $this->console->writeLine( 169 | str_pad($line, $this->width-1, ' ', STR_PAD_RIGHT), 170 | Color::NORMAL, Color::YELLOW 171 | ); 172 | } else { 173 | $line = $results->getFailureCount() . ' failures, '; 174 | $line .= $results->getWarningCount() . ' warnings'; 175 | 176 | if ($results->getSkipCount() > 0) { 177 | $line .= ', ' . $results->getSkipCount() . ' skipped checks'; 178 | } 179 | 180 | if ($results->getUnknownCount() > 0) { 181 | $line .= ', ' . $results->getUnknownCount() . ' unknown check results'; 182 | } 183 | 184 | $line .= ', ' . $results->getSuccessCount() . ' successful checks'; 185 | 186 | $line .= '.'; 187 | 188 | $this->console->writeLine( 189 | str_pad($line, $this->width, ' ', STR_PAD_RIGHT), 190 | Color::NORMAL, Color::RED 191 | ); 192 | } 193 | 194 | $this->console->writeLine(); 195 | 196 | // Display a list of failures and warnings 197 | foreach ($results as $check) { 198 | /* @var $check CheckInterface */ 199 | /* @var $result ResultInterface */ 200 | $result = $results[$check]; 201 | 202 | if ($result instanceof Failure) { 203 | $this->console->writeLine('Failure: ' . $check->getLabel(), Color::RED); 204 | $message = $result->getMessage(); 205 | if ($message) { 206 | $this->console->writeLine($message, Color::RED); 207 | } 208 | $this->console->writeLine(); 209 | } elseif ($result instanceof Warning) { 210 | $this->console->writeLine('Warning: ' . $check->getLabel(), Color::YELLOW); 211 | $message = $result->getMessage(); 212 | if ($message) { 213 | $this->console->writeLine($message, Color::YELLOW); 214 | } 215 | $this->console->writeLine(); 216 | } elseif ($result instanceof Skip) { 217 | $this->console->writeLine('Skipped: ' . $check->getLabel(), Color::YELLOW); 218 | $message = $result->getMessage(); 219 | if ($message) { 220 | $this->console->writeLine($message, Color::YELLOW); 221 | } 222 | $this->console->writeLine(); 223 | } elseif (!$result instanceof Success) { 224 | $this->console->writeLine('Unknown result ' . get_class($result) . ': ' . $check->getLabel(), Color::YELLOW); 225 | $message = $result->getMessage(); 226 | if ($message) { 227 | $this->console->writeLine($message, Color::YELLOW); 228 | } 229 | $this->console->writeLine(); 230 | } 231 | } 232 | 233 | // Display information that the check has been aborted. 234 | if ($this->stopped) { 235 | $this->console->writeLine('Diagnostics aborted because of a failure.', Color::RED); 236 | } 237 | } 238 | 239 | /** 240 | * Set Console adapter to use. 241 | * 242 | * @param Console $console 243 | */ 244 | public function setConsole($console) 245 | { 246 | $this->console = $console; 247 | 248 | // Update width 249 | $this->width = $console->getWidth(); 250 | } 251 | 252 | /** 253 | * Get currently used Console adapter 254 | * @return Console 255 | */ 256 | public function getConsole() 257 | { 258 | return $this->console; 259 | } 260 | } 261 | -------------------------------------------------------------------------------- /src/ZFTool/Diagnostics/Reporter/VerboseConsole.php: -------------------------------------------------------------------------------- 1 | console = $console; 70 | $this->stringUtils = StringUtils::getWrapper(); 71 | $this->displayData = $displayData; 72 | } 73 | 74 | /** 75 | * This method is called right after Reporter starts running, via Runner::run() 76 | * 77 | * @param ArrayObject $checks A collection of Checks that will be performed 78 | * @param array $runnerConfig Complete Runner configuration, obtained via Runner::getConfig() 79 | * @return void 80 | */ 81 | public function onStart(ArrayObject $checks, $runnerConfig) 82 | { 83 | $this->stopped = false; 84 | $this->width = $this->console->getWidth(); 85 | $this->total = $checks->count(); 86 | 87 | $this->console->writeLine('Starting diagnostics:'); 88 | } 89 | 90 | /** 91 | * This method is called before each individual Check is performed. If this 92 | * method returns false, the Check will not be performed (will be skipped). 93 | * 94 | * @param CheckInterface $check Check instance that is about to be performed. 95 | * @param bool $alias The alias being targeted by the check 96 | * @return bool|void Return false to prevent check from happening 97 | */ 98 | public function onBeforeRun(CheckInterface $check, $alias = null) 99 | { 100 | } 101 | 102 | /** 103 | * This method is called every time a Check has been performed. If this method 104 | * returns false, the Runner will not perform any additional checks and stop 105 | * its run. 106 | * 107 | * @param CheckInterface $check A Check instance that has just finished running 108 | * @param ResultInterface $result Result for that particular check instance 109 | * @param bool $alias The alias being targeted by the check 110 | * @return bool|void Return false to prevent from running additional Checks 111 | */ 112 | public function onAfterRun(CheckInterface $check, ResultInterface $result, $alias = null) 113 | { 114 | $descr = ' ' . $check->getLabel(); 115 | if ($message = $result->getMessage()) { 116 | $descr .= ': ' . $result->getMessage(); 117 | } 118 | 119 | if ($this->displayData && ($data = $result->getData())) { 120 | $descr .= PHP_EOL . str_repeat('-', $this->width - 7); 121 | $data = $result->getData(); 122 | if (is_object($data) && $data instanceof \Exception) { 123 | $descr .= PHP_EOL . get_class($data) . PHP_EOL . $data->getMessage() . $data->getTraceAsString(); 124 | } else { 125 | $descr .= PHP_EOL . @var_export($result->getData(), true); 126 | } 127 | 128 | $descr .= PHP_EOL . str_repeat('-', $this->width - 7); 129 | } 130 | 131 | // Draw status line 132 | if ($result instanceof Success) { 133 | $this->console->write(' OK ', Color::WHITE, Color::GREEN); 134 | $this->console->writeLine( 135 | $this->strColPad( 136 | $descr, 137 | $this->width - 7, 138 | ' ' 139 | ), Color::GREEN 140 | ); 141 | } elseif ($result instanceof Failure) { 142 | $this->console->write(' FAIL ', Color::WHITE, Color::RED); 143 | $this->console->writeLine( 144 | $this->strColPad( 145 | $descr, 146 | $this->width - 7, 147 | ' ' 148 | ), Color::RED 149 | ); 150 | } elseif ($result instanceof Warning) { 151 | $this->console->write(' WARN ', Color::NORMAL, Color::YELLOW); 152 | $this->console->writeLine( 153 | $this->strColPad( 154 | $descr, 155 | $this->width - 7, 156 | ' ' 157 | ), Color::YELLOW 158 | ); 159 | } elseif ($result instanceof Skip) { 160 | $this->console->write(' SKIP ', Color::NORMAL, Color::YELLOW); 161 | $this->console->writeLine( 162 | $this->strColPad( 163 | $descr, 164 | $this->width - 7, 165 | ' ' 166 | ), Color::YELLOW 167 | ); 168 | } else { 169 | $this->console->write(' ???? ', Color::NORMAL, Color::YELLOW); 170 | $this->console->writeLine( 171 | $this->strColPad( 172 | $descr, 173 | $this->width - 7, 174 | ' ' 175 | ), Color::YELLOW 176 | ); 177 | } 178 | } 179 | 180 | /** 181 | * This method is called when Runner has been aborted and could not finish the 182 | * whole run(). 183 | * 184 | * @param ResultsCollection $results Collection of Results for performed Checks. 185 | * @return void 186 | */ 187 | public function onStop(ResultsCollection $results) 188 | { 189 | $this->stopped = true; 190 | } 191 | 192 | /** 193 | * This method is called when Runner has finished its run. 194 | * 195 | * @param ResultsCollection $results Collection of Results for performed Checks. 196 | * @return void 197 | */ 198 | public function onFinish(ResultsCollection $results) 199 | { 200 | $this->console->writeLine(); 201 | 202 | // Display information that the check has been aborted. 203 | if ($this->stopped) { 204 | $this->console->writeLine('Diagnostics aborted because of a failure.', Color::RED); 205 | } 206 | 207 | // Display a summary line 208 | if ($results->getFailureCount() == 0 && $results->getWarningCount() == 0 && $results->getUnknownCount() == 0) { 209 | $line = 'OK (' . $this->total . ' diagnostic checks)'; 210 | $this->console->writeLine( 211 | str_pad($line, $this->width - 1, ' ', STR_PAD_RIGHT), 212 | Color::NORMAL, Color::GREEN 213 | ); 214 | } elseif ($results->getFailureCount() == 0) { 215 | $line = $results->getWarningCount() . ' warnings, '; 216 | $line .= $results->getSuccessCount() . ' successful checks'; 217 | 218 | if ($results->getSkipCount() > 0) { 219 | $line .= ', ' . $results->getSkipCount() . ' skipped checks'; 220 | } 221 | 222 | if ($results->getUnknownCount() > 0) { 223 | $line .= ', ' . $results->getUnknownCount() . ' unknown check results'; 224 | } 225 | 226 | $line .= '.'; 227 | 228 | $this->console->writeLine( 229 | str_pad($line, $this->width - 1, ' ', STR_PAD_RIGHT), 230 | Color::NORMAL, Color::YELLOW 231 | ); 232 | } else { 233 | $line = $results->getFailureCount() . ' failures, '; 234 | $line .= $results->getWarningCount() . ' warnings, '; 235 | $line .= $results->getSuccessCount() . ' successful checks'; 236 | 237 | if ($results->getSkipCount() > 0) { 238 | $line .= ', ' . $results->getSkipCount() . ' skipped checks'; 239 | } 240 | 241 | if ($results->getUnknownCount() > 0) { 242 | $line .= ', ' . $results->getUnknownCount() . ' unknown check results'; 243 | } 244 | 245 | $line .= '.'; 246 | 247 | $this->console->writeLine( 248 | str_pad($line, $this->width, ' ', STR_PAD_RIGHT), 249 | Color::NORMAL, Color::RED 250 | ); 251 | } 252 | 253 | $this->console->writeLine(); 254 | } 255 | 256 | /** 257 | * Set Console adapter to use 258 | * 259 | * @param Console $console 260 | */ 261 | public function setConsole($console) 262 | { 263 | $this->console = $console; 264 | 265 | // Update width 266 | $this->width = $console->getWidth(); 267 | } 268 | 269 | /** 270 | * Get currently used Console adapter 271 | * 272 | * @return Console 273 | */ 274 | public function getConsole() 275 | { 276 | return $this->console; 277 | } 278 | 279 | /** 280 | * Set if result data should be displayed on the screen 281 | * 282 | * @param bool $displayData 283 | */ 284 | public function setDisplayData($displayData) 285 | { 286 | $this->displayData = (bool) $displayData; 287 | } 288 | 289 | /** 290 | * Get the flag value, if result data should be displayed on the screen 291 | * @return bool 292 | */ 293 | public function getDisplayData() 294 | { 295 | return $this->displayData; 296 | } 297 | 298 | /** 299 | * Apply padding and word-wrapping for a string. 300 | * 301 | * @param string $string The string to transform 302 | * @param int $width Maximum width at which the string should be wrapped to the next line 303 | * @param int $padding The left-side padding to apply 304 | * @return string The padded and wrapped string 305 | */ 306 | protected function strColPad($string, $width, $padding) 307 | { 308 | $string = $this->stringUtils->wordWrap($string, $width, PHP_EOL, true); 309 | $lines = explode(PHP_EOL, $string); 310 | for ($x = 1; $x < count($lines); $x++) { 311 | $lines[$x] = $padding . $lines[$x]; 312 | } 313 | 314 | return implode(PHP_EOL, $lines); 315 | } 316 | } 317 | -------------------------------------------------------------------------------- /src/ZFTool/Diagnostics/Runner.php: -------------------------------------------------------------------------------- 1 | setConfig($config); 27 | } 28 | 29 | return parent::__construct(array(), $checks, $reporter); 30 | } 31 | 32 | /** 33 | * Run all Checks and return a Result\Collection for every check. 34 | * 35 | * @param string|null $checkAlias An alias of Check instance to run, or null to run all checks. 36 | * @return ResultsCollection The result of running Checks 37 | */ 38 | public function run($checkAlias = null) 39 | { 40 | $this->breakOnFailure = $this->config->getBreakOnFailure(); 41 | $this->catchErrorSeverity = $this->config->getBreakOnFailure(); 42 | 43 | return parent::run($checkAlias); 44 | } 45 | 46 | /** 47 | * @param ConfigInterface|array $config 48 | * @throws Exception\InvalidArgumentException 49 | * @return void 50 | */ 51 | public function setConfig($config) 52 | { 53 | if ($config instanceof ConfigInterface) { 54 | $this->config = $config; 55 | } elseif (is_array($config) || $config instanceof Traversable) { 56 | $this->config = new Config($config); 57 | } else { 58 | throw new Exception\InvalidArgumentException( 59 | 'Diagnostics Runner setConfig() expects an array, traversable or instance of ConfigInterface' 60 | ); 61 | } 62 | } 63 | 64 | /** 65 | * @return ConfigInterface 66 | */ 67 | public function getConfig() 68 | { 69 | return $this->config; 70 | } 71 | 72 | /** 73 | * Set if checking should abort on first failure. 74 | * 75 | * @param boolean $breakOnFailure 76 | */ 77 | public function setBreakOnFailure($breakOnFailure) 78 | { 79 | $this->config->setBreakOnFailure((bool) $breakOnFailure); 80 | } 81 | 82 | /** 83 | * @return boolean 84 | */ 85 | public function getBreakOnFailure() 86 | { 87 | return $this->config->getBreakOnFailure(); 88 | } 89 | 90 | /** 91 | * Set severity of error that will result in a check failing. Defaults to: 92 | * E_WARNING|E_PARSE|E_USER_ERROR|E_USER_WARNING|E_RECOVERABLE_ERROR 93 | * 94 | * @param int $catchErrorSeverity 95 | */ 96 | public function setCatchErrorSeverity($catchErrorSeverity) 97 | { 98 | $this->config->setCatchErrorSeverity((int) $catchErrorSeverity); 99 | } 100 | 101 | /** 102 | * Get current severity of error that will result in a check failing. 103 | * 104 | * @return int 105 | */ 106 | public function getCatchErrorSeverity() 107 | { 108 | return $this->config->getCatchErrorSeverity(); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/ZFTool/Model/Config.php: -------------------------------------------------------------------------------- 1 | configPath = $configPath; 32 | if (file_exists($configPath)) { 33 | $this->config = include($configPath); 34 | } 35 | } 36 | 37 | public function write($dottedName, $value) 38 | { 39 | $getset = function ($getset, $name, $value, &$array) { 40 | $n = array_shift($name); 41 | if (count($name) > 0) { 42 | $array[$n] = array(); 43 | $newArray = &$array[$n]; 44 | $getset($getset, $name, $value, $newArray); 45 | } else { 46 | $array[$n] = $value; 47 | } 48 | }; 49 | 50 | $newNestedArray = array(); 51 | $getset($getset, explode('.', $dottedName), $value, $newNestedArray); 52 | 53 | $newFullConfig = ArrayUtils::merge($this->config, $newNestedArray); 54 | 55 | $phpArray = new PhpArray(); 56 | $phpArray->toFile($this->configPath, $newFullConfig); 57 | } 58 | 59 | public function read($dottedName) 60 | { 61 | return static::findValueInArray($dottedName, $this->config); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/ZFTool/Model/Skeleton.php: -------------------------------------------------------------------------------- 1 | $last) { 57 | $file = $f; 58 | } 59 | } 60 | return $file; 61 | } 62 | 63 | /** 64 | * Get the .zip file name based on the last commit 65 | * 66 | * @param string $dir 67 | * @param array $commit 68 | * @return string 69 | */ 70 | public static function getTmpFileName($dir, $commit) 71 | { 72 | $filename = ''; 73 | if (is_array($commit) && isset($commit['sha'])) { 74 | $filename = $dir . '/' . self::SKELETON_FILE . '_' . $commit['sha'] . '.zip'; 75 | } 76 | return $filename; 77 | } 78 | 79 | /** 80 | * Export the $config array in a human readable format 81 | * 82 | * @param array $config 83 | * @param integer $space the initial indentation value 84 | * @return string 85 | */ 86 | public static function exportConfig($config, $indent = 0) 87 | { 88 | if (empty(static::$valueGenerator)) { 89 | static::$valueGenerator = new ValueGenerator(); 90 | } 91 | static::$valueGenerator->setValue($config); 92 | static::$valueGenerator->setArrayDepth($indent); 93 | 94 | return static::$valueGenerator; 95 | } 96 | 97 | /** 98 | * Return the Module.php content 99 | * 100 | * @param string $name 101 | * @return string 102 | */ 103 | public static function getModule($name) 104 | { 105 | return << array( 120 | 'namespaces' => array( 121 | __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__, 122 | ), 123 | ), 124 | ); 125 | } 126 | } 127 | 128 | EOD; 129 | } 130 | 131 | /** 132 | * 133 | * @param type $name 134 | * @return type 135 | */ 136 | public static function getModuleConfig($name) 137 | { 138 | return << array( 164 | 'proxy' => 'tcp://' . $config_env[1], 165 | 'request_fulluri' => true, 166 | 'header' => "Proxy-Authorization: Basic $auth", 167 | ), 168 | ); 169 | 170 | return stream_context_create($aContext); 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /src/ZFTool/Model/Utility.php: -------------------------------------------------------------------------------- 1 | getSubPathName(); 30 | if ($item->isDir()) { 31 | if (!file_exists($destName)) { 32 | if (!@mkdir($destName)) { 33 | return false; 34 | } 35 | } 36 | } else { 37 | if (!@copy($item, $destName)) { 38 | return false; 39 | } 40 | chmod($destName, fileperms($item)); 41 | } 42 | } 43 | return true; 44 | } 45 | 46 | /** 47 | * Delete a folder recursively from source to destination 48 | * 49 | * @param string $source 50 | * @return boolean 51 | */ 52 | public static function deleteFolder($source) 53 | { 54 | if (!file_exists($source)) { 55 | return false; 56 | } 57 | $iterator = new RecursiveIteratorIterator( 58 | new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS), 59 | RecursiveIteratorIterator::CHILD_FIRST 60 | ); 61 | foreach ($iterator as $item) { 62 | if ($item->isDir()) { 63 | if (!@rmdir($item->getRealPath())) { 64 | return false; 65 | } 66 | } else { 67 | if (!@unlink($item->getRealPath())) { 68 | return false; 69 | } 70 | } 71 | } 72 | return @rmdir($source); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/ZFTool/Model/Zf.php: -------------------------------------------------------------------------------- 1 | sm = $e->getApplication()->getServiceManager(); 31 | } 32 | 33 | public function getConfig() 34 | { 35 | return include __DIR__ . '/../../config/module.config.php'; 36 | } 37 | 38 | public function getAutoloaderConfig() 39 | { 40 | return array( 41 | 'Zend\Loader\StandardAutoloader' => array( 42 | 'namespaces' => array( 43 | __NAMESPACE__ => __DIR__, 44 | ), 45 | ), 46 | ); 47 | } 48 | 49 | public function getConsoleBanner(ConsoleAdapterInterface $console) 50 | { 51 | return self::NAME; 52 | } 53 | 54 | public function getConsoleUsage(ConsoleAdapterInterface $console) 55 | { 56 | $config = $this->sm->get('config'); 57 | if (!empty($config['ZFTool']) && !empty($config['ZFTool']['disable_usage'])) { 58 | return; // usage information has been disabled 59 | } 60 | 61 | // TODO: Load strings from a translation container 62 | return array( 63 | 64 | 'Basic information:', 65 | 'modules [list]' => 'show loaded modules', 66 | 'version | --version' => 'display current Zend Framework version', 67 | 68 | 'Diagnostics', 69 | 'diag [options] [module name]' => 'run diagnostics', 70 | array('[module name]' , '(Optional) name of module to test'), 71 | array('-v --verbose' , 'Display detailed information.'), 72 | array('-b --break' , 'Stop testing on first failure'), 73 | array('-q --quiet' , 'Do not display any output unless an error occurs.'), 74 | array('--debug' , 'Display raw debug info from tests.'), 75 | 76 | 'Application configuration:', 77 | 'config list' => 'list all configuration options', 78 | 'config get ' => 'display a single config value, i.e. "config get db.host"', 79 | 'config set ' => 'set a single config value (use only to change scalar values)', 80 | 81 | 'Project creation:', 82 | 'create project ' => 'create a skeleton application', 83 | array('', 'The path of the project to be created'), 84 | 85 | 'Module creation:', 86 | 'create module []' => 'create a module', 87 | array('', 'The name of the module to be created'), 88 | array('', 'The root path of a ZF2 application where to create the module'), 89 | 90 | 'Controller creation:', 91 | 'create controller []' => 'create a controller in module', 92 | array('', 'The name of the controller to be created'), 93 | array('', 'The module in which the controller should be created'), 94 | array('', 'The root path of a ZF2 application where to create the controller'), 95 | 96 | 'Action creation:', 97 | 'create action []' => 'create an action in a controller', 98 | array('', 'The name of the action to be created'), 99 | array('', 'The name of the controller in which the action should be created'), 100 | array('', 'The module containing the controller'), 101 | array('', 'The root path of a ZF2 application where to create the action'), 102 | 103 | 'Classmap generator:', 104 | 'classmap generate [--append|-a] [--overwrite|-w]' => '', 105 | array('', 'The directory to scan for PHP classes (use "." to use current directory)'), 106 | array('', 'File name for generated class map file or - for standard output. '. 107 | 'If not supplied, defaults to autoload_classmap.php inside .'), 108 | array('--append | -a', 'Append to classmap file if it exists'), 109 | array('--overwrite | -w', 'Whether or not to overwrite existing classmap file'), 110 | 111 | 'Zend Framework 2 installation:', 112 | 'install zf []' => '', 113 | array('', 'The directory where to install the ZF2 library'), 114 | array('', 'The version to install, if not specified uses the last available'), 115 | ); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /tests/Bootstrap.php: -------------------------------------------------------------------------------- 1 | config = new ArrayObject(array( 64 | 'diagnostics' => array() 65 | )); 66 | 67 | $this->sm = new ServiceManager(); 68 | $this->sm->setService('console', new ConsoleAdapter()); 69 | $this->sm->setService('config', $this->config); 70 | $this->sm->setAlias('configuration', 'config'); 71 | 72 | $this->mm = new InjectableModuleManager(); 73 | $this->sm->setService('modulemanager', $this->mm); 74 | 75 | $event = new MvcEvent(); 76 | $this->routeMatch = new RouteMatch(array( 77 | 'controller' => 'ZFTools\Controller\Diagnostics', 78 | 'action' => 'run' 79 | )); 80 | $event->setRouteMatch($this->routeMatch); 81 | $this->controller = new DiagnosticsController(); 82 | $this->controller->setServiceLocator($this->sm); 83 | $this->controller->setEvent($event); 84 | 85 | // Top-level output buffering to prevent leaking info to the console 86 | ob_start(); 87 | } 88 | 89 | public function teardown() 90 | { 91 | // Discard any output from the diag controller 92 | ob_end_clean(); 93 | } 94 | 95 | public function invalidDefinitionsProvider() 96 | { 97 | $res = fopen('php://memory', 'r'); 98 | fclose($res); 99 | 100 | return array( 101 | 'an empty array' => array( 102 | array(), 103 | 'Cannot use an empty array%a' 104 | ), 105 | 'an invalid check instance' => array( 106 | new \stdClass(), 107 | 'Cannot use object of class "stdClass"%a' 108 | ), 109 | 'an unknown definition type' => array( 110 | $res, 111 | 'Cannot understand diagnostic check definition %a' 112 | ), 113 | 'an invalid class name' => array( 114 | 'stdClass', 115 | 'The check object of class stdClass does not implement ZendDiagnostics\Check\CheckInterface' 116 | ), 117 | 'an unknown check identifier' => array( 118 | 'some\unknown\class\or\service\identifier', 119 | 'Cannot find check class or service with the name of "some\unknown\class\or\service\identifier"%a' 120 | ) 121 | ); 122 | } 123 | 124 | public function testNoChecks() 125 | { 126 | $result = $this->controller->dispatch(new ConsoleRequest()); 127 | $this->assertInstanceOf('Zend\View\Model\ViewModel', $result); 128 | $this->assertEquals(1, $result->getErrorLevel()); 129 | } 130 | 131 | /** 132 | * 'diagnostics' => array( 133 | * 'group' => array( 134 | * 'check label' => new Check() 135 | * ) 136 | * ) 137 | */ 138 | public function testConfigBasedTestInstance() 139 | { 140 | $expectedResult = new Success('bar'); 141 | $check = new ReturnThisCheck($expectedResult); 142 | $this->config['diagnostics']['group']['foo'] = $check; 143 | $result = $this->controller->dispatch(new ConsoleRequest()); 144 | 145 | $this->assertInstanceOf('Zend\View\Model\ViewModel', $result); 146 | $this->assertInstanceOf('ZendDiagnostics\Result\Collection', $result->getVariable('results')); 147 | 148 | /** @var Collection $results */ 149 | $results = $result->getVariable('results'); 150 | $this->assertEquals(1, $results->count()); 151 | $this->assertTrue($results->offsetExists($check)); 152 | $this->assertSame($expectedResult, $results[$check]); 153 | $this->assertSame('group: foo', $check->getLabel()); 154 | } 155 | 156 | /** 157 | * 'diagnostics' => array( 158 | * 'group' => array( 159 | * 'check label' => 'My\Namespace\ClassName' 160 | * ) 161 | * ) 162 | */ 163 | public function testConfigBasedTestClassName() 164 | { 165 | $this->config['diagnostics']['group']['foo'] = 'ZFToolTest\Diagnostics\TestAsset\AlwaysSuccessCheck'; 166 | $result = $this->controller->dispatch(new ConsoleRequest()); 167 | 168 | $this->assertInstanceOf('Zend\View\Model\ViewModel', $result); 169 | $this->assertInstanceOf('ZendDiagnostics\Result\Collection', $result->getVariable('results')); 170 | 171 | $results = $result->getVariable('results'); 172 | $this->assertEquals(1, $results->count()); 173 | $checks = ArrayUtils::iteratorToArray(($results)); 174 | $check = array_pop($checks); 175 | 176 | $this->assertInstanceOf('ZFToolTest\Diagnostics\TestAsset\AlwaysSuccessCheck', $check); 177 | $this->assertSame('group: foo', $check->getLabel()); 178 | $this->assertInstanceOf('ZendDiagnostics\Result\Success', $results[$check]); 179 | } 180 | 181 | /** 182 | * 'diagnostics' => array( 183 | * 'group' => array( 184 | * 'check label' => array('My\Namespace\ClassName', 'methodName') 185 | * ) 186 | * ) 187 | */ 188 | public function testConfigBasedStaticMethod() 189 | { 190 | static::$staticTestMethodCalled = false; 191 | $this->config['diagnostics']['group']['foo'] = array(__CLASS__, 'staticTestMethod'); 192 | $result = $this->controller->dispatch(new ConsoleRequest()); 193 | 194 | $this->assertInstanceOf('Zend\View\Model\ViewModel', $result); 195 | $this->assertInstanceOf('ZendDiagnostics\Result\Collection', $result->getVariable('results')); 196 | 197 | $results = $result->getVariable('results'); 198 | $this->assertEquals(1, $results->count()); 199 | $checks = ArrayUtils::iteratorToArray(($results)); 200 | $check = array_pop($checks); 201 | 202 | $this->assertInstanceOf('ZendDiagnostics\Check\Callback', $check); 203 | $this->assertTrue(static::$staticTestMethodCalled); 204 | $this->assertSame('group: foo', $check->getLabel()); 205 | $this->assertInstanceOf('ZendDiagnostics\Result\Success', $results[$check]); 206 | $this->assertEquals('bar', $results[$check]->getMessage()); 207 | } 208 | 209 | /** 210 | * 'diagnostics' => array( 211 | * 'group' => array( 212 | * 'check label' => array( 213 | * array('My\Namespace\ClassName', 'methodName'), 214 | * 'param1', 215 | * 'param2', 216 | * ) 217 | * ) 218 | * ) 219 | */ 220 | public function testConfigBasedStaticMethodWithParams() 221 | { 222 | static::$staticTestMethodCalled = false; 223 | $expectedData = mt_rand(1, PHP_INT_MAX); 224 | $expectedMessage = mt_rand(1, PHP_INT_MAX); 225 | $this->config['diagnostics']['group']['foo'] = array( 226 | array(__CLASS__, 'staticTestMethod'), 227 | $expectedMessage, 228 | $expectedData 229 | ); 230 | $result = $this->controller->dispatch(new ConsoleRequest()); 231 | 232 | $this->assertInstanceOf('Zend\View\Model\ViewModel', $result); 233 | $this->assertInstanceOf('ZendDiagnostics\Result\Collection', $result->getVariable('results')); 234 | 235 | $results = $result->getVariable('results'); 236 | $this->assertEquals(1, $results->count()); 237 | $checks = ArrayUtils::iteratorToArray(($results)); 238 | $check = array_pop($checks); 239 | 240 | $this->assertInstanceOf('ZendDiagnostics\Check\Callback', $check); 241 | $this->assertTrue(static::$staticTestMethodCalled); 242 | $this->assertSame('group: foo', $check->getLabel()); 243 | $this->assertInstanceOf('ZendDiagnostics\Result\Success', $results[$check]); 244 | $this->assertEquals($expectedMessage, $results[$check]->getMessage()); 245 | $this->assertEquals($expectedData, $results[$check]->getData()); 246 | } 247 | 248 | /** 249 | * 'diagnostics' => array( 250 | * 'group' => array( 251 | * 'check label' => 'someFunctionName' 252 | * ) 253 | * ) 254 | */ 255 | public function testConfigBasedFunction() 256 | { 257 | $this->config['diagnostics']['group']['foo'] = __NAMESPACE__ . '\testOutlineFunction'; 258 | $result = $this->controller->dispatch(new ConsoleRequest()); 259 | 260 | $this->assertInstanceOf('Zend\View\Model\ViewModel', $result); 261 | $this->assertInstanceOf('ZendDiagnostics\Result\Collection', $result->getVariable('results')); 262 | 263 | $results = $result->getVariable('results'); 264 | $this->assertEquals(1, $results->count()); 265 | $checks = ArrayUtils::iteratorToArray(($results)); 266 | $check = array_pop($checks); 267 | 268 | $this->assertInstanceOf('ZendDiagnostics\Check\Callback', $check); 269 | $this->assertSame('group: foo', $check->getLabel()); 270 | $this->assertInstanceOf('ZendDiagnostics\Result\Success', $results[$check]); 271 | $this->assertEquals('bar', $results[$check]->getMessage()); 272 | } 273 | 274 | /** 275 | * 'diagnostics' => array( 276 | * 'group' => array( 277 | * 'check label' => array('someFunctionName', 'param1', 'param2') 278 | * ) 279 | * ) 280 | */ 281 | public function testConfigBasedFunctionWithParams() 282 | { 283 | $expectedData = mt_rand(1, PHP_INT_MAX); 284 | $expectedMessage = mt_rand(1, PHP_INT_MAX); 285 | $this->config['diagnostics']['group']['foo'] = array( 286 | __NAMESPACE__ . '\testOutlineFunction', 287 | $expectedMessage, 288 | $expectedData 289 | ); 290 | $result = $this->controller->dispatch(new ConsoleRequest()); 291 | 292 | $this->assertInstanceOf('Zend\View\Model\ViewModel', $result); 293 | $this->assertInstanceOf('ZendDiagnostics\Result\Collection', $result->getVariable('results')); 294 | 295 | $results = $result->getVariable('results'); 296 | $this->assertEquals(1, $results->count()); 297 | $checks = ArrayUtils::iteratorToArray(($results)); 298 | $check = array_pop($checks); 299 | 300 | $this->assertInstanceOf('ZendDiagnostics\Check\Callback', $check); 301 | $this->assertSame('group: foo', $check->getLabel()); 302 | $this->assertInstanceOf('ZendDiagnostics\Result\Success', $results[$check]); 303 | $this->assertEquals($expectedMessage, $results[$check]->getMessage()); 304 | $this->assertEquals($expectedData, $results[$check]->getData()); 305 | } 306 | 307 | /** 308 | * 'diagnostics' => array( 309 | * 'group' => array( 310 | * 'check label' => array('ClassExists', 'params') 311 | * ) 312 | * ) 313 | */ 314 | public function testConfigBasedBuiltinTest() 315 | { 316 | $this->config['diagnostics']['group']['foo'] = array('ClassExists', __CLASS__); 317 | $result = $this->controller->dispatch(new ConsoleRequest()); 318 | 319 | $this->assertInstanceOf('Zend\View\Model\ViewModel', $result); 320 | $this->assertInstanceOf('ZendDiagnostics\Result\Collection', $result->getVariable('results')); 321 | 322 | $results = $result->getVariable('results'); 323 | $this->assertEquals(1, $results->count()); 324 | $checks = ArrayUtils::iteratorToArray(($results)); 325 | $check = array_pop($checks); 326 | 327 | $this->assertInstanceOf('ZendDiagnostics\Check\ClassExists', $check); 328 | $this->assertSame('group: foo', $check->getLabel()); 329 | $this->assertInstanceOf('ZendDiagnostics\Result\Success', $results[$check]); 330 | } 331 | 332 | /** 333 | * 'diagnostics' => array( 334 | * 'group' => array( 335 | * 'check label' => 'Some\ServiceManager\Identifier' 336 | * ) 337 | * ), 338 | * 'service_manager' => array( 339 | * 'invokables' => array( 340 | * 'Some\ServiceManager\Identifier' => 'Some\Check\Class' 341 | * ) 342 | * ) 343 | */ 344 | public function testConfigBasedServiceName() 345 | { 346 | $expectedData = mt_rand(1, PHP_INT_MAX); 347 | $expectedMessage = mt_rand(1, PHP_INT_MAX); 348 | $check = new Callback(function () use ($expectedMessage, $expectedData) { 349 | return new Success($expectedMessage, $expectedData); 350 | }); 351 | $this->sm->setService('ZFToolTest\TestService', $check); 352 | 353 | $this->config['diagnostics']['group']['foo'] = 'ZFToolTest\TestService'; 354 | 355 | $result = $this->controller->dispatch(new ConsoleRequest()); 356 | 357 | $this->assertInstanceOf('Zend\View\Model\ViewModel', $result); 358 | $this->assertInstanceOf('ZendDiagnostics\Result\Collection', $result->getVariable('results')); 359 | 360 | $results = $result->getVariable('results'); 361 | $this->assertEquals(1, $results->count()); 362 | $checks = ArrayUtils::iteratorToArray(($results)); 363 | $this->assertSame($check, array_pop($checks)); 364 | 365 | $this->assertSame('group: foo', $check->getLabel()); 366 | $this->assertInstanceOf('ZendDiagnostics\Result\Success', $results[$check]); 367 | $this->assertEquals($expectedMessage, $results[$check]->getMessage()); 368 | $this->assertEquals($expectedData, $results[$check]->getData()); 369 | } 370 | 371 | /** 372 | * 'diagnostics' => array( 373 | * 'group' => array( 374 | * 'check label' => 'PhpVersion' 375 | * ) 376 | * ) 377 | */ 378 | public function testBuiltInBeforeCallable() 379 | { 380 | $this->config['diagnostics']['group']['foo'] = array('PhpVersion', '1.0.0'); 381 | $result = $this->controller->dispatch(new ConsoleRequest()); 382 | 383 | $this->assertInstanceOf('Zend\View\Model\ViewModel', $result); 384 | $this->assertInstanceOf('ZendDiagnostics\Result\Collection', $result->getVariable('results')); 385 | 386 | $results = $result->getVariable('results'); 387 | $this->assertEquals(1, $results->count()); 388 | $checks = ArrayUtils::iteratorToArray(($results)); 389 | $check = array_pop($checks); 390 | 391 | $this->assertInstanceOf('ZendDiagnostics\Check\PhpVersion', $check); 392 | } 393 | 394 | public function testModuleProvidedDefinitions() 395 | { 396 | $module = new DummyModule($this->sm); 397 | $this->mm->injectModule('dummymodule', $module); 398 | $result = $this->controller->dispatch(new ConsoleRequest()); 399 | 400 | $this->assertInstanceOf('Zend\View\Model\ViewModel', $result); 401 | $this->assertInstanceOf('ZendDiagnostics\Result\Collection', $result->getVariable('results')); 402 | 403 | $results = $result->getVariable('results'); 404 | $this->assertEquals(5, $results->count()); 405 | 406 | $expected = array( 407 | array('dummymodule: test1', 'ZendDiagnostics\Result\Success', 'test1 success'), 408 | array('dummymodule: test2', 'ZendDiagnostics\Result\Success', ''), 409 | array('dummymodule: test3', 'ZendDiagnostics\Result\Failure', ''), 410 | array('dummymodule: test4', 'ZendDiagnostics\Result\Failure', 'static check message'), 411 | array('dummymodule: test5', 'ZendDiagnostics\Result\Failure', 'someOtherMessage'), 412 | ); 413 | 414 | $x = 0; 415 | foreach ($results as $check) { 416 | $result = $results[$check]; 417 | list($label, $class, $message) = $expected[$x++]; 418 | error_reporting(E_ERROR); 419 | $this->assertInstanceOf('ZendDiagnostics\Check\CheckInterface', $check); 420 | $this->assertEquals($label, $check->getLabel()); 421 | $this->assertEquals($message, $result->getMessage()); 422 | $this->assertInstanceOf($class, $result); 423 | } 424 | } 425 | 426 | public function testTriggerAWarning() 427 | { 428 | $check = new Callback(function () { 429 | 1/0; // < throw a warning 430 | }); 431 | 432 | $this->config['diagnostics']['group']['foo'] = $check; 433 | 434 | $result = $this->controller->dispatch(new ConsoleRequest()); 435 | 436 | $this->assertInstanceOf('Zend\View\Model\ViewModel', $result); 437 | $this->assertInstanceOf('ZendDiagnostics\Result\Collection', $result->getVariable('results')); 438 | 439 | $results = $result->getVariable('results'); 440 | $this->assertEquals(1, $results->count()); 441 | $checks = ArrayUtils::iteratorToArray(($results)); 442 | $this->assertSame($check, array_pop($checks)); 443 | 444 | $this->assertSame('group: foo', $check->getLabel()); 445 | $this->assertInstanceOf('ZendDiagnostics\Result\Failure', $results[$check]); 446 | } 447 | 448 | public function testThrowingAnException() 449 | { 450 | $e = new \Exception(); 451 | $check = new Callback(function () use (&$e) { 452 | throw $e; 453 | }); 454 | 455 | $this->config['diagnostics']['group']['foo'] = $check; 456 | 457 | $result = $this->controller->dispatch(new ConsoleRequest()); 458 | 459 | $this->assertInstanceOf('Zend\View\Model\ViewModel', $result); 460 | $this->assertInstanceOf('ZendDiagnostics\Result\Collection', $result->getVariable('results')); 461 | 462 | $results = $result->getVariable('results'); 463 | $this->assertEquals(1, $results->count()); 464 | $checks = ArrayUtils::iteratorToArray(($results)); 465 | $this->assertSame($check, array_pop($checks)); 466 | 467 | $this->assertSame('group: foo', $check->getLabel()); 468 | $this->assertInstanceOf('ZendDiagnostics\Result\Failure', $results[$check]); 469 | $this->assertSame($e, $results[$check]->getData()); 470 | } 471 | 472 | public function testInvalidResult() 473 | { 474 | $someObj = new \stdClass; 475 | $check = new ReturnThisCheck($someObj); 476 | $this->config['diagnostics']['group']['foo'] = $check; 477 | 478 | $dispatchResult = $this->controller->dispatch(new ConsoleRequest()); 479 | $this->assertInstanceOf('Zend\View\Model\ViewModel', $dispatchResult); 480 | $this->assertInstanceOf('ZendDiagnostics\Result\Collection', $dispatchResult->getVariable('results')); 481 | $results = $dispatchResult->getVariable('results'); 482 | $this->assertEquals(1, $results->count()); 483 | $check = array_pop(ArrayUtils::iteratorToArray(($results))); 484 | $this->assertSame('group: foo', $check->getLabel()); 485 | $this->assertInstanceOf('ZendDiagnostics\Result\Failure', $results[$check]); 486 | $this->assertSame($someObj, $results[$check]->getData()); 487 | 488 | $someResource = fopen('php://memory', 'r'); 489 | fclose($someResource); 490 | $check = new ReturnThisCheck($someResource); 491 | $this->config['diagnostics']['group']['foo'] = $check; 492 | $dispatchResult = $this->controller->dispatch(new ConsoleRequest()); 493 | $this->assertInstanceOf('Zend\View\Model\ViewModel', $dispatchResult); 494 | $this->assertInstanceOf('ZendDiagnostics\Result\Collection', $dispatchResult->getVariable('results')); 495 | $results = $dispatchResult->getVariable('results'); 496 | $check = array_pop(ArrayUtils::iteratorToArray(($results))); 497 | $this->assertInstanceOf('ZendDiagnostics\Result\Failure', $results[$check]); 498 | $this->assertSame($someResource, $results[$check]->getData()); 499 | 500 | $check = new ReturnThisCheck(123); 501 | $this->config['diagnostics']['group']['foo'] = $check; 502 | $dispatchResult = $this->controller->dispatch(new ConsoleRequest()); 503 | $this->assertInstanceOf('Zend\View\Model\ViewModel', $dispatchResult); 504 | $this->assertInstanceOf('ZendDiagnostics\Result\Collection', $dispatchResult->getVariable('results')); 505 | $results = $dispatchResult->getVariable('results'); 506 | $check = array_pop(ArrayUtils::iteratorToArray(($results))); 507 | $this->assertInstanceOf('ZendDiagnostics\Result\Warning', $results[$check]); 508 | $this->assertEquals(123, $results[$check]->getData()); 509 | } 510 | 511 | /** 512 | * 'diagnostics' => array( 513 | * 'group' => array( 514 | * 'Some\Check', 515 | * 'Some\Other\Check', 516 | * 'test3' => 'Another\One' 517 | * ) 518 | * ), 519 | */ 520 | public function testIgnoreNumericLabel() 521 | { 522 | $this->config['diagnostics']['group'][] = array('ClassExists',__CLASS__); 523 | $this->config['diagnostics']['group'][] = array('ClassExists',__CLASS__); 524 | $this->config['diagnostics']['group']['test3'] = array('ClassExists',__CLASS__); 525 | $result = $this->controller->dispatch(new ConsoleRequest()); 526 | 527 | $this->assertInstanceOf('Zend\View\Model\ViewModel', $result); 528 | $this->assertInstanceOf('ZendDiagnostics\Result\Collection', $result->getVariable('results')); 529 | 530 | $results = $result->getVariable('results'); 531 | $this->assertEquals(3, $results->count()); 532 | $checks = ArrayUtils::iteratorToArray(($results)); 533 | 534 | $check = array_shift($checks); 535 | $this->assertInstanceOf('ZendDiagnostics\Check\ClassExists', $check); 536 | $this->assertInstanceOf('ZendDiagnostics\Result\Success', $results[$check]); 537 | 538 | $check = array_shift($checks); 539 | $this->assertInstanceOf('ZendDiagnostics\Check\ClassExists', $check); 540 | $this->assertInstanceOf('ZendDiagnostics\Result\Success', $results[$check]); 541 | 542 | $check = array_shift($checks); 543 | $this->assertInstanceOf('ZendDiagnostics\Check\ClassExists', $check); 544 | $this->assertSame('group: test3', $check->getLabel()); 545 | $this->assertInstanceOf('ZendDiagnostics\Result\Success', $results[$check]); 546 | } 547 | 548 | /** 549 | * @dataProvider invalidDefinitionsProvider 550 | */ 551 | public function testInvalidDefinitions($definition, $exceptionMessage) 552 | { 553 | $this->config['diagnostics']['group']['foo'] = $definition; 554 | try { 555 | $res = $this->controller->dispatch(new ConsoleRequest()); 556 | } catch (RuntimeException $e) { 557 | $this->assertStringMatchesFormat($exceptionMessage, $e->getMessage()); 558 | 559 | return; 560 | } 561 | $this->fail('Definition is invalid!'); 562 | } 563 | 564 | public function testFiltering() 565 | { 566 | $this->config['diagnostics']['group1']['test11'] = $check11 = new AlwaysSuccessCheck(); 567 | $this->config['diagnostics']['group2']['test21'] = $check21 = new AlwaysSuccessCheck(); 568 | $this->config['diagnostics']['group2']['test22'] = $check22 = new AlwaysSuccessCheck(); 569 | $this->routeMatch->setParam('filter', 'group2'); 570 | $result = $this->controller->dispatch(new ConsoleRequest()); 571 | 572 | $this->assertInstanceOf('Zend\View\Model\ViewModel', $result); 573 | $this->assertInstanceOf('ZendDiagnostics\Result\Collection', $result->getVariable('results')); 574 | 575 | $results = $result->getVariable('results'); 576 | $this->assertEquals(2, $results->count()); 577 | $checks = ArrayUtils::iteratorToArray(($results)); 578 | $this->assertSame($check21, $check = array_shift($checks)); 579 | $this->assertEquals('group2: test21', $check->getLabel()); 580 | $this->assertInstanceOf('ZendDiagnostics\Result\Success', $results[$check]); 581 | $this->assertSame($check22, $check = array_shift($checks)); 582 | $this->assertEquals('group2: test22', $check->getLabel()); 583 | $this->assertInstanceOf('ZendDiagnostics\Result\Success', $results[$check]); 584 | } 585 | 586 | /** 587 | * @depends testModuleProvidedDefinitions 588 | */ 589 | public function testFilteringByModuleName() 590 | { 591 | $this->mm->injectModule('foomodule1', new DummyModule($this->sm)); 592 | $this->mm->injectModule('foomodule2', new DummyModule($this->sm)); 593 | $this->mm->injectModule('foomodule3', new DummyModule($this->sm)); 594 | $this->routeMatch->setParam('filter', 'foomodule2'); 595 | $result = $this->controller->dispatch(new ConsoleRequest()); 596 | 597 | $this->assertInstanceOf('Zend\View\Model\ViewModel', $result); 598 | $this->assertInstanceOf('ZendDiagnostics\Result\Collection', $result->getVariable('results')); 599 | 600 | $results = $result->getVariable('results'); 601 | $this->assertEquals(5, $results->count()); 602 | $checks = ArrayUtils::iteratorToArray(($results)); 603 | $this->assertInstanceOf('ZendDiagnostics\Check\CheckInterface', $check = array_shift($checks)); 604 | $this->assertEquals('foomodule2: test1', $check->getLabel()); 605 | $this->assertInstanceOf('ZendDiagnostics\Result\Success', $results[$check]); 606 | } 607 | 608 | public function testFilteringFailure() 609 | { 610 | $this->config['diagnostics']['group1']['test11'] = $check11 = new AlwaysSuccessCheck(); 611 | $this->config['diagnostics']['group2']['test21'] = $check21 = new AlwaysSuccessCheck(); 612 | $this->config['diagnostics']['group2']['test22'] = $check22 = new AlwaysSuccessCheck(); 613 | $this->routeMatch->setParam('filter', 'non-existent-group'); 614 | $result = $this->controller->dispatch(new ConsoleRequest()); 615 | $this->assertInstanceOf('Zend\View\Model\ViewModel', $result); 616 | $this->assertEquals(1, $result->getErrorLevel()); 617 | } 618 | 619 | public function testBreakOnFailure() 620 | { 621 | $this->config['diagnostics']['group']['test1'] = $check1 = new AlwaysSuccessCheck(); 622 | $this->config['diagnostics']['group']['test2'] = $check2 = new ReturnThisCheck(new Failure()); 623 | $this->config['diagnostics']['group']['test3'] = $check3 = new AlwaysSuccessCheck(); 624 | $this->routeMatch->setParam('break', true); 625 | $result = $this->controller->dispatch(new ConsoleRequest()); 626 | 627 | $this->assertInstanceOf('Zend\View\Model\ViewModel', $result); 628 | $this->assertInstanceOf('ZendDiagnostics\Result\Collection', $result->getVariable('results')); 629 | 630 | $results = $result->getVariable('results'); 631 | $this->assertEquals(2, $results->count()); 632 | $checks = ArrayUtils::iteratorToArray(($results)); 633 | $this->assertSame($check1, $check = array_shift($checks)); 634 | $this->assertEquals('group: test1', $check->getLabel()); 635 | $this->assertInstanceOf('ZendDiagnostics\Result\Success', $results[$check]); 636 | $this->assertSame($check2, $check = array_shift($checks)); 637 | $this->assertEquals('group: test2', $check->getLabel()); 638 | $this->assertInstanceOf('ZendDiagnostics\Result\Failure', $results[$check]); 639 | $this->assertNull(array_shift($checks)); 640 | } 641 | 642 | public function testBasicOutput() 643 | { 644 | $this->config['diagnostics']['group']['test1'] = $check1 = new AlwaysSuccessCheck(); 645 | 646 | ob_start(); 647 | $result = $this->controller->dispatch(new ConsoleRequest()); 648 | $this->assertStringMatchesFormat('Starting%a.%aOK%a', ob_get_clean()); 649 | 650 | $this->assertInstanceOf('Zend\View\Model\ConsoleModel', $result); 651 | $this->assertInstanceOf('ZendDiagnostics\Result\Collection', $result->getVariable('results')); 652 | } 653 | 654 | public function testVerboseOutput() 655 | { 656 | $this->config['diagnostics']['group']['test1'] = $check1 = new AlwaysSuccessCheck(); 657 | $this->routeMatch->setParam('verbose', true); 658 | 659 | ob_start(); 660 | $result = $this->controller->dispatch(new ConsoleRequest()); 661 | $this->assertStringMatchesFormat('Starting%aOK%agroup: test1%aOK (1 diagnostic check%a', ob_get_clean()); 662 | 663 | $this->assertInstanceOf('Zend\View\Model\ConsoleModel', $result); 664 | $this->assertInstanceOf('ZendDiagnostics\Result\Collection', $result->getVariable('results')); 665 | } 666 | 667 | public function testDebugOutput() 668 | { 669 | $this->config['diagnostics']['group']['test1'] = $check1 = new ReturnThisCheck( 670 | new Success('foo', 'bar') 671 | ); 672 | $this->routeMatch->setParam('debug', true); 673 | 674 | ob_start(); 675 | $result = $this->controller->dispatch(new ConsoleRequest()); 676 | $this->assertStringMatchesFormat('Starting%aOK%agroup: test1%afoo%abar%aOK (1 diagnostic check%a', ob_get_clean()); 677 | 678 | $this->assertInstanceOf('Zend\View\Model\ConsoleModel', $result); 679 | $this->assertInstanceOf('ZendDiagnostics\Result\Collection', $result->getVariable('results')); 680 | } 681 | 682 | public function testQuietMode() 683 | { 684 | $this->config['diagnostics']['group']['test1'] = $check1 = new AlwaysSuccessCheck(); 685 | $this->routeMatch->setParam('quiet', true); 686 | 687 | ob_start(); 688 | $result = $this->controller->dispatch(new ConsoleRequest()); 689 | $this->assertEquals('', ob_get_clean()); 690 | 691 | $this->assertInstanceOf('Zend\View\Model\ConsoleModel', $result); 692 | $this->assertInstanceOf('ZendDiagnostics\Result\Collection', $result->getVariable('results')); 693 | } 694 | 695 | public function testHttpMode() 696 | { 697 | $this->config['diagnostics']['group']['test1'] = $check1 = new AlwaysSuccessCheck(); 698 | 699 | $result = $this->controller->dispatch(new Http\Request()); 700 | 701 | $this->assertInstanceOf('Zend\View\Model\ViewModel', $result); 702 | $this->assertInstanceOf('ZendDiagnostics\Result\Collection', $result->getVariable('results')); 703 | } 704 | 705 | public function testJsonMode() 706 | { 707 | $this->config['diagnostics']['group']['test1'] = $check1 = new AlwaysSuccessCheck(); 708 | 709 | $request = new Http\Request(); 710 | $request->getHeaders()->addHeader(Http\Header\Accept::fromString('Accept: application/json')); 711 | $result = $this->controller->dispatch($request); 712 | 713 | $this->assertInstanceOf('Zend\View\Model\JsonModel', $result); 714 | $this->assertTrue($result->getVariable('passed')); 715 | $this->assertSame(1, $result->getVariable('success')); 716 | $this->assertSame(0, $result->getVariable('failure')); 717 | } 718 | 719 | public function testJsonModeFail() 720 | { 721 | $this->config['diagnostics']['group']['test1'] = $check1 = new AlwaysFailCheck(); 722 | 723 | $request = new Http\Request(); 724 | $request->getHeaders()->addHeader(Http\Header\Accept::fromString('Accept: application/json')); 725 | $result = $this->controller->dispatch($request); 726 | 727 | $this->assertInstanceOf('Zend\View\Model\JsonModel', $result); 728 | $this->assertFalse($result->getVariable('passed')); 729 | $this->assertSame(0, $result->getVariable('success')); 730 | $this->assertSame(1, $result->getVariable('failure')); 731 | } 732 | 733 | public function testUnknownAccept() 734 | { 735 | $this->config['diagnostics']['group']['test1'] = $check1 = new AlwaysSuccessCheck(); 736 | 737 | $request = new Http\Request(); 738 | $request->getHeaders()->addHeader(Http\Header\Accept::fromString('Accept: application/baz')); 739 | $result = $this->controller->dispatch($request); 740 | 741 | $this->assertInstanceOf('Zend\View\Model\ViewModel', $result); 742 | $this->assertInstanceOf('ZendDiagnostics\Result\Collection', $result->getVariable('results')); 743 | } 744 | 745 | public function testErrorCodes() 746 | { 747 | $this->routeMatch->setParam('quiet', true); 748 | 749 | $this->config['diagnostics']['group']['test1'] = $check1 = new AlwaysSuccessCheck(); 750 | $result = $this->controller->dispatch(new ConsoleRequest()); 751 | $this->assertInstanceOf('Zend\View\Model\ConsoleModel', $result); 752 | $this->assertEquals(0, $result->getErrorLevel()); 753 | 754 | $this->config['diagnostics']['group']['test1'] = $check1 = new ReturnThisCheck(new Failure()); 755 | $result = $this->controller->dispatch(new ConsoleRequest()); 756 | $this->assertInstanceOf('Zend\View\Model\ConsoleModel', $result); 757 | $this->assertEquals(1, $result->getErrorLevel()); 758 | 759 | $this->config['diagnostics']['group']['test1'] = $check1 = new ReturnThisCheck(new Warning()); 760 | $result = $this->controller->dispatch(new ConsoleRequest()); 761 | $this->assertInstanceOf('Zend\View\Model\ConsoleModel', $result); 762 | $this->assertEquals(0, $result->getErrorLevel()); 763 | } 764 | 765 | public static function staticTestMethod($message = 'bar', $data = null) 766 | { 767 | static::$staticTestMethodCalled = true; 768 | 769 | return new Success($message, $data); 770 | } 771 | } 772 | 773 | function testOutlineFunction($message = 'bar', $data = null) 774 | { 775 | return new Success($message, $data); 776 | } 777 | -------------------------------------------------------------------------------- /tests/ZFToolTest/Diagnostics/Reporter/BasicConsoleTest.php: -------------------------------------------------------------------------------- 1 | console = new ConsoleAdapter(); 41 | $this->console->setCharset(new Ascii()); 42 | $this->console->setTestUtf8(true); 43 | $this->assertEquals(true, $this->console->isUtf8()); 44 | $this->reporter = new BasicConsole($this->console); 45 | } 46 | 47 | public function testDummyReporter() 48 | { 49 | $reporter = new DummyReporter(); 50 | } 51 | public function testConsoleSettingGetting() 52 | { 53 | $this->assertSame($this->console, $this->reporter->getConsole()); 54 | 55 | $newConsole = new ConsoleAdapter(); 56 | $this->reporter->setConsole($newConsole); 57 | $this->assertSame($newConsole, $this->reporter->getConsole()); 58 | } 59 | 60 | public function testStartMessage() 61 | { 62 | $checks = new ArrayObject(array( 63 | new AlwaysSuccessCheck() 64 | )); 65 | 66 | ob_start(); 67 | $this->reporter->onStart($checks, array()); 68 | $this->assertStringMatchesFormat('Starting%A', ob_get_clean()); 69 | } 70 | 71 | public function testProgressDots() 72 | { 73 | $checks = new ArrayObject(array_fill(0, 5, new AlwaysSuccessCheck())); 74 | ob_start(); 75 | $this->reporter->onStart($checks, array()); 76 | ob_clean(); 77 | 78 | foreach ($checks as $check) { 79 | $result = new Success(); 80 | $this->reporter->onAfterRun($check, $result); 81 | } 82 | 83 | $this->assertEquals('.....', ob_get_clean()); 84 | } 85 | 86 | public function testWarningSymbols() 87 | { 88 | $checks = new ArrayObject(array_fill(0, 5, new AlwaysSuccessCheck())); 89 | ob_start(); 90 | $this->reporter->onStart($checks, array()); 91 | ob_get_clean(); 92 | 93 | ob_start(); 94 | foreach ($checks as $check) { 95 | $result = new Warning(); 96 | $this->reporter->onAfterRun($check, $result); 97 | } 98 | 99 | $this->assertEquals('!!!!!', ob_get_clean()); 100 | } 101 | 102 | public function testFailureSymbols() 103 | { 104 | $checks = new ArrayObject(array_fill(0, 5, new AlwaysSuccessCheck())); 105 | 106 | ob_start(); 107 | $this->reporter->onStart($checks, array()); 108 | ob_get_clean(); 109 | 110 | ob_start(); 111 | foreach ($checks as $check) { 112 | $result = new Failure(); 113 | $this->reporter->onAfterRun($check, $result); 114 | } 115 | 116 | $this->assertEquals('FFFFF', ob_get_clean()); 117 | } 118 | 119 | public function testUnknownSymbols() 120 | { 121 | $checks = new ArrayObject(array_fill(0, 5, new AlwaysSuccessCheck())); 122 | 123 | ob_start(); 124 | $this->reporter->onStart($checks, array()); 125 | ob_get_clean(); 126 | 127 | ob_start(); 128 | foreach ($checks as $check) { 129 | $result = new Unknown(); 130 | 131 | $this->reporter->onAfterRun($check, $result); 132 | } 133 | 134 | $this->assertEquals('?????', ob_get_clean()); 135 | } 136 | 137 | public function testProgressDotsNoGutter() 138 | { 139 | $this->console->setTestWidth(40); 140 | $checks = new ArrayObject(array_fill(0, 40, new AlwaysSuccessCheck())); 141 | 142 | ob_start(); 143 | $this->reporter->onStart($checks, array()); 144 | ob_get_clean(); 145 | 146 | ob_start(); 147 | foreach ($checks as $check) { 148 | $result = new Success(); 149 | $this->reporter->onAfterRun($check, $result); 150 | } 151 | 152 | $this->assertEquals(str_repeat('.', 40), ob_get_clean()); 153 | } 154 | 155 | public function testProgressOverflow() 156 | { 157 | $this->console->setTestWidth(40); 158 | $checks = new ArrayObject(array_fill(0, 80, new AlwaysSuccessCheck())); 159 | 160 | ob_start(); 161 | $this->reporter->onStart($checks, array()); 162 | ob_get_clean(); 163 | 164 | ob_start(); 165 | foreach ($checks as $check) { 166 | $result = new Success(); 167 | $this->reporter->onAfterRun($check, $result); 168 | } 169 | 170 | $expected = '......................... 25 / 80 ( 31%)'; 171 | $expected .= '......................... 50 / 80 ( 63%)'; 172 | $expected .= '......................... 75 / 80 ( 94%)'; 173 | $expected .= '.....'; 174 | 175 | $this->assertEquals($expected, ob_get_clean()); 176 | } 177 | 178 | public function testProgressOverflowMatch() 179 | { 180 | $this->console->setTestWidth(40); 181 | $checks = new ArrayObject(array_fill(0, 75, new AlwaysSuccessCheck())); 182 | 183 | ob_start(); 184 | $this->reporter->onStart($checks, array()); 185 | ob_get_clean(); 186 | 187 | ob_start(); 188 | foreach ($checks as $check) { 189 | $result = new Success(); 190 | $this->reporter->onAfterRun($check, $result); 191 | } 192 | 193 | $expected = '......................... 25 / 75 ( 33%)'; 194 | $expected .= '......................... 50 / 75 ( 67%)'; 195 | $expected .= '......................... 75 / 75 (100%)'; 196 | 197 | $this->assertEquals($expected, ob_get_clean()); 198 | } 199 | 200 | public function testSummaryAllSuccessful() 201 | { 202 | $checks = new ArrayObject(); 203 | $check = null; 204 | $results = new Collection(); 205 | for ($x = 0; $x < 20; $x++) { 206 | $checks[] = $check = new AlwaysSuccessCheck(); 207 | $results[$check] = new Success(); 208 | } 209 | 210 | ob_start(); 211 | $this->reporter->onStart($checks, array()); 212 | ob_clean(); 213 | 214 | $this->reporter->onFinish($results); 215 | $this->assertStringStartsWith('OK (20 diagnostic checks)', trim(ob_get_clean())); 216 | } 217 | 218 | public function testSummaryWithWarnings() 219 | { 220 | $checks = new ArrayObject(); 221 | $check = null; 222 | $results = new Collection(); 223 | for ($x = 0; $x < 15; $x++) { 224 | $checks[] = $check = new AlwaysSuccessCheck(); 225 | $results[$check] = new Success(); 226 | } 227 | 228 | for ($x = 0; $x < 5; $x++) { 229 | $checks[] = $check = new AlwaysSuccessCheck(); 230 | $results[$check] = new Warning(); 231 | } 232 | 233 | ob_start(); 234 | $this->reporter->onStart($checks, array()); 235 | ob_clean(); 236 | 237 | $this->reporter->onFinish($results); 238 | $this->assertStringStartsWith('5 warnings, 15 successful checks', trim(ob_get_clean())); 239 | } 240 | 241 | public function testSummaryWithFailures() 242 | { 243 | $checks = new ArrayObject(); 244 | $check = null; 245 | $results = new Collection(); 246 | for ($x = 0; $x < 15; $x++) { 247 | $checks[] = $check = new AlwaysSuccessCheck(); 248 | $results[$check] = new Success(); 249 | } 250 | 251 | for ($x = 0; $x < 5; $x++) { 252 | $checks[] = $check = new AlwaysSuccessCheck(); 253 | $results[$check] = new Warning(); 254 | } 255 | 256 | for ($x = 0; $x < 5; $x++) { 257 | $checks[] = $check = new AlwaysSuccessCheck(); 258 | $results[$check] = new Failure(); 259 | } 260 | 261 | ob_start(); 262 | $this->reporter->onStart($checks, array()); 263 | ob_clean(); 264 | 265 | $this->reporter->onFinish($results); 266 | $this->assertStringStartsWith('5 failures, 5 warnings, 15 successful checks', trim(ob_get_clean())); 267 | } 268 | 269 | public function testSummaryWithUnknowns() 270 | { 271 | $checks = new ArrayObject(); 272 | $check = null; 273 | $results = new Collection(); 274 | for ($x = 0; $x < 15; $x++) { 275 | $checks[] = $check = new AlwaysSuccessCheck(); 276 | $results[$check] = new Success(); 277 | } 278 | 279 | for ($x = 0; $x < 5; $x++) { 280 | $checks[] = $check = new AlwaysSuccessCheck(); 281 | $results[$check] = new Warning(); 282 | } 283 | 284 | for ($x = 0; $x < 5; $x++) { 285 | $checks[] = $check = new AlwaysSuccessCheck(); 286 | $results[$check] = new Unknown(); 287 | } 288 | 289 | ob_start(); 290 | $this->reporter->onStart($checks, array()); 291 | ob_clean(); 292 | 293 | $this->reporter->onFinish($results); 294 | $this->assertStringMatchesFormat('%A5 unknown check results%A', trim(ob_get_clean())); 295 | } 296 | 297 | public function testWarnings() 298 | { 299 | $checks = new ArrayObject(); 300 | $check = null; 301 | $results = new Collection(); 302 | for ($x = 0; $x < 15; $x++) { 303 | $checks[] = $check = new AlwaysSuccessCheck(); 304 | $results[$check] = new Success(); 305 | } 306 | 307 | $checks[] = $check = new AlwaysSuccessCheck(); 308 | $results[$check] = new Warning('foo'); 309 | 310 | ob_start(); 311 | $this->reporter->onStart($checks, array()); 312 | ob_clean(); 313 | 314 | $this->reporter->onFinish($results); 315 | $this->assertStringMatchesFormat( 316 | '%AWarning: Always Successful Check%wfoo', 317 | trim(ob_get_clean()) 318 | ); 319 | } 320 | 321 | public function testFailures() 322 | { 323 | $checks = new ArrayObject(); 324 | $check = null; 325 | $results = new Collection(); 326 | for ($x = 0; $x < 15; $x++) { 327 | $checks[] = $check = new AlwaysSuccessCheck(); 328 | $results[$check] = new Success(); 329 | } 330 | 331 | $checks[] = $check = new AlwaysSuccessCheck(); 332 | $results[$check] = new Failure('bar'); 333 | 334 | ob_start(); 335 | $this->reporter->onStart($checks, array()); 336 | ob_clean(); 337 | 338 | $this->reporter->onFinish($results); 339 | $this->assertStringMatchesFormat( 340 | '%AFailure: Always Successful Check%wbar', 341 | trim(ob_get_clean()) 342 | ); 343 | } 344 | 345 | public function testUnknowns() 346 | { 347 | $checks = new ArrayObject(); 348 | $check = null; 349 | $results = new Collection(); 350 | for ($x = 0; $x < 15; $x++) { 351 | $checks[] = $check = new AlwaysSuccessCheck(); 352 | $results[$check] = new Success(); 353 | } 354 | 355 | $checks[] = $check = new AlwaysSuccessCheck(); 356 | $results[$check] = new Unknown('baz'); 357 | 358 | ob_start(); 359 | $this->reporter->onStart($checks, array()); 360 | ob_clean(); 361 | 362 | $this->reporter->onFinish($results); 363 | $this->assertStringMatchesFormat( 364 | '%AUnknown result ZFToolTest\Diagnostics\TestAsset\UnknownResult: Always Successful Check%wbaz%A', 365 | trim(ob_get_clean()) 366 | ); 367 | } 368 | 369 | public function testStoppedNotice() 370 | { 371 | $checks = new ArrayObject(); 372 | $check = null; 373 | $results = new Collection(); 374 | for ($x = 0; $x < 15; $x++) { 375 | $checks[] = $check = new AlwaysSuccessCheck(); 376 | $results[$check] = new Success(); 377 | } 378 | 379 | ob_start(); 380 | $this->reporter->onStart($checks, array()); 381 | ob_clean(); 382 | 383 | $this->reporter->onStop($results); 384 | 385 | $this->reporter->onFinish($results); 386 | $this->assertStringMatchesFormat('%ADiagnostics aborted%A', trim(ob_get_clean())); 387 | } 388 | } 389 | -------------------------------------------------------------------------------- /tests/ZFToolTest/Diagnostics/Reporter/ReporterTest.php: -------------------------------------------------------------------------------- 1 | addReporter($reporter); 18 | $runner->removeReporter($reporter); 19 | } 20 | 21 | public function testDummyReporterStandardRun() 22 | { 23 | $reporter = new DummyReporter(); 24 | $runner = new Runner(); 25 | $runner->addReporter($reporter); 26 | $check = new AlwaysSuccessCheck(); 27 | $runner->addCheck($check); 28 | $runner->run(); 29 | } 30 | 31 | public function testDummyReporterStopped() 32 | { 33 | $reporter = new DummyReporter(true); 34 | $runner = new Runner(); 35 | $runner->addReporter($reporter); 36 | $check1 = new AlwaysSuccessCheck(); 37 | $check2 = new AlwaysSuccessCheck(); 38 | $runner->addCheck($check1); 39 | $runner->addCheck($check2); 40 | $result = $runner->run(); 41 | $this->assertFalse($result->offsetExists($check2)); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /tests/ZFToolTest/Diagnostics/Reporter/VerboseConsoleTest.php: -------------------------------------------------------------------------------- 1 | console = new ConsoleAdapter(); 34 | $this->console->setCharset(new Ascii()); 35 | $this->reporter = new VerboseConsole($this->console); 36 | } 37 | 38 | public function testConsoleSettingGetting() 39 | { 40 | $this->assertSame($this->console, $this->reporter->getConsole()); 41 | 42 | $newConsole = new ConsoleAdapter(); 43 | $this->reporter->setConsole($newConsole); 44 | $this->assertSame($newConsole, $this->reporter->getConsole()); 45 | } 46 | 47 | public function testStartMessage() 48 | { 49 | $checks = new ArrayObject(array( 50 | new AlwaysSuccessCheck() 51 | )); 52 | 53 | ob_start(); 54 | $this->reporter->onStart($checks, array()); 55 | $this->assertStringMatchesFormat('Starting diagnostics%A', ob_get_clean()); 56 | } 57 | 58 | public function testSuccessProgress() 59 | { 60 | $checks = new ArrayObject(array( 61 | new AlwaysSuccessCheck(), 62 | new AlwaysSuccessCheck(), 63 | )); 64 | 65 | ob_start(); 66 | $this->reporter->onStart($checks, array()); 67 | ob_clean(); 68 | 69 | $result = new Success(); 70 | $this->reporter->onAfterRun($checks[0], $result); 71 | $this->assertEquals(' OK Always Successful Check' . PHP_EOL, ob_get_clean()); 72 | 73 | ob_start(); 74 | $result = new Success('this is a message'); 75 | $this->reporter->onAfterRun($checks[1], $result); 76 | $this->assertEquals(' OK Always Successful Check: this is a message' . PHP_EOL, ob_get_clean()); 77 | } 78 | 79 | public function testWarningProgress() 80 | { 81 | $checks = new ArrayObject(array( 82 | new AlwaysSuccessCheck(), 83 | new AlwaysSuccessCheck(), 84 | )); 85 | 86 | ob_start(); 87 | $this->reporter->onStart($checks, array()); 88 | ob_clean(); 89 | 90 | $result = new Warning(); 91 | $this->reporter->onAfterRun($checks[0], $result); 92 | $this->assertEquals(' WARN Always Successful Check' . PHP_EOL, ob_get_clean()); 93 | 94 | ob_start(); 95 | $result = new Warning('this is a message'); 96 | $this->reporter->onAfterRun($checks[1], $result); 97 | $this->assertEquals(' WARN Always Successful Check: this is a message' . PHP_EOL, ob_get_clean()); 98 | } 99 | 100 | public function testFailureProgress() 101 | { 102 | $checks = new ArrayObject(array( 103 | new AlwaysSuccessCheck(), 104 | new AlwaysSuccessCheck(), 105 | )); 106 | 107 | ob_start(); 108 | $this->reporter->onStart($checks, array()); 109 | ob_clean(); 110 | 111 | $result = new Failure(); 112 | $this->reporter->onAfterRun($checks[0], $result); 113 | $this->assertEquals(' FAIL Always Successful Check' . PHP_EOL, ob_get_clean()); 114 | 115 | ob_start(); 116 | $result = new Failure('this is a message'); 117 | $this->reporter->onAfterRun($checks[1], $result); 118 | $this->assertEquals(' FAIL Always Successful Check: this is a message' . PHP_EOL, ob_get_clean()); 119 | } 120 | 121 | public function testUnknownSymbols() 122 | { 123 | $checks = new ArrayObject(array( 124 | new AlwaysSuccessCheck(), 125 | new AlwaysSuccessCheck(), 126 | )); 127 | 128 | ob_start(); 129 | $this->reporter->onStart($checks, array()); 130 | ob_clean(); 131 | 132 | $result = new Unknown(); 133 | $this->reporter->onAfterRun($checks[0], $result); 134 | $this->assertEquals(' ???? Always Successful Check' . PHP_EOL, ob_get_clean()); 135 | 136 | ob_start(); 137 | $result = new Unknown('this is a message'); 138 | $this->reporter->onAfterRun($checks[1], $result); 139 | $this->assertEquals(' ???? Always Successful Check: this is a message' . PHP_EOL, ob_get_clean()); 140 | } 141 | 142 | public function testInfoOverflow() 143 | { 144 | $this->console->setTestWidth(40); 145 | 146 | $checks = new ArrayObject(array( 147 | new AlwaysSuccessCheck(), 148 | new AlwaysSuccessCheck(), 149 | )); 150 | 151 | ob_start(); 152 | $this->reporter->onStart($checks, array()); 153 | ob_clean(); 154 | 155 | $result = new Success( 156 | 'foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo foo' 157 | ); 158 | 159 | $this->reporter->onAfterRun($checks[0], $result); 160 | $this->assertEquals( 161 | ' OK Always Successful Check: foo foo' . PHP_EOL . 162 | ' foo foo foo foo foo foo foo foo' . PHP_EOL . 163 | ' foo foo foo foo foo foo foo' . PHP_EOL, ob_get_clean() 164 | ); 165 | ob_start(); 166 | 167 | $result = new Failure( 168 | 'foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo' 169 | ); 170 | 171 | $this->reporter->onAfterRun($checks[1], $result); 172 | $this->assertEquals( 173 | ' FAIL Always Successful Check:' . PHP_EOL . 174 | ' foofoofoofoofoofoofoofoofoofoofoo' . PHP_EOL . 175 | ' foofoofoofoofoofoofoofoofoofoofoo' . PHP_EOL . 176 | ' foo' . PHP_EOL, ob_get_clean() 177 | ); 178 | } 179 | 180 | public function testDataDump() 181 | { 182 | $this->console->setTestWidth(40); 183 | $this->reporter->getDisplayData(); 184 | $this->reporter->setDisplayData(true); 185 | 186 | $checks = new ArrayObject(array( 187 | new AlwaysSuccessCheck(), 188 | new AlwaysSuccessCheck(), 189 | )); 190 | 191 | ob_start(); 192 | $this->reporter->onStart($checks, array()); 193 | ob_clean(); 194 | 195 | $result = new Success('foo', array('1', 2, 3)); 196 | $this->reporter->onAfterRun($checks[0], $result); 197 | $this->assertEquals( 198 | ' OK Always Successful Check: foo' . PHP_EOL . 199 | ' ---------------------------------' . PHP_EOL . 200 | ' array (' . PHP_EOL . 201 | ' 0 => \'1\',' . PHP_EOL . 202 | ' 1 => 2,' . PHP_EOL . 203 | ' 2 => 3,' . PHP_EOL . 204 | ' )' . PHP_EOL . 205 | ' ---------------------------------' . PHP_EOL, ob_get_clean() 206 | ); 207 | ob_start(); 208 | } 209 | 210 | public function testSummaryAllSuccessful() 211 | { 212 | $checks = new ArrayObject(array()); 213 | $check = null; 214 | $results = new Collection(); 215 | for ($x = 0; $x < 20; $x++) { 216 | $checks[] = $check = new AlwaysSuccessCheck(); 217 | $results[$check] = new Success(); 218 | } 219 | 220 | ob_start(); 221 | $this->reporter->onStart($checks, array()); 222 | ob_clean(); 223 | 224 | $this->reporter->onFinish($results); 225 | $this->assertStringStartsWith('OK (20 diagnostic checks)', trim(ob_get_clean())); 226 | } 227 | 228 | public function testSummaryWithWarnings() 229 | { 230 | $checks = new ArrayObject(array()); 231 | $check = null; 232 | $results = new Collection(); 233 | for ($x = 0; $x < 15; $x++) { 234 | $checks[] = $check = new AlwaysSuccessCheck(); 235 | $results[$check] = new Success(); 236 | } 237 | 238 | for ($x = 0; $x < 5; $x++) { 239 | $checks[] = $check = new AlwaysSuccessCheck(); 240 | $results[$check] = new Warning(); 241 | } 242 | 243 | ob_start(); 244 | $this->reporter->onStart($checks, array()); 245 | ob_clean(); 246 | 247 | $this->reporter->onFinish($results); 248 | $this->assertStringStartsWith('5 warnings, 15 successful checks', trim(ob_get_clean())); 249 | } 250 | 251 | public function testSummaryWithFailures() 252 | { 253 | $checks = new ArrayObject(array()); 254 | $check = null; 255 | $results = new Collection(); 256 | for ($x = 0; $x < 15; $x++) { 257 | $checks[] = $check = new AlwaysSuccessCheck(); 258 | $results[$check] = new Success(); 259 | } 260 | 261 | for ($x = 0; $x < 5; $x++) { 262 | $checks[] = $check = new AlwaysSuccessCheck(); 263 | $results[$check] = new Warning(); 264 | } 265 | 266 | for ($x = 0; $x < 5; $x++) { 267 | $checks[] = $check = new AlwaysSuccessCheck(); 268 | $results[$check] = new Failure(); 269 | } 270 | 271 | ob_start(); 272 | $this->reporter->onStart($checks, array()); 273 | ob_clean(); 274 | 275 | $this->reporter->onFinish($results); 276 | $this->assertStringStartsWith('5 failures, 5 warnings, 15 successful checks', trim(ob_get_clean())); 277 | } 278 | 279 | public function testSummaryWithUnknowns() 280 | { 281 | $checks = new ArrayObject(array()); 282 | $check = null; 283 | $results = new Collection(); 284 | for ($x = 0; $x < 15; $x++) { 285 | $checks[] = $check = new AlwaysSuccessCheck(); 286 | $results[$check] = new Success(); 287 | } 288 | 289 | for ($x = 0; $x < 5; $x++) { 290 | $checks[] = $check = new AlwaysSuccessCheck(); 291 | $results[$check] = new Warning(); 292 | } 293 | 294 | for ($x = 0; $x < 5; $x++) { 295 | $checks[] = $check = new AlwaysSuccessCheck(); 296 | $results[$check] = new Unknown(); 297 | } 298 | 299 | ob_start(); 300 | $this->reporter->onStart($checks, array()); 301 | ob_clean(); 302 | 303 | $this->reporter->onFinish($results); 304 | $this->assertStringMatchesFormat('%A5 unknown check results%A', trim(ob_get_clean())); 305 | } 306 | 307 | public function testSummaryWithUnknownsAndFailures() 308 | { 309 | $checks = new ArrayObject(array()); 310 | $check = null; 311 | $results = new Collection(); 312 | for ($x = 0; $x < 15; $x++) { 313 | $checks[] = $check = new AlwaysSuccessCheck(); 314 | $results[$check] = new Success(); 315 | } 316 | 317 | for ($x = 0; $x < 5; $x++) { 318 | $checks[] = $check = new AlwaysSuccessCheck(); 319 | $results[$check] = new Failure(); 320 | } 321 | 322 | for ($x = 0; $x < 5; $x++) { 323 | $checks[] = $check = new AlwaysSuccessCheck(); 324 | $results[$check] = new Unknown(); 325 | } 326 | 327 | ob_start(); 328 | $this->reporter->onStart($checks, array()); 329 | ob_clean(); 330 | 331 | $this->reporter->onFinish($results); 332 | $result = trim(ob_get_clean()); 333 | $this->assertStringMatchesFormat('%A5 failures%A', $result); 334 | $this->assertStringMatchesFormat('%A5 unknown check results%A', $result); 335 | } 336 | 337 | public function testStoppedNotice() 338 | { 339 | $checks = new ArrayObject(array()); 340 | $check = null; 341 | $results = new Collection(); 342 | for ($x = 0; $x < 15; $x++) { 343 | $checks[] = $check = new AlwaysSuccessCheck(); 344 | $results[$check] = new Success(); 345 | } 346 | 347 | ob_start(); 348 | $this->reporter->onStart($checks, array()); 349 | ob_clean(); 350 | 351 | $this->reporter->onStop($results); 352 | $this->reporter->onFinish($results); 353 | $this->assertStringMatchesFormat('%ADiagnostics aborted%A', trim(ob_get_clean())); 354 | } 355 | } 356 | -------------------------------------------------------------------------------- /tests/ZFToolTest/Diagnostics/RunnerTest.php: -------------------------------------------------------------------------------- 1 | runner = new Runner(array()); 25 | } 26 | 27 | public function testConfig() 28 | { 29 | $this->assertInstanceOf('ZFTool\Diagnostics\Config', $this->runner->getConfig()); 30 | $this->assertInstanceOf('ZFTool\Diagnostics\ConfigInterface', $this->runner->getConfig()); 31 | 32 | $newConfig = new Config(); 33 | $this->runner->setConfig($newConfig); 34 | $this->assertInstanceOf('ZFTool\Diagnostics\Config', $this->runner->getConfig()); 35 | $this->assertSame($newConfig, $this->runner->getConfig()); 36 | 37 | $newConfig->setBreakOnFailure(true); 38 | $this->assertTrue($newConfig->getBreakOnFailure()); 39 | $this->assertTrue($this->runner->getBreakOnFailure()); 40 | 41 | $this->runner->setBreakOnFailure(false); 42 | $this->assertFalse($this->runner->getBreakOnFailure()); 43 | $this->assertFalse($newConfig->getBreakOnFailure()); 44 | 45 | $newConfig->setCatchErrorSeverity(100); 46 | $this->assertEquals(100, $newConfig->getCatchErrorSeverity()); 47 | $this->assertEquals(100, $this->runner->getCatchErrorSeverity()); 48 | 49 | $this->runner->setCatchErrorSeverity(200); 50 | $this->assertEquals(200, $newConfig->getCatchErrorSeverity()); 51 | $this->assertEquals(200, $this->runner->getCatchErrorSeverity()); 52 | 53 | $this->setExpectedException('ZFTool\Diagnostics\Exception\InvalidArgumentException'); 54 | $this->runner->setConfig('foo'); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /tests/ZFToolTest/Diagnostics/TestAsset/AlwaysFailCheck.php: -------------------------------------------------------------------------------- 1 | testWidth = $width; 32 | } 33 | 34 | /** 35 | * Force reported utf8 capability. 36 | * 37 | * @param bool $isUtf8 38 | */ 39 | public function setTestUtf8($isUtf8) 40 | { 41 | $this->testIsUtf8 = $isUtf8; 42 | } 43 | 44 | public function isUtf8() 45 | { 46 | return $this->testIsUtf8; 47 | } 48 | 49 | public function getWidth() 50 | { 51 | return $this->testWidth; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /tests/ZFToolTest/Diagnostics/TestAsset/DummyModule.php: -------------------------------------------------------------------------------- 1 | sm = $sm; 21 | } 22 | 23 | public function getDiagnostics() 24 | { 25 | return array( 26 | 'test1' => function () {return new Success('test1 success');}, 27 | 'test2' => array('is_string', 'a'), 28 | 'test3' => array('stristr', 'abc','d'), 29 | 'test4' => array(__CLASS__,'staticTestMethod'), 30 | 'test5' => array(array(__CLASS__,'staticTestMethod'), 'someOtherMessage'), 31 | ); 32 | } 33 | 34 | public static function staticTestMethod($message = 'static check message') 35 | { 36 | return new Failure($message); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tests/ZFToolTest/Diagnostics/TestAsset/DummyReporter.php: -------------------------------------------------------------------------------- 1 | stopAfterRun = false; 22 | } 23 | 24 | /** 25 | * This method is called right after Reporter starts running, via Runner::run() 26 | * 27 | * @param ArrayObject $checks A collection of Checks that will be performed 28 | * @param array $runnerConfig Complete Runner configuration, obtained via Runner::getConfig() 29 | * @return void 30 | */ 31 | public function onStart(ArrayObject $checks, $runnerConfig) 32 | { 33 | } 34 | 35 | /** 36 | * This method is called before each individual Check is performed. If this 37 | * method returns false, the Check will not be performed (will be skipped). 38 | * 39 | * @param CheckInterface $check Check instance that is about to be performed. 40 | * @param bool $alias Test alias. 41 | * @return bool|void Return false to prevent check from happening 42 | */ 43 | public function onBeforeRun(CheckInterface $check, $alias = null) 44 | { 45 | } 46 | 47 | /** 48 | * This method is called every time a Check has been performed. If this method 49 | * returns false, the Runner will not perform any additional checks and stop 50 | * its run. 51 | * 52 | * @param CheckInterface $check A Check instance that has just finished running 53 | * @param ResultInterface $result Result for that particular check instance 54 | * @param bool $alias Test alias. 55 | * @return bool|void Return false to prevent from running additional Checks 56 | */ 57 | public function onAfterRun(CheckInterface $check, ResultInterface $result, $alias = null) 58 | { 59 | if (!$this->stopAfterRun) { 60 | return false; 61 | } 62 | } 63 | 64 | /** 65 | * This method is called when Runner has been aborted and could not finish the 66 | * whole run(). 67 | * 68 | * @param ResultsCollection $results Collection of Results for performed Checks. 69 | * @return void 70 | */ 71 | public function onStop(ResultsCollection $results) 72 | { 73 | } 74 | 75 | /** 76 | * This method is called when Runner has finished its run. 77 | * 78 | * @param ResultsCollection $results Collection of Results for performed Checks. 79 | * @return void 80 | */ 81 | public function onFinish(ResultsCollection $results) 82 | { 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /tests/ZFToolTest/Diagnostics/TestAsset/InjectableModuleManager.php: -------------------------------------------------------------------------------- 1 | loadedModules[$name] = $module; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/ZFToolTest/Diagnostics/TestAsset/ReturnThisCheck.php: -------------------------------------------------------------------------------- 1 | value = $valueToReturn; 15 | $this->label = gettype($valueToReturn); 16 | } 17 | 18 | public function check() 19 | { 20 | return $this->value; 21 | } 22 | 23 | public function setLabel($label) 24 | { 25 | $this->label = $label; 26 | } 27 | 28 | public function getLabel() 29 | { 30 | return $this->label; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/ZFToolTest/Diagnostics/TestAsset/UnknownResult.php: -------------------------------------------------------------------------------- 1 | assertTrue(is_array($result)); 14 | } else { 15 | $this->markTestSkipped('The github API is not accessible.'); 16 | } 17 | } 18 | 19 | public function testGetSkeletonApp() 20 | { 21 | $tmpFile = sys_get_temp_dir() . '/testZFTool.zip'; 22 | $result = Skeleton::getSkeletonApp($tmpFile); 23 | if ($result) { 24 | $this->assertTrue(file_exists($tmpFile)); 25 | @unlink($tmpFile); 26 | } else { 27 | $this->markTestSkipped('The ZF2 Skeleton github repository is not accessible.'); 28 | } 29 | } 30 | 31 | public function testGetLastZip() 32 | { 33 | $tmpFile = sys_get_temp_dir() . '/' . Skeleton::SKELETON_FILE . '_test.zip'; 34 | Skeleton::getSkeletonApp($tmpFile); 35 | if (file_exists($tmpFile)) { 36 | $result = Skeleton::getLastZip(sys_get_temp_dir()); 37 | $this->assertTrue(!empty($result)); 38 | unlink($tmpFile); 39 | } else { 40 | $this->markTestSkipped('The ZF2 Skeleton github repository is not accessible.'); 41 | } 42 | } 43 | 44 | public function testGetTmpFileName() 45 | { 46 | $commit = array('sha' => 'test'); 47 | $path = sys_get_temp_dir(); 48 | $result = Skeleton::getTmpFileName($path, $commit); 49 | $this->assertEquals($result, $path . '/' . Skeleton::SKELETON_FILE . '_test.zip'); 50 | } 51 | 52 | public function testGetTmpFileNameWrongCommit() 53 | { 54 | $commit = array('foo' => 'bar'); 55 | $path = sys_get_temp_dir(); 56 | $result = Skeleton::getTmpFileName($path, $commit); 57 | $this->assertEquals('', $result); 58 | } 59 | 60 | public function testExportConfig() 61 | { 62 | $config = array( 63 | 'foo' => array( 64 | 'foo2' => 'bar2', 65 | 'foo3' => 'bar3' 66 | ), 67 | 'bar' 68 | ); 69 | $export = Skeleton::exportConfig($config); 70 | $expected = << array( 73 | 'foo2' => 'bar2', 74 | 'foo3' => 'bar3', 75 | ), 76 | 'bar', 77 | ) 78 | EOD; 79 | $this->assertEquals($expected, (string) $export); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /tests/ZFToolTest/Model/UtilityTest.php: -------------------------------------------------------------------------------- 1 | tmp = sys_get_temp_dir() . '/testZFTool'; 14 | 15 | mkdir($this->tmp); 16 | file_put_contents($this->tmp . '/foo', 'bar'); 17 | chmod($this->tmp . '/foo', 0755); 18 | mkdir($this->tmp . '/foo-dir'); 19 | file_put_contents($this->tmp . '/foo-dir/foo2', 'bar2'); 20 | } 21 | 22 | public function tearDown() 23 | { 24 | @unlink($this->tmp . '/foo-dir/foo2'); 25 | @rmdir($this->tmp . '/foo-dir'); 26 | @unlink($this->tmp . '/foo'); 27 | @rmdir($this->tmp); 28 | } 29 | 30 | public function testCopyFiles() 31 | { 32 | $tmpDir2 = $this->tmp . '2'; 33 | 34 | $result = Utility::copyFiles($this->tmp, $tmpDir2); 35 | $this->assertTrue($result); 36 | $this->assertTrue(file_exists($tmpDir2 . '/foo')); 37 | $this->assertEquals('bar', file_get_contents($tmpDir2 . '/foo')); 38 | $this->assertEquals(fileperms($this->tmp . '/foo'), fileperms($tmpDir2 . '/foo')); 39 | $this->assertTrue(file_exists($tmpDir2 . '/foo-dir')); 40 | $this->assertTrue(file_exists($tmpDir2 . '/foo-dir/foo2')); 41 | $this->assertEquals(fileperms($this->tmp . '/foo-dir/foo2'), fileperms($tmpDir2 . '/foo-dir/foo2')); 42 | $this->assertEquals('bar2', file_get_contents($tmpDir2 . '/foo-dir/foo2')); 43 | 44 | unlink($tmpDir2 . '/foo-dir/foo2'); 45 | rmdir($tmpDir2 . '/foo-dir'); 46 | unlink($tmpDir2 . '/foo'); 47 | rmdir($tmpDir2); 48 | } 49 | 50 | public function testDeleteFolder() 51 | { 52 | $result = Utility::deleteFolder($this->tmp); 53 | $this->assertTrue($result); 54 | $this->assertFalse(file_exists($this->tmp)); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /tests/phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ./ZFToolTest 7 | 8 | 9 | 10 | 11 | 12 | disable 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /view/diagnostics/run.phtml: -------------------------------------------------------------------------------- 1 | 91 |

Diagnostics

92 |
93 | results as $test): 96 | $x++; 97 | $result = $this->results[$test]; 98 | $resultClass = get_class($result); 99 | $resultClass = strtolower(substr($resultClass, strrpos($resultClass, '\\') + 1)); 100 | ?> 101 | 105 | 106 |
107 | 108 | getFailureCount() == 0 && $results->getWarningCount() == 0 && $results->getUnknownCount() == 0) { 110 | echo '

OK (' . $results->getSuccessCount().' diagnostic tests)

'; 111 | } elseif ($results->getFailureCount() == 0) { 112 | echo '

'; 113 | echo $results->getWarningCount().' warning(s), '; 114 | echo $results->getSuccessCount().' successful test(s)'; 115 | if ($results->getUnknownCount()) { 116 | echo ', ' . $results->getUnknownCount().' unknown test result(s)'; 117 | } 118 | echo '

'; 119 | } else { 120 | echo '

'; 121 | echo $results->getFailureCount().' failure(s), '; 122 | echo $results->getWarningCount().' warning(s), '; 123 | echo $results->getSuccessCount().' successful test(s)'; 124 | if ($results->getUnknownCount()) { 125 | echo ', ' . $results->getUnknownCount().' unknown test result(s)'; 126 | } 127 | echo '

'; 128 | 129 | } 130 | ?> 131 | 132 |

Details

133 |
    134 | results as $test): 137 | $x++; 138 | $result = $this->results[$test]; 139 | $resultClass = get_class($result); 140 | $resultClass = strtolower(substr($resultClass, strrpos($resultClass, '\\') + 1)); 141 | switch($resultClass){ 142 | case 'success': $resultNoun = 'OK'; break; 143 | case 'failure': $resultNoun = 'FAIL'; break; 144 | case 'warning': $resultNoun = 'WARN'; break; 145 | default: 146 | case 'unknown': $resultNoun = '????'; break; 147 | }; 148 | ?> 149 |
  • 150 | 151 | 152 | getLabel(); 154 | if($message = $result->getMessage()) { 155 | echo ': ' . $message; 156 | } 157 | 158 | if($data = $result->getData()) { 159 | echo '[debug]'; 160 | echo '
    ';
    161 |                 echo $this->escapeHtml(print_r($data, true));
    162 |                 echo '
    '; 163 | } 164 | ?> 165 | 166 |
  • 167 | 168 |
169 | 187 | -------------------------------------------------------------------------------- /zf.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | array( 36 | 'ZFTool', 37 | ), 38 | 'module_listener_options' => array( 39 | 'config_glob_paths' => array( 40 | 'config/autoload/{,*.}{global,local}.php', 41 | ), 42 | 'module_paths' => array( 43 | '.', 44 | './vendor', 45 | ), 46 | ), 47 | ); 48 | } 49 | 50 | Zend\Mvc\Application::init($appConfig)->run(); 51 | -------------------------------------------------------------------------------- /zf2.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | php %~dp0zf.php %* --------------------------------------------------------------------------------