├── wp-cli.yml ├── .gitignore ├── command.php ├── composer.json ├── src ├── Build_Generate_Command.php ├── Build_Parser.php ├── Build_Command.php ├── Helper │ ├── WP_API.php │ └── Utils.php └── Processor │ ├── Core.php │ ├── Item.php │ └── Generate.php ├── README.md └── composer.lock /wp-cli.yml: -------------------------------------------------------------------------------- 1 | require: 2 | - command.php -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore directories generated by Composer 2 | /vendor/ 3 | 4 | # Ignore DDEV local development environment 5 | .ddev/config.yaml 6 | 7 | # Ignore files generated by common IDEs 8 | /.idea/ 9 | /.vscode/ 10 | -------------------------------------------------------------------------------- /command.php: -------------------------------------------------------------------------------- 1 | 'Parse the build file and download, install or update the core, plugins or themes on it.' 22 | ) ); 23 | 24 | WP_CLI::add_command( 'build-generate', Build_Generate_Command::class, array( 25 | 'shortdesc' => 'Generates a build file according to current WordPress installation.' 26 | ) ); 27 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "front/wp-cli-build", 3 | "description": "Fetch specific versions of plugins/themes from wordpress.org using a build file", 4 | "type": "wp-cli-package", 5 | "homepage": "https://github.com/front/wp-cli-build", 6 | "license": "MIT", 7 | "authors": [ 8 | { 9 | "name": "Frontkom", 10 | "email": "hello@frontkom.com", 11 | "homepage": "https://frontkom.com" 12 | } 13 | ], 14 | "minimum-stability": "dev", 15 | "prefer-stable": true, 16 | "config": { 17 | "discard-changes": true, 18 | "sort-packages": true, 19 | "allow-plugins": { 20 | "dealerdirect/phpcodesniffer-composer-installer": true 21 | } 22 | }, 23 | "autoload": { 24 | "files": [ 25 | "command.php" 26 | ] 27 | }, 28 | "require": { 29 | "php": "~7.4.0", 30 | "alchemy/zippy": "0.4.4", 31 | "phar-io/version": "^1.0", 32 | "symfony/yaml": "3.4.4", 33 | "wp-cli/wp-cli": "^2.0" 34 | }, 35 | "require-dev": { 36 | "dealerdirect/phpcodesniffer-composer-installer": "^v0.7.2", 37 | "phpstan/phpstan": "^1.8.6", 38 | "roave/security-advisories": "dev-latest", 39 | "slevomat/coding-standard": "^8.5.2", 40 | "squizlabs/php_codesniffer": "^3.7.1" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Build_Generate_Command.php: -------------------------------------------------------------------------------- 1 | ] 16 | * : Where to output build generation result (json file) 17 | * 18 | * [--format] 19 | * : Build file format: json or yml 20 | * 21 | * [--skip-git] 22 | * : .gitignore will not be generated 23 | * 24 | * [--all] 25 | * : Includes all plugins/themes whether they're activated or not 26 | * 27 | * [--yes] 28 | * : Skip overwriting confirmation if the destination build file already exists 29 | * 30 | * ## EXAMPLES 31 | * 32 | * wp build-generate 33 | * wp build-generate --file=production.yml 34 | * 35 | */ 36 | public function __invoke( $args = NULL, $assoc_args = NULL ) { 37 | 38 | // Build file. 39 | $build_filename = Utils::get_build_filename( $assoc_args ); 40 | 41 | // If file exists, prompt if the user want to replace it. 42 | if ( file_exists( Utils::wp_path( $build_filename ) ) ) { 43 | if ( empty( $assoc_args['yes'] ) ) { 44 | WP_CLI::confirm( WP_CLI::colorize( "%WFile %Y$build_filename%n%W exists, do you want to overwrite it?%n" ) ); 45 | } 46 | } 47 | 48 | // New generator class. 49 | $generator = new Generate( $assoc_args, $build_filename ); 50 | 51 | // Attempt to create build file. 52 | $generator->create_build_file(); 53 | 54 | // Attempt to gitignore. 55 | if ( empty( $assoc_args['skip-git'] ) ) { 56 | $generator->create_gitignore(); 57 | } 58 | 59 | } 60 | 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/Build_Parser.php: -------------------------------------------------------------------------------- 1 | filename = empty( $filename ) ? 'build.json' : $filename; 17 | // Set format. 18 | $this->format = ( strpos( $this->filename, 'yml' ) !== FALSE ) ? 'yml' : 'json'; 19 | // Set arguments. 20 | $this->assoc_args = $assoc_args; 21 | 22 | // Parse the Build file and Build sure it's valid. 23 | $this->parse(); 24 | } 25 | 26 | private function parse() { 27 | // Full Build file path. 28 | $file_path = ( Utils::is_absolute_path( $this->filename ) ) ? $this->filename : realpath( '.' ) . '/' . $this->filename; 29 | // Set specified path with --path argument if no --file argument is set 30 | if ( ! empty( WP_CLI::get_runner()->config['path'] ) && empty( $this->assoc_args['file'] ) ) { 31 | $file_path = WP_CLI::get_runner()->config['path'] . '/' . $this->filename; 32 | } 33 | // Check if the file exists. 34 | if ( ! file_exists( $file_path ) ) { 35 | return NULL; 36 | } 37 | // Check if the Build file is a valid yaml file. 38 | if ( $this->format == 'yml' ) { 39 | try { 40 | $this->build = Yaml::parse( file_get_contents( $file_path ) ); 41 | } catch ( \Exception $e ) { 42 | WP_CLI::error( 'Error parsing YAML from Build file (' . $this->filename . ').' ); 43 | 44 | return FALSE; 45 | } 46 | 47 | return TRUE; 48 | } 49 | 50 | // Build.json 51 | try { 52 | $this->build = json_decode( file_get_contents( $file_path ), TRUE ); 53 | } catch ( \Exception $e ) { 54 | WP_CLI::error( 'Error parsing JSON from Build file (' . $this->filename . ').' ); 55 | 56 | return FALSE; 57 | } 58 | 59 | return TRUE; 60 | } 61 | 62 | public function get( $key = NULL, $sub_key = NULL ) { 63 | 64 | // With subkey. 65 | if ( ! empty( $this->build[ $key ][ $sub_key ] ) ) { 66 | return $this->build[ $key ][ $sub_key ]; 67 | } 68 | 69 | // With key. 70 | if ( ( ! empty( $this->build[ $key ] ) ) && ( empty( $sub_key ) ) ) { 71 | return $this->build[ $key ]; 72 | } 73 | 74 | return []; 75 | } 76 | 77 | public function get_core_version() { 78 | if ( ! empty( $this->build['core']['download']['version'] ) ) { 79 | return $this->build['core']['download']['version']; 80 | } 81 | 82 | return NULL; 83 | } 84 | 85 | public function get_plugin_version( $slug ) { 86 | if ( ! empty( $this->build['plugins'][ $slug ]['version'] ) ) { 87 | return $this->build['plugins'][ $slug ]['version']; 88 | } 89 | 90 | return NULL; 91 | } 92 | 93 | public function get_theme_version( $slug ) { 94 | if ( ! empty( $this->build['themes'][ $slug ]['version'] ) ) { 95 | return $this->build['themes'][ $slug ]['version']; 96 | } 97 | 98 | return NULL; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/Build_Command.php: -------------------------------------------------------------------------------- 1 | ] 16 | * : Specify custom build file (default: build.json) 17 | * 18 | * [--clean] 19 | * : Deletes and re-download all plugins and themes listed in build file 20 | * 21 | * [--ignore-core] 22 | * : Don't process core 23 | * 24 | * [--ignore-plugins] 25 | * : Don't process plugins 26 | * 27 | * [--ignore-themes] 28 | * : Don't process themes 29 | * 30 | * [--yes] 31 | * : Skip confirmation of some questions 32 | * 33 | * [--dbname] 34 | * : Database name for wp-config.php (if WP is not installed) 35 | * 36 | * [--dbuser] 37 | * : Database user for wp-config.php (if WP is not installed) 38 | * 39 | * [--dbpass] 40 | * : Database pass for wp-config.php (if WP is not installed) 41 | * 42 | * [--dbhost] 43 | * : Database host for wp-config.php (if WP is not installed) 44 | * 45 | * [--dbprefix] 46 | * : Database prefix for wp-config.php (if WP is not installed) 47 | * 48 | * [--dbcharset] 49 | * : Database charset for wp-config.php (if WP is not installed) 50 | * 51 | * [--dbcollate] 52 | * : Database collate for wp-config.php (if WP is not installed) 53 | * 54 | * [--locale] 55 | * : Locale for wp-config.php (if WP is not installed) 56 | * 57 | * [--skip-salts] 58 | * : If set, keys and salts won't be generated for wp-config.php (if WP is not installed) 59 | * 60 | * [--skip-check] 61 | * : If set, the database connection is not checked. 62 | * 63 | * [--force] 64 | * : Overwrites existing wp-config.php 65 | * 66 | * ## EXAMPLES 67 | * 68 | * wp build 69 | * wp build --file=production.json --ignore-plugins 70 | * 71 | * @when before_wp_load 72 | */ 73 | public function __invoke( $args = NULL, $assoc_args = NULL ) { 74 | 75 | $build_filename = Utils::get_build_filename( $assoc_args ); 76 | WP_CLI::line( WP_CLI::colorize( "%GParsing %W$build_filename%n%G, please wait...%n" ) ); 77 | 78 | // Clean mode check 79 | if ( ( ! empty( $assoc_args['clean'] ) ) && ( empty( $assoc_args['yes'] ) ) ) { 80 | WP_CLI::confirm( WP_CLI::colorize( "\n%RItems will be deleted! => This will delete and re-download all plugins and themes listed in build file.\n%n%YAre you sure you want to continue?%n" ) ); 81 | } 82 | 83 | // Process core. 84 | if ( empty( $assoc_args['ignore-core'] ) ) { 85 | $core = new Core( $assoc_args ); 86 | $core = $core->process(); 87 | } 88 | 89 | // Item processor. 90 | $item = new Item( $assoc_args ); 91 | 92 | // Process plugins. 93 | if ( empty( $assoc_args['ignore-plugins'] ) ) { 94 | $plugins = $item->run( 'plugin' ); 95 | } 96 | 97 | // Process themes. 98 | if ( empty( $assoc_args['ignore-themes'] ) ) { 99 | $themes = $item->run( 'theme' ); 100 | } 101 | 102 | // Nothing to do! 103 | if ( empty( $core ) && empty( $plugins ) && empty( $themes ) ) { 104 | WP_CLI::line( WP_CLI::colorize( "%WNothing to do.%n" ) ); 105 | } else { 106 | WP_CLI::line( WP_CLI::colorize( "%WFinished.%n" ) ); 107 | } 108 | 109 | } 110 | 111 | } 112 | -------------------------------------------------------------------------------- /src/Helper/WP_API.php: -------------------------------------------------------------------------------- 1 | body ) ) { 11 | $core = json_decode( $response->body, true ); 12 | if ( ( ! empty( $core ) ) && ( is_array( $core ) ) ) { 13 | $config_version = Utils::determine_core_version( array_keys( $core ), $config_version ); 14 | } 15 | } 16 | 17 | return $config_version; 18 | } 19 | 20 | return null; 21 | } 22 | 23 | public static function plugin_info( $slug = null, $config_version = null ) { 24 | if ( ! empty( $slug ) ) { 25 | $response = Requests::get( "http://api.wordpress.org/plugins/info/1.2/?action=plugin_information&request[slug]={$slug}" ); 26 | if ( ! empty( $response->body ) ) { 27 | $plugin = json_decode( $response->body ); 28 | // Determine the version to be used. 29 | if ( ! empty( $plugin->version ) ) { 30 | $resolved_version = $plugin->version; 31 | if ( ! empty( $plugin->versions ) ) { 32 | $resolved_version = Utils::determine_version( $config_version, $plugin->version, $plugin->versions ); 33 | } 34 | $plugin = self::_get_item_download_link( $plugin, $resolved_version ); 35 | 36 | return $plugin; 37 | } 38 | } 39 | 40 | } 41 | 42 | return null; 43 | } 44 | 45 | public static function theme_info( $slug = null, $config_version = null ) { 46 | if ( ! empty( $slug ) ) { 47 | $response = Requests::post( 48 | 'http://api.wordpress.org/themes/info/1.1/', 49 | [], 50 | [ 'action' => 'theme_information', 'request' => [ 'slug' => $slug, 'fields' => [ 'versions' => true ] ] ] 51 | ); 52 | if ( ! empty( $response->body ) ) { 53 | $theme = json_decode( $response->body ); 54 | // Determine the version to be used. 55 | if ( ! empty( $theme->version ) ) { 56 | $resolved_version = $theme->version; 57 | if ( ! empty( $theme->versions ) ) { 58 | $resolved_version = Utils::determine_version( $config_version, $theme->version, $theme->versions ); 59 | } 60 | $theme = self::_get_item_download_link( $theme, $resolved_version ); 61 | 62 | return $theme; 63 | } 64 | } 65 | 66 | } 67 | 68 | return null; 69 | } 70 | 71 | // Changes item download link with the specified version. 72 | private static function _get_item_download_link( $item, $version ) { 73 | if ( ! empty( $item->download_link ) ) { 74 | // WordPress.org forces https, but still sometimes returns http 75 | // See https://twitter.com/nacin/status/512362694205140992 76 | $item->download_link = str_replace( 'http://', 'https://', $item->download_link ); 77 | // Saves original API version. 78 | $item->original_version = $item->version; 79 | // If the version to download is the current item version, return download link as is. 80 | if ( $item->version == $version ) { 81 | return $item; 82 | } 83 | // Build download link. 84 | list( $link ) = explode( $item->slug, $item->download_link ); 85 | // If 'dev' version, return download with slug only with no version attached. 86 | if ( $version == 'dev' ) { 87 | $item->version_link = $link . $item->slug . '.zip'; 88 | $item->version = 'Development Version'; 89 | } // Build download link with version attached. 90 | else { 91 | // Build the download link 92 | $item->version_link = $link . $item->slug . '.' . $version . '.zip'; 93 | $item->version = $version; 94 | } 95 | } 96 | 97 | return $item; 98 | 99 | } 100 | 101 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![WP-CLI Build](https://wputvikling.no/wp-cli-build.png) 2 | 3 | **WP-CLI Build** helps you to start your WP site in an organized way and simplifies maintenance: you don't need to version code that you don't maintain yourself like WP core, themes or 3rd party plugins. This makes it easy to have [auto updates](https://github.com/front/wp-cli-build/wiki/Auto-update-your-website), without messing up your Git setup. **WP-CLI Build** is also useful for [rebuilding your site after a hack](https://github.com/front/wp-cli-build/wiki/Rebuild-from-an-attack). 4 | ```sh 5 | $ wp build 6 | ``` 7 | For more background, check out [A Git Friendly Way to Handle WordPress Updates – Slides from WordCamp Oslo 2018](https://www.slideshare.net/frontkomnorway/a-git-friendly-way-to-handle-wordpress-updates-wordcamp-oslo-2018-89758006) 8 | 9 | ## Getting Started 10 | ### Prerequistes 11 | This package requires [WP-CLI](https://make.wordpress.org/cli/handbook/installing/) v2.0 or greater. You can check WP-CLI version with `$ wp --version` and update to the latest stable release with `$ wp cli update`. 12 | 13 | ### Installing 14 | **PHP 7.4:** Install **WP-CLI Build** from our git repo 15 | ```sh 16 | $ wp package install front/wp-cli-build 17 | ``` 18 | **PHP 8.0:** Install **WP-CLI Build** from our git repo 19 | ```sh 20 | $ wp package install front/wp-cli-build:8.0.0 21 | ``` 22 | **PHP 8.1:** Install **WP-CLI Build** from our git repo 23 | ```sh 24 | $ wp package install front/wp-cli-build:8.1.0 25 | ``` 26 | **PHP 8.2:** Install **WP-CLI Build** from our git repo 27 | ```sh 28 | $ wp package install front/wp-cli-build:8.2.0 29 | ``` 30 | 31 | **Note:** The WP-CLI package installer will fail silently if your memory limit is too low. To see if installation was successful, run `$ wp package list`. If empty, locate your php.ini and increase the memory_limit. 32 | 33 | ## Quick Start 34 | The ***build*** file is the base of **WP-CLI Build** and will contain your WP site core configuration and the list of used public plugins and themes. The latest version of **WP-CLI Build** will generate a *`build.json`* file, but we still support *`build.yml`*, so you can use both. 35 | 36 | To generate the ***build*** file you should run: 37 | ```sh 38 | $ wp build-generate 39 | ``` 40 | It will also rewrite your ***.gitignore*** file to make sure only custom plugins and themes are indexed. Additionally, if there is a `composer.json` file present, any plugins or themes that are installed with Composer will be excluded from the "custom plugins and themes" section. 41 | 42 | Bellow, you can see a sample of the *WP-CLI BUILD BLOCK* added to ***.gitignore***: 43 | ``` 44 | # ----------------------------------------------------------------------------- 45 | # START WP-CLI BUILD BLOCK 46 | # ----------------------------------------------------------------------------- 47 | # This block is auto generated every time you run 'wp build-generate'. 48 | # Rules: Exclude everything from Git except for your custom plugins and themes 49 | # (that is: those that are not on wordpress.org). 50 | # ----------------------------------------------------------------------------- 51 | /* 52 | !.gitignore 53 | !.gitlab-ci.yml 54 | !build.json 55 | !composer.json 56 | !README.md 57 | !patches 58 | !wp-content 59 | wp-content/* 60 | !wp-content/plugins 61 | wp-content/plugins/* 62 | !wp-content/themes 63 | wp-content/themes/* 64 | # ----------------------------------------------------------------------------- 65 | # Your custom plugins and themes. 66 | # Added automagically by WP-CLI Build ('wp build-generate'). 67 | # ----------------------------------------------------------------------------- 68 | !wp-content/plugins/custom-plugin-slug/ 69 | !wp-content/themes/custom-theme-slug/ 70 | # ----------------------------------------------------------------------------- 71 | # END WP-CLI BUILD BLOCK 72 | # ----------------------------------------------------------------------------- 73 | 74 | # ----------------------------------------------------------------------------- 75 | # START CUSTOM BLOCK 76 | # ----------------------------------------------------------------------------- 77 | # Place any additional items here. 78 | # ----------------------------------------------------------------------------- 79 | !custom-items 80 | # ----------------------------------------------------------------------------- 81 | # END CUSTOM BLOCK 82 | # ----------------------------------------------------------------------------- 83 | 84 | ``` 85 | 86 | ***Note:** Only active plugins and themes will be listed in **build** file and **gitignore**, unless you specify `--all` argument*. 87 | 88 | For more options, see `$ wp build-generate --help` 89 | 90 | ## Using *build* file 91 | You can run `$ wp build` to install the WordPress core of your site, 3rd party plugins and themes. It parses your ***build*** file, and works its magic! 92 | 93 | A sample of a ***build.json*** file: 94 | 95 | ``` 96 | { 97 | "core": { 98 | "download": { 99 | "version": "~6.2.2", 100 | "locale": "en_US" 101 | } 102 | }, 103 | "plugins": { 104 | "advanced-custom-fields": { 105 | "version": "*" 106 | }, 107 | "timber-library": { 108 | "version": "^1.22.1" 109 | }, 110 | "wordpress-seo": { 111 | "version": "*" 112 | } 113 | }, 114 | "themes": { 115 | "twentytwentyone": { 116 | "version": "1.8" 117 | } 118 | } 119 | } 120 | 121 | ``` 122 | 123 | A sample of a ***build.yml*** file: 124 | ``` 125 | core: 126 | download: 127 | version: "~6.2.2" 128 | locale: en_US 129 | plugins: 130 | advanced-custom-fields 131 | version: "*" 132 | timber-library: 133 | version: "^1.22.1" 134 | wordpress-seo: 135 | version: "*" 136 | themes: 137 | twentytwentyone: 138 | version: 1.8 139 | 140 | ``` 141 | 142 | Notice that you can use `~`, `*` and `^` operators when you don't want to refer a fixed version. 143 | 144 | ### Updating *build* and *.gitignore* 145 | When you add a new plugin to your WP site, you should run `$ wp build-generate` to update ***build*** and ***.gitignore*** files. 146 | 147 | For more options run `$ wp --help build-generate` and `$ wp --help build` 148 | 149 | ### Clean install 150 | Adding `--clean` option to `$ wp build` command forces all plugins to be deleted and downloaded again. It helps you make sure plugins are not corrupted. 151 | 152 | ## Contributing 153 | We appreciate you taking the initiative to contribute to this project! 154 | 155 | Contributing isn’t limited to just code. We encourage you to contribute in the way that best fits your abilities, by writing tutorials, giving a demo at your local meetup, helping other users with their support questions, or revising our documentation. 156 | 157 | ### Reporting a bug 158 | 159 | Think you’ve found a bug? We’d love for you to help us get it fixed. 160 | 161 | Before you create a new issue, you should [search existing issues](https://github.com/front/wp-cli-build/issues?q=label%3Abug%20) to see if there’s an existing resolution to it, or if it’s already been fixed in a newer version. 162 | 163 | Once you’ve done a bit of searching and discovered there isn’t an open or fixed issue for your bug, please [create a new issue](https://github.com/front/wp-cli-build/issues/new) with the following: 164 | 165 | 1. What you were doing (e.g. "When I run `wp build` ..."). 166 | 2. What you saw (e.g. "I see a fatal about a class being undefined."). 167 | 3. What you expected to see (e.g. "I expected to see the list of posts.") 168 | 169 | Include as much detail as you can, and clear steps to reproduce if possible. 170 | 171 | ### Creating a pull request 172 | 173 | Want to contribute a new feature? Please first [open a new issue](https://github.com/front/wp-cli-build/issues/new) to discuss whether the feature is a good fit for the project. 174 | -------------------------------------------------------------------------------- /src/Processor/Core.php: -------------------------------------------------------------------------------- 1 | build = new Build_Parser( Utils::get_build_filename( $assoc_args ), $assoc_args ); 16 | // Set command arguments. 17 | $this->assoc_args = $assoc_args; 18 | } 19 | 20 | public function process() { 21 | // WP installation status. 22 | $installed = Utils::wp_installed(); 23 | // Check if we have core info in build.yml. 24 | if ( ! empty( $this->build->get( 'core' ) ) ) { 25 | // If WordPress is not installed... 26 | if ( ! $installed ) { 27 | // Download WordPress. 28 | $download = $this->download_wordpress(); 29 | // Configure WordPress. 30 | $config = $this->config_wordpress(); 31 | // Install WordPress. 32 | $install = $this->install_wordpress(); 33 | } else { 34 | // Update WordPress. 35 | $update = $this->update_wordpress(); 36 | } 37 | } 38 | 39 | // Return false if nothing was done. 40 | if ( empty( $update ) && empty( $download ) && empty( $config ) && empty( $install ) ) { 41 | return FALSE; 42 | } 43 | 44 | return TRUE; 45 | } 46 | 47 | // Update WordPress if build.yml version is higher than currently installed. 48 | private function update_wordpress() { 49 | // Config 50 | $config = $this->build->get( 'core', 'download' ); 51 | $installed_version = Utils::wp_version(); 52 | $config_version = empty( $config['version'] ) ? NULL : $config['version']; 53 | $version_to_install = WP_API::core_version_check( $config_version ); 54 | // Compare installed version with the one in build.yml. 55 | if ( version_compare( $installed_version, $version_to_install ) === - 1 ) { 56 | // Change config version. 57 | $config['version'] = $version_to_install; 58 | // Status. 59 | Utils::line( "- Updating WordPress (%W{$installed_version}%n => %Y{$version_to_install}%n)" ); 60 | // Update WordPress. 61 | $result = Utils::launch_self( 'core', [ 'update' ], $config, FALSE, TRUE, [], FALSE, FALSE ); 62 | 63 | // Print result. 64 | return Utils::result( $result ); 65 | } 66 | 67 | return NULL; 68 | } 69 | 70 | // Download WordPress if not downloaded or if force setting is defined. 71 | private function download_wordpress() { 72 | // Version check. 73 | $version_check = Utils::wp_version(); 74 | // Config 75 | $config = $this->build->get( 'core', 'download' ); 76 | // If version is false or force is true, download WordPress. 77 | if ( ( ( $version_check === FALSE ) || ( ( ! empty( $config['force'] ) ) && ( $config['force'] === TRUE ) ) ) ) { 78 | if ( ! empty( $config['version'] ) ) { 79 | // WP Version. 80 | $download_args['version'] = WP_API::core_version_check( $config['version'] ); 81 | // Locale. 82 | if ( ! empty( $config['locale'] ) ) { 83 | $download_args['locale'] = $config['locale']; 84 | } 85 | // Download WP without the default themes and plugins 86 | $download_args['skip-content'] = isset( $config['skip-content'] ) ? $config['skip-content'] : TRUE; 87 | // Whether to exit on error or not 88 | $exit_on_error = isset( $config['exit-on-error'] ) ? $config['exit-on-error'] : FALSE; 89 | // Force download. 90 | if ( ( ! empty( $config['force'] ) ) && ( $config['force'] === TRUE ) ) { 91 | $download_args['force'] = TRUE; 92 | } 93 | // Download WordPress. 94 | $extra = empty( $config['locale'] ) ? "%G{$config['version']}%n (%Yen_US%n)" : "%G{$download_args['version']}%n (%Y{$config['locale']}%n)"; 95 | Utils::line( "- Downloading WordPress $extra" ); 96 | $result = Utils::launch_self( 'core', [ 'download' ], $download_args, FALSE, TRUE, [], FALSE, FALSE ); 97 | 98 | // Print result. 99 | return Utils::result( $result ); 100 | 101 | } 102 | } 103 | 104 | return NULL; 105 | } 106 | 107 | // Configure WordPress if 'wp-config.php' is not found. 108 | private function config_wordpress() { 109 | // Check if wp-config.php exists. 110 | if ( ( ! Utils::wp_config_exists() ) || ( ! empty( $this->assoc_args['force'] ) ) ) { 111 | // Version check. 112 | $version_check = Utils::wp_version(); 113 | // Config 114 | $config = $this->build->get( 'core', 'config' ); 115 | // Set config from assoc args (override). 116 | if ( ! empty( $this->assoc_args ) ) { 117 | // Set database details. 118 | if ( ! empty( $this->assoc_args['dbname'] ) ) { 119 | $config['dbname'] = $this->assoc_args['dbname']; 120 | } 121 | if ( ! empty( $this->assoc_args['dbuser'] ) ) { 122 | $config['dbuser'] = $this->assoc_args['dbuser']; 123 | } 124 | if ( ! empty( $this->assoc_args['dbpass'] ) ) { 125 | $config['dbpass'] = $this->assoc_args['dbpass']; 126 | } 127 | } 128 | // Only proceed with configuration if we have the database name, user and password. 129 | if ( ( $version_check !== FALSE ) && ( ! empty( $config['dbname'] ) ) && ( ! empty( $config['dbuser'] ) ) && ( ! empty( $config['dbpass'] ) ) ) { 130 | // Status. 131 | Utils::line( "- Generating '%Gwp-config.php%n'" ); 132 | // Override more config parameters from command line. 133 | if ( ! empty( $this->assoc_args['dbhost'] ) ) { 134 | $config['dbhost'] = $this->assoc_args['dbhost']; 135 | } 136 | if ( ! empty( $this->assoc_args['dbprefix'] ) ) { 137 | $config['dbprefix'] = $this->assoc_args['dbprefix']; 138 | } 139 | if ( ! empty( $this->assoc_args['dbcharset'] ) ) { 140 | $config['dbcharset'] = $this->assoc_args['dbcharset']; 141 | } 142 | if ( ! empty( $this->assoc_args['dbcollate'] ) ) { 143 | $config['dbcollate'] = $this->assoc_args['dbcollate']; 144 | } 145 | if ( ! empty( $this->assoc_args['locale'] ) ) { 146 | $config['locale'] = $this->assoc_args['locale']; 147 | } 148 | if ( ! empty( $this->assoc_args['skip-salts'] ) ) { 149 | $config['skip-salts'] = $this->assoc_args['skip-salts']; 150 | } 151 | if ( ! empty( $this->assoc_args['skip-check'] ) ) { 152 | $config['skip-check'] = $this->assoc_args['skip-check']; 153 | } 154 | if ( ! empty( $this->assoc_args['force'] ) ) { 155 | $config['force'] = $this->assoc_args['force']; 156 | } 157 | // Set global parameter: path. 158 | if ( ! empty( WP_CLI::get_runner()->config['path'] ) ) { 159 | $config['path'] = WP_CLI::get_runner()->config['path']; 160 | } 161 | // Config WordPress. 162 | $result = Utils::launch_self( 'config', [ 'create' ], $config, FALSE, TRUE, [], FALSE, FALSE ); 163 | 164 | // Print result. 165 | return Utils::result( $result ); 166 | } 167 | } 168 | 169 | return NULL; 170 | } 171 | 172 | private function install_wordpress() { 173 | // Check if wp-config.php exists. 174 | if ( Utils::wp_config_exists() ) { 175 | // Config 176 | $config = $this->build->get( 'core', 'install' ); 177 | // If version exists, blog is not installed and we have install section defined, try to install. 178 | if ( ( ! Utils::wp_installed() ) && ( ! empty( $config ) ) ) { 179 | 180 | // Status. 181 | Utils::line( "- Installing WordPress..." ); 182 | 183 | $install_args = []; 184 | if ( ! empty( $config['url'] ) ) { 185 | $install_args['url'] = $config['url']; 186 | } 187 | if ( ! empty( $config['title'] ) ) { 188 | $install_args['title'] = $config['title']; 189 | } 190 | if ( ! empty( $config['admin-user'] ) ) { 191 | $install_args['admin_user'] = $config['admin-user']; 192 | } 193 | if ( ! empty( $config['admin-email'] ) ) { 194 | $install_args['admin_email'] = $config['admin-email']; 195 | } 196 | if ( ! empty( $config['skip-email'] ) ) { 197 | $install_args['skip-email'] = TRUE; 198 | } 199 | 200 | // Check if admin password is set, if not, ask for it. 201 | if ( empty( $config['admin-pass'] ) ) { 202 | $config['admin-pass'] = NULL; 203 | do { 204 | $config['admin-pass'] = Utils::prompt( WP_CLI::colorize( " Enter the admin %Rpassword%n for the user %G{$config['admin-user']}%n: " ) ); 205 | } while ( $config['admin-pass'] == NULL ); 206 | } 207 | $install_args['admin_password'] = $config['admin-pass']; 208 | 209 | // Install WordPress. 210 | $result = Utils::launch_self( 'core', [ 'install' ], $install_args, FALSE, TRUE, [], TRUE ); 211 | 212 | // Print result. 213 | return Utils::result( $result ); 214 | 215 | } 216 | } 217 | 218 | return NULL; 219 | } 220 | 221 | } 222 | -------------------------------------------------------------------------------- /src/Processor/Item.php: -------------------------------------------------------------------------------- 1 | build = new Build_Parser( Utils::get_build_filename( $assoc_args ), $assoc_args ); 15 | $this->filesystem = new Filesystem(); 16 | $this->clean = empty( $assoc_args['clean'] ) ? FALSE : TRUE; 17 | } 18 | 19 | // Starts processing items. 20 | public function run( $item_type = NULL ) { 21 | $result = FALSE; 22 | if ( ( $item_type == 'plugin' ) || ( $item_type == 'theme' ) ) { 23 | if ( ! empty( $this->build ) ) { 24 | $items = $this->build->get( $item_type . 's' ); 25 | if ( ! empty( $items ) ) { 26 | $defaults = $this->build->get( 'defaults', $item_type . 's' ); 27 | $result = $this->process( $item_type, $items, $defaults ); 28 | } 29 | } 30 | } 31 | 32 | return $result; 33 | } 34 | 35 | // Process item (plugin or theme). 36 | private function process( $type = NULL, $items = [], $defaults = [] ) { 37 | $result = FALSE; 38 | if ( ( $type == 'theme' || $type == 'plugin' ) && ( ! empty( $items ) ) ) { 39 | // Check if WP is installed. 40 | $wp_installed = Utils::wp_installed(); 41 | $status = FALSE; 42 | foreach ( $items as $item => $item_info ) { 43 | // Sets item version. 44 | $item_info['version'] = $this->set_item_version( $type, $item, $item_info['version'] ); 45 | // Download, install or activate the item depending on WordPress installation status. 46 | if ( ( $wp_installed ) && ( ! $this->clean ) ) { 47 | // Install if the plugin doesn't exist. 48 | $item_status = $this->status( $type, $item ); 49 | if ( $item_status === FALSE ) { 50 | $status = $this->install( $type, $item, $item_info, $defaults ); 51 | } // If the plugin is inactive, activate it. 52 | elseif ( $item_status === 'inactive' ) { 53 | $status = $this->activate( $type, $item, $item_info ); 54 | } // Update if the version differs. 55 | elseif ( $item_status === 'active' ) { 56 | // Get item info. 57 | if ( ! empty( $item_info['version'] ) ) { 58 | // Check if we need an update 59 | if ( $item_info['version'] != $this->version( $type, $item ) ) { 60 | $status = $this->update( $type, $item, $item_info ); 61 | } 62 | } 63 | } 64 | } else { 65 | // If we're in clean mode, delete item folder. 66 | if ( $this->clean ) { 67 | $this->delete_item_folder( $type, $item ); 68 | } 69 | $status = $this->download( $type, $item, $item_info ); 70 | } 71 | 72 | // Change result to TRUE, if something was downloaded, updated, installed or activated. 73 | if ( $status ) { 74 | $result = TRUE; 75 | } 76 | 77 | } 78 | } 79 | 80 | return $result; 81 | } 82 | 83 | // Download an item. 84 | private function download( $type = NULL, $item = NULL, $item_info = NULL ) { 85 | if ( ( $type == 'theme' || $type == 'plugin' ) && ( ! empty( $item ) ) && ( ! empty( $item_info ) ) ) { 86 | // Check if the item folder already exists or not. 87 | // If the folder exists and the version is the same as the build file, skip it. 88 | $folder = Utils::wp_item_dir( $type, $item ); 89 | $exists = $this->filesystem->exists( $folder ); 90 | // If the folder doesn't exist, download the plugin. 91 | if ( ! $exists ) { 92 | Utils::line( "- Downloading %G$item%n (%Y{$item_info['version']}%n)" ); 93 | $download_status = Utils::item_download( $type, $item, (string) $item_info['version'] ); 94 | if ( $download_status === TRUE ) { 95 | Utils::line( ": done%n\n" ); 96 | } else { 97 | Utils::line( ": %R{$download_status}%n\n" ); 98 | } 99 | 100 | return TRUE; 101 | } 102 | } 103 | } 104 | 105 | // Install and activate an item. 106 | private function install( $type = NULL, $item = NULL, $item_info = NULL, $defaults = [] ) { 107 | // Processing text. 108 | $process = "- Installing %G$item%n"; 109 | 110 | // Item install point. 111 | $install_point = empty( $item['url'] ) ? $item : $item['url']; 112 | 113 | // Item install arguments. 114 | $install_args = []; 115 | 116 | // Defaults merge. 117 | $defaults_code = [ 'version' => 'latest', 'force' => FALSE, 'activate' => FALSE, 'activate-network' => FALSE, 'gitignore' => FALSE ]; 118 | $defaults = array_merge( $defaults_code, $defaults ); 119 | 120 | // Merge item info with the defaults (ixtem info will override defaults). 121 | $item_info = array_merge( $defaults, $item_info ); 122 | 123 | // Item version. 124 | $process .= " (%Y{$item_info['version']}%n)"; 125 | if ( ( ! empty( $item_info['version'] ) ) && ( $item_info['version'] != 'latest' ) ) { 126 | $install_args['version'] = $item_info['version']; 127 | } 128 | 129 | // Wether to force installation if the item is already installed. 130 | if ( ( ! empty( $item_info['force'] ) ) && ( $item_info['force'] ) ) { 131 | $install_args['force'] = TRUE; 132 | } 133 | 134 | // Active it on network after installing. 135 | if ( ( ! empty( $item_info['activate-network'] ) ) && ( $item_info['activate-network'] ) ) { 136 | $install_args['activate-network'] = TRUE; 137 | } 138 | 139 | // Processing message. 140 | Utils::line( $process ); 141 | 142 | // Install item. 143 | $result = Utils::launch_self( $type, [ 'install', $install_point ], $install_args, FALSE, TRUE, [], FALSE, FALSE ); 144 | 145 | // Silently activate item. 146 | if ( ! $this->is_active( $type, $item ) ) { 147 | Utils::launch_self( $type, [ 'activate', $item ], [], FALSE, TRUE, [], FALSE, FALSE ); 148 | } 149 | 150 | // Print result. 151 | return Utils::result( $result ); 152 | } 153 | 154 | // Activate an item. 155 | private function activate( $type = NULL, $item = NULL, $item_info = NULL ) { 156 | // Processing text. 157 | $process = "- Activating %G$item%n (%Y{$item_info['version']}%n)"; 158 | 159 | // Processing message. 160 | Utils::line( $process ); 161 | 162 | // Install item. 163 | $result = Utils::launch_self( $type, [ 'activate', $item ], [], FALSE, TRUE, [], FALSE, FALSE ); 164 | 165 | // Print result. 166 | return Utils::result( $result ); 167 | } 168 | 169 | // Activate an item. 170 | private function update( $type = NULL, $item = NULL, $item_info = NULL ) { 171 | 172 | // Current version. 173 | $old_version = $this->version( $type, $item ); 174 | 175 | // Update/Downgrade. 176 | $action_label = ( version_compare( $old_version, $item_info['version'] ) === - 1 ) ? 'Updating' : 'Downgrading'; 177 | 178 | // Processing text. 179 | $process = "- {$action_label} %G$item%n (%W{$old_version}%n => %Y{$item_info['version']}%n)"; 180 | 181 | // Processing message. 182 | Utils::line( $process ); 183 | 184 | // Install item. 185 | $result = Utils::launch_self( $type, [ 'update', $item ], [ 'version' => $item_info['version'] ], FALSE, TRUE, [], FALSE, FALSE ); 186 | 187 | // Print result. 188 | return Utils::result( $result ); 189 | } 190 | 191 | private function version( $type = NULL, $name = NULL ) { 192 | if ( ( $type == 'theme' || $type == 'plugin' ) && ( ! empty( $name ) ) ) { 193 | $result = Utils::launch_self( $type, [ 'get', $name ], [ 'field' => 'version' ], FALSE, TRUE, [], FALSE, FALSE ); 194 | if ( ! empty( $result->stdout ) ) { 195 | return trim( $result->stdout ); 196 | } 197 | } 198 | 199 | return FALSE; 200 | } 201 | 202 | private function status( $type = NULL, $name = NULL ) { 203 | if ( ( $type == 'theme' || $type == 'plugin' ) && ( ! empty( $name ) ) ) { 204 | $result = Utils::launch_self( $type, [ 'status', $name ], [], FALSE, TRUE, [], FALSE, FALSE ); 205 | $result = trim( strtolower( $result->stdout ) ); 206 | if ( strpos( $result, 'status: active' ) ) { 207 | return 'active'; 208 | } 209 | if ( strpos( $result, 'status: inactive' ) ) { 210 | return 'inactive'; 211 | } 212 | } 213 | 214 | return FALSE; 215 | } 216 | 217 | private function is_active( $type = NULL, $name = NULL ) { 218 | if ( ( $type == 'theme' || $type == 'plugin' ) && ( ! empty( $name ) ) ) { 219 | $result = Utils::launch_self( $type, [ 'is-active', $name ], [], FALSE, TRUE, [], FALSE, FALSE ); 220 | if ( empty( $result->return_code ) ) { 221 | return TRUE; 222 | } 223 | } 224 | 225 | return FALSE; 226 | } 227 | 228 | private function get_item_info( $type = NULL, $slug = NULL, $version = '*', $field = NULL ) { 229 | if ( ( $type == 'theme' || $type == 'plugin' ) && ( ! empty( $slug ) ) ) { 230 | $info_fn = $type . '_info'; 231 | $info = WP_API::$info_fn( $slug, $version, FALSE ); 232 | if ( ! empty( $info->{$field} ) ) { 233 | return $info->{$field}; 234 | } 235 | 236 | return $info; 237 | } 238 | 239 | return NULL; 240 | } 241 | 242 | private function set_item_version( $type = NULL, $slug = NULL, $item_version = '*' ) { 243 | if ( ( $type == 'theme' || $type == 'plugin' ) && ( ! empty( $slug ) ) ) { 244 | $item_info = $this->get_item_info( $type, $slug, $item_version ); 245 | if ( ! empty( $item_info->version ) ) { 246 | return $item_info->version; 247 | } 248 | } 249 | 250 | return ( $item_version === '*' ) ? 'latest' : $item_version; 251 | } 252 | 253 | private function delete_item_folder( $type = NULL, $item = NULL ) { 254 | if ( ( ! empty( $type ) ) && ( ! empty( $item ) ) ) { 255 | $folder = Utils::wp_item_dir( $type, $item ); 256 | 257 | return $this->filesystem->remove( $folder ); 258 | } 259 | 260 | return FALSE; 261 | } 262 | 263 | } 264 | -------------------------------------------------------------------------------- /src/Helper/Utils.php: -------------------------------------------------------------------------------- 1 | stdout ) ) { 27 | return trim( $result->stdout ); 28 | } 29 | 30 | return false; 31 | } 32 | 33 | // Check if WP is installed. 34 | public static function wp_installed() { 35 | $result = self::launch_self( 'core', [ 'is-installed' ], [], false, true, [], false, false ); 36 | if ( ! empty( $result->return_code ) ) { 37 | return false; 38 | } 39 | 40 | return true; 41 | } 42 | 43 | public static function wp_path( $path = NULL ) { 44 | $wp_path = self::get_absolute_path(ABSPATH); 45 | if ( ! empty( $path ) ) { 46 | $wp_path .= '/' . $path; 47 | } 48 | 49 | return $wp_path; 50 | } 51 | 52 | public static function wp_item_dir( $type = '', $item = '' ) { 53 | $options = array( 54 | 'return' => true, 55 | 'parse' => false, 56 | 'launch' => false, 57 | 'exit_error' => false, 58 | 'command_args' => [ '--quiet' ], 59 | ); 60 | 61 | switch ( $type ) { 62 | case 'theme': 63 | @$wp_theme_dir = WP_CLI::runcommand( 'config get WP_THEME_DIR', $options ); 64 | $wp_theme_dir = empty( $wp_theme_dir ) ? 'wp-content/themes' : $wp_theme_dir; 65 | $wp_theme_dir = preg_replace('/[\x00-\x1F\x7F\xA0]/u', '', $wp_theme_dir); 66 | $wp_item_dir = self::get_absolute_path($wp_theme_dir) . '/' . $item ; 67 | break; 68 | case 'plugin': 69 | @$wp_plugin_dir = WP_CLI::runcommand( 'config get WP_PLUGIN_DIR', $options ); 70 | $wp_plugin_dir = empty( $wp_plugin_dir ) ? 'wp-content/plugins' : $wp_plugin_dir; 71 | $wp_plugin_dir = preg_replace('/[\x00-\x1F\x7F\xA0]/u', '', $wp_plugin_dir); 72 | $wp_item_dir = self::get_absolute_path($wp_plugin_dir) . '/' . $item ; 73 | break; 74 | default: 75 | $wp_item_dir = ''; 76 | break; 77 | } 78 | 79 | return $wp_item_dir; 80 | } 81 | 82 | public static function line( $text, $pseudo_tab = false ) { 83 | $spaces = ( $pseudo_tab ) ? ' ' : null; 84 | echo $spaces . WP_CLI::colorize( $text ); 85 | } 86 | 87 | public static function prompt( $question ) { 88 | if ( function_exists( 'readline' ) ) { 89 | return readline( $question ); 90 | } else { 91 | echo $question; 92 | 93 | return stream_get_line( STDIN, 1024, PHP_EOL ); 94 | } 95 | } 96 | 97 | public static function get_absolute_path( $path ) { 98 | return ( ( ! self::is_absolute_path( $path ) ) || ( $path == '/' ) ) ? getcwd() . '/' . $path : $path; 99 | } 100 | 101 | public static function is_absolute_path( $path ) { 102 | if ( ! is_string( $path ) ) { 103 | $mess = sprintf( 'String expected but was given %s', gettype( $path ) ); 104 | throw new \InvalidArgumentException( $mess ); 105 | } 106 | if ( ! ctype_print( $path ) ) { 107 | $mess = 'Path can NOT have non-printable characters or be empty'; 108 | throw new \DomainException( $mess ); 109 | } 110 | // Optional wrapper(s). 111 | $regExp = '%^(?(?:[[:print:]]{2,}://)*)'; 112 | // Optional root prefix. 113 | $regExp .= '(?(?:[[:alpha:]]:/|/)?)'; 114 | // Actual path. 115 | $regExp .= '(?(?:[[:print:]]*))$%'; 116 | $parts = []; 117 | if ( ! preg_match( $regExp, $path, $parts ) ) { 118 | $mess = sprintf( 'Path is NOT valid, was given %s', $path ); 119 | throw new \DomainException( $mess ); 120 | } 121 | if ( '' !== $parts['root'] ) { 122 | return true; 123 | } 124 | 125 | return false; 126 | } 127 | 128 | public static function launch_self( $command, $args = [], $assoc_args = [], $exit_on_error = true, $return_detailed = false, $runtime_args = [], $exit_on_error_print = false, $print = true ) { 129 | // Work around to add 'cache dir' as env var, to avoid permission errors. 130 | $full_command = self::get_launch_self_workaround_command( $command, $args, $assoc_args, $runtime_args ); 131 | // Run command. 132 | $result = WP_CLI::launch( $full_command, $exit_on_error, $return_detailed ); 133 | // Standard output. 134 | if ( ! empty( $result->stdout ) && ( empty( $result->stderr ) ) && ( $print ) ) { 135 | $stdout = str_replace( [ 'Success:', 'Error:', 'Warning:' ], [ '%GSuccess:%n', '%RError:%n', '%YWarning:%n' ], $result->stdout ); 136 | WP_CLI::line( ' ' . WP_CLI::colorize( $stdout ) ); 137 | } 138 | // Output error. 139 | if ( ( ! empty( $result->stderr ) ) && ( $print ) ) { 140 | $stderr = str_replace( [ 'Error:', 'Warning:' ], [ '%RError:%n', '%YWarning:%n' ], $result->stderr ); 141 | WP_CLI::line( ' ' . WP_CLI::colorize( $stderr ) ); 142 | if ( $exit_on_error_print ) { 143 | exit( 1 ); 144 | } 145 | } 146 | 147 | return $result; 148 | } 149 | 150 | private static function get_launch_self_workaround_command( $command = null, $args = [], $assoc_args = [], $runtime_args = [] ) { 151 | $reused_runtime_args = [ 152 | 'path', 153 | 'url', 154 | 'user', 155 | 'allow-root', 156 | ]; 157 | foreach ( $reused_runtime_args as $key ) { 158 | if ( isset( $runtime_args[ $key ] ) ) { 159 | $assoc_args[ $key ] = $runtime_args[ $key ]; 160 | } elseif ( $value = WP_CLI::get_runner()->config[ $key ] ) { 161 | $assoc_args[ $key ] = $value; 162 | } 163 | } 164 | $php_bin = escapeshellarg( \WP_CLI\Utils\get_php_binary() ); 165 | $script_path = $GLOBALS['argv'][0]; 166 | if ( getenv( 'WP_CLI_CONFIG_PATH' ) ) { 167 | $config_path = getenv( 'WP_CLI_CONFIG_PATH' ); 168 | } else { 169 | $config_path = \WP_CLI\Utils\get_home_dir() . '/.wp-cli/config.yml'; 170 | } 171 | $config_path = escapeshellarg( $config_path ); 172 | $args = implode( ' ', array_map( 'escapeshellarg', $args ) ); 173 | $assoc_args = \WP_CLI\Utils\assoc_args_to_str( $assoc_args ); 174 | $cache_dir = getenv( 'WP_CLI_CACHE_DIR' ) ? getenv( 'WP_CLI_CACHE_DIR' ) : escapeshellarg( \WP_CLI\Utils\get_home_dir() . '/.wp-cli/cache' ); 175 | 176 | return "WP_CLI_CACHE_DIR={$cache_dir} WP_CLI_CONFIG_PATH={$config_path} {$php_bin} {$script_path} {$command} {$args} {$assoc_args}"; 177 | } 178 | 179 | public static function item_download( $type = null, $slug = null, $version = null ) { 180 | if ( ( ! empty( $slug ) ) && ( $type == 'plugin' || $type == 'theme' ) && ( ! empty( $version ) ) ) { 181 | $info_fn = $type . '_info'; 182 | $info = WP_API::$info_fn( $slug, $version ); 183 | if ( ! empty( $info->error ) ) { 184 | return 'not available in wordpress.org'; 185 | } 186 | // Status message. 187 | $status = ''; 188 | // Uses custom 'version_link' to download the item. 189 | if ( ! empty( $info->version_link ) ) { 190 | $failed_version_download = false; 191 | $filename = basename( $info->version_link ); 192 | if ( ! empty( $filename ) ) { 193 | $download = Utils::download_url( $info->version_link ); 194 | if ( $download !== true ) { 195 | $failed_version_download = true; 196 | $status .= "failed to download specified version of the plugin, trying latest version...%n\n\n\t%YFailed link:%n {$info->version_link}\n\t%BHTTP code:%n {$download}"; 197 | } 198 | if ( empty( $status ) && ( Utils::item_unzip( $type, $filename ) ) ) { 199 | return true; 200 | } else { 201 | $status .= "failed to unzip $type, deleting $filename..."; 202 | } 203 | } 204 | } 205 | // Uses API 'download_link' to download the item. 206 | if ( ! empty( $info->download_link ) ) { 207 | $filename = basename( $info->download_link ); 208 | if ( ! empty( $filename ) ) { 209 | $download = Utils::download_url( $info->download_link ); 210 | if ( $download !== true ) { 211 | if ( ! empty( $status ) ) { 212 | $status .= ""; 213 | } 214 | $status .= "failed to download plugin, details below...%n\n\n\t%YLink:%n {$info->download_link}\n\t%BHTTP status code:%n {$download}\n"; 215 | } 216 | if ( empty( $status ) || ( $download === true ) ) { 217 | if ( ! Utils::item_unzip( $type, $filename ) ) { 218 | $status .= "failed to unzip $type, deleting $filename..."; 219 | } 220 | } 221 | if ( ( ! empty( $status ) ) && ( $failed_version_download ) ) { 222 | $status .= "\n\n\t%GSuccess!%n\n\t%YLink:%n {$info->download_link}\n\t%BVersion:%n $info->original_version\n%n"; 223 | } 224 | } else { 225 | return "failed to determine filename from the plugin download link: {$info->download_link}"; 226 | } 227 | } else { 228 | return 'no download link provided by the WordPress API, failed.'; 229 | } 230 | 231 | return empty( $status ) ? true : $status; 232 | } 233 | 234 | return null; 235 | } 236 | 237 | public static function download_url( $url = null ) { 238 | // If we have an URL proceed. 239 | if ( ! empty( $url ) ) { 240 | $filename = basename( $url ); 241 | if ( ! empty( $filename ) ) { 242 | $save_dir = self::wp_path( 'wp-content/' ); 243 | $create_dir = self::mkdir( $save_dir ); 244 | if ( $create_dir === true ) { 245 | $save_path = $save_dir . $filename; 246 | $download = Requests::get( $url, [], [ 'filename' => $save_path, 'verify' => false, 'timeout' => 20 ] ); 247 | if ( $download->status_code == 200 ) { 248 | return true; 249 | } 250 | 251 | return $download->status_code; 252 | } 253 | 254 | return $create_dir; 255 | } 256 | } 257 | 258 | // Delete the file if we don't get a 200 code. 259 | if ( ( ! empty( $save_path ) ) && ( file_exists( $save_path ) ) ) { 260 | @unlink( $save_path ); 261 | } 262 | 263 | return false; 264 | } 265 | 266 | public static function item_unzip( $type, $filename ) { 267 | $file_path = self::wp_path( 'wp-content/' . $filename ); 268 | if ( file_exists( $file_path ) ) { 269 | if ( self::unzip( $file_path, Utils::wp_item_dir( $type ) ) ) { 270 | return true; 271 | } 272 | } 273 | 274 | return false; 275 | } 276 | 277 | public static function unzip( $file, $to, $delete = true ) { 278 | if ( ( ! empty( $file ) ) && ( ! empty( $to ) ) ) { 279 | 280 | // Create the directory to extract to. 281 | $create_dir = self::mkdir( $to ); 282 | if ( $create_dir ) { 283 | $zippy = Zippy::load(); 284 | $archive = $zippy->open( $file ); 285 | try { 286 | $archive->extract( $to ); 287 | } catch ( InvalidArgumentException $e ) { 288 | @unlink( $file ); 289 | 290 | return false; 291 | } catch ( RuntimeException $e ) { 292 | @unlink( $file ); 293 | 294 | return false; 295 | } 296 | 297 | if ( $delete ) { 298 | @unlink( $file ); 299 | } 300 | 301 | return true; 302 | } 303 | 304 | } 305 | 306 | return false; 307 | } 308 | 309 | public static function mkdir( $dir = null ) { 310 | if ( ! empty( $dir ) ) { 311 | if ( ! file_exists( $dir ) ) { 312 | $fs = new Filesystem(); 313 | try { 314 | $fs->mkdir( $dir, 0755 ); 315 | } catch ( IOException $e ) { 316 | return $e->getMessage(); 317 | } catch ( IOExceptionInterface $e ) { 318 | return $e->getMessage(); 319 | } 320 | 321 | return file_exists( $dir ); 322 | } else { 323 | return true; 324 | } 325 | } 326 | 327 | return false; 328 | } 329 | 330 | // Print success or error message. 331 | public static function result( $result = null ) { 332 | if ( ! empty( $result ) ) { 333 | // Success. 334 | if ( ! empty( $result->stdout ) && ( empty( $result->stderr ) ) ) { 335 | self::line( ": done\n" ); 336 | 337 | return true; 338 | } 339 | 340 | // Output error. 341 | if ( ! empty( $result->stderr ) ) { 342 | $stderr = str_replace( [ 'Error:', 'Warning:' ], [ '', '' ], $result->stderr ); 343 | self::line( ": %R" . trim( $stderr ) . "%n\n" ); 344 | } 345 | } 346 | 347 | return false; 348 | } 349 | 350 | public static function convert_to_numeric( $version = null ) { 351 | if ( ( ! empty( $version ) ) && ( is_numeric( $version ) ) ) { 352 | return strpos( $version, '.' ) === false ? (int) $version : (float) $version; 353 | } 354 | 355 | return $version; 356 | } 357 | 358 | public static function get_build_filename( $assoc_args = null ) { 359 | // Legacy YAML support. 360 | if ( file_exists( self::wp_path( 'build.yml' ) ) ) { 361 | return 'build.yml'; 362 | } 363 | 364 | // Format argument. 365 | if ( ! empty( $assoc_args['format'] ) ) { 366 | if ( $assoc_args['format'] == 'yml' ) { 367 | return empty( $assoc_args['file'] ) ? 'build.yml' : $assoc_args['file']; 368 | } 369 | } 370 | 371 | return empty( $assoc_args['file'] ) ? 'build.json' : $assoc_args['file']; 372 | } 373 | 374 | public static function strposa( $haystack, $needles = [], $offset = 0 ) { 375 | $chr = []; 376 | foreach ( $needles as $needle ) { 377 | $res = strpos( $haystack, $needle, $offset ); 378 | if ( $res !== false ) { 379 | $chr[ $needle ] = $res; 380 | } 381 | } 382 | if ( empty( $chr ) ) { 383 | return false; 384 | } 385 | 386 | return min( $chr ); 387 | } 388 | 389 | public static function determine_core_version( $versions, $config_version ) { 390 | if ( ( ! empty( $versions ) ) && ( $config_version ) ) { 391 | // Determine config version major and min version (if applicable). 392 | asort( $versions ); 393 | $parser = new VersionConstraintParser(); 394 | try { 395 | $parsed_version = $parser->parse( $config_version ); 396 | // Loop through versions to determine the one to applicate. 397 | foreach ( $versions as $v ) { 398 | try { 399 | $complies = $parsed_version->complies( new Version( $v ) ); 400 | if ( $complies ) { 401 | $config_version = $v; 402 | } 403 | } catch ( \Exception $e ) { 404 | } 405 | } 406 | } catch ( \Exception $e ) { 407 | return $versions[ count( $versions ) - 1 ]; 408 | } 409 | } 410 | 411 | return $config_version; 412 | } 413 | 414 | public static function version_comply( $version, $latest_version ) { 415 | // Determine the item version if we have '^', '~' or '*'. 416 | if ( Utils::strposa( $version, [ '~', '^', '*' ] ) !== false ) { 417 | // Return latest version if '*'. 418 | if ( strpos( $version, '*' ) === 0 ) { 419 | return $latest_version; 420 | } 421 | // Figure out version if '^', '~' or '*' operators are used. 422 | $parser = new VersionConstraintParser(); 423 | $caret_constraint = $parser->parse( $version ); 424 | try { 425 | $complies = $caret_constraint->complies( new Version( $latest_version ) ); 426 | if ( $complies ) { 427 | return $latest_version; 428 | } 429 | } catch ( \Exception $e ) { 430 | } 431 | } 432 | 433 | return $version; 434 | } 435 | 436 | public static function determine_version( $item_version, $wporg_latest, $wporg_versions ) { 437 | // Return latest version if '*'. 438 | if ( $item_version == '*' ) { 439 | return $wporg_latest; 440 | } 441 | // Determine the item version if we have '^', '~' or '*'. 442 | if ( Utils::strposa( $item_version, [ '~', '^', '.*' ] ) !== false ) { 443 | // Figure out the version if '^', '~' and '.*' are used. 444 | if ( ! empty( $wporg_versions ) ) { 445 | $parser = new VersionConstraintParser(); 446 | $caret_constraint = $parser->parse( $item_version ); 447 | $wporg_versions->{$wporg_latest} = 'latest'; 448 | foreach ( $wporg_versions as $version => $url ) { 449 | $complies = false; 450 | try { 451 | if ( version_compare( $item_version, $version, '<' ) ) { 452 | $complies = $caret_constraint->complies( new Version( $version ) ); 453 | } 454 | } catch ( \Exception $e ) { 455 | } 456 | if ( $complies ) { 457 | $item_version = $version; 458 | } 459 | } 460 | if ( Utils::strposa( $item_version, [ '~', '^', '.*' ] ) !== false ) { 461 | return $wporg_latest; 462 | } 463 | 464 | return $item_version; 465 | } 466 | } 467 | 468 | return $item_version; 469 | } 470 | 471 | } -------------------------------------------------------------------------------- /src/Processor/Generate.php: -------------------------------------------------------------------------------- 1 | assoc_args = $assoc_args; 26 | 27 | // Existing build file (if any). 28 | $this->build_filename = $build_filename ?? 'build.json'; 29 | $this->build_file = new Build_Parser( Utils::get_build_filename( $assoc_args ), $assoc_args ); 30 | 31 | // WP core, plugins and themes information. 32 | // Verbose output 33 | Utils::line( "%WCompiling information from the existing installation, please wait...\n\n" ); 34 | $this->core = $this->get_core(); 35 | $this->plugins = $this->get_plugins(); 36 | $this->themes = $this->get_themes(); 37 | } 38 | 39 | public function create_build_file() { 40 | 41 | // Build structure. 42 | $build = []; 43 | if ( ! empty( $this->core ) ) { 44 | $build['core'] = $this->core; 45 | } 46 | if ( ! empty( $this->plugins['wp.org'] ) ) { 47 | $build['plugins'] = $this->plugins['wp.org']; 48 | } 49 | if ( ! empty( $this->themes['wp.org'] ) ) { 50 | $build['themes'] = $this->themes['wp.org']; 51 | } 52 | 53 | // No content, skip build file creation. 54 | if ( empty( $build ) ) { 55 | Utils::line( "Not enough content to generate the build file." ); 56 | 57 | return FALSE; 58 | } 59 | 60 | Utils::line( "%WGenerating %n%Y$this->build_filename%n%W with the items from %Ywp.org%n%W, please wait...%n" ); 61 | 62 | // Filter empty build items. 63 | $build = $this->filter_empty_build_items( $build ); 64 | 65 | // Order build items. 66 | $build = $this->order_build_items( $build ); 67 | 68 | // YAML. 69 | if ( ( ( ! empty( $this->assoc_args['format'] ) ) && ( $this->assoc_args['format'] == 'yml' ) ) || ( strpos( $this->build_filename, 'yml' ) !== FALSE ) ) { 70 | $content = Yaml::dump( $build, 10 ); 71 | } 72 | 73 | // JSON. 74 | if ( empty( $content ) ) { 75 | $content = json_encode( $build, JSON_PRETTY_PRINT ); 76 | $content = ( ! empty( $content ) ) ? $content . "\n" : ''; 77 | } 78 | 79 | // Write to file. 80 | if ( ! empty( $content ) ) { 81 | @file_put_contents( $this->build_filename, $content ); 82 | Utils::line( "%G done%n\n" ); 83 | 84 | return TRUE; 85 | } 86 | Utils::line( "%Rfail :(%n\n" ); 87 | 88 | return FALSE; 89 | 90 | } 91 | 92 | public function create_gitignore() { 93 | $custom_items = []; 94 | if ( ! empty( $this->plugins['custom'] ) ) { 95 | $custom_items['plugins'] = $this->plugins['custom']; 96 | } 97 | if ( ! empty( $this->themes['custom'] ) ) { 98 | $custom_items['themes'] = $this->themes['custom']; 99 | } 100 | 101 | // Skip gitignore creation. 102 | if ( empty( $custom_items ) ) { 103 | Utils::line( "%WNo %Rcustom%n%W items found, skipping %Y$this->gitignore_filename%n%W creation.%n\n" ); 104 | 105 | return FALSE; 106 | } 107 | 108 | // Create gitignore. 109 | Utils::line( "%WGenerating %n%Y$this->gitignore_filename%n%W, please wait..." ); 110 | if ( $this->save_gitignore( $custom_items ) ) { 111 | Utils::line( "%Gdone%n\n" ); 112 | 113 | return TRUE; 114 | } 115 | Utils::line( "%Rfail :(%n\n" ); 116 | 117 | return FALSE; 118 | } 119 | 120 | private function get_core() { 121 | // Verbose output 122 | Utils::line( "%W- Checking %n%Ccore%n%W...\n" ); 123 | // Get locale 124 | $locale = get_locale(); 125 | // If the core version from existing file is the latest, set it. 126 | $version = ( Utils::strposa( $this->build_file->get_core_version(), [ '~', '^', '*', 'latest' ] ) !== FALSE ) ? $this->build_file->get_core_version() : Utils::wp_version(); 127 | // Verbose output 128 | Utils::line( " %Gversion%n: $version\n %Glocale%n: $locale\n\n" ); 129 | 130 | return array( 131 | 'download' => array( 132 | 'version' => $version, 133 | 'locale' => $locale 134 | ) 135 | ); 136 | } 137 | 138 | private function get_plugins() { 139 | // Verbose output 140 | Utils::line( "%W- Checking %n%Cplugins%n%W...\n" ); 141 | $installed_plugins = get_plugins(); 142 | $plugins = NULL; 143 | if ( ! empty( $installed_plugins ) ) { 144 | require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; 145 | foreach ( $installed_plugins as $file => $details ) { 146 | // Plugin slug. 147 | $slug = strtolower( WP_CLI_Utils\get_plugin_name( $file ) ); 148 | // Plugin version. 149 | $build_version = $this->build_file->get_plugin_version( $slug ); 150 | $version = ( Utils::strposa( $build_version, [ '~', '^', '*', 'latest' ] ) !== FALSE ) ? str_replace( 'latest', '*', $build_version ) : $details['Version']; 151 | // Check if plugin is active. 152 | if ( ( is_plugin_active( $file ) ) || ( ! empty( $this->assoc_args['all'] ) ) ) { 153 | // Check plugin information on wp official repository. 154 | $api = plugins_api( 'plugin_information', [ 'slug' => $slug ] ); 155 | // Origin. 156 | $plugin_origin = ( is_wp_error( $api ) || ( empty( $api->download_link ) ) || ( ! empty( $api->external ) ) ) ? 'custom' : 'wp.org'; 157 | // Verbose output. 158 | $plugin_origin_colorize = ( $plugin_origin == 'wp.org' ) ? "%Y$plugin_origin%n" : "%R$plugin_origin%n"; 159 | Utils::line( "%W %n%G$slug%n%W (%n$plugin_origin_colorize%W):%n {$version}\n" ); 160 | // Add plugin to the list. 161 | $plugins[ $plugin_origin ][ $slug ]['version'] = $version; 162 | // Plugin network activation. 163 | if ( ! empty( $details['Network'] ) ) { 164 | $plugins[ $plugin_origin ][ $slug ]['activate-network'] = 'yes'; 165 | } 166 | } 167 | 168 | } 169 | } 170 | Utils::line( "\n" ); 171 | 172 | return $plugins; 173 | } 174 | 175 | private function get_themes() { 176 | // Verbose output 177 | Utils::line( "%W- Checking %n%Cthemes%n%W...\n" ); 178 | $installed_themes = wp_get_themes(); 179 | $themes = NULL; 180 | if ( ! empty( $installed_themes ) ) { 181 | $current_theme = get_stylesheet(); 182 | foreach ( $installed_themes as $slug => $theme ) { 183 | // Version. 184 | $build_version = $this->build_file->get_theme_version( $slug ); 185 | $version = ( Utils::strposa( $build_version, [ '~', '^', '*', 'latest' ] ) !== FALSE ) ? str_replace( 'latest', '*', $build_version ) : $theme->display( 'Version' ); 186 | if ( ( $slug == $current_theme ) || ( ! empty( $this->assoc_args['all'] ) ) ) { 187 | // Check theme information on wp.org. 188 | $api = themes_api( 'theme_information', [ 'slug' => $slug ] ); 189 | // Origin. 190 | $origin = is_wp_error( $api ) ? 'custom' : 'wp.org'; 191 | // Origin color. 192 | $origin_colorize = ( $origin == 'wp.org' ) ? "%Y$origin%n" : "%R$origin%n"; 193 | // Message. 194 | $message = empty( $version ) ? "%W %n%G$slug%n%W (%n$origin_colorize%W)\n" : "%W %n%G$slug%n%W (%n$origin_colorize%W):%n {$version}\n"; 195 | Utils::line( $message ); 196 | // Add theme to the list. 197 | $themes[ $origin ][ $slug ]['version'] = $version; 198 | // Add main theme in case the theme we've added have '-child' in the name. 199 | $is_child_theme = strpos( $slug, '-child' ); 200 | if ( $is_child_theme !== FALSE ) { 201 | // Generate main theme name. 202 | $main_theme = substr( $slug, 0, $is_child_theme ); 203 | // Check theme information on wp.org. 204 | $api = themes_api( 'theme_information', [ 'slug' => $main_theme ] ); 205 | // Origin. 206 | $origin = is_wp_error( $api ) ? 'custom' : 'wp.org'; 207 | // Origin color. 208 | $origin_colorize = ( $origin == 'wp.org' ) ? "%Y$origin%n" : "%R$origin%n"; 209 | // Message. 210 | Utils::line( "%W %n%G$main_theme%n%W (%n$origin_colorize%W)\n" ); 211 | // Add theme to the themes list. 212 | $themes[ $origin ][ $main_theme ] = NULL; 213 | } 214 | } 215 | } 216 | } 217 | Utils::line( "\n" ); 218 | 219 | return $themes; 220 | } 221 | 222 | private function get_custom_gitignore( $current_gitignore = [] ) { 223 | if ( empty( $current_gitignore ) ) { 224 | return []; 225 | } 226 | 227 | // Remove WP-CLI Build block. 228 | $start = array_search( "# START WP-CLI BUILD BLOCK\n", $current_gitignore ); 229 | $end = array_search( "# END WP-CLI BUILD BLOCK\n", $current_gitignore ); 230 | $custom_gitignore = $current_gitignore; 231 | 232 | if ( ( is_int( $start ) ) && ( is_int( $end ) ) ) { 233 | for ( $i = $start; $i <= $end; $i ++ ) { 234 | unset( $custom_gitignore[ $i ] ); 235 | } 236 | } 237 | 238 | // Remove custom block text. 239 | foreach( $custom_gitignore as $key => $line ) { 240 | if ( ( strpos( $line, '# ------' ) !== false ) || ( strpos( $line, '# START CUSTOM' ) !== false ) || ( strpos( $line, '# Place any' ) !== false ) || ( strpos( $line, '# END CUSTOM' ) !== false ) ) { 241 | unset( $custom_gitignore[$key] ); 242 | } 243 | } 244 | 245 | // Remove multiple consecutive empty lines, 246 | // and any empty line at the beginning. 247 | $previous_line = "\n"; 248 | 249 | foreach( $custom_gitignore as $key => $line ) { 250 | if ( ( $line === "\n" ) && ( $line === $previous_line ) ) { 251 | unset( $custom_gitignore[$key] ); 252 | } 253 | 254 | $previous_line = $line; 255 | } 256 | 257 | // Remove empty line at the end. 258 | if ( end( $custom_gitignore ) === "\n") { 259 | array_pop( $custom_gitignore ); 260 | } 261 | 262 | // Make sure the last line ends with a newline character. 263 | $last_line = array_pop( $custom_gitignore ); 264 | 265 | if ( ! empty ($last_line) && $last_line[-1] !== "\n") { 266 | $last_line .= "\n"; 267 | } 268 | 269 | $custom_gitignore[] = $last_line; 270 | 271 | return $custom_gitignore; 272 | } 273 | 274 | private function filter_composer_items( $custom_items = [], $composer_require = [] ) { 275 | $filtered_items = []; 276 | 277 | if ( empty( $custom_items ) ) { 278 | return $filtered_items; 279 | } 280 | elseif ( empty( $composer_require ) ) { 281 | return $custom_items; 282 | } 283 | 284 | $package_names = []; 285 | 286 | foreach ( $composer_require as $package => $version ) { 287 | $package_parts = explode( '/', $package ); 288 | $package_names[] = end( $package_parts ); 289 | } 290 | 291 | foreach ( $custom_items as $type => $items ) { 292 | foreach ( $items as $slug => $contents ) { 293 | if ( ! empty( $slug ) && ! in_array( $slug, $package_names ) ) { 294 | $filtered_items[$type][$slug] = $contents; 295 | } 296 | } 297 | } 298 | 299 | return $filtered_items; 300 | } 301 | 302 | private function filter_empty_build_items( $build_items = [] ) { 303 | $filtered_items = []; 304 | 305 | foreach ( $build_items as $type => $items ) { 306 | foreach ( $items as $slug => $contents ) { 307 | if ( ! empty( $contents['version'] ) ) { 308 | $filtered_items[$type] = $items; 309 | } 310 | } 311 | } 312 | 313 | return $filtered_items; 314 | } 315 | 316 | private function order_build_items( $build_items = [] ) { 317 | $ordered_items = []; 318 | 319 | foreach ( $build_items as $type => $items ) { 320 | if ( is_array( $items ) ) { 321 | ksort( $items ); 322 | 323 | $ordered_items[$type] = $items; 324 | } 325 | } 326 | 327 | return $ordered_items; 328 | } 329 | 330 | private function generate_gitignore( $custom_gitignore = [], $custom_items = [], $optional_items = [] ) { 331 | $gitignore = []; 332 | 333 | // Start WP-CLI Build block. 334 | $gitignore[] = "# -----------------------------------------------------------------------------\n"; 335 | $gitignore[] = "# START WP-CLI BUILD BLOCK\n"; 336 | $gitignore[] = "# -----------------------------------------------------------------------------\n"; 337 | $gitignore[] = "# This block is auto generated every time you run 'wp build-generate'.\n"; 338 | $gitignore[] = "# Rules: Exclude everything from Git except for your custom plugins and themes\n"; 339 | $gitignore[] = "# (that is: those that are not on wordpress.org).\n"; 340 | $gitignore[] = "# -----------------------------------------------------------------------------\n"; 341 | 342 | // Add default items. 343 | $gitignore[] = "/*\n"; 344 | $gitignore[] = "!{$this->gitignore_filename}\n"; 345 | 346 | // Add GitLab file. 347 | if ( ! empty( $optional_items[$this->gitlab_filename] ) ) { 348 | $gitignore[] = "!{$this->gitlab_filename}\n"; 349 | } 350 | 351 | // Add build file. 352 | $gitignore[] = "!{$this->build_filename}\n"; 353 | 354 | // Add Composer file. 355 | if ( ! empty( $optional_items[$this->composer_filename] ) ) { 356 | $gitignore[] = "!{$this->composer_filename}\n"; 357 | } 358 | 359 | // Add readme file. 360 | if ( ! empty( $optional_items[$this->readme_filename] ) ) { 361 | $gitignore[] = "!{$this->readme_filename}\n"; 362 | } 363 | 364 | // Add patches directory. 365 | if ( ! empty( $optional_items['patches'] ) ) { 366 | $gitignore[] = "!{$this->patches_dirname}\n"; 367 | } 368 | 369 | // Add common items. 370 | $gitignore[] = "!wp-content\n"; 371 | $gitignore[] = "wp-content/*\n"; 372 | $gitignore[] = "!wp-content/plugins\n"; 373 | $gitignore[] = "wp-content/plugins/*\n"; 374 | $gitignore[] = "!wp-content/themes\n"; 375 | $gitignore[] = "wp-content/themes/*\n"; 376 | 377 | // Add custom plugins and themes. 378 | if ( ! empty( $custom_items ) ) { 379 | $gitignore[] = "# -----------------------------------------------------------------------------\n"; 380 | $gitignore[] = "# Your custom plugins and themes.\n"; 381 | $gitignore[] = "# Added automagically by WP-CLI Build ('wp build-generate').\n"; 382 | $gitignore[] = "# -----------------------------------------------------------------------------\n"; 383 | 384 | foreach ( $custom_items as $type => $items ) { 385 | foreach ( $items as $slug => $contents ) { 386 | if ( ! empty( $slug ) ) { 387 | $gitignore[] = "!wp-content/$type/$slug/\n"; 388 | } 389 | } 390 | } 391 | } 392 | 393 | // End WP-CLI Build block. 394 | $gitignore[] = "# -----------------------------------------------------------------------------\n"; 395 | $gitignore[] = "# END WP-CLI BUILD BLOCK\n"; 396 | $gitignore[] = "# -----------------------------------------------------------------------------\n\n"; 397 | 398 | // Start custom block. 399 | $gitignore[] = "# -----------------------------------------------------------------------------\n"; 400 | $gitignore[] = "# START CUSTOM BLOCK\n"; 401 | $gitignore[] = "# -----------------------------------------------------------------------------\n"; 402 | $gitignore[] = "# Place any additional items here.\n"; 403 | $gitignore[] = "# -----------------------------------------------------------------------------\n"; 404 | 405 | // Add custom items. 406 | $gitignore = array_merge( $gitignore, $custom_gitignore ); 407 | 408 | // End custom block. 409 | $gitignore[] = "# -----------------------------------------------------------------------------\n"; 410 | $gitignore[] = "# END CUSTOM BLOCK\n"; 411 | $gitignore[] = "# -----------------------------------------------------------------------------\n"; 412 | 413 | // Optimize gitignore. 414 | $gitignore = $this->optimize_gitignore( $gitignore ); 415 | 416 | return $gitignore; 417 | } 418 | 419 | private function optimize_gitignore( $gitignore = [] ) { 420 | $optimized_gitignore = []; 421 | 422 | // Remove duplicate lines. 423 | foreach( $gitignore as $key => $line ) { 424 | if ( ( $line === "\n" ) || ( strpos( $line, '# ------' ) !== false ) || ( ! in_array( $line, $optimized_gitignore ) ) ) { 425 | $optimized_gitignore[] = $line; 426 | } 427 | } 428 | 429 | return $optimized_gitignore; 430 | } 431 | 432 | private function save_gitignore( $custom_items = [] ) { 433 | // Get absolute path to the root directory of WordPress. 434 | $abspath = ABSPATH !== '/' ? ABSPATH : ( realpath( '.' ) . ABSPATH ); 435 | 436 | // Check if the gitignore file exists and load it. 437 | $gitignore_path = $abspath . $this->gitignore_filename; 438 | $custom_gitignore = []; 439 | 440 | if ( file_exists( $gitignore_path ) ) { 441 | $current_gitignore = @file( $gitignore_path ); 442 | 443 | // Check if the gitignore file is not empty and get custom items. 444 | if ( ! empty( $current_gitignore ) ) { 445 | $custom_gitignore = $this->get_custom_gitignore( $current_gitignore ); 446 | } 447 | } 448 | 449 | // Optional items to be added to gitignore if they are present. 450 | $optional_items = []; 451 | 452 | // Check if the GitLab file exists. 453 | $gitlab_path = $abspath . $this->gitlab_filename; 454 | $optional_items[$this->gitlab_filename] = false; 455 | 456 | if ( file_exists( $gitlab_path ) ) { 457 | $optional_items[$this->gitlab_filename] = true; 458 | } 459 | 460 | // Check if the Composer file exists and load it. 461 | $composer_path = $abspath . $this->composer_filename; 462 | $optional_items[$this->composer_filename] = false; 463 | 464 | if ( file_exists( $composer_path ) ) { 465 | $optional_items[$this->composer_filename] = true; 466 | $composer = file_get_contents( $composer_path ); 467 | 468 | if ( ! empty( $composer ) ) { 469 | $composer = json_decode( $composer, true ); 470 | 471 | if ( ! empty( $composer['require'] ) ) { 472 | $custom_items = $this->filter_composer_items( $custom_items, $composer['require'] ); 473 | } 474 | } 475 | } 476 | 477 | // Check if the readme file exists. 478 | $readme_path = $abspath . $this->readme_filename; 479 | $optional_items[$this->readme_filename] = false; 480 | 481 | if ( file_exists( $readme_path ) ) { 482 | $optional_items[$this->readme_filename] = true; 483 | } 484 | 485 | // Check if the patches directory exists and is not empty. 486 | $patches_path = $abspath . $this->patches_dirname; 487 | $optional_items[$this->patches_dirname] = false; 488 | 489 | if ( file_exists( $patches_path ) && is_dir( $patches_path ) && ( ( new \FilesystemIterator( $patches_path ) )->valid() ) ) { 490 | $optional_items[$this->patches_dirname] = true; 491 | } 492 | 493 | // Order custom items. 494 | $custom_items = $this->order_build_items( $custom_items ); 495 | 496 | // Generate gitignore. 497 | $gitignore = $this->generate_gitignore( $custom_gitignore, $custom_items, $optional_items ); 498 | 499 | // Put content in gitignore. 500 | if ( ! empty( $gitignore ) ) { 501 | @file_put_contents( $gitignore_path, $gitignore ); 502 | 503 | return TRUE; 504 | } 505 | 506 | return FALSE; 507 | } 508 | 509 | } 510 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "7347eb901890ab64361fae90f3f01baa", 8 | "packages": [ 9 | { 10 | "name": "alchemy/zippy", 11 | "version": "0.4.4", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/alchemy-fr/Zippy.git", 15 | "reference": "647f55c1e836c834e16e3764f38dc0c257252098" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/alchemy-fr/Zippy/zipball/647f55c1e836c834e16e3764f38dc0c257252098", 20 | "reference": "647f55c1e836c834e16e3764f38dc0c257252098", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "doctrine/collections": "~1.0", 25 | "ext-mbstring": "*", 26 | "php": ">=5.5", 27 | "symfony/filesystem": "^2.0.5|^3.0", 28 | "symfony/process": "^2.1|^3.0" 29 | }, 30 | "require-dev": { 31 | "ext-zip": "*", 32 | "guzzle/guzzle": "~3.0", 33 | "guzzlehttp/guzzle": "^6.0", 34 | "phpunit/phpunit": "^4.0|^5.0", 35 | "symfony/finder": "^2.0.5|^3.0" 36 | }, 37 | "suggest": { 38 | "ext-zip": "To use the ZipExtensionAdapter", 39 | "guzzle/guzzle": "To use the GuzzleTeleporter with Guzzle 3", 40 | "guzzlehttp/guzzle": "To use the GuzzleTeleporter with Guzzle 6" 41 | }, 42 | "type": "library", 43 | "extra": { 44 | "branch-alias": { 45 | "dev-master": "0.4.x-dev" 46 | } 47 | }, 48 | "autoload": { 49 | "psr-4": { 50 | "Alchemy\\Zippy\\": "src/" 51 | } 52 | }, 53 | "notification-url": "https://packagist.org/downloads/", 54 | "license": [ 55 | "MIT" 56 | ], 57 | "authors": [ 58 | { 59 | "name": "Alchemy", 60 | "email": "dev.team@alchemy.fr", 61 | "homepage": "http://www.alchemy.fr/" 62 | } 63 | ], 64 | "description": "Zippy, the archive manager companion", 65 | "keywords": [ 66 | "bzip", 67 | "compression", 68 | "tar", 69 | "zip" 70 | ], 71 | "support": { 72 | "issues": "https://github.com/alchemy-fr/Zippy/issues", 73 | "source": "https://github.com/alchemy-fr/Zippy/tree/master" 74 | }, 75 | "time": "2016-11-03T16:49:36+00:00" 76 | }, 77 | { 78 | "name": "doctrine/collections", 79 | "version": "1.8.0", 80 | "source": { 81 | "type": "git", 82 | "url": "https://github.com/doctrine/collections.git", 83 | "reference": "2b44dd4cbca8b5744327de78bafef5945c7e7b5e" 84 | }, 85 | "dist": { 86 | "type": "zip", 87 | "url": "https://api.github.com/repos/doctrine/collections/zipball/2b44dd4cbca8b5744327de78bafef5945c7e7b5e", 88 | "reference": "2b44dd4cbca8b5744327de78bafef5945c7e7b5e", 89 | "shasum": "" 90 | }, 91 | "require": { 92 | "doctrine/deprecations": "^0.5.3 || ^1", 93 | "php": "^7.1.3 || ^8.0" 94 | }, 95 | "require-dev": { 96 | "doctrine/coding-standard": "^9.0 || ^10.0", 97 | "phpstan/phpstan": "^1.4.8", 98 | "phpunit/phpunit": "^7.5 || ^8.5 || ^9.1.5", 99 | "vimeo/psalm": "^4.22" 100 | }, 101 | "type": "library", 102 | "autoload": { 103 | "psr-4": { 104 | "Doctrine\\Common\\Collections\\": "lib/Doctrine/Common/Collections" 105 | } 106 | }, 107 | "notification-url": "https://packagist.org/downloads/", 108 | "license": [ 109 | "MIT" 110 | ], 111 | "authors": [ 112 | { 113 | "name": "Guilherme Blanco", 114 | "email": "guilhermeblanco@gmail.com" 115 | }, 116 | { 117 | "name": "Roman Borschel", 118 | "email": "roman@code-factory.org" 119 | }, 120 | { 121 | "name": "Benjamin Eberlei", 122 | "email": "kontakt@beberlei.de" 123 | }, 124 | { 125 | "name": "Jonathan Wage", 126 | "email": "jonwage@gmail.com" 127 | }, 128 | { 129 | "name": "Johannes Schmitt", 130 | "email": "schmittjoh@gmail.com" 131 | } 132 | ], 133 | "description": "PHP Doctrine Collections library that adds additional functionality on top of PHP arrays.", 134 | "homepage": "https://www.doctrine-project.org/projects/collections.html", 135 | "keywords": [ 136 | "array", 137 | "collections", 138 | "iterators", 139 | "php" 140 | ], 141 | "support": { 142 | "issues": "https://github.com/doctrine/collections/issues", 143 | "source": "https://github.com/doctrine/collections/tree/1.8.0" 144 | }, 145 | "time": "2022-09-01T20:12:10+00:00" 146 | }, 147 | { 148 | "name": "doctrine/deprecations", 149 | "version": "v1.1.1", 150 | "source": { 151 | "type": "git", 152 | "url": "https://github.com/doctrine/deprecations.git", 153 | "reference": "612a3ee5ab0d5dd97b7cf3874a6efe24325efac3" 154 | }, 155 | "dist": { 156 | "type": "zip", 157 | "url": "https://api.github.com/repos/doctrine/deprecations/zipball/612a3ee5ab0d5dd97b7cf3874a6efe24325efac3", 158 | "reference": "612a3ee5ab0d5dd97b7cf3874a6efe24325efac3", 159 | "shasum": "" 160 | }, 161 | "require": { 162 | "php": "^7.1 || ^8.0" 163 | }, 164 | "require-dev": { 165 | "doctrine/coding-standard": "^9", 166 | "phpstan/phpstan": "1.4.10 || 1.10.15", 167 | "phpstan/phpstan-phpunit": "^1.0", 168 | "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", 169 | "psalm/plugin-phpunit": "0.18.4", 170 | "psr/log": "^1 || ^2 || ^3", 171 | "vimeo/psalm": "4.30.0 || 5.12.0" 172 | }, 173 | "suggest": { 174 | "psr/log": "Allows logging deprecations via PSR-3 logger implementation" 175 | }, 176 | "type": "library", 177 | "autoload": { 178 | "psr-4": { 179 | "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" 180 | } 181 | }, 182 | "notification-url": "https://packagist.org/downloads/", 183 | "license": [ 184 | "MIT" 185 | ], 186 | "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", 187 | "homepage": "https://www.doctrine-project.org/", 188 | "support": { 189 | "issues": "https://github.com/doctrine/deprecations/issues", 190 | "source": "https://github.com/doctrine/deprecations/tree/v1.1.1" 191 | }, 192 | "time": "2023-06-03T09:27:29+00:00" 193 | }, 194 | { 195 | "name": "mustache/mustache", 196 | "version": "v2.14.2", 197 | "source": { 198 | "type": "git", 199 | "url": "https://github.com/bobthecow/mustache.php.git", 200 | "reference": "e62b7c3849d22ec55f3ec425507bf7968193a6cb" 201 | }, 202 | "dist": { 203 | "type": "zip", 204 | "url": "https://api.github.com/repos/bobthecow/mustache.php/zipball/e62b7c3849d22ec55f3ec425507bf7968193a6cb", 205 | "reference": "e62b7c3849d22ec55f3ec425507bf7968193a6cb", 206 | "shasum": "" 207 | }, 208 | "require": { 209 | "php": ">=5.2.4" 210 | }, 211 | "require-dev": { 212 | "friendsofphp/php-cs-fixer": "~1.11", 213 | "phpunit/phpunit": "~3.7|~4.0|~5.0" 214 | }, 215 | "type": "library", 216 | "autoload": { 217 | "psr-0": { 218 | "Mustache": "src/" 219 | } 220 | }, 221 | "notification-url": "https://packagist.org/downloads/", 222 | "license": [ 223 | "MIT" 224 | ], 225 | "authors": [ 226 | { 227 | "name": "Justin Hileman", 228 | "email": "justin@justinhileman.info", 229 | "homepage": "http://justinhileman.com" 230 | } 231 | ], 232 | "description": "A Mustache implementation in PHP.", 233 | "homepage": "https://github.com/bobthecow/mustache.php", 234 | "keywords": [ 235 | "mustache", 236 | "templating" 237 | ], 238 | "support": { 239 | "issues": "https://github.com/bobthecow/mustache.php/issues", 240 | "source": "https://github.com/bobthecow/mustache.php/tree/v2.14.2" 241 | }, 242 | "time": "2022-08-23T13:07:01+00:00" 243 | }, 244 | { 245 | "name": "phar-io/version", 246 | "version": "1.0.1", 247 | "source": { 248 | "type": "git", 249 | "url": "https://github.com/phar-io/version.git", 250 | "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" 251 | }, 252 | "dist": { 253 | "type": "zip", 254 | "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", 255 | "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", 256 | "shasum": "" 257 | }, 258 | "require": { 259 | "php": "^5.6 || ^7.0" 260 | }, 261 | "type": "library", 262 | "autoload": { 263 | "classmap": [ 264 | "src/" 265 | ] 266 | }, 267 | "notification-url": "https://packagist.org/downloads/", 268 | "license": [ 269 | "BSD-3-Clause" 270 | ], 271 | "authors": [ 272 | { 273 | "name": "Arne Blankerts", 274 | "email": "arne@blankerts.de", 275 | "role": "Developer" 276 | }, 277 | { 278 | "name": "Sebastian Heuer", 279 | "email": "sebastian@phpeople.de", 280 | "role": "Developer" 281 | }, 282 | { 283 | "name": "Sebastian Bergmann", 284 | "email": "sebastian@phpunit.de", 285 | "role": "Developer" 286 | } 287 | ], 288 | "description": "Library for handling version information and constraints", 289 | "support": { 290 | "issues": "https://github.com/phar-io/version/issues", 291 | "source": "https://github.com/phar-io/version/tree/master" 292 | }, 293 | "time": "2017-03-05T17:38:23+00:00" 294 | }, 295 | { 296 | "name": "symfony/deprecation-contracts", 297 | "version": "v2.5.2", 298 | "source": { 299 | "type": "git", 300 | "url": "https://github.com/symfony/deprecation-contracts.git", 301 | "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66" 302 | }, 303 | "dist": { 304 | "type": "zip", 305 | "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66", 306 | "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66", 307 | "shasum": "" 308 | }, 309 | "require": { 310 | "php": ">=7.1" 311 | }, 312 | "type": "library", 313 | "extra": { 314 | "branch-alias": { 315 | "dev-main": "2.5-dev" 316 | }, 317 | "thanks": { 318 | "name": "symfony/contracts", 319 | "url": "https://github.com/symfony/contracts" 320 | } 321 | }, 322 | "autoload": { 323 | "files": [ 324 | "function.php" 325 | ] 326 | }, 327 | "notification-url": "https://packagist.org/downloads/", 328 | "license": [ 329 | "MIT" 330 | ], 331 | "authors": [ 332 | { 333 | "name": "Nicolas Grekas", 334 | "email": "p@tchwork.com" 335 | }, 336 | { 337 | "name": "Symfony Community", 338 | "homepage": "https://symfony.com/contributors" 339 | } 340 | ], 341 | "description": "A generic function and convention to trigger deprecation notices", 342 | "homepage": "https://symfony.com", 343 | "support": { 344 | "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.2" 345 | }, 346 | "funding": [ 347 | { 348 | "url": "https://symfony.com/sponsor", 349 | "type": "custom" 350 | }, 351 | { 352 | "url": "https://github.com/fabpot", 353 | "type": "github" 354 | }, 355 | { 356 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 357 | "type": "tidelift" 358 | } 359 | ], 360 | "time": "2022-01-02T09:53:40+00:00" 361 | }, 362 | { 363 | "name": "symfony/filesystem", 364 | "version": "v3.4.47", 365 | "source": { 366 | "type": "git", 367 | "url": "https://github.com/symfony/filesystem.git", 368 | "reference": "e58d7841cddfed6e846829040dca2cca0ebbbbb3" 369 | }, 370 | "dist": { 371 | "type": "zip", 372 | "url": "https://api.github.com/repos/symfony/filesystem/zipball/e58d7841cddfed6e846829040dca2cca0ebbbbb3", 373 | "reference": "e58d7841cddfed6e846829040dca2cca0ebbbbb3", 374 | "shasum": "" 375 | }, 376 | "require": { 377 | "php": "^5.5.9|>=7.0.8", 378 | "symfony/polyfill-ctype": "~1.8" 379 | }, 380 | "type": "library", 381 | "autoload": { 382 | "psr-4": { 383 | "Symfony\\Component\\Filesystem\\": "" 384 | }, 385 | "exclude-from-classmap": [ 386 | "/Tests/" 387 | ] 388 | }, 389 | "notification-url": "https://packagist.org/downloads/", 390 | "license": [ 391 | "MIT" 392 | ], 393 | "authors": [ 394 | { 395 | "name": "Fabien Potencier", 396 | "email": "fabien@symfony.com" 397 | }, 398 | { 399 | "name": "Symfony Community", 400 | "homepage": "https://symfony.com/contributors" 401 | } 402 | ], 403 | "description": "Symfony Filesystem Component", 404 | "homepage": "https://symfony.com", 405 | "support": { 406 | "source": "https://github.com/symfony/filesystem/tree/v3.4.47" 407 | }, 408 | "funding": [ 409 | { 410 | "url": "https://symfony.com/sponsor", 411 | "type": "custom" 412 | }, 413 | { 414 | "url": "https://github.com/fabpot", 415 | "type": "github" 416 | }, 417 | { 418 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 419 | "type": "tidelift" 420 | } 421 | ], 422 | "time": "2020-10-24T10:57:07+00:00" 423 | }, 424 | { 425 | "name": "symfony/finder", 426 | "version": "v5.4.21", 427 | "source": { 428 | "type": "git", 429 | "url": "https://github.com/symfony/finder.git", 430 | "reference": "078e9a5e1871fcfe6a5ce421b539344c21afef19" 431 | }, 432 | "dist": { 433 | "type": "zip", 434 | "url": "https://api.github.com/repos/symfony/finder/zipball/078e9a5e1871fcfe6a5ce421b539344c21afef19", 435 | "reference": "078e9a5e1871fcfe6a5ce421b539344c21afef19", 436 | "shasum": "" 437 | }, 438 | "require": { 439 | "php": ">=7.2.5", 440 | "symfony/deprecation-contracts": "^2.1|^3", 441 | "symfony/polyfill-php80": "^1.16" 442 | }, 443 | "type": "library", 444 | "autoload": { 445 | "psr-4": { 446 | "Symfony\\Component\\Finder\\": "" 447 | }, 448 | "exclude-from-classmap": [ 449 | "/Tests/" 450 | ] 451 | }, 452 | "notification-url": "https://packagist.org/downloads/", 453 | "license": [ 454 | "MIT" 455 | ], 456 | "authors": [ 457 | { 458 | "name": "Fabien Potencier", 459 | "email": "fabien@symfony.com" 460 | }, 461 | { 462 | "name": "Symfony Community", 463 | "homepage": "https://symfony.com/contributors" 464 | } 465 | ], 466 | "description": "Finds files and directories via an intuitive fluent interface", 467 | "homepage": "https://symfony.com", 468 | "support": { 469 | "source": "https://github.com/symfony/finder/tree/v5.4.21" 470 | }, 471 | "funding": [ 472 | { 473 | "url": "https://symfony.com/sponsor", 474 | "type": "custom" 475 | }, 476 | { 477 | "url": "https://github.com/fabpot", 478 | "type": "github" 479 | }, 480 | { 481 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 482 | "type": "tidelift" 483 | } 484 | ], 485 | "time": "2023-02-16T09:33:00+00:00" 486 | }, 487 | { 488 | "name": "symfony/polyfill-ctype", 489 | "version": "v1.27.0", 490 | "source": { 491 | "type": "git", 492 | "url": "https://github.com/symfony/polyfill-ctype.git", 493 | "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" 494 | }, 495 | "dist": { 496 | "type": "zip", 497 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", 498 | "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", 499 | "shasum": "" 500 | }, 501 | "require": { 502 | "php": ">=7.1" 503 | }, 504 | "provide": { 505 | "ext-ctype": "*" 506 | }, 507 | "suggest": { 508 | "ext-ctype": "For best performance" 509 | }, 510 | "type": "library", 511 | "extra": { 512 | "branch-alias": { 513 | "dev-main": "1.27-dev" 514 | }, 515 | "thanks": { 516 | "name": "symfony/polyfill", 517 | "url": "https://github.com/symfony/polyfill" 518 | } 519 | }, 520 | "autoload": { 521 | "files": [ 522 | "bootstrap.php" 523 | ], 524 | "psr-4": { 525 | "Symfony\\Polyfill\\Ctype\\": "" 526 | } 527 | }, 528 | "notification-url": "https://packagist.org/downloads/", 529 | "license": [ 530 | "MIT" 531 | ], 532 | "authors": [ 533 | { 534 | "name": "Gert de Pagter", 535 | "email": "BackEndTea@gmail.com" 536 | }, 537 | { 538 | "name": "Symfony Community", 539 | "homepage": "https://symfony.com/contributors" 540 | } 541 | ], 542 | "description": "Symfony polyfill for ctype functions", 543 | "homepage": "https://symfony.com", 544 | "keywords": [ 545 | "compatibility", 546 | "ctype", 547 | "polyfill", 548 | "portable" 549 | ], 550 | "support": { 551 | "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0" 552 | }, 553 | "funding": [ 554 | { 555 | "url": "https://symfony.com/sponsor", 556 | "type": "custom" 557 | }, 558 | { 559 | "url": "https://github.com/fabpot", 560 | "type": "github" 561 | }, 562 | { 563 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 564 | "type": "tidelift" 565 | } 566 | ], 567 | "time": "2022-11-03T14:55:06+00:00" 568 | }, 569 | { 570 | "name": "symfony/polyfill-php80", 571 | "version": "v1.27.0", 572 | "source": { 573 | "type": "git", 574 | "url": "https://github.com/symfony/polyfill-php80.git", 575 | "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" 576 | }, 577 | "dist": { 578 | "type": "zip", 579 | "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", 580 | "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", 581 | "shasum": "" 582 | }, 583 | "require": { 584 | "php": ">=7.1" 585 | }, 586 | "type": "library", 587 | "extra": { 588 | "branch-alias": { 589 | "dev-main": "1.27-dev" 590 | }, 591 | "thanks": { 592 | "name": "symfony/polyfill", 593 | "url": "https://github.com/symfony/polyfill" 594 | } 595 | }, 596 | "autoload": { 597 | "files": [ 598 | "bootstrap.php" 599 | ], 600 | "psr-4": { 601 | "Symfony\\Polyfill\\Php80\\": "" 602 | }, 603 | "classmap": [ 604 | "Resources/stubs" 605 | ] 606 | }, 607 | "notification-url": "https://packagist.org/downloads/", 608 | "license": [ 609 | "MIT" 610 | ], 611 | "authors": [ 612 | { 613 | "name": "Ion Bazan", 614 | "email": "ion.bazan@gmail.com" 615 | }, 616 | { 617 | "name": "Nicolas Grekas", 618 | "email": "p@tchwork.com" 619 | }, 620 | { 621 | "name": "Symfony Community", 622 | "homepage": "https://symfony.com/contributors" 623 | } 624 | ], 625 | "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", 626 | "homepage": "https://symfony.com", 627 | "keywords": [ 628 | "compatibility", 629 | "polyfill", 630 | "portable", 631 | "shim" 632 | ], 633 | "support": { 634 | "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0" 635 | }, 636 | "funding": [ 637 | { 638 | "url": "https://symfony.com/sponsor", 639 | "type": "custom" 640 | }, 641 | { 642 | "url": "https://github.com/fabpot", 643 | "type": "github" 644 | }, 645 | { 646 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 647 | "type": "tidelift" 648 | } 649 | ], 650 | "time": "2022-11-03T14:55:06+00:00" 651 | }, 652 | { 653 | "name": "symfony/process", 654 | "version": "v3.4.47", 655 | "source": { 656 | "type": "git", 657 | "url": "https://github.com/symfony/process.git", 658 | "reference": "b8648cf1d5af12a44a51d07ef9bf980921f15fca" 659 | }, 660 | "dist": { 661 | "type": "zip", 662 | "url": "https://api.github.com/repos/symfony/process/zipball/b8648cf1d5af12a44a51d07ef9bf980921f15fca", 663 | "reference": "b8648cf1d5af12a44a51d07ef9bf980921f15fca", 664 | "shasum": "" 665 | }, 666 | "require": { 667 | "php": "^5.5.9|>=7.0.8" 668 | }, 669 | "type": "library", 670 | "autoload": { 671 | "psr-4": { 672 | "Symfony\\Component\\Process\\": "" 673 | }, 674 | "exclude-from-classmap": [ 675 | "/Tests/" 676 | ] 677 | }, 678 | "notification-url": "https://packagist.org/downloads/", 679 | "license": [ 680 | "MIT" 681 | ], 682 | "authors": [ 683 | { 684 | "name": "Fabien Potencier", 685 | "email": "fabien@symfony.com" 686 | }, 687 | { 688 | "name": "Symfony Community", 689 | "homepage": "https://symfony.com/contributors" 690 | } 691 | ], 692 | "description": "Symfony Process Component", 693 | "homepage": "https://symfony.com", 694 | "support": { 695 | "source": "https://github.com/symfony/process/tree/v3.4.47" 696 | }, 697 | "funding": [ 698 | { 699 | "url": "https://symfony.com/sponsor", 700 | "type": "custom" 701 | }, 702 | { 703 | "url": "https://github.com/fabpot", 704 | "type": "github" 705 | }, 706 | { 707 | "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", 708 | "type": "tidelift" 709 | } 710 | ], 711 | "time": "2020-10-24T10:57:07+00:00" 712 | }, 713 | { 714 | "name": "symfony/yaml", 715 | "version": "v3.4.4", 716 | "source": { 717 | "type": "git", 718 | "url": "https://github.com/symfony/yaml.git", 719 | "reference": "eab73b6c21d27ae4cd037c417618dfd4befb0bfe" 720 | }, 721 | "dist": { 722 | "type": "zip", 723 | "url": "https://api.github.com/repos/symfony/yaml/zipball/eab73b6c21d27ae4cd037c417618dfd4befb0bfe", 724 | "reference": "eab73b6c21d27ae4cd037c417618dfd4befb0bfe", 725 | "shasum": "" 726 | }, 727 | "require": { 728 | "php": "^5.5.9|>=7.0.8" 729 | }, 730 | "conflict": { 731 | "symfony/console": "<3.4" 732 | }, 733 | "require-dev": { 734 | "symfony/console": "~3.4|~4.0" 735 | }, 736 | "suggest": { 737 | "symfony/console": "For validating YAML files using the lint command" 738 | }, 739 | "type": "library", 740 | "extra": { 741 | "branch-alias": { 742 | "dev-master": "3.4-dev" 743 | } 744 | }, 745 | "autoload": { 746 | "psr-4": { 747 | "Symfony\\Component\\Yaml\\": "" 748 | }, 749 | "exclude-from-classmap": [ 750 | "/Tests/" 751 | ] 752 | }, 753 | "notification-url": "https://packagist.org/downloads/", 754 | "license": [ 755 | "MIT" 756 | ], 757 | "authors": [ 758 | { 759 | "name": "Fabien Potencier", 760 | "email": "fabien@symfony.com" 761 | }, 762 | { 763 | "name": "Symfony Community", 764 | "homepage": "https://symfony.com/contributors" 765 | } 766 | ], 767 | "description": "Symfony Yaml Component", 768 | "homepage": "https://symfony.com", 769 | "support": { 770 | "source": "https://github.com/symfony/yaml/tree/3.4" 771 | }, 772 | "time": "2018-01-21T19:05:02+00:00" 773 | }, 774 | { 775 | "name": "wp-cli/mustangostang-spyc", 776 | "version": "0.6.3", 777 | "source": { 778 | "type": "git", 779 | "url": "https://github.com/wp-cli/spyc.git", 780 | "reference": "6aa0b4da69ce9e9a2c8402dab8d43cf32c581cc7" 781 | }, 782 | "dist": { 783 | "type": "zip", 784 | "url": "https://api.github.com/repos/wp-cli/spyc/zipball/6aa0b4da69ce9e9a2c8402dab8d43cf32c581cc7", 785 | "reference": "6aa0b4da69ce9e9a2c8402dab8d43cf32c581cc7", 786 | "shasum": "" 787 | }, 788 | "require": { 789 | "php": ">=5.3.1" 790 | }, 791 | "require-dev": { 792 | "phpunit/phpunit": "4.3.*@dev" 793 | }, 794 | "type": "library", 795 | "extra": { 796 | "branch-alias": { 797 | "dev-master": "0.5.x-dev" 798 | } 799 | }, 800 | "autoload": { 801 | "files": [ 802 | "includes/functions.php" 803 | ], 804 | "psr-4": { 805 | "Mustangostang\\": "src/" 806 | } 807 | }, 808 | "notification-url": "https://packagist.org/downloads/", 809 | "license": [ 810 | "MIT" 811 | ], 812 | "authors": [ 813 | { 814 | "name": "mustangostang", 815 | "email": "vlad.andersen@gmail.com" 816 | } 817 | ], 818 | "description": "A simple YAML loader/dumper class for PHP (WP-CLI fork)", 819 | "homepage": "https://github.com/mustangostang/spyc/", 820 | "support": { 821 | "source": "https://github.com/wp-cli/spyc/tree/autoload" 822 | }, 823 | "time": "2017-04-25T11:26:20+00:00" 824 | }, 825 | { 826 | "name": "wp-cli/php-cli-tools", 827 | "version": "v0.11.19", 828 | "source": { 829 | "type": "git", 830 | "url": "https://github.com/wp-cli/php-cli-tools.git", 831 | "reference": "2d27f0db5c36f5aa0064abecddd6d05f28c4d001" 832 | }, 833 | "dist": { 834 | "type": "zip", 835 | "url": "https://api.github.com/repos/wp-cli/php-cli-tools/zipball/2d27f0db5c36f5aa0064abecddd6d05f28c4d001", 836 | "reference": "2d27f0db5c36f5aa0064abecddd6d05f28c4d001", 837 | "shasum": "" 838 | }, 839 | "require": { 840 | "php": ">= 5.3.0" 841 | }, 842 | "require-dev": { 843 | "roave/security-advisories": "dev-latest", 844 | "wp-cli/wp-cli-tests": "^3.1.6" 845 | }, 846 | "type": "library", 847 | "extra": { 848 | "branch-alias": { 849 | "dev-master": "0.11.x-dev" 850 | } 851 | }, 852 | "autoload": { 853 | "files": [ 854 | "lib/cli/cli.php" 855 | ], 856 | "psr-0": { 857 | "cli": "lib/" 858 | } 859 | }, 860 | "notification-url": "https://packagist.org/downloads/", 861 | "license": [ 862 | "MIT" 863 | ], 864 | "authors": [ 865 | { 866 | "name": "Daniel Bachhuber", 867 | "email": "daniel@handbuilt.co", 868 | "role": "Maintainer" 869 | }, 870 | { 871 | "name": "James Logsdon", 872 | "email": "jlogsdon@php.net", 873 | "role": "Developer" 874 | } 875 | ], 876 | "description": "Console utilities for PHP", 877 | "homepage": "http://github.com/wp-cli/php-cli-tools", 878 | "keywords": [ 879 | "cli", 880 | "console" 881 | ], 882 | "support": { 883 | "issues": "https://github.com/wp-cli/php-cli-tools/issues", 884 | "source": "https://github.com/wp-cli/php-cli-tools/tree/v0.11.19" 885 | }, 886 | "time": "2023-07-21T11:37:15+00:00" 887 | }, 888 | { 889 | "name": "wp-cli/wp-cli", 890 | "version": "v2.8.1", 891 | "source": { 892 | "type": "git", 893 | "url": "https://github.com/wp-cli/wp-cli.git", 894 | "reference": "5dd2340b9a01c3cfdbaf5e93a140759fdd190eee" 895 | }, 896 | "dist": { 897 | "type": "zip", 898 | "url": "https://api.github.com/repos/wp-cli/wp-cli/zipball/5dd2340b9a01c3cfdbaf5e93a140759fdd190eee", 899 | "reference": "5dd2340b9a01c3cfdbaf5e93a140759fdd190eee", 900 | "shasum": "" 901 | }, 902 | "require": { 903 | "ext-curl": "*", 904 | "mustache/mustache": "^2.14.1", 905 | "php": "^5.6 || ^7.0 || ^8.0", 906 | "symfony/finder": ">2.7", 907 | "wp-cli/mustangostang-spyc": "^0.6.3", 908 | "wp-cli/php-cli-tools": "~0.11.2" 909 | }, 910 | "require-dev": { 911 | "roave/security-advisories": "dev-latest", 912 | "wp-cli/db-command": "^1.3 || ^2", 913 | "wp-cli/entity-command": "^1.2 || ^2", 914 | "wp-cli/extension-command": "^1.1 || ^2", 915 | "wp-cli/package-command": "^1 || ^2", 916 | "wp-cli/wp-cli-tests": "^3.1.6" 917 | }, 918 | "suggest": { 919 | "ext-readline": "Include for a better --prompt implementation", 920 | "ext-zip": "Needed to support extraction of ZIP archives when doing downloads or updates" 921 | }, 922 | "bin": [ 923 | "bin/wp", 924 | "bin/wp.bat" 925 | ], 926 | "type": "library", 927 | "extra": { 928 | "branch-alias": { 929 | "dev-main": "2.9.x-dev" 930 | } 931 | }, 932 | "autoload": { 933 | "psr-0": { 934 | "WP_CLI\\": "php/" 935 | }, 936 | "classmap": [ 937 | "php/class-wp-cli.php", 938 | "php/class-wp-cli-command.php" 939 | ] 940 | }, 941 | "notification-url": "https://packagist.org/downloads/", 942 | "license": [ 943 | "MIT" 944 | ], 945 | "description": "WP-CLI framework", 946 | "homepage": "https://wp-cli.org", 947 | "keywords": [ 948 | "cli", 949 | "wordpress" 950 | ], 951 | "support": { 952 | "docs": "https://make.wordpress.org/cli/handbook/", 953 | "issues": "https://github.com/wp-cli/wp-cli/issues", 954 | "source": "https://github.com/wp-cli/wp-cli" 955 | }, 956 | "time": "2023-06-05T06:55:55+00:00" 957 | } 958 | ], 959 | "packages-dev": [ 960 | { 961 | "name": "dealerdirect/phpcodesniffer-composer-installer", 962 | "version": "v0.7.2", 963 | "source": { 964 | "type": "git", 965 | "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", 966 | "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db" 967 | }, 968 | "dist": { 969 | "type": "zip", 970 | "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", 971 | "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", 972 | "shasum": "" 973 | }, 974 | "require": { 975 | "composer-plugin-api": "^1.0 || ^2.0", 976 | "php": ">=5.3", 977 | "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" 978 | }, 979 | "require-dev": { 980 | "composer/composer": "*", 981 | "php-parallel-lint/php-parallel-lint": "^1.3.1", 982 | "phpcompatibility/php-compatibility": "^9.0" 983 | }, 984 | "type": "composer-plugin", 985 | "extra": { 986 | "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" 987 | }, 988 | "autoload": { 989 | "psr-4": { 990 | "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" 991 | } 992 | }, 993 | "notification-url": "https://packagist.org/downloads/", 994 | "license": [ 995 | "MIT" 996 | ], 997 | "authors": [ 998 | { 999 | "name": "Franck Nijhof", 1000 | "email": "franck.nijhof@dealerdirect.com", 1001 | "homepage": "http://www.frenck.nl", 1002 | "role": "Developer / IT Manager" 1003 | }, 1004 | { 1005 | "name": "Contributors", 1006 | "homepage": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer/graphs/contributors" 1007 | } 1008 | ], 1009 | "description": "PHP_CodeSniffer Standards Composer Installer Plugin", 1010 | "homepage": "http://www.dealerdirect.com", 1011 | "keywords": [ 1012 | "PHPCodeSniffer", 1013 | "PHP_CodeSniffer", 1014 | "code quality", 1015 | "codesniffer", 1016 | "composer", 1017 | "installer", 1018 | "phpcbf", 1019 | "phpcs", 1020 | "plugin", 1021 | "qa", 1022 | "quality", 1023 | "standard", 1024 | "standards", 1025 | "style guide", 1026 | "stylecheck", 1027 | "tests" 1028 | ], 1029 | "support": { 1030 | "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues", 1031 | "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer" 1032 | }, 1033 | "time": "2022-02-04T12:51:07+00:00" 1034 | }, 1035 | { 1036 | "name": "phpstan/phpdoc-parser", 1037 | "version": "1.23.0", 1038 | "source": { 1039 | "type": "git", 1040 | "url": "https://github.com/phpstan/phpdoc-parser.git", 1041 | "reference": "a2b24135c35852b348894320d47b3902a94bc494" 1042 | }, 1043 | "dist": { 1044 | "type": "zip", 1045 | "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/a2b24135c35852b348894320d47b3902a94bc494", 1046 | "reference": "a2b24135c35852b348894320d47b3902a94bc494", 1047 | "shasum": "" 1048 | }, 1049 | "require": { 1050 | "php": "^7.2 || ^8.0" 1051 | }, 1052 | "require-dev": { 1053 | "doctrine/annotations": "^2.0", 1054 | "nikic/php-parser": "^4.15", 1055 | "php-parallel-lint/php-parallel-lint": "^1.2", 1056 | "phpstan/extension-installer": "^1.0", 1057 | "phpstan/phpstan": "^1.5", 1058 | "phpstan/phpstan-phpunit": "^1.1", 1059 | "phpstan/phpstan-strict-rules": "^1.0", 1060 | "phpunit/phpunit": "^9.5", 1061 | "symfony/process": "^5.2" 1062 | }, 1063 | "type": "library", 1064 | "autoload": { 1065 | "psr-4": { 1066 | "PHPStan\\PhpDocParser\\": [ 1067 | "src/" 1068 | ] 1069 | } 1070 | }, 1071 | "notification-url": "https://packagist.org/downloads/", 1072 | "license": [ 1073 | "MIT" 1074 | ], 1075 | "description": "PHPDoc parser with support for nullable, intersection and generic types", 1076 | "support": { 1077 | "issues": "https://github.com/phpstan/phpdoc-parser/issues", 1078 | "source": "https://github.com/phpstan/phpdoc-parser/tree/1.23.0" 1079 | }, 1080 | "time": "2023-07-23T22:17:56+00:00" 1081 | }, 1082 | { 1083 | "name": "phpstan/phpstan", 1084 | "version": "1.10.26", 1085 | "source": { 1086 | "type": "git", 1087 | "url": "https://github.com/phpstan/phpstan.git", 1088 | "reference": "5d660cbb7e1b89253a47147ae44044f49832351f" 1089 | }, 1090 | "dist": { 1091 | "type": "zip", 1092 | "url": "https://api.github.com/repos/phpstan/phpstan/zipball/5d660cbb7e1b89253a47147ae44044f49832351f", 1093 | "reference": "5d660cbb7e1b89253a47147ae44044f49832351f", 1094 | "shasum": "" 1095 | }, 1096 | "require": { 1097 | "php": "^7.2|^8.0" 1098 | }, 1099 | "conflict": { 1100 | "phpstan/phpstan-shim": "*" 1101 | }, 1102 | "bin": [ 1103 | "phpstan", 1104 | "phpstan.phar" 1105 | ], 1106 | "type": "library", 1107 | "autoload": { 1108 | "files": [ 1109 | "bootstrap.php" 1110 | ] 1111 | }, 1112 | "notification-url": "https://packagist.org/downloads/", 1113 | "license": [ 1114 | "MIT" 1115 | ], 1116 | "description": "PHPStan - PHP Static Analysis Tool", 1117 | "keywords": [ 1118 | "dev", 1119 | "static analysis" 1120 | ], 1121 | "support": { 1122 | "docs": "https://phpstan.org/user-guide/getting-started", 1123 | "forum": "https://github.com/phpstan/phpstan/discussions", 1124 | "issues": "https://github.com/phpstan/phpstan/issues", 1125 | "security": "https://github.com/phpstan/phpstan/security/policy", 1126 | "source": "https://github.com/phpstan/phpstan-src" 1127 | }, 1128 | "funding": [ 1129 | { 1130 | "url": "https://github.com/ondrejmirtes", 1131 | "type": "github" 1132 | }, 1133 | { 1134 | "url": "https://github.com/phpstan", 1135 | "type": "github" 1136 | }, 1137 | { 1138 | "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", 1139 | "type": "tidelift" 1140 | } 1141 | ], 1142 | "time": "2023-07-19T12:44:37+00:00" 1143 | }, 1144 | { 1145 | "name": "roave/security-advisories", 1146 | "version": "dev-latest", 1147 | "source": { 1148 | "type": "git", 1149 | "url": "https://github.com/Roave/SecurityAdvisories.git", 1150 | "reference": "4bdecf23905dae843494483debeae99c08e4f66f" 1151 | }, 1152 | "dist": { 1153 | "type": "zip", 1154 | "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/4bdecf23905dae843494483debeae99c08e4f66f", 1155 | "reference": "4bdecf23905dae843494483debeae99c08e4f66f", 1156 | "shasum": "" 1157 | }, 1158 | "conflict": { 1159 | "3f/pygmentize": "<1.2", 1160 | "admidio/admidio": "<4.2.10", 1161 | "adodb/adodb-php": "<=5.20.20|>=5.21,<=5.21.3", 1162 | "aheinze/cockpit": "<2.2", 1163 | "aimeos/aimeos-typo3": "<19.10.12|>=20,<20.10.5", 1164 | "akaunting/akaunting": "<2.1.13", 1165 | "akeneo/pim-community-dev": "<5.0.119|>=6,<6.0.53", 1166 | "alextselegidis/easyappointments": "<1.5", 1167 | "alterphp/easyadmin-extension-bundle": ">=1.2,<1.2.11|>=1.3,<1.3.1", 1168 | "amazing/media2click": ">=1,<1.3.3", 1169 | "amphp/artax": "<1.0.6|>=2,<2.0.6", 1170 | "amphp/http": "<1.0.1", 1171 | "amphp/http-client": ">=4,<4.4", 1172 | "anchorcms/anchor-cms": "<=0.12.7", 1173 | "andreapollastri/cipi": "<=3.1.15", 1174 | "andrewhaine/silverstripe-form-capture": ">=0.2,<=0.2.3|>=1,<1.0.2|>=2,<2.2.5", 1175 | "apereo/phpcas": "<1.6", 1176 | "api-platform/core": ">=2.2,<2.2.10|>=2.3,<2.3.6|>=2.6,<2.7.10|>=3,<3.0.12|>=3.1,<3.1.3", 1177 | "appwrite/server-ce": "<=1.2.1", 1178 | "arc/web": "<3", 1179 | "area17/twill": "<1.2.5|>=2,<2.5.3", 1180 | "artesaos/seotools": "<0.17.2", 1181 | "asymmetricrypt/asymmetricrypt": ">=0,<9.9.99", 1182 | "athlon1600/php-proxy": "<=5.1", 1183 | "athlon1600/php-proxy-app": "<=3", 1184 | "automad/automad": "<1.8", 1185 | "awesome-support/awesome-support": "<=6.0.7", 1186 | "aws/aws-sdk-php": ">=3,<3.2.1", 1187 | "azuracast/azuracast": "<0.18.3", 1188 | "backdrop/backdrop": "<1.24.2", 1189 | "backpack/crud": "<3.4.9", 1190 | "badaso/core": "<2.7", 1191 | "bagisto/bagisto": "<0.1.5", 1192 | "barrelstrength/sprout-base-email": "<1.2.7", 1193 | "barrelstrength/sprout-forms": "<3.9", 1194 | "barryvdh/laravel-translation-manager": "<0.6.2", 1195 | "barzahlen/barzahlen-php": "<2.0.1", 1196 | "baserproject/basercms": "<4.7.5", 1197 | "bassjobsen/bootstrap-3-typeahead": ">4.0.2", 1198 | "bigfork/silverstripe-form-capture": ">=3,<3.1.1", 1199 | "billz/raspap-webgui": "<2.8.9", 1200 | "bk2k/bootstrap-package": ">=7.1,<7.1.2|>=8,<8.0.8|>=9,<9.0.4|>=9.1,<9.1.3|>=10,<10.0.10|>=11,<11.0.3", 1201 | "bmarshall511/wordpress_zero_spam": "<5.2.13", 1202 | "bolt/bolt": "<3.7.2", 1203 | "bolt/core": "<=4.2", 1204 | "bottelet/flarepoint": "<2.2.1", 1205 | "brightlocal/phpwhois": "<=4.2.5", 1206 | "brotkrueml/codehighlight": "<2.7", 1207 | "brotkrueml/schema": "<1.13.1|>=2,<2.5.1", 1208 | "brotkrueml/typo3-matomo-integration": "<1.3.2", 1209 | "buddypress/buddypress": "<7.2.1", 1210 | "bugsnag/bugsnag-laravel": ">=2,<2.0.2", 1211 | "bytefury/crater": "<6.0.2", 1212 | "cachethq/cachet": "<2.5.1", 1213 | "cakephp/cakephp": "<3.10.3|>=4,<4.0.10|>=4.2,<4.2.12|>=4.3,<4.3.11|>=4.4,<4.4.10|= 1.3.7|>=4.1,<4.1.4", 1214 | "cakephp/database": ">=4.2,<4.2.12|>=4.3,<4.3.11|>=4.4,<4.4.10", 1215 | "cardgate/magento2": "<2.0.33", 1216 | "cardgate/woocommerce": "<=3.1.15", 1217 | "cart2quote/module-quotation": ">=4.1.6,<=4.4.5|>=5,<5.4.4", 1218 | "cartalyst/sentry": "<=2.1.6", 1219 | "catfan/medoo": "<1.7.5", 1220 | "centreon/centreon": "<22.10-beta.1", 1221 | "cesnet/simplesamlphp-module-proxystatistics": "<3.1", 1222 | "cockpit-hq/cockpit": "<2.6", 1223 | "codeception/codeception": "<3.1.3|>=4,<4.1.22", 1224 | "codeigniter/framework": "<=3.0.6", 1225 | "codeigniter4/framework": "<4.3.5", 1226 | "codeigniter4/shield": "<1-beta.4|= 1.0.0-beta", 1227 | "codiad/codiad": "<=2.8.4", 1228 | "composer/composer": "<1.10.26|>=2-alpha.1,<2.2.12|>=2.3,<2.3.5", 1229 | "concrete5/concrete5": "<9.2|>= 9.0.0RC1, < 9.1.3", 1230 | "concrete5/core": "<8.5.8|>=9,<9.1", 1231 | "contao-components/mediaelement": ">=2.14.2,<2.21.1", 1232 | "contao/contao": ">=4,<4.4.56|>=4.5,<4.9.40|>=4.10,<4.11.7|>=4.13,<4.13.21|>=5.1,<5.1.4", 1233 | "contao/core": ">=2,<3.5.39", 1234 | "contao/core-bundle": "<4.9.40|>=4.10,<4.11.7|>=4.13,<4.13.21|>=5.1,<5.1.4|= 4.10.0", 1235 | "contao/listing-bundle": ">=4,<4.4.8", 1236 | "contao/managed-edition": "<=1.5", 1237 | "cosenary/instagram": "<=2.3", 1238 | "craftcms/cms": "<=4.4.9|>= 4.0.0-RC1, < 4.4.12|>= 4.0.0-RC1, <= 4.4.5|>= 4.0.0-RC1, <= 4.4.6|>= 4.0.0-RC1, < 4.4.6|>= 4.0.0-RC1, < 4.3.7|>= 4.0.0-RC1, < 4.2.1", 1239 | "croogo/croogo": "<3.0.7", 1240 | "cuyz/valinor": "<0.12", 1241 | "czproject/git-php": "<4.0.3", 1242 | "darylldoyle/safe-svg": "<1.9.10", 1243 | "datadog/dd-trace": ">=0.30,<0.30.2", 1244 | "david-garcia/phpwhois": "<=4.3.1", 1245 | "dbrisinajumi/d2files": "<1", 1246 | "dcat/laravel-admin": "<=2.1.3-beta", 1247 | "derhansen/fe_change_pwd": "<2.0.5|>=3,<3.0.3", 1248 | "derhansen/sf_event_mgt": "<4.3.1|>=5,<5.1.1", 1249 | "desperado/xml-bundle": "<=0.1.7", 1250 | "directmailteam/direct-mail": "<5.2.4", 1251 | "doctrine/annotations": ">=1,<1.2.7", 1252 | "doctrine/cache": ">=1,<1.3.2|>=1.4,<1.4.2", 1253 | "doctrine/common": ">=2,<2.4.3|>=2.5,<2.5.1", 1254 | "doctrine/dbal": ">=2,<2.0.8|>=2.1,<2.1.2|>=3,<3.1.4", 1255 | "doctrine/doctrine-bundle": "<1.5.2", 1256 | "doctrine/doctrine-module": "<=0.7.1", 1257 | "doctrine/mongodb-odm": ">=1,<1.0.2", 1258 | "doctrine/mongodb-odm-bundle": ">=2,<3.0.1", 1259 | "doctrine/orm": ">=2,<2.4.8|>=2.5,<2.5.1|>=2.8.3,<2.8.4", 1260 | "dolibarr/dolibarr": "<17.0.1|= 12.0.5|>= 3.3.beta1, < 13.0.2", 1261 | "dompdf/dompdf": "<2.0.2|= 2.0.2", 1262 | "drupal/core": ">=7,<7.96|>=8,<9.4.14|>=9.5,<9.5.8|>=10,<10.0.8", 1263 | "drupal/drupal": ">=7,<7.80|>=8,<8.9.16|>=9,<9.1.12|>=9.2,<9.2.4", 1264 | "dweeves/magmi": "<=0.7.24", 1265 | "ecodev/newsletter": "<=4", 1266 | "ectouch/ectouch": "<=2.7.2", 1267 | "elefant/cms": "<1.3.13", 1268 | "elgg/elgg": "<3.3.24|>=4,<4.0.5", 1269 | "encore/laravel-admin": "<=1.8.19", 1270 | "endroid/qr-code-bundle": "<3.4.2", 1271 | "enshrined/svg-sanitize": "<0.15", 1272 | "erusev/parsedown": "<1.7.2", 1273 | "ether/logs": "<3.0.4", 1274 | "exceedone/exment": "<4.4.3|>=5,<5.0.3", 1275 | "exceedone/laravel-admin": "= 3.0.0|<2.2.3", 1276 | "ezsystems/demobundle": ">=5.4,<5.4.6.1", 1277 | "ezsystems/ez-support-tools": ">=2.2,<2.2.3", 1278 | "ezsystems/ezdemo-ls-extension": ">=5.4,<5.4.2.1", 1279 | "ezsystems/ezfind-ls": ">=5.3,<5.3.6.1|>=5.4,<5.4.11.1|>=2017.12,<2017.12.0.1", 1280 | "ezsystems/ezplatform": "<=1.13.6|>=2,<=2.5.24", 1281 | "ezsystems/ezplatform-admin-ui": ">=1.3,<1.3.5|>=1.4,<1.4.6|>=1.5,<1.5.29|>=2.3,<2.3.26", 1282 | "ezsystems/ezplatform-admin-ui-assets": ">=4,<4.2.1|>=5,<5.0.1|>=5.1,<5.1.1", 1283 | "ezsystems/ezplatform-graphql": ">=1-rc.1,<1.0.13|>=2-beta.1,<2.3.12", 1284 | "ezsystems/ezplatform-kernel": "<1.2.5.1|>=1.3,<1.3.26", 1285 | "ezsystems/ezplatform-rest": ">=1.2,<=1.2.2|>=1.3,<1.3.8", 1286 | "ezsystems/ezplatform-richtext": ">=2.3,<2.3.7.1", 1287 | "ezsystems/ezplatform-user": ">=1,<1.0.1", 1288 | "ezsystems/ezpublish-kernel": "<6.13.8.2|>=7,<7.5.30", 1289 | "ezsystems/ezpublish-legacy": "<=2017.12.7.3|>=2018.6,<=2019.3.5.1", 1290 | "ezsystems/platform-ui-assets-bundle": ">=4.2,<4.2.3", 1291 | "ezsystems/repository-forms": ">=2.3,<2.3.2.1|>=2.5,<2.5.15", 1292 | "ezyang/htmlpurifier": "<4.1.1", 1293 | "facade/ignition": "<1.16.15|>=2,<2.4.2|>=2.5,<2.5.2", 1294 | "facturascripts/facturascripts": "<=2022.8", 1295 | "feehi/cms": "<=2.1.1", 1296 | "feehi/feehicms": "<=2.1.1", 1297 | "fenom/fenom": "<=2.12.1", 1298 | "filegator/filegator": "<7.8", 1299 | "firebase/php-jwt": "<6", 1300 | "fixpunkt/fp-masterquiz": "<2.2.1|>=3,<3.5.2", 1301 | "fixpunkt/fp-newsletter": "<1.1.1|>=2,<2.1.2|>=2.2,<3.2.6", 1302 | "flarum/core": "<1.7", 1303 | "flarum/mentions": "<1.6.3", 1304 | "flarum/sticky": ">=0.1-beta.14,<=0.1-beta.15", 1305 | "flarum/tags": "<=0.1-beta.13", 1306 | "fluidtypo3/vhs": "<5.1.1", 1307 | "fof/byobu": ">=0.3-beta.2,<1.1.7", 1308 | "fof/upload": "<1.2.3", 1309 | "fooman/tcpdf": "<6.2.22", 1310 | "forkcms/forkcms": "<5.11.1", 1311 | "fossar/tcpdf-parser": "<6.2.22", 1312 | "francoisjacquet/rosariosis": "<11", 1313 | "frappant/frp-form-answers": "<3.1.2|>=4,<4.0.2", 1314 | "friendsofsymfony/oauth2-php": "<1.3", 1315 | "friendsofsymfony/rest-bundle": ">=1.2,<1.2.2", 1316 | "friendsofsymfony/user-bundle": ">=1.2,<1.3.5", 1317 | "friendsoftypo3/mediace": ">=7.6.2,<7.6.5", 1318 | "froala/wysiwyg-editor": "<3.2.7", 1319 | "froxlor/froxlor": "<2.1", 1320 | "fuel/core": "<1.8.1", 1321 | "funadmin/funadmin": "<=3.2|>=3.3.2,<=3.3.3", 1322 | "gaoming13/wechat-php-sdk": "<=1.10.2", 1323 | "genix/cms": "<=1.1.11", 1324 | "getgrav/grav": "<=1.7.42.1", 1325 | "getkirby/cms": "= 3.8.0|<3.5.8.2|>=3.6,<3.6.6.2|>=3.7,<3.7.5.1", 1326 | "getkirby/panel": "<2.5.14", 1327 | "getkirby/starterkit": "<=3.7.0.2", 1328 | "gilacms/gila": "<=1.11.4", 1329 | "globalpayments/php-sdk": "<2", 1330 | "gogentooss/samlbase": "<1.2.7", 1331 | "google/protobuf": "<3.15", 1332 | "gos/web-socket-bundle": "<1.10.4|>=2,<2.6.1|>=3,<3.3", 1333 | "gree/jose": "<2.2.1", 1334 | "gregwar/rst": "<1.0.3", 1335 | "grumpydictator/firefly-iii": "<6", 1336 | "guzzlehttp/guzzle": "<6.5.8|>=7,<7.4.5", 1337 | "guzzlehttp/psr7": "<1.9.1|>=2,<2.4.5", 1338 | "haffner/jh_captcha": "<=2.1.3|>=3,<=3.0.2", 1339 | "harvesthq/chosen": "<1.8.7", 1340 | "helloxz/imgurl": "= 2.31|<=2.31", 1341 | "hhxsv5/laravel-s": "<3.7.36", 1342 | "hillelcoren/invoice-ninja": "<5.3.35", 1343 | "himiklab/yii2-jqgrid-widget": "<1.0.8", 1344 | "hjue/justwriting": "<=1", 1345 | "hov/jobfair": "<1.0.13|>=2,<2.0.2", 1346 | "httpsoft/http-message": "<1.0.12", 1347 | "hyn/multi-tenant": ">=5.6,<5.7.2", 1348 | "ibexa/admin-ui": ">=4.2,<4.2.3", 1349 | "ibexa/core": ">=4,<4.0.7|>=4.1,<4.1.4|>=4.2,<4.2.3", 1350 | "ibexa/graphql": ">=2.5,<2.5.31|>=3.3,<3.3.28|>=4.2,<4.2.3", 1351 | "ibexa/post-install": "<=1.0.4", 1352 | "ibexa/user": ">=4,<4.4.3", 1353 | "icecoder/icecoder": "<=8.1", 1354 | "idno/known": "<=1.3.1", 1355 | "illuminate/auth": ">=4,<4.0.99|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.10", 1356 | "illuminate/cookie": ">=4,<=4.0.11|>=4.1,<=4.1.99999|>=4.2,<=4.2.99999|>=5,<=5.0.99999|>=5.1,<=5.1.99999|>=5.2,<=5.2.99999|>=5.3,<=5.3.99999|>=5.4,<=5.4.99999|>=5.5,<=5.5.49|>=5.6,<=5.6.99999|>=5.7,<=5.7.99999|>=5.8,<=5.8.99999|>=6,<6.18.31|>=7,<7.22.4", 1357 | "illuminate/database": "<6.20.26|>=7,<7.30.5|>=8,<8.40", 1358 | "illuminate/encryption": ">=4,<=4.0.11|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.40|>=5.6,<5.6.15", 1359 | "illuminate/view": "<6.20.42|>=7,<7.30.6|>=8,<8.75", 1360 | "impresscms/impresscms": "<=1.4.5", 1361 | "in2code/femanager": "<5.5.3|>=6,<6.3.4|>=7,<7.1", 1362 | "in2code/ipandlanguageredirect": "<5.1.2", 1363 | "in2code/lux": "<17.6.1|>=18,<24.0.2", 1364 | "innologi/typo3-appointments": "<2.0.6", 1365 | "intelliants/subrion": "<=4.2.1", 1366 | "islandora/islandora": ">=2,<2.4.1", 1367 | "ivankristianto/phpwhois": "<=4.3", 1368 | "jackalope/jackalope-doctrine-dbal": "<1.7.4", 1369 | "james-heinrich/getid3": "<1.9.21", 1370 | "jasig/phpcas": "<1.3.3", 1371 | "joomla/archive": "<1.1.12|>=2,<2.0.1", 1372 | "joomla/filesystem": "<1.6.2|>=2,<2.0.1", 1373 | "joomla/filter": "<1.4.4|>=2,<2.0.1", 1374 | "joomla/framework": ">=2.5.4,<=3.8.12", 1375 | "joomla/input": ">=2,<2.0.2", 1376 | "joomla/joomla-cms": ">=3,<3.9.12", 1377 | "joomla/session": "<1.3.1", 1378 | "joyqi/hyper-down": "<=2.4.27", 1379 | "jsdecena/laracom": "<2.0.9", 1380 | "jsmitty12/phpwhois": "<5.1", 1381 | "kazist/phpwhois": "<=4.2.6", 1382 | "kelvinmo/simplexrd": "<3.1.1", 1383 | "kevinpapst/kimai2": "<1.16.7", 1384 | "khodakhah/nodcms": "<=3", 1385 | "kimai/kimai": "<1.1", 1386 | "kitodo/presentation": "<3.2.3|>=3.3,<3.3.4", 1387 | "klaviyo/magento2-extension": ">=1,<3", 1388 | "knplabs/knp-snappy": "<1.4.2", 1389 | "krayin/laravel-crm": "<1.2.2", 1390 | "kreait/firebase-php": ">=3.2,<3.8.1", 1391 | "la-haute-societe/tcpdf": "<6.2.22", 1392 | "laminas/laminas-diactoros": "<2.18.1|>=2.24,<2.24.2|>=2.25,<2.25.2|= 2.23.0|= 2.22.0|= 2.21.0|= 2.20.0|= 2.19.0", 1393 | "laminas/laminas-form": "<2.17.1|>=3,<3.0.2|>=3.1,<3.1.1", 1394 | "laminas/laminas-http": "<2.14.2", 1395 | "laravel/fortify": "<1.11.1", 1396 | "laravel/framework": "<6.20.44|>=7,<7.30.6|>=8,<8.75", 1397 | "laravel/socialite": ">=1,<1.0.99|>=2,<2.0.10", 1398 | "latte/latte": "<2.10.8", 1399 | "lavalite/cms": "= 9.0.0|<=9", 1400 | "lcobucci/jwt": ">=3.4,<3.4.6|>=4,<4.0.4|>=4.1,<4.1.5", 1401 | "league/commonmark": "<0.18.3", 1402 | "league/flysystem": "<1.1.4|>=2,<2.1.1", 1403 | "league/oauth2-server": ">=8.3.2,<8.5.3", 1404 | "lexik/jwt-authentication-bundle": "<2.10.7|>=2.11,<2.11.3", 1405 | "librenms/librenms": "<22.10", 1406 | "liftkit/database": "<2.13.2", 1407 | "limesurvey/limesurvey": "<3.27.19", 1408 | "livehelperchat/livehelperchat": "<=3.91", 1409 | "livewire/livewire": ">2.2.4,<2.2.6", 1410 | "lms/routes": "<2.1.1", 1411 | "localizationteam/l10nmgr": "<7.4|>=8,<8.7|>=9,<9.2", 1412 | "luyadev/yii-helpers": "<1.2.1", 1413 | "magento/community-edition": "= 2.4.0|<=2.4", 1414 | "magento/magento1ce": "<1.9.4.3", 1415 | "magento/magento1ee": ">=1,<1.14.4.3", 1416 | "magento/product-community-edition": ">=2,<2.2.10|>=2.3,<2.3.2-p.2", 1417 | "maikuolan/phpmussel": ">=1,<1.6", 1418 | "mantisbt/mantisbt": "<=2.25.5", 1419 | "marcwillmann/turn": "<0.3.3", 1420 | "matyhtf/framework": "<3.0.6", 1421 | "mautic/core": "<4.3|= 2.13.1", 1422 | "mediawiki/core": ">=1.27,<1.27.6|>=1.29,<1.29.3|>=1.30,<1.30.2|>=1.31,<1.31.9|>=1.32,<1.32.6|>=1.32.99,<1.33.3|>=1.33.99,<1.34.3|>=1.34.99,<1.35", 1423 | "mediawiki/matomo": "<2.4.3", 1424 | "melisplatform/melis-asset-manager": "<5.0.1", 1425 | "melisplatform/melis-cms": "<5.0.1", 1426 | "melisplatform/melis-front": "<5.0.1", 1427 | "mezzio/mezzio-swoole": "<3.7|>=4,<4.3", 1428 | "mgallegos/laravel-jqgrid": "<=1.3", 1429 | "microweber/microweber": "= 1.1.18|<=1.3.4", 1430 | "miniorange/miniorange-saml": "<1.4.3", 1431 | "mittwald/typo3_forum": "<1.2.1", 1432 | "mobiledetect/mobiledetectlib": "<2.8.32", 1433 | "modx/revolution": "<2.8|<= 2.8.3-pl", 1434 | "mojo42/jirafeau": "<4.4", 1435 | "monolog/monolog": ">=1.8,<1.12", 1436 | "moodle/moodle": "<4.2-rc.2|= 3.4.3|= 3.5|= 3.7|= 3.9|= 3.8|= 4.2.0|= 3.11", 1437 | "movim/moxl": ">=0.8,<=0.10", 1438 | "mpdf/mpdf": "<=7.1.7", 1439 | "mustache/mustache": ">=2,<2.14.1", 1440 | "namshi/jose": "<2.2", 1441 | "neoan3-apps/template": "<1.1.1", 1442 | "neorazorx/facturascripts": "<2022.4", 1443 | "neos/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.12|>=3.1,<3.1.10|>=3.2,<3.2.13|>=3.3,<3.3.13|>=4,<4.0.6", 1444 | "neos/form": ">=1.2,<4.3.3|>=5,<5.0.9|>=5.1,<5.1.3", 1445 | "neos/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<2.9.99|>=3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<5.3.10|>=7,<7.0.9|>=7.1,<7.1.7|>=7.2,<7.2.6|>=7.3,<7.3.4|>=8,<8.0.2", 1446 | "neos/swiftmailer": ">=4.1,<4.1.99|>=5.4,<5.4.5", 1447 | "netgen/tagsbundle": ">=3.4,<3.4.11|>=4,<4.0.15", 1448 | "nette/application": ">=2,<2.0.19|>=2.1,<2.1.13|>=2.2,<2.2.10|>=2.3,<2.3.14|>=2.4,<2.4.16|>=3,<3.0.6", 1449 | "nette/nette": ">=2,<2.0.19|>=2.1,<2.1.13", 1450 | "nilsteampassnet/teampass": "<3.0.10", 1451 | "notrinos/notrinos-erp": "<=0.7", 1452 | "noumo/easyii": "<=0.9", 1453 | "nukeviet/nukeviet": "<4.5.2", 1454 | "nyholm/psr7": "<1.6.1", 1455 | "nystudio107/craft-seomatic": "<3.4.12", 1456 | "nzo/url-encryptor-bundle": ">=4,<4.3.2|>=5,<5.0.1", 1457 | "october/backend": "<1.1.2", 1458 | "october/cms": "= 1.1.1|= 1.0.471|= 1.0.469|>=1.0.319,<1.0.469", 1459 | "october/october": "<1.0.466|>=2.1,<2.1.12", 1460 | "october/rain": "<1.0.472|>=1.1,<1.1.2", 1461 | "october/system": "<1.0.476|>=1.1,<1.1.12|>=2,<2.2.34|>=3,<3.0.66", 1462 | "onelogin/php-saml": "<2.10.4", 1463 | "oneup/uploader-bundle": "<1.9.3|>=2,<2.1.5", 1464 | "open-web-analytics/open-web-analytics": "<1.7.4", 1465 | "opencart/opencart": "<=3.0.3.7", 1466 | "openid/php-openid": "<2.3", 1467 | "openmage/magento-lts": "<19.4.22|>=20,<20.0.19", 1468 | "opensource-workshop/connect-cms": "<1.7.2|>=2,<2.3.2", 1469 | "orchid/platform": ">=9,<9.4.4|>=14-alpha.4,<14.5", 1470 | "oro/commerce": ">=4.1,<5.0.6", 1471 | "oro/crm": ">=1.7,<1.7.4|>=3.1,<4.1.17|>=4.2,<4.2.7", 1472 | "oro/platform": ">=1.7,<1.7.4|>=3.1,<3.1.29|>=4.1,<4.1.17|>=4.2,<4.2.8", 1473 | "packbackbooks/lti-1-3-php-library": "<5", 1474 | "padraic/humbug_get_contents": "<1.1.2", 1475 | "pagarme/pagarme-php": ">=0,<3", 1476 | "pagekit/pagekit": "<=1.0.18", 1477 | "paragonie/random_compat": "<2", 1478 | "passbolt/passbolt_api": "<2.11", 1479 | "paypal/merchant-sdk-php": "<3.12", 1480 | "pear/archive_tar": "<1.4.14", 1481 | "pear/crypt_gpg": "<1.6.7", 1482 | "pear/pear": "<=1.10.1", 1483 | "pegasus/google-for-jobs": "<1.5.1|>=2,<2.1.1", 1484 | "personnummer/personnummer": "<3.0.2", 1485 | "phanan/koel": "<5.1.4", 1486 | "php-mod/curl": "<2.3.2", 1487 | "phpbb/phpbb": "<3.2.10|>=3.3,<3.3.1", 1488 | "phpfastcache/phpfastcache": "<6.1.5|>=7,<7.1.2|>=8,<8.0.7", 1489 | "phpmailer/phpmailer": "<6.5", 1490 | "phpmussel/phpmussel": ">=1,<1.6", 1491 | "phpmyadmin/phpmyadmin": "<5.2.1", 1492 | "phpmyfaq/phpmyfaq": "<=3.1.7", 1493 | "phpoffice/phpexcel": "<1.8", 1494 | "phpoffice/phpspreadsheet": "<1.16", 1495 | "phpseclib/phpseclib": "<2.0.31|>=3,<3.0.19", 1496 | "phpservermon/phpservermon": "<3.6", 1497 | "phpsysinfo/phpsysinfo": "<3.2.5", 1498 | "phpunit/phpunit": ">=4.8.19,<4.8.28|>=5,<5.6.3", 1499 | "phpwhois/phpwhois": "<=4.2.5", 1500 | "phpxmlrpc/extras": "<0.6.1", 1501 | "phpxmlrpc/phpxmlrpc": "<4.9.2", 1502 | "pi/pi": "<=2.5", 1503 | "pimcore/admin-ui-classic-bundle": "<1.0.3", 1504 | "pimcore/customer-management-framework-bundle": "<3.4.1", 1505 | "pimcore/data-hub": "<1.2.4", 1506 | "pimcore/perspective-editor": "<1.5.1", 1507 | "pimcore/pimcore": "<10.6.4", 1508 | "pixelfed/pixelfed": "<=0.11.4", 1509 | "pocketmine/bedrock-protocol": "<8.0.2", 1510 | "pocketmine/pocketmine-mp": "<4.22.3|>=5,<5.2.1|< 4.18.0-ALPHA2|>= 4.0.0-BETA5, < 4.4.2", 1511 | "pressbooks/pressbooks": "<5.18", 1512 | "prestashop/autoupgrade": ">=4,<4.10.1", 1513 | "prestashop/blockwishlist": ">=2,<2.1.1", 1514 | "prestashop/contactform": ">=1.0.1,<4.3", 1515 | "prestashop/gamification": "<2.3.2", 1516 | "prestashop/prestashop": "<8.0.4", 1517 | "prestashop/productcomments": "<5.0.2", 1518 | "prestashop/ps_emailsubscription": "<2.6.1", 1519 | "prestashop/ps_facetedsearch": "<3.4.1", 1520 | "prestashop/ps_linklist": "<3.1", 1521 | "privatebin/privatebin": "<1.4", 1522 | "processwire/processwire": "<=3.0.200", 1523 | "propel/propel": ">=2-alpha.1,<=2-alpha.7", 1524 | "propel/propel1": ">=1,<=1.7.1", 1525 | "pterodactyl/panel": "<1.7", 1526 | "ptrofimov/beanstalk_console": "<1.7.14", 1527 | "pusher/pusher-php-server": "<2.2.1", 1528 | "pwweb/laravel-core": "<=0.3.6-beta", 1529 | "pyrocms/pyrocms": "<=3.9.1", 1530 | "rainlab/debugbar-plugin": "<3.1", 1531 | "rankmath/seo-by-rank-math": "<=1.0.95", 1532 | "rap2hpoutre/laravel-log-viewer": "<0.13", 1533 | "react/http": ">=0.7,<1.9", 1534 | "really-simple-plugins/complianz-gdpr": "<6.4.2", 1535 | "remdex/livehelperchat": "<3.99", 1536 | "rmccue/requests": ">=1.6,<1.8", 1537 | "robrichards/xmlseclibs": "<3.0.4", 1538 | "roots/soil": "<4.1", 1539 | "rudloff/alltube": "<3.0.3", 1540 | "s-cart/core": "<6.9", 1541 | "s-cart/s-cart": "<6.9", 1542 | "sabberworm/php-css-parser": ">=1,<1.0.1|>=2,<2.0.1|>=3,<3.0.1|>=4,<4.0.1|>=5,<5.0.9|>=5.1,<5.1.3|>=5.2,<5.2.1|>=6,<6.0.2|>=7,<7.0.4|>=8,<8.0.1|>=8.1,<8.1.1|>=8.2,<8.2.1|>=8.3,<8.3.1", 1543 | "sabre/dav": "<1.7.11|>=1.8,<1.8.9", 1544 | "scheb/two-factor-bundle": ">=0,<3.26|>=4,<4.11", 1545 | "sensiolabs/connect": "<4.2.3", 1546 | "serluck/phpwhois": "<=4.2.6", 1547 | "sfroemken/url_redirect": "<=1.2.1", 1548 | "sheng/yiicms": "<=1.2", 1549 | "shopware/core": "<=6.4.20", 1550 | "shopware/platform": "<=6.4.20", 1551 | "shopware/production": "<=6.3.5.2", 1552 | "shopware/shopware": "<=5.7.17", 1553 | "shopware/storefront": "<=6.4.8.1", 1554 | "shopxo/shopxo": "<2.2.6", 1555 | "showdoc/showdoc": "<2.10.4", 1556 | "silverstripe-australia/advancedreports": ">=1,<=2", 1557 | "silverstripe/admin": "<1.12.7", 1558 | "silverstripe/assets": ">=1,<1.11.1", 1559 | "silverstripe/cms": "<4.11.3", 1560 | "silverstripe/comments": ">=1.3,<1.9.99|>=2,<2.9.99|>=3,<3.1.1", 1561 | "silverstripe/forum": "<=0.6.1|>=0.7,<=0.7.3", 1562 | "silverstripe/framework": "<4.12.5", 1563 | "silverstripe/graphql": "<3.5.2|>=4-alpha.1,<4-alpha.2|>=4.1.1,<4.1.2|>=4.2.2,<4.2.3|= 4.0.0-alpha1", 1564 | "silverstripe/hybridsessions": ">=1,<2.4.1|>=2.5,<2.5.1", 1565 | "silverstripe/recipe-cms": ">=4.5,<4.5.3", 1566 | "silverstripe/registry": ">=2.1,<2.1.2|>=2.2,<2.2.1", 1567 | "silverstripe/restfulserver": ">=1,<1.0.9|>=2,<2.0.4", 1568 | "silverstripe/silverstripe-omnipay": "<2.5.2|>=3,<3.0.2|>=3.1,<3.1.4|>=3.2,<3.2.1", 1569 | "silverstripe/subsites": ">=2,<2.6.1", 1570 | "silverstripe/taxonomy": ">=1.3,<1.3.1|>=2,<2.0.1", 1571 | "silverstripe/userforms": "<3", 1572 | "silverstripe/versioned-admin": ">=1,<1.11.1", 1573 | "simple-updates/phpwhois": "<=1", 1574 | "simplesamlphp/saml2": "<1.10.6|>=2,<2.3.8|>=3,<3.1.4", 1575 | "simplesamlphp/simplesamlphp": "<1.18.6", 1576 | "simplesamlphp/simplesamlphp-module-infocard": "<1.0.1", 1577 | "simplesamlphp/simplesamlphp-module-openid": "<1", 1578 | "simplesamlphp/simplesamlphp-module-openidprovider": "<0.9", 1579 | "simplito/elliptic-php": "<1.0.6", 1580 | "sitegeist/fluid-components": "<3.5", 1581 | "sjbr/sr-freecap": "<=2.5.2", 1582 | "slim/psr7": "<1.4.1|>=1.5,<1.5.1|>=1.6,<1.6.1", 1583 | "slim/slim": "<2.6", 1584 | "smarty/smarty": "<3.1.48|>=4,<4.3.1", 1585 | "snipe/snipe-it": "<=6.0.14|>= 6.0.0-RC-1, <= 6.0.0-RC-5", 1586 | "socalnick/scn-social-auth": "<1.15.2", 1587 | "socialiteproviders/steam": "<1.1", 1588 | "spatie/browsershot": "<3.57.4", 1589 | "spipu/html2pdf": "<5.2.4", 1590 | "spoon/library": "<1.4.1", 1591 | "spoonity/tcpdf": "<6.2.22", 1592 | "squizlabs/php_codesniffer": ">=1,<2.8.1|>=3,<3.0.1", 1593 | "ssddanbrown/bookstack": "<22.2.3", 1594 | "statamic/cms": "<4.10", 1595 | "stormpath/sdk": ">=0,<9.9.99", 1596 | "studio-42/elfinder": "<2.1.62", 1597 | "subhh/libconnect": "<7.0.8|>=8,<8.1", 1598 | "subrion/cms": "<=4.2.1", 1599 | "sukohi/surpass": "<1", 1600 | "sulu/sulu": "= 2.4.0-RC1|<1.6.44|>=2,<2.2.18|>=2.3,<2.3.8", 1601 | "sumocoders/framework-user-bundle": "<1.4", 1602 | "swag/paypal": "<5.4.4", 1603 | "swiftmailer/swiftmailer": ">=4,<5.4.5", 1604 | "sylius/admin-bundle": ">=1,<1.0.17|>=1.1,<1.1.9|>=1.2,<1.2.2", 1605 | "sylius/grid": ">=1,<1.1.19|>=1.2,<1.2.18|>=1.3,<1.3.13|>=1.4,<1.4.5|>=1.5,<1.5.1", 1606 | "sylius/grid-bundle": "<1.10.1", 1607 | "sylius/paypal-plugin": ">=1,<1.2.4|>=1.3,<1.3.1", 1608 | "sylius/resource-bundle": "<1.3.14|>=1.4,<1.4.7|>=1.5,<1.5.2|>=1.6,<1.6.4", 1609 | "sylius/sylius": "<1.9.10|>=1.10,<1.10.11|>=1.11,<1.11.2", 1610 | "symbiote/silverstripe-multivaluefield": ">=3,<3.0.99", 1611 | "symbiote/silverstripe-queuedjobs": ">=3,<3.0.2|>=3.1,<3.1.4|>=4,<4.0.7|>=4.1,<4.1.2|>=4.2,<4.2.4|>=4.3,<4.3.3|>=4.4,<4.4.3|>=4.5,<4.5.1|>=4.6,<4.6.4", 1612 | "symbiote/silverstripe-seed": "<6.0.3", 1613 | "symbiote/silverstripe-versionedfiles": "<=2.0.3", 1614 | "symfont/process": ">=0", 1615 | "symfony/cache": ">=3.1,<3.4.35|>=4,<4.2.12|>=4.3,<4.3.8", 1616 | "symfony/dependency-injection": ">=2,<2.0.17|>=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7", 1617 | "symfony/error-handler": ">=4.4,<4.4.4|>=5,<5.0.4", 1618 | "symfony/form": ">=2.3,<2.3.35|>=2.4,<2.6.12|>=2.7,<2.7.50|>=2.8,<2.8.49|>=3,<3.4.20|>=4,<4.0.15|>=4.1,<4.1.9|>=4.2,<4.2.1", 1619 | "symfony/framework-bundle": ">=2,<2.3.18|>=2.4,<2.4.8|>=2.5,<2.5.2|>=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7|>=5.3.14,<=5.3.14|>=5.4.3,<=5.4.3|>=6.0.3,<=6.0.3|= 6.0.3|= 5.4.3|= 5.3.14", 1620 | "symfony/http-foundation": ">=2,<2.8.52|>=3,<3.4.35|>=4,<4.2.12|>=4.3,<4.3.8|>=4.4,<4.4.7|>=5,<5.0.7", 1621 | "symfony/http-kernel": ">=2,<4.4.50|>=5,<5.4.20|>=6,<6.0.20|>=6.1,<6.1.12|>=6.2,<6.2.6", 1622 | "symfony/intl": ">=2.7,<2.7.38|>=2.8,<2.8.31|>=3,<3.2.14|>=3.3,<3.3.13", 1623 | "symfony/maker-bundle": ">=1.27,<1.29.2|>=1.30,<1.31.1", 1624 | "symfony/mime": ">=4.3,<4.3.8", 1625 | "symfony/phpunit-bridge": ">=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7", 1626 | "symfony/polyfill": ">=1,<1.10", 1627 | "symfony/polyfill-php55": ">=1,<1.10", 1628 | "symfony/proxy-manager-bridge": ">=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7", 1629 | "symfony/routing": ">=2,<2.0.19", 1630 | "symfony/security": ">=2,<2.7.51|>=2.8,<3.4.49|>=4,<4.4.24|>=5,<5.2.8", 1631 | "symfony/security-bundle": ">=2,<4.4.50|>=5,<5.4.20|>=6,<6.0.20|>=6.1,<6.1.12|>=6.2,<6.2.6", 1632 | "symfony/security-core": ">=2.4,<2.6.13|>=2.7,<2.7.9|>=2.7.30,<2.7.32|>=2.8,<3.4.49|>=4,<4.4.24|>=5,<5.2.9", 1633 | "symfony/security-csrf": ">=2.4,<2.7.48|>=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11", 1634 | "symfony/security-guard": ">=2.8,<3.4.48|>=4,<4.4.23|>=5,<5.2.8", 1635 | "symfony/security-http": ">=2.3,<2.3.41|>=2.4,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.2.12|>=4.3,<4.3.8|>=4.4,<4.4.7|>=5,<5.0.7|>=5.1,<5.2.8|>=5.3,<5.3.2", 1636 | "symfony/serializer": ">=2,<2.0.11|>=4.1,<4.4.35|>=5,<5.3.12", 1637 | "symfony/symfony": ">=2,<4.4.50|>=5,<5.4.20|>=6,<6.0.20|>=6.1,<6.1.12|>=6.2,<6.2.6", 1638 | "symfony/translation": ">=2,<2.0.17", 1639 | "symfony/validator": ">=2,<2.0.24|>=2.1,<2.1.12|>=2.2,<2.2.5|>=2.3,<2.3.3", 1640 | "symfony/var-exporter": ">=4.2,<4.2.12|>=4.3,<4.3.8", 1641 | "symfony/web-profiler-bundle": ">=2,<2.3.19|>=2.4,<2.4.9|>=2.5,<2.5.4", 1642 | "symfony/yaml": ">=2,<2.0.22|>=2.1,<2.1.7", 1643 | "t3/dce": ">=2.2,<2.6.2", 1644 | "t3g/svg-sanitizer": "<1.0.3", 1645 | "tastyigniter/tastyigniter": "<3.3", 1646 | "tcg/voyager": "<=1.4", 1647 | "tecnickcom/tcpdf": "<6.2.22", 1648 | "terminal42/contao-tablelookupwizard": "<3.3.5", 1649 | "thelia/backoffice-default-template": ">=2.1,<2.1.2", 1650 | "thelia/thelia": ">=2.1-beta.1,<2.1.3", 1651 | "theonedemon/phpwhois": "<=4.2.5", 1652 | "thinkcmf/thinkcmf": "<=5.1.7", 1653 | "thorsten/phpmyfaq": "<3.2-beta.2", 1654 | "tinymce/tinymce": "<5.10.7|>=6,<6.3.1", 1655 | "tinymighty/wiki-seo": "<1.2.2", 1656 | "titon/framework": ">=0,<9.9.99", 1657 | "tobiasbg/tablepress": "<= 2.0-RC1", 1658 | "topthink/framework": "<6.0.14", 1659 | "topthink/think": "<=6.1.1", 1660 | "topthink/thinkphp": "<=3.2.3", 1661 | "tpwd/ke_search": "<4.0.3|>=4.1,<4.6.6|>=5,<5.0.2", 1662 | "tribalsystems/zenario": "<=9.3.57595", 1663 | "truckersmp/phpwhois": "<=4.3.1", 1664 | "ttskch/pagination-service-provider": "<1", 1665 | "twig/twig": "<1.44.7|>=2,<2.15.3|>=3,<3.4.3", 1666 | "typo3/cms": "<2.0.5|>=3,<3.0.3|>=6.2,<=6.2.38|>=7,<7.6.32|>=8,<8.7.38|>=9,<9.5.29|>=10,<10.4.35|>=11,<11.5.23|>=12,<12.2", 1667 | "typo3/cms-backend": ">=7,<=7.6.50|>=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.13|>=11,<=11.1", 1668 | "typo3/cms-core": "<8.7.51|>=9,<9.5.40|>=10,<10.4.36|>=11,<11.5.23|>=12,<12.2", 1669 | "typo3/cms-form": ">=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.13|>=11,<=11.1", 1670 | "typo3/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.12|>=3.1,<3.1.10|>=3.2,<3.2.13|>=3.3,<3.3.13|>=4,<4.0.6", 1671 | "typo3/html-sanitizer": ">=1,<1.5|>=2,<2.1.1", 1672 | "typo3/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<2.3.99|>=3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<3.3.23|>=4,<4.0.17|>=4.1,<4.1.16|>=4.2,<4.2.12|>=4.3,<4.3.3", 1673 | "typo3/phar-stream-wrapper": ">=1,<2.1.1|>=3,<3.1.1", 1674 | "typo3/swiftmailer": ">=4.1,<4.1.99|>=5.4,<5.4.5", 1675 | "typo3fluid/fluid": ">=2,<2.0.8|>=2.1,<2.1.7|>=2.2,<2.2.4|>=2.3,<2.3.7|>=2.4,<2.4.4|>=2.5,<2.5.11|>=2.6,<2.6.10", 1676 | "ua-parser/uap-php": "<3.8", 1677 | "unisharp/laravel-filemanager": "<=2.5.1", 1678 | "userfrosting/userfrosting": ">=0.3.1,<4.6.3", 1679 | "usmanhalalit/pixie": "<1.0.3|>=2,<2.0.2", 1680 | "uvdesk/community-skeleton": "<=1.1.1", 1681 | "vanilla/safecurl": "<0.9.2", 1682 | "verot/class.upload.php": "<=1.0.3|>=2,<=2.0.4", 1683 | "vova07/yii2-fileapi-widget": "<0.1.9", 1684 | "vrana/adminer": "<4.8.1", 1685 | "wallabag/tcpdf": "<6.2.22", 1686 | "wallabag/wallabag": "<=2.5.4", 1687 | "wanglelecc/laracms": "<=1.0.3", 1688 | "web-auth/webauthn-framework": ">=3.3,<3.3.4", 1689 | "webbuilders-group/silverstripe-kapost-bridge": "<0.4", 1690 | "webcoast/deferred-image-processing": "<1.0.2", 1691 | "webklex/laravel-imap": "<5.3", 1692 | "webklex/php-imap": "<5.3", 1693 | "webpa/webpa": "<3.1.2", 1694 | "wikibase/wikibase": "<=1.39.3", 1695 | "wikimedia/parsoid": "<0.12.2", 1696 | "willdurand/js-translation-bundle": "<2.1.1", 1697 | "wintercms/winter": "<1.2.3", 1698 | "woocommerce/woocommerce": "<6.6", 1699 | "wp-cli/wp-cli": "<2.5", 1700 | "wp-graphql/wp-graphql": "<=1.14.5", 1701 | "wpanel/wpanel4-cms": "<=4.3.1", 1702 | "wpcloud/wp-stateless": "<3.2", 1703 | "wwbn/avideo": "<=12.4", 1704 | "xataface/xataface": "<3", 1705 | "xpressengine/xpressengine": "<3.0.15", 1706 | "yeswiki/yeswiki": "<4.1", 1707 | "yetiforce/yetiforce-crm": "<=6.4", 1708 | "yidashi/yii2cmf": "<=2", 1709 | "yii2mod/yii2-cms": "<1.9.2", 1710 | "yiisoft/yii": "<1.1.27", 1711 | "yiisoft/yii2": "<2.0.38", 1712 | "yiisoft/yii2-bootstrap": "<2.0.4", 1713 | "yiisoft/yii2-dev": "<2.0.43", 1714 | "yiisoft/yii2-elasticsearch": "<2.0.5", 1715 | "yiisoft/yii2-gii": "<=2.2.4", 1716 | "yiisoft/yii2-jui": "<2.0.4", 1717 | "yiisoft/yii2-redis": "<2.0.8", 1718 | "yikesinc/yikes-inc-easy-mailchimp-extender": "<6.8.6", 1719 | "yoast-seo-for-typo3/yoast_seo": "<7.2.3", 1720 | "yourls/yourls": "<=1.8.2", 1721 | "zencart/zencart": "<1.5.8", 1722 | "zendesk/zendesk_api_client_php": "<2.2.11", 1723 | "zendframework/zend-cache": ">=2.4,<2.4.8|>=2.5,<2.5.3", 1724 | "zendframework/zend-captcha": ">=2,<2.4.9|>=2.5,<2.5.2", 1725 | "zendframework/zend-crypt": ">=2,<2.4.9|>=2.5,<2.5.2", 1726 | "zendframework/zend-db": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.2,<2.2.10|>=2.3,<2.3.5", 1727 | "zendframework/zend-developer-tools": ">=1.2.2,<1.2.3", 1728 | "zendframework/zend-diactoros": "<1.8.4", 1729 | "zendframework/zend-feed": "<2.10.3", 1730 | "zendframework/zend-form": ">=2,<2.2.7|>=2.3,<2.3.1", 1731 | "zendframework/zend-http": "<2.8.1", 1732 | "zendframework/zend-json": ">=2.1,<2.1.6|>=2.2,<2.2.6", 1733 | "zendframework/zend-ldap": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.2,<2.2.8|>=2.3,<2.3.3", 1734 | "zendframework/zend-mail": ">=2,<2.4.11|>=2.5,<2.7.2", 1735 | "zendframework/zend-navigation": ">=2,<2.2.7|>=2.3,<2.3.1", 1736 | "zendframework/zend-session": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.2,<2.2.9|>=2.3,<2.3.4", 1737 | "zendframework/zend-validator": ">=2.3,<2.3.6", 1738 | "zendframework/zend-view": ">=2,<2.2.7|>=2.3,<2.3.1", 1739 | "zendframework/zend-xmlrpc": ">=2.1,<2.1.6|>=2.2,<2.2.6", 1740 | "zendframework/zendframework": "<=3", 1741 | "zendframework/zendframework1": "<1.12.20", 1742 | "zendframework/zendopenid": ">=2,<2.0.2", 1743 | "zendframework/zendxml": ">=1,<1.0.1", 1744 | "zenstruck/collection": "<0.2.1", 1745 | "zetacomponents/mail": "<1.8.2", 1746 | "zf-commons/zfc-user": "<1.2.2", 1747 | "zfcampus/zf-apigility-doctrine": ">=1,<1.0.3", 1748 | "zfr/zfr-oauth2-server-module": "<0.1.2", 1749 | "zoujingli/thinkadmin": "<6.0.22" 1750 | }, 1751 | "default-branch": true, 1752 | "type": "metapackage", 1753 | "notification-url": "https://packagist.org/downloads/", 1754 | "license": [ 1755 | "MIT" 1756 | ], 1757 | "authors": [ 1758 | { 1759 | "name": "Marco Pivetta", 1760 | "email": "ocramius@gmail.com", 1761 | "role": "maintainer" 1762 | }, 1763 | { 1764 | "name": "Ilya Tribusean", 1765 | "email": "slash3b@gmail.com", 1766 | "role": "maintainer" 1767 | } 1768 | ], 1769 | "description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it", 1770 | "keywords": [ 1771 | "dev" 1772 | ], 1773 | "support": { 1774 | "issues": "https://github.com/Roave/SecurityAdvisories/issues", 1775 | "source": "https://github.com/Roave/SecurityAdvisories/tree/latest" 1776 | }, 1777 | "funding": [ 1778 | { 1779 | "url": "https://github.com/Ocramius", 1780 | "type": "github" 1781 | }, 1782 | { 1783 | "url": "https://tidelift.com/funding/github/packagist/roave/security-advisories", 1784 | "type": "tidelift" 1785 | } 1786 | ], 1787 | "time": "2023-07-21T23:04:36+00:00" 1788 | }, 1789 | { 1790 | "name": "slevomat/coding-standard", 1791 | "version": "8.13.2", 1792 | "source": { 1793 | "type": "git", 1794 | "url": "https://github.com/slevomat/coding-standard.git", 1795 | "reference": "83fb531a75950b6c6c7c37d7813836c3df8fc8d1" 1796 | }, 1797 | "dist": { 1798 | "type": "zip", 1799 | "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/83fb531a75950b6c6c7c37d7813836c3df8fc8d1", 1800 | "reference": "83fb531a75950b6c6c7c37d7813836c3df8fc8d1", 1801 | "shasum": "" 1802 | }, 1803 | "require": { 1804 | "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7 || ^1.0", 1805 | "php": "^7.2 || ^8.0", 1806 | "phpstan/phpdoc-parser": "^1.23.0", 1807 | "squizlabs/php_codesniffer": "^3.7.1" 1808 | }, 1809 | "require-dev": { 1810 | "phing/phing": "2.17.4", 1811 | "php-parallel-lint/php-parallel-lint": "1.3.2", 1812 | "phpstan/phpstan": "1.10.26", 1813 | "phpstan/phpstan-deprecation-rules": "1.1.3", 1814 | "phpstan/phpstan-phpunit": "1.3.13", 1815 | "phpstan/phpstan-strict-rules": "1.5.1", 1816 | "phpunit/phpunit": "7.5.20|8.5.21|9.6.8|10.2.6" 1817 | }, 1818 | "type": "phpcodesniffer-standard", 1819 | "extra": { 1820 | "branch-alias": { 1821 | "dev-master": "8.x-dev" 1822 | } 1823 | }, 1824 | "autoload": { 1825 | "psr-4": { 1826 | "SlevomatCodingStandard\\": "SlevomatCodingStandard/" 1827 | } 1828 | }, 1829 | "notification-url": "https://packagist.org/downloads/", 1830 | "license": [ 1831 | "MIT" 1832 | ], 1833 | "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", 1834 | "keywords": [ 1835 | "dev", 1836 | "phpcs" 1837 | ], 1838 | "support": { 1839 | "issues": "https://github.com/slevomat/coding-standard/issues", 1840 | "source": "https://github.com/slevomat/coding-standard/tree/8.13.2" 1841 | }, 1842 | "funding": [ 1843 | { 1844 | "url": "https://github.com/kukulich", 1845 | "type": "github" 1846 | }, 1847 | { 1848 | "url": "https://tidelift.com/funding/github/packagist/slevomat/coding-standard", 1849 | "type": "tidelift" 1850 | } 1851 | ], 1852 | "time": "2023-07-24T10:09:44+00:00" 1853 | }, 1854 | { 1855 | "name": "squizlabs/php_codesniffer", 1856 | "version": "3.7.2", 1857 | "source": { 1858 | "type": "git", 1859 | "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", 1860 | "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879" 1861 | }, 1862 | "dist": { 1863 | "type": "zip", 1864 | "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ed8e00df0a83aa96acf703f8c2979ff33341f879", 1865 | "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879", 1866 | "shasum": "" 1867 | }, 1868 | "require": { 1869 | "ext-simplexml": "*", 1870 | "ext-tokenizer": "*", 1871 | "ext-xmlwriter": "*", 1872 | "php": ">=5.4.0" 1873 | }, 1874 | "require-dev": { 1875 | "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" 1876 | }, 1877 | "bin": [ 1878 | "bin/phpcs", 1879 | "bin/phpcbf" 1880 | ], 1881 | "type": "library", 1882 | "extra": { 1883 | "branch-alias": { 1884 | "dev-master": "3.x-dev" 1885 | } 1886 | }, 1887 | "notification-url": "https://packagist.org/downloads/", 1888 | "license": [ 1889 | "BSD-3-Clause" 1890 | ], 1891 | "authors": [ 1892 | { 1893 | "name": "Greg Sherwood", 1894 | "role": "lead" 1895 | } 1896 | ], 1897 | "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", 1898 | "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", 1899 | "keywords": [ 1900 | "phpcs", 1901 | "standards", 1902 | "static analysis" 1903 | ], 1904 | "support": { 1905 | "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", 1906 | "source": "https://github.com/squizlabs/PHP_CodeSniffer", 1907 | "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" 1908 | }, 1909 | "time": "2023-02-22T23:07:41+00:00" 1910 | } 1911 | ], 1912 | "aliases": [], 1913 | "minimum-stability": "dev", 1914 | "stability-flags": { 1915 | "roave/security-advisories": 20 1916 | }, 1917 | "prefer-stable": true, 1918 | "prefer-lowest": false, 1919 | "platform": { 1920 | "php": "~7.4.0" 1921 | }, 1922 | "platform-dev": [], 1923 | "plugin-api-version": "2.3.0" 1924 | } 1925 | --------------------------------------------------------------------------------