├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── bin └── zf-development-mode ├── composer.json ├── development.config.php.dist ├── development.local.php.dist └── src ├── AutoComposer.php ├── Command.php ├── ConfigDiscoveryTrait.php ├── Disable.php ├── Enable.php ├── Help.php └── Status.php /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file, in reverse chronological order by release. 4 | 5 | ## 3.2.1 - TBD 6 | 7 | ### Added 8 | 9 | - Nothing. 10 | 11 | ### Changed 12 | 13 | - Nothing. 14 | 15 | ### Deprecated 16 | 17 | - Nothing. 18 | 19 | ### Removed 20 | 21 | - Nothing. 22 | 23 | ### Fixed 24 | 25 | - Nothing. 26 | 27 | ## 3.2.0 - 2018-05-07 28 | 29 | ### Added 30 | 31 | - [#35](https://github.com/zfcampus/zf-development-mode/pull/35) adds support for PHP 7.2. 32 | 33 | - [#32](https://github.com/zfcampus/zf-development-mode/pull/32) adds a new sub-command, `auto-composer`. When invoked, it uses the value of 34 | the environment variable COMPOSER_DEV_MODE to determine whether to enable or disable development 35 | mode locally. If the variable is not present, it does nothing; if `0`, it disables development 36 | mode, and if `1`, it enables development mode. This can be particularly useful as a composer script: 37 | 38 | ```json 39 | "scripts": { 40 | "development-auto": "zf-development-mode auto-composer", 41 | "post-install-cmd": ["@development-auto"], 42 | "post-update-cmd": ["@development-auto"] 43 | } 44 | ``` 45 | 46 | ### Changed 47 | 48 | - [#29](https://github.com/zfcampus/zf-development-mode/pull/29) modifies how the `enable` subcommand copies development config files into 49 | the filesystem. On operating systems that are known to support `symlink()` predictably, 50 | the command will now create symlinks instead of copies. These include most Linux, BSD, 51 | and MacOS variants. 52 | 53 | ### Deprecated 54 | 55 | - Nothing. 56 | 57 | ### Removed 58 | 59 | - [#35](https://github.com/zfcampus/zf-development-mode/pull/35) removes support for HHVM. 60 | 61 | ### Fixed 62 | 63 | - Nothing. 64 | 65 | ## 3.1.0 - 2017-01-09 66 | 67 | ### Added 68 | 69 | - [#23](https://github.com/zfcampus/zf-development-mode/pull/23) adds support 70 | for [Expressive](https://docs.zendframework.com/zend-expressive) applications. 71 | 72 | ### Deprecated 73 | 74 | - Nothing. 75 | 76 | ### Removed 77 | 78 | - Nothing. 79 | 80 | ### Fixed 81 | 82 | - Nothing. 83 | 84 | ## 3.0.0 - 2016-06-22 85 | 86 | ### Added 87 | 88 | - [#19](https://github.com/zfcampus/zf-development-mode/pull/19) adds a 89 | standalone vendor binary, which may be invoked as 90 | `./vendor/bin/zf-development-mode`. 91 | - [#19](https://github.com/zfcampus/zf-development-mode/pull/19) adds support 92 | for PHP 7. 93 | 94 | ### Deprecated 95 | 96 | - Nothing. 97 | 98 | ### Removed 99 | 100 | - [#19](https://github.com/zfcampus/zf-development-mode/pull/19) removes 101 | integration with zend-mvc/zend-console. 102 | - [#19](https://github.com/zfcampus/zf-development-mode/pull/19) removes 103 | the suggestions to install ZendDeveloperTools and ZFTool, as they are not 104 | ready for zend-mvc v3. 105 | - [#19](https://github.com/zfcampus/zf-development-mode/pull/19) removes 106 | support for PHP versions less than 5.6. 107 | 108 | ### Fixed 109 | 110 | - Nothing. 111 | 112 | ## 2.1.2 - 2015-12-21 113 | 114 | ### Added 115 | 116 | - [#35](https://github.com/zfcampus/zf-development-mode/pull/35) adds support for PHP 7.2. 117 | 118 | ### Changed 119 | 120 | - Nothing. 121 | 122 | ### Deprecated 123 | 124 | - Nothing. 125 | 126 | ### Removed 127 | 128 | - Nothing. 129 | 130 | ### Fixed 131 | 132 | - [#17](https://github.com/zfcampus/zf-development-mode/pull/17) fixes the 133 | `DevelopmentModeControllerFactory` to check for configuration caching settings 134 | under the `module_listener_options` top-level key (instead of the settings 135 | root). 136 | 137 | ## 2.1.1 - 2015-08-31 138 | 139 | ### Added 140 | 141 | - Nothing. 142 | 143 | ### Deprecated 144 | 145 | - Nothing. 146 | 147 | ### Removed 148 | 149 | - Nothing. 150 | 151 | ### Fixed 152 | 153 | - [#13](https://github.com/zfcampus/zf-development-mode/pull/13) ensures that 154 | the application configuration cache file is always removed when switching 155 | to and from development mode. 156 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014-2018, Zend Technologies USA, Inc. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | - Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | - Redistributions in binary form must reproduce the above copyright notice, this 11 | list of conditions and the following disclaimer in the documentation and/or 12 | other materials provided with the distribution. 13 | 14 | - Neither the name of Zend Technologies USA, Inc. nor the names of its 15 | contributors may be used to endorse or promote products derived from this 16 | software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # zf-development-mode 2 | 3 | > ## Repository abandoned 2019-12-31 4 | > 5 | > This repository has moved to [laminas/laminas-development-mode](https://github.com/laminas/laminas-development-mode). 6 | 7 | [![Build Status](https://secure.travis-ci.org/zfcampus/zf-development-mode.svg?branch=master)](https://secure.travis-ci.org/zfcampus/zf-development-mode) 8 | [![Coverage Status](https://coveralls.io/repos/github/zfcampus/zf-development-mode/badge.svg?branch=master)](https://coveralls.io/github/zfcampus/zf-development-mode?branch=master) 9 | [![Total Downloads](https://poser.pugx.org/zfcampus/zf-development-mode/downloads)](https://packagist.org/packages/zfcampus/zf-development-mode) 10 | 11 | This package provides a script to allow you to enable and disable development 12 | mode for [zend-mvc](https://docs.zendframework.com/zend-mvc) (both versions 2 13 | and 3) and [Expressive](https://docs.zendframework.com/zend-expressive) 14 | applications. The script allows you to specify configuration and modules that 15 | should only be enabled when in development, and not when in production. 16 | 17 | ## Note to v2 users 18 | 19 | If you were using a v2 version of this package previously, invocation has 20 | changed. Previously, you would invoke it via the MVC CLI bootstrap: 21 | 22 | ```bash 23 | $ php public/index.php development enable # enable development mode 24 | $ php public/index.php development disable # disable development mode 25 | ``` 26 | 27 | v3 releases now install this as a vendor binary, with no dependencies on other 28 | components: 29 | 30 | ```bash 31 | $ ./vendor/bin/zf-development-mode enable # enable development mode 32 | $ ./vendor/bin/zf-development-mode disable # disable development mode 33 | ``` 34 | 35 | ## Installation 36 | 37 | Install this package using Composer: 38 | 39 | ```bash 40 | $ composer require zfcampus/zf-development-mode 41 | ``` 42 | 43 | Once installed, you will need to copy a base development configuration into your 44 | application; this configuration will allow you to override modules and bootstrap 45 | configuration: 46 | 47 | ```bash 48 | $ cp vendor/zfcampus/zf-development-mode/development.config.php.dist config/ 49 | ``` 50 | 51 | Optionally, if you want to also have development-specific application 52 | configuration, you can copy another base configuration into your configuration 53 | autoload directory: 54 | 55 | ```bash 56 | $ cp vendor/zfcampus/zf-development-mode/development.local.php.dist config/autoload/ 57 | ``` 58 | 59 | In order for the bootstrap development configuration to run, you may need to 60 | update your application bootstrap. Look for the following lines (or similar) in 61 | `public/index.php`: 62 | 63 | ```php 64 | // Run the application! 65 | Zend\Mvc\Application::init(require 'config/application.config.php')->run(); 66 | ``` 67 | 68 | Replace the above with the following: 69 | 70 | ```php 71 | // Config 72 | $appConfig = include 'config/application.config.php'; 73 | if (file_exists('config/development.config.php')) { 74 | $appConfig = Zend\Stdlib\ArrayUtils::merge($appConfig, include 'config/development.config.php'); 75 | } 76 | 77 | // Run the application! 78 | Zend\Mvc\Application::init($appConfig)->run(); 79 | ``` 80 | 81 | ## To enable development mode 82 | 83 | ```bash 84 | $ cd path/to/project 85 | $ ./vendor/bin/zf-development-mode enable 86 | ``` 87 | 88 | Note: enabling development mode will also clear your module configuation cache, 89 | to allow safely updating dependencies and ensuring any new configuration is 90 | picked up by your application. 91 | 92 | # To disable development mode 93 | 94 | ```bash 95 | $ cd path/to/project 96 | $ ./vendor/bin/zf-development-mode disable 97 | ``` 98 | 99 | **Note:** Don't run development mode on your production server! 100 | -------------------------------------------------------------------------------- /bin/zf-development-mode: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | [ 6 | ], 7 | 8 | 'module_listener_options' => [ 9 | // Turn off caching 10 | 'config_cache_enabled' => false, 11 | 'module_map_cache_enabled' => false, 12 | ], 13 | ]; 14 | -------------------------------------------------------------------------------- /development.local.php.dist: -------------------------------------------------------------------------------- 1 | [ 5 | 'display_exceptions' => true, 6 | ] 7 | ]; 8 | -------------------------------------------------------------------------------- /src/AutoComposer.php: -------------------------------------------------------------------------------- 1 | composerDevMode = getenv(self::COMPOSER_DEV_MODE); 53 | $this->projectDir = $projectDir; 54 | $this->errorStream = is_resource($errorStream) ? $errorStream : STDERR; 55 | } 56 | 57 | /** 58 | * Enable or disable developer mode based on composerDevMode. 59 | * 60 | * @return int 61 | */ 62 | public function __invoke() 63 | { 64 | if ($this->composerDevMode === '' || $this->composerDevMode === false) { 65 | // Not running under composer; do nothing. 66 | echo 'COMPOSER_DEV_MODE not set. Nothing to do.' . PHP_EOL; 67 | return 0; 68 | } 69 | 70 | if ($this->composerDevMode === '0') { 71 | $disable = new Disable($this->projectDir, $this->errorStream); 72 | return $disable(); 73 | } 74 | 75 | if ($this->composerDevMode === '1') { 76 | $enable = new Enable($this->projectDir, $this->errorStream); 77 | return $enable(); 78 | } 79 | 80 | printf( 81 | 'COMPOSER_DEV_MODE set to unexpected value (%s). Nothing to do.%s', 82 | var_export($this->composerDevMode, true), 83 | PHP_EOL 84 | ); 85 | return 1; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/Command.php: -------------------------------------------------------------------------------- 1 | getConfigCacheFile(); 43 | 44 | if (! $configCacheFile || ! file_exists($configCacheFile)) { 45 | return; 46 | } 47 | 48 | unlink($configCacheFile); 49 | } 50 | 51 | /** 52 | * Retrieve the config cache file, if any. 53 | * 54 | * @return false|string 55 | */ 56 | private function getConfigCacheFile() 57 | { 58 | $config = $this->getApplicationConfig(); 59 | 60 | if (isset($config['config_cache_path'])) { 61 | return $config['config_cache_path']; 62 | } 63 | 64 | $configCacheDir = $this->getConfigCacheDir(); 65 | 66 | if (! $configCacheDir) { 67 | return false; 68 | } 69 | 70 | $path = sprintf('%s/%s.', $configCacheDir, $this->configCacheBase); 71 | 72 | $configCacheKey = $this->getConfigCacheKey(); 73 | if ($configCacheKey) { 74 | $path .= $configCacheKey . '.'; 75 | } 76 | 77 | return $path . 'php'; 78 | } 79 | 80 | /** 81 | * Return the configured configuration cache directory, if any. 82 | * 83 | * @return null|string 84 | */ 85 | private function getConfigCacheDir() 86 | { 87 | $config = $this->getApplicationConfig(); 88 | if (empty($config['module_listener_options']['cache_dir'])) { 89 | return null; 90 | } 91 | 92 | return $config['module_listener_options']['cache_dir']; 93 | } 94 | 95 | /** 96 | * Return the configured configuration cache key, if any. 97 | * 98 | * @return null|string 99 | */ 100 | private function getConfigCacheKey() 101 | { 102 | $config = $this->getApplicationConfig(); 103 | if (empty($config['module_listener_options']['config_cache_key'])) { 104 | return null; 105 | } 106 | 107 | return $config['module_listener_options']['config_cache_key']; 108 | } 109 | 110 | /** 111 | * Return the application configuration. 112 | * 113 | * Raises an exception if retrieved configuration is not an array. 114 | * 115 | * @return array 116 | * @throws RuntimeException if config/application.config.php does not 117 | * return an array 118 | */ 119 | private function getApplicationConfig() 120 | { 121 | if (null !== $this->applicationConfig) { 122 | return $this->applicationConfig; 123 | } 124 | 125 | $configFile = isset($this->projectDir) 126 | ? sprintf('%s/%s', $this->projectDir, $this->applicationConfigPath) 127 | : $this->applicationConfigPath; 128 | 129 | $configFile = file_exists($configFile) ? $configFile : $this->expressiveConfigPath; 130 | 131 | if (! file_exists($configFile)) { 132 | $this->applicationConfig = []; 133 | return $this->applicationConfig; 134 | } 135 | 136 | $this->applicationConfig = include $configFile; 137 | 138 | if (! is_array($this->applicationConfig)) { 139 | throw new RuntimeException( 140 | 'Invalid configuration returned from config/application.config.php or config/config.php;' . PHP_EOL 141 | . 'is this a Zend Framework or Zend Expressive application?' . PHP_EOL 142 | ); 143 | } 144 | 145 | return $this->applicationConfig; 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /src/Disable.php: -------------------------------------------------------------------------------- 1 | projectDir = $projectDir; 36 | $this->errorStream = is_resource($errorStream) ? $errorStream : STDERR; 37 | } 38 | 39 | /** 40 | * Disable development mode. 41 | * 42 | * @return int 43 | */ 44 | public function __invoke() 45 | { 46 | $develConfig = $this->projectDir 47 | ? sprintf('%s/%s', $this->projectDir, self::DEVEL_CONFIG) 48 | : self::DEVEL_CONFIG; 49 | if (! file_exists($develConfig)) { 50 | // nothing to do 51 | echo 'Development mode was already disabled.', PHP_EOL; 52 | return 0; 53 | } 54 | 55 | try { 56 | $this->removeConfigCacheFile(); 57 | } catch (RuntimeException $ex) { 58 | fwrite($this->errorStream, $ex->getMessage()); 59 | return 1; 60 | } 61 | 62 | $develLocalConfig = $this->projectDir 63 | ? sprintf('%s/%s', $this->projectDir, self::DEVEL_LOCAL) 64 | : self::DEVEL_LOCAL; 65 | if (file_exists($develLocalConfig)) { 66 | // optional application config override 67 | unlink($develLocalConfig); 68 | } 69 | 70 | unlink($develConfig); 71 | 72 | echo 'Development mode is now disabled.', PHP_EOL; 73 | return 0; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/Enable.php: -------------------------------------------------------------------------------- 1 | projectDir = $projectDir; 38 | $this->errorStream = is_resource($errorStream) ? $errorStream : STDERR; 39 | } 40 | 41 | /** 42 | * Enable development mode. 43 | * 44 | * @return int 45 | */ 46 | public function __invoke() 47 | { 48 | $develConfig = $this->projectDir 49 | ? sprintf('%s/%s', $this->projectDir, self::DEVEL_CONFIG) 50 | : self::DEVEL_CONFIG; 51 | if (file_exists($develConfig)) { 52 | // nothing to do 53 | echo 'Already in development mode!', PHP_EOL; 54 | return 0; 55 | } 56 | 57 | $develConfigDist = $this->projectDir 58 | ? sprintf('%s/%s', $this->projectDir, self::DEVEL_CONFIG_DIST) 59 | : self::DEVEL_CONFIG_DIST; 60 | if (! file_exists($develConfigDist)) { 61 | fwrite( 62 | $this->errorStream, 63 | 'MISSING "config/development.config.php.dist". Could not switch to development mode!' . PHP_EOL 64 | ); 65 | return 1; 66 | } 67 | 68 | try { 69 | $this->removeConfigCacheFile(); 70 | } catch (RuntimeException $ex) { 71 | fwrite($this->errorStream, $ex->getMessage()); 72 | return 1; 73 | } 74 | 75 | $this->copy($develConfigDist, $develConfig); 76 | 77 | $develLocalDist = $this->projectDir 78 | ? sprintf('%s/%s', $this->projectDir, self::DEVEL_LOCAL_DIST) 79 | : self::DEVEL_LOCAL_DIST; 80 | if (file_exists($develLocalDist)) { 81 | // optional application config override 82 | $develLocal = $this->projectDir 83 | ? sprintf('%s/%s', $this->projectDir, self::DEVEL_LOCAL) 84 | : self::DEVEL_LOCAL; 85 | $this->copy($develLocalDist, $develLocal); 86 | } 87 | 88 | echo 'You are now in development mode.', PHP_EOL; 89 | return 0; 90 | } 91 | 92 | /** 93 | * Returns whether the OS support symlinks reliably. 94 | * 95 | * This approach uses a pre-configured whitelist of PHP_OS values that 96 | * typically support symlinks reliably. This may omit some systems that 97 | * also support symlinks properly; if you find this to be the case, please 98 | * send a pull request with the PHP_OS value for us to match. 99 | * 100 | * This method is marked protected so that we can mock it. 101 | * 102 | * @return bool 103 | */ 104 | protected function supportsSymlinks() 105 | { 106 | return in_array(PHP_OS, ['Linux', 'Unix', 'Darwin']); 107 | } 108 | 109 | /** 110 | * Copy, or symlink, the source to the destination. 111 | * 112 | * @param string $source 113 | * @param string $destination 114 | * @return void 115 | */ 116 | private function copy($source, $destination) 117 | { 118 | if ($this->supportsSymlinks()) { 119 | symlink(basename($source), $destination); 120 | return; 121 | } 122 | 123 | copy($source, $destination); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/Help.php: -------------------------------------------------------------------------------- 1 | message; 65 | return; 66 | } 67 | 68 | fwrite($stream, $this->message); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/Status.php: -------------------------------------------------------------------------------- 1 | develConfigFile = self::DEVEL_CONFIG; 26 | return; 27 | } 28 | 29 | $this->develConfigFile = sprintf('%s/%s', $projectDir, self::DEVEL_CONFIG); 30 | } 31 | 32 | /** 33 | * Indicate whether or not development mode is enabled. 34 | * 35 | * @return int 36 | */ 37 | public function __invoke() 38 | { 39 | if (file_exists($this->develConfigFile)) { 40 | // nothing to do 41 | echo 'Development mode is ENABLED', PHP_EOL; 42 | return 0; 43 | } 44 | 45 | echo 'Development mode is DISABLED', PHP_EOL; 46 | return 0; 47 | } 48 | } 49 | --------------------------------------------------------------------------------