├── .gitattributes ├── .gitignore ├── Gruntfile.js ├── README.md ├── composer.json ├── composer.lock ├── docs ├── README.md ├── add-command.html ├── add-command.md ├── commands.html ├── commands.md ├── css │ ├── bootstrap.min.css │ ├── font-awesome.min.css │ ├── highlight.dark.css │ └── main.css ├── faqs.html ├── faqs.md ├── fonts │ ├── FontAwesome.otf │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.svg │ ├── fontawesome-webfont.ttf │ └── fontawesome-webfont.woff ├── hooks.html ├── hooks.md ├── images │ ├── wp-composer-help.png │ ├── wp-composer-plugin-install-hook.gif │ └── wp-composer-plugin-uninstall-hook.gif ├── index.html ├── install-command.html ├── install-command.md ├── installation.html ├── installation.md ├── js │ └── app.js ├── plugin-command.html ├── plugin-command.md ├── plugins-command.html ├── plugins-command.md ├── roadmap.html ├── roadmap.md ├── screenshot.png ├── theme-command.html ├── theme-command.md ├── themes-command.html └── themes-command.md ├── index.php ├── package.json ├── readme.txt ├── wp-composer-dependencies.php └── wp-composer-dependencies ├── admin.php ├── dependencies.php └── wpcli.php /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set the default behavior, in case people don't have core.autocrlf set. 2 | * text=auto 3 | 4 | # Denote all files that are truly binary and should not be modified. 5 | *.png binary 6 | *.jpg binary 7 | *.gif binary 8 | *.svn binary 9 | 10 | # Ignore differences between minified files 11 | *.min.css binary -diff 12 | *.min.js binary -diff 13 | 14 | # Ignore files from distribution 15 | /bin export-ignore 16 | /coverage export-ignore 17 | /tests export-ignore 18 | /vendor/phpdocumentor export-ignore 19 | /vendor/doctrine export-ignore 20 | /vendor/phpspec export-ignore 21 | /vendor/phpunit export-ignore 22 | /vendor/sebastian export-ignore 23 | /vendor/symfony export-ignore 24 | /vendor/webmozart export-ignore 25 | /vendor/whatthejeff export-ignore 26 | /vendor/bin export-ignore -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Dev Files 2 | .sass-cache/ 3 | node_modules/ 4 | 5 | # Project Files 6 | .idea/ 7 | *.sublime-* 8 | sftp-config.json 9 | 10 | # Random Files 11 | /*.sql 12 | .DS_Store 13 | **/.DS_Store 14 | __MACOSX/ 15 | **/__MACOSX 16 | .editorconfig 17 | 18 | # Vendor Files 19 | /vendor 20 | /vendor/phpdocumentor 21 | /vendor/doctrine 22 | /vendor/phpspec 23 | /vendor/phpunit 24 | /vendor/sebastian 25 | /vendor/symfony 26 | /vendor/webmozart 27 | /vendor/whatthejeff 28 | /vendor/bin 29 | 30 | # Documentation files 31 | website/.generated 32 | website/.couscous -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function( grunt ) { 2 | 3 | 'use strict'; 4 | var banner = '/**\n * <%= pkg.homepage %>\n * Copyright (c) <%= grunt.template.today("yyyy") %>\n * This file is generated automatically. Do not edit.\n */\n'; 5 | // Project configuration 6 | grunt.initConfig( { 7 | 8 | pkg: grunt.file.readJSON( 'package.json' ), 9 | 10 | addtextdomain: { 11 | options: { 12 | textdomain: 'wp-composer-dependencies', 13 | }, 14 | target: { 15 | files: { 16 | src: [ '*.php', '**/*.php', '!node_modules/**', '!php-tests/**', '!bin/**' ] 17 | } 18 | } 19 | }, 20 | 21 | wp_readme_to_markdown: { 22 | your_target: { 23 | files: { 24 | 'README.md': 'readme.txt' 25 | } 26 | }, 27 | }, 28 | 29 | makepot: { 30 | target: { 31 | options: { 32 | domainPath: '/languages', 33 | mainFile: 'wp-composer-dependencies.php', 34 | potFilename: 'wp-composer-dependencies.pot', 35 | potHeaders: { 36 | poedit: true, 37 | 'x-poedit-keywordslist': true 38 | }, 39 | type: 'wp-plugin', 40 | updateTimestamp: true 41 | } 42 | } 43 | }, 44 | } ); 45 | 46 | grunt.loadNpmTasks( 'grunt-wp-i18n' ); 47 | grunt.loadNpmTasks( 'grunt-wp-readme-to-markdown' ); 48 | grunt.registerTask( 'i18n', ['addtextdomain', 'makepot'] ); 49 | grunt.registerTask( 'readme', ['wp_readme_to_markdown'] ); 50 | 51 | grunt.util.linefeed = '\n'; 52 | 53 | }; 54 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WP Composer 2 | 3 | WP Composer is a WP-CLI package for managing your WordPress theme and plugin dependencies. By using the power of WP-CLI and [composer](https://getcomposer.org/doc/00-intro.html), you can declare the themes and plugins your WordPress site depends on. 4 | 5 | ## Install 6 | 7 | ### Installing as a WP-CLI package (preferred installation method) 8 | --- 9 | wp package install rxnlabs/wp-composer-dependencies 10 | --- 11 | 12 | ### Installing as a plugin 13 | 14 | Clone this repo into plugins/ folder of your WordPress site, run: 15 | 16 | --- 17 | composer install --no-dev --prefer-dist 18 | --- 19 | 20 | This installs the plugin dependencies. Then, activate the plugin. 21 | 22 | ## Requirements 23 | 24 | * PHP 5.4 and up 25 | * Requires [WP-CLI](http://wp-cli.org/) version 0.24.0 and up. 26 | 27 | ### Optional Requirements 28 | 29 | > **Note:** Only needed if you're using as a plugin and not as a WP-CLI package. Composer is useful in a lot of other scenarios. Learn more about [Composer](https://getcomposer.org/doc/00-intro.md). 30 | 31 | * [Composer](https://getcomposer.org/) 32 | 33 | After installing as a WP-CLI package or as a plugin, run `wp composer --help` to see the list of commands and subcommands available. 34 | 35 | ![WP Composer Help Output](docs/images/wp-composer-help.png) 36 | 37 | ## Commands 38 | 39 | | Command | Description | 40 | | ---------------- | -------------------------- | 41 | | [`composer plugins`](https://rxnlabs.github.io/wp-composer/plugins-command.html) | Manage dependencies of installed plugins | 42 | | [`composer themes`](https://rxnlabs.github.io/wp-composer/themes-command.html) | Manage dependencies of installed themes | 43 | | [`composer plugin`](https://rxnlabs.github.io/wp-composer/plugin-command.html) | Manage dependencies of a specific plugin | 44 | | [`composer theme`](https://rxnlabs.github.io/wp-composer/theme-command.html) | Manage dependencies of a specific theme | 45 | | [`composer add`](https://rxnlabs.github.io/wp-composer/add-command.html) | Add installed plugins and themes to composer.json | 46 | | [`composer install`](https://rxnlabs.github.io/wp-composer/install-command.html) | Install the dependencies of third-party themes and plugins | 47 | 48 | ## Hooks 49 | 50 | List of [hooks](https://rxnlabs.github.io/wp-composer/hooks.html) available for the plugin 51 | 52 | ## Documentation and Examples 53 | 54 | Learn more about the plugin and the commands available by visiting [https://rxnlabs.github.io/wp-composer/](https://rxnlabs.github.io/wp-composer/) 55 | 56 | > **Note** This plugin currently does **not** support premium plugins and themes, as well as plugins and themes not hosted on WordPress.org. This is a limitation I would like to fix at some point. In the meantime, you can manage your premium plugins in other ways such as submodules, subtrees, and plenty of other ways. 57 | 58 | ## Bugs and Issues 59 | 60 | When you find issues, please report theme: 61 | * web: https://github.com/rxnlabs/wp-composer/issues 62 | 63 | Be sure to include any relevant details including PHP version, plugins installed on the site, error messages, themes install on the site, WP-CLI version. 64 | 65 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rxnlabs/wp-composer-dependencies", 3 | "description": "Manage your WordPress dependencies using the power of Composer, WP-CLI, and http://wpackagist.org/", 4 | "type": "wp-cli-package", 5 | "version": "1.0.21", 6 | "support": { 7 | "issues": "https://github.com/rxnlabs/wp-composer/issues" 8 | }, 9 | "authors": [ 10 | { 11 | "name": "De'Yonté W.", 12 | "email": "dev@rxnlabs.com", 13 | "homepage": "https://rxnlabs.com" 14 | } 15 | ], 16 | "keywords": [ 17 | "wordpress wp composer dependencies wp-cli" 18 | ], 19 | "config": { 20 | "preferred-install": "dist" 21 | }, 22 | "require": { 23 | "php": ">=5.4.0", 24 | "camspiers/json-pretty": "^1.0", 25 | "league/flysystem": "^1.0" 26 | }, 27 | "require-dev": { 28 | "phpunit/phpunit": "4.8.26", 29 | "whatthejeff/nyancat-phpunit-resultprinter": "^1.2", 30 | "mockery/mockery": "^0.9.4", 31 | "10up/wp_mock": "dev-master" 32 | }, 33 | "minimum-stability": "dev", 34 | "autoload": { 35 | "classmap": [ 36 | "wp-composer-dependencies" 37 | ], 38 | "files": ["wp-composer-dependencies.php"] 39 | }, 40 | "archive": { 41 | "exclude": [ 42 | ".gitignore", 43 | ".gitattributes", 44 | ".travis.yml", 45 | "tests", 46 | "phpunit.xml", 47 | ".editorconfig", 48 | "coverage", 49 | "docs/", 50 | "docs/*", 51 | "couscous.yml" 52 | ] 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # WP Composer 2 | 3 | WP Composer is a [WP-CLI package](http://wp-cli.org/package-index/) for managing your WordPress theme and plugin dependencies. By using the power of WP-CLI and [Composer](https://getcomposer.org/doc/00-intro.md), you can declare the themes and plugins your WordPress site depends on. 4 | 5 | ## How it works 6 | Your themes and plugins will be stored in a [composer.json](https://getcomposer.org/doc/01-basic-usage.md) file along, the same way you would manage other PHP dependencies. 7 | 8 | ## Installation 9 | 10 | ### Installing as a WP-CLI package (preferred installation method) 11 | --- 12 | wp package install rxnlabs/wp-composer-dependencies 13 | --- 14 | 15 | ### Installing as a plugin (you need to have Composer installed) 16 | 17 | Clone this repo into plugins/ folder of your WordPress site, run: 18 | 19 | --- 20 | composer install --no-dev --prefer-dist 21 | --- 22 | 23 | This installs the plugin dependencies. Then, activate the plugin. 24 | 25 | ## Requirements 26 | 27 | * PHP 5.4 and up 28 | * Requires [WP-CLI](http://wp-cli.org/) version 0.24.0 and up. 29 | 30 | ### Optional Requirements 31 | 32 | > **Note:** Only needed if you're using as a plugin and not as a WP-CLI package. Composer is useful in a lot of other scenarios. Learn more about [Composer](https://getcomposer.org/doc/00-intro.md). 33 | 34 | * [Composer](https://getcomposer.org/) 35 | 36 | After installing as a WP-CLI package or as a plugin, run `wp composer --help` to see the list of commands and subcommands available. 37 | ![WP Composer Help Output](images/wp-composer-help.png) 38 | 39 | ## Commands 40 | | Command | Description | 41 | | ---------------- | -------------------------- | 42 | | [`composer plugins`](plugins-command.md) | Manage dependencies of installed plugins | 43 | | [`composer themes`](themes-command.md) | Manage dependencies of installed themes | 44 | | [`composer plugin`](plugin-command.md) | Manage dependencies of a specific plugin | 45 | | [`composer theme`](theme-command.md) | Manage dependencies of a specific theme | 46 | | [`composer add`](add-command.md) | Add installed plugins and themes to composer.json | 47 | | [`composer install`](install-command.md) | Install the dependencies of third-party themes and plugins | -------------------------------------------------------------------------------- /docs/add-command.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Add Command - WP Composer 8 | 9 | 10 | 11 | 12 | 13 | 22 | 32 | 33 | 34 | 35 | 49 | 50 |
51 |
52 | 53 | 54 | 126 | 127 | 128 |
129 |

Add Command

130 |

Add installed plugins and themes to composer.json

131 |
132 |

Note Some commands will generate a composer.json file if one does not currently exist

133 |
134 |

add

135 |

Add all plugins and themes to the composer.json file

136 |
137 |
wp composer add
138 |
139 |
Example
140 |

Let's say that your site has the themes twentyeleven, and twentysixteeen installed. It also has the plugins bbpress, and buddypress installed.

141 |
142 |
# Add all installed plugins and themes as dependencies to a composer.json file
143 | wp composer add --file=web/assets
144 |
145 |
Result
146 |

A composer.json file will be generated and saved to web/assets/composer.json with twentysixteen added as a dependency and twentyfourteen added as a dev dependency

147 |
{
148 |     "name": "wp-composer-dependencies",
149 |     "description": "Theme and plugin dependencies for the site http://example.com",
150 |     "repositories": [
151 |         {
152 |             "type": "composer",
153 |             "url": "https://wpackagist.org"
154 |         }
155 |     ],
156 |     "require": {
157 |         "wpackagist-theme/twentysixteen": "*",
158 |         "wpackagist-theme/twentyeleven": "*",
159 |         "wpackagist-plugin/bbpress": "*",
160 |         "wpackagist-plugin/buddypress": "*"
161 |     },
162 |     "extra": {
163 |         "installer-paths": {
164 |             "wp-content/themes/{$name}": [
165 |                 "type:wordpress-theme"
166 |             ],
167 |             "wp-content/plugins/{$name}": [
168 |                 "type:wordpress-plugin"
169 |             ],
170 |             "wp-content/mu-plugins/{$name}": [
171 |                 "type:wordpress-muplugin"
172 |             ]
173 |         }
174 |     }
175 | }
176 |

Options

177 |

[--file]

178 |

    Path to save the composer.json file

179 |

[--latest]

180 |

    Always use the latest version from whatever repo the theme is coming from. default.

181 |
182 |

Note Unlike plugins, themes on wordpress.org don't have specific versions (e.g. v1.0, v2.0, etc...), so the latest version of a theme will always be downloaded

183 |
184 |

[--installer-paths] OR [--ip]

185 |

    Set the WordPress plugins and themes installer path

186 |

[--dev]

187 |

    Add theme as a dev requirement in composer.json

188 |
189 | 190 |
191 |
192 | 193 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 213 | 214 | 215 | 216 | -------------------------------------------------------------------------------- /docs/add-command.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Add Command - WP Composer 3 | --- 4 | ##Add Command 5 | Add installed plugins and themes to composer.json 6 | > **Note** Some commands will generate a composer.json file if one does not currently exist 7 | 8 | ###add 9 | 10 | Add all plugins and themes to the composer.json file 11 | 12 | --- 13 | wp composer add 14 | --- 15 | #####Example 16 | 17 | Let's say that your site has the themes twentyeleven, and twentysixteeen installed. It also has the plugins bbpress, and buddypress installed. 18 | 19 | --- 20 | # Add all installed plugins and themes as dependencies to a composer.json file 21 | wp composer add --file=web/assets 22 | --- 23 | 24 | #####Result 25 | A composer.json file will be generated and saved to web/assets/composer.json with twentysixteen added as a dependency and twentyfourteen added as a dev dependency 26 | ```json 27 | { 28 | "name": "wp-composer-dependencies", 29 | "description": "Theme and plugin dependencies for the site http://example.com", 30 | "repositories": [ 31 | { 32 | "type": "composer", 33 | "url": "https://wpackagist.org" 34 | } 35 | ], 36 | "require": { 37 | "wpackagist-theme/twentysixteen": "*", 38 | "wpackagist-theme/twentyeleven": "*", 39 | "wpackagist-plugin/bbpress": "*", 40 | "wpackagist-plugin/buddypress": "*" 41 | }, 42 | "extra": { 43 | "installer-paths": { 44 | "wp-content/themes/{$name}": [ 45 | "type:wordpress-theme" 46 | ], 47 | "wp-content/plugins/{$name}": [ 48 | "type:wordpress-plugin" 49 | ], 50 | "wp-content/mu-plugins/{$name}": [ 51 | "type:wordpress-muplugin" 52 | ] 53 | } 54 | } 55 | } 56 | ``` 57 | 58 | ####Options 59 | *[--file]* 60 | 61 |     Path to save the composer.json file 62 | 63 | *[--latest]* 64 | 65 |     Always use the latest version from whatever repo the theme is coming from. **default**. 66 | 67 | > **Note** Unlike plugins, themes on wordpress.org don't have specific versions (e.g. v1.0, v2.0, etc...), so the latest version of a theme will always be downloaded 68 | 69 | *[--installer-paths]* OR *[--ip]* 70 | 71 |     Set the WordPress plugins and themes installer path 72 | 73 | *[--dev]* 74 | 75 |     Add theme as a dev requirement in composer.json 76 | -------------------------------------------------------------------------------- /docs/commands.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | List of Commands Available - WP Composer 8 | 9 | 10 | 11 | 12 | 13 | 22 | 33 | 34 | 35 | 36 | 50 | 51 |
52 |
53 | 54 | 55 | 127 | 128 |
129 |

Commands

130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 |
CommandDescription
composer pluginsManage dependencies of installed plugins
composer themesManage dependencies of installed themes
composer pluginManage dependencies of a specific plugin
composer themeManage dependencies of a specific theme
composer addAdd installed plugins and themes to composer.json
composer installInstall the dependencies of third-party themes and plugins
164 |
165 | 166 |
167 |
168 | 169 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 189 | 190 | 191 | 192 | -------------------------------------------------------------------------------- /docs/commands.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: List of Commands Available - WP Composer 3 | --- 4 | # Commands 5 | 6 | | Command | Description | 7 | | ---------------- | -------------------------- | 8 | | [`composer plugins`](plugins-command.md) | Manage dependencies of installed plugins | 9 | | [`composer themes`](themes-command.md) | Manage dependencies of installed themes | 10 | | [`composer plugin`](plugin-command.md) | Manage dependencies of a specific plugin | 11 | | [`composer theme`](theme-command.md) | Manage dependencies of a specific theme | 12 | | [`composer add`](add-command.md) | Add installed plugins and themes to composer.json | 13 | | [`composer install`](install-command.md) | Install the dependencies of third-party themes and plugins | -------------------------------------------------------------------------------- /docs/css/font-awesome.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.2.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.2.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff?v=4.2.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.2.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"} -------------------------------------------------------------------------------- /docs/css/highlight.dark.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Dark style from softwaremaniacs.org (c) Ivan Sagalaev 4 | 5 | */ 6 | 7 | .hljs { 8 | display: block; 9 | overflow-x: auto; 10 | padding: 0.5em; 11 | background: #444; 12 | -webkit-text-size-adjust: none; 13 | } 14 | 15 | .hljs-keyword, 16 | .hljs-literal, 17 | .hljs-change, 18 | .hljs-winutils, 19 | .hljs-flow, 20 | .nginx .hljs-title, 21 | .tex .hljs-special { 22 | color: white; 23 | } 24 | 25 | .hljs, 26 | .hljs-subst { 27 | color: #ddd; 28 | } 29 | 30 | .hljs-string, 31 | .hljs-title, 32 | .hljs-type, 33 | .ini .hljs-title, 34 | .hljs-tag .hljs-value, 35 | .css .hljs-rules .hljs-value, 36 | .hljs-preprocessor, 37 | .hljs-pragma, 38 | .ruby .hljs-symbol, 39 | .ruby .hljs-symbol .hljs-string, 40 | .ruby .hljs-class .hljs-parent, 41 | .hljs-built_in, 42 | .django .hljs-template_tag, 43 | .django .hljs-variable, 44 | .smalltalk .hljs-class, 45 | .hljs-javadoc, 46 | .ruby .hljs-string, 47 | .django .hljs-filter .hljs-argument, 48 | .smalltalk .hljs-localvars, 49 | .smalltalk .hljs-array, 50 | .hljs-attr_selector, 51 | .hljs-pseudo, 52 | .hljs-addition, 53 | .hljs-stream, 54 | .hljs-envvar, 55 | .apache .hljs-tag, 56 | .apache .hljs-cbracket, 57 | .tex .hljs-command, 58 | .hljs-prompt, 59 | .coffeescript .hljs-attribute { 60 | color: #d88; 61 | } 62 | 63 | .hljs-comment, 64 | .hljs-annotation, 65 | .hljs-decorator, 66 | .hljs-pi, 67 | .hljs-doctype, 68 | .hljs-deletion, 69 | .hljs-shebang, 70 | .apache .hljs-sqbracket, 71 | .tex .hljs-formula { 72 | color: #777; 73 | } 74 | 75 | .hljs-keyword, 76 | .hljs-literal, 77 | .hljs-title, 78 | .css .hljs-id, 79 | .hljs-phpdoc, 80 | .hljs-dartdoc, 81 | .hljs-type, 82 | .vbscript .hljs-built_in, 83 | .rsl .hljs-built_in, 84 | .smalltalk .hljs-class, 85 | .diff .hljs-header, 86 | .hljs-chunk, 87 | .hljs-winutils, 88 | .bash .hljs-variable, 89 | .apache .hljs-tag, 90 | .tex .hljs-special, 91 | .hljs-request, 92 | .hljs-status { 93 | font-weight: bold; 94 | } 95 | 96 | .coffeescript .javascript, 97 | .javascript .xml, 98 | .tex .hljs-formula, 99 | .xml .javascript, 100 | .xml .vbscript, 101 | .xml .css, 102 | .xml .hljs-cdata { 103 | opacity: 0.5; 104 | } 105 | -------------------------------------------------------------------------------- /docs/css/main.css: -------------------------------------------------------------------------------- 1 | html { 2 | position: relative; 3 | min-height: 100%; 4 | } 5 | body { 6 | font-size: 19px; 7 | } 8 | 9 | @media (min-width: 1200px) { 10 | .container { 11 | width: 970px; 12 | } 13 | } 14 | 15 | main { 16 | margin-top: 90px; 17 | } 18 | 19 | section { 20 | margin-bottom: 120px; 21 | } 22 | 23 | footer { 24 | position: absolute; 25 | bottom: 0; 26 | width: 100%; 27 | background-color: #f5f5f5; 28 | padding: 25px 0; 29 | font-size: 15px; 30 | text-align: center; 31 | text-transform: uppercase; 32 | opacity: 0.6; 33 | transition: opacity .2s ease; 34 | } 35 | footer:hover { 36 | opacity: 1.0; 37 | transition: opacity .2s ease; 38 | } 39 | footer p { 40 | margin: 0; 41 | } 42 | 43 | h3 { 44 | font-size: 23px; 45 | } 46 | 47 | li { 48 | margin-bottom: 3px; 49 | } 50 | 51 | #content img { 52 | max-width: 100%; 53 | padding: 4px; 54 | background-color: #fff; 55 | border: 1px solid #ddd; 56 | border-radius: 4px; 57 | } 58 | 59 | header.navbar { 60 | opacity: 0.9; 61 | } 62 | .navbar .navbar-brand { 63 | font-size: 28px; 64 | height: auto; 65 | line-height: 40px; 66 | margin-left: 20px; 67 | } 68 | .navbar .navbar-brand small { 69 | font-size: 18px; 70 | font-weight: 300; 71 | margin-left: 10px; 72 | } 73 | 74 | @media (min-width: 768px) { 75 | #sidebar { 76 | position:fixed; 77 | margin-top: 30px; 78 | } 79 | } 80 | @media (max-width: 960px) { 81 | body { 82 | font-size: 17px; 83 | } 84 | pre { 85 | font-size: 12px; 86 | } 87 | } 88 | 89 | .page-header { 90 | margin-top: 0; 91 | } 92 | 93 | #sidebar .text-muted { 94 | color: #bbbbbb; 95 | } 96 | 97 | pre { 98 | padding: 0; 99 | border-radius: 4px; 100 | margin: 15px; 101 | font-size: 15px; 102 | } 103 | pre code { 104 | border: none; 105 | } 106 | 107 | td { 108 | padding-left: 5px; 109 | padding-right: 5px; 110 | } 111 | 112 | .well { 113 | padding: 0; 114 | margin-top: 15px; 115 | background-color: transparent; 116 | } 117 | 118 | #content img { 119 | width: 100%; 120 | } -------------------------------------------------------------------------------- /docs/faqs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Frequently Asked Questions - WP Composer 8 | 9 | 10 | 11 | 12 | 13 | 22 | 33 | 34 | 35 | 36 | 50 | 51 |
52 |
53 | 54 | 55 | 127 | 128 | 129 |
130 |

Frequently Asked Questions

131 |

that no one has asked yet.

132 |
    133 |
  • Why did I create this? 134 |
      135 |
    • I needed to migrate a bunch of individual WordPress sites into a multisite installation. I created a script to get all of the WordPress plugins installed on each site and add them all to a composer.json file to not have to have all of the third-party plugin code in the repo.
    • 136 |
  • 137 |
  • Isn't there already a Composer plugin for WordPress? 138 |
      139 |
    • Yes, there is but it hasn't been updated in three years and does not work without changing the name of the main plugin file. Also, it doesn't have as many options as this one.
    • 140 |
  • 141 |
  • What is a good use case for this? 142 |
      143 |
    • When you need to manage the plugin and theme dependencies of your WordPress site but you don't want a bunch of third-party code in your repo, which increases its size. Also, managing the dependencies of a Multisite.
    • 144 |
  • 145 |
  • Does this plugin manage premium plugins? 146 |
      147 |
    • This plugin currently does not support premium plugins and themes, as well as plugins and themes not hosted on WordPress.org. This is a limitation I would like to fix at some point. In the meantime, you can manage your premium plugins in other ways such as submodules, subtrees, and plenty of other ways.
    • 148 |
  • 149 |
150 |

Frequently Asked Questions that someone has asked

151 |
    152 |
  • I see this is a wrapper for WPackagist. I don't mind but I don't see the huge benefit either other than saving you from having to type "wpackagist-plugin/slug", or am I missing something? 153 |
      154 |
    • In essence, this is very similar to just using composer and running the command. The biggest benefit is just using WP-CLI commands and using the command of the package to automatically add your plugins to the composer.json file. 155 |
      156 | Also it hooks into the command wp plugin install plugin-name and will automatically add that plugin to the composer.json file. It also hooks into wp plugin uninstall plugin-name command to remove the plugin you uninstalled from your composer.json file. This also applies to the wp theme commands. It also just works well for bulk installing your plugins using wp-cli, though you could do this WP-CLI as well.
    • 157 |
  • 158 |
159 |
160 | 161 |
162 |
163 | 164 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 184 | 185 | 186 | 187 | -------------------------------------------------------------------------------- /docs/faqs.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Frequently Asked Questions - WP Composer 3 | --- 4 | #Frequently Asked Questions 5 | that no one has asked yet. 6 | 7 | * Why did I create this? 8 | * I needed to migrate a bunch of individual WordPress sites into a multisite installation. I created a script to get all of the WordPress plugins installed on each site and add them all to a composer.json file to not have to have all of the third-party plugin code in the repo. 9 | * Isn't there already a [Composer plugin](https://wordpress.org/plugins/composer/) for WordPress? 10 | * Yes, there is but it hasn't been updated in three years and does not work without changing the name of the main plugin file. Also, it doesn't have as many options as this one. 11 | * What is a good use case for this? 12 | * When you need to manage the plugin and theme dependencies of your WordPress site but you don't want a bunch of third-party code in your repo, which increases its size. Also, managing the dependencies of a Multisite. 13 | * Does this plugin manage premium plugins? 14 | * This plugin currently does **not** support premium plugins and themes, as well as plugins and themes not hosted on WordPress.org. This is a limitation I would like to fix at some point. In the meantime, you can manage your premium plugins in other ways such as submodules, subtrees, and plenty of other ways. 15 | 16 | ##Frequently Asked Questions that someone has asked 17 | * I see this is a wrapper for WPackagist. I don't mind but I don't see the huge benefit either other than saving you from having to type "wpackagist-plugin/slug", or am I missing something? 18 | * In essence, this is very similar to just using composer and running the command. The biggest benefit is just using WP-CLI commands and using the command of the package to automatically add your plugins to the composer.json file. 19 | Also it [hooks into the command](https://rxnlabs.github.io/wp-composer/hooks.html "Hooks for WP-Composer") wp plugin install plugin-name and will automatically add that plugin to the composer.json file. It also hooks into wp plugin uninstall plugin-name command to remove the plugin you uninstalled from your composer.json file. This also applies to the wp theme commands. It also just works well for bulk installing your plugins using wp-cli, though you could do this WP-CLI as well. -------------------------------------------------------------------------------- /docs/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxnlabs/wp-composer/29d633e5109dd4bec689af032e70cad3edfa0ff5/docs/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /docs/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxnlabs/wp-composer/29d633e5109dd4bec689af032e70cad3edfa0ff5/docs/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxnlabs/wp-composer/29d633e5109dd4bec689af032e70cad3edfa0ff5/docs/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /docs/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxnlabs/wp-composer/29d633e5109dd4bec689af032e70cad3edfa0ff5/docs/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /docs/hooks.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | List of Hooks Available - WP Composer 8 | 9 | 10 | 11 | 12 | 13 | 22 | 33 | 34 | 35 | 36 | 50 | 51 |
52 |
53 | 54 | 55 | 127 | 128 | 129 |
130 |

Hooks

131 |

Hooks used by this plugin

132 |

This plugin hooks into the command `wp plugin install plugin-name` and will automatically add that plugin to the composer.json file.

133 |

Example

134 |
wp plugin install buddypress
135 |

Result

136 | WP Composer Plugin Install Hook 137 |
138 |

It also hooks into the command `wp plugin uninstall plugin-name` by automatically removing plugin-name from the composer.json file

139 |

Example

140 |
wp plugin uninstall buddypress --deactivate
141 |

Result

142 | WP Composer Plugin Uninstall Hook 143 |
144 |

This also applies to the `wp theme install theme-name` 145 |

wp theme install twentysixteen
146 |

This also applies to the wp theme uninstall theme-name 147 |

wp theme uninstall twentysixteen  --deactivate
148 |

Hooks available for this plugin

149 |

None at this time. If you're writing a WP-CLI command, you can use the hooks provided by WP-CLI add_hook function

150 |
151 | 152 |
153 |
154 | 155 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 175 | 176 | 177 | 178 | -------------------------------------------------------------------------------- /docs/hooks.md: -------------------------------------------------------------------------------- 1 | # Hooks 2 | 3 | ## Hooks used by this plugin 4 | 5 | This plugin hooks into the command `wp plugin install plugin-name` and will automatically add that plugin to the composer.json file. 6 | 7 | ### Example 8 | 9 | --- 10 | wp plugin install buddypress 11 | --- 12 | 13 | ### Result 14 | 15 | ![WP Composer Plugin Install Hook](images/wp-composer-plugin-install-hook.gif) 16 | 17 | It also hooks into the command `wp plugin uninstall plugin-name` by automatically removing plugin-name from the composer.json file 18 | 19 | ### Example 20 | 21 | --- 22 | wp plugin uninstall buddypress --deactivate 23 | --- 24 | 25 | ### Result 26 | 27 | ![WP Composer Plugin Uninstall Hook](images/wp-composer-plugin-uninstall-hook.gif) 28 | 29 | This also applies to the `wp theme install theme-name` 30 | 31 | --- 32 | wp theme install twentysixteen 33 | --- 34 | 35 | This also applies to the `wp theme uninstall theme-name` 36 | 37 | --- 38 | wp theme uninstall twentysixteen --deactivate 39 | --- 40 | 41 | ## Hooks available for this plugin 42 | 43 | None at this time. If you're writing a WP-CLI command, you can use the hooks provided by [WP-CLI add_hook function](https://wp-cli.org/docs/internal-api/wp-cli-add-hook/) -------------------------------------------------------------------------------- /docs/images/wp-composer-help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxnlabs/wp-composer/29d633e5109dd4bec689af032e70cad3edfa0ff5/docs/images/wp-composer-help.png -------------------------------------------------------------------------------- /docs/images/wp-composer-plugin-install-hook.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxnlabs/wp-composer/29d633e5109dd4bec689af032e70cad3edfa0ff5/docs/images/wp-composer-plugin-install-hook.gif -------------------------------------------------------------------------------- /docs/images/wp-composer-plugin-uninstall-hook.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxnlabs/wp-composer/29d633e5109dd4bec689af032e70cad3edfa0ff5/docs/images/wp-composer-plugin-uninstall-hook.gif -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | WP Composer 8 | 9 | 10 | 11 | 12 | 13 | 22 | 33 | 34 | 35 | 36 | 50 | 51 |
52 |
53 | 54 | 55 | 127 | 128 | 129 |
130 |

WP Composer

131 |

WP Composer is a WP-CLI package for managing your WordPress theme and plugin dependencies. By using the power of WP-CLI and Composer, you can declare the themes and plugins your WordPress site depends on.

132 |

How it works

133 |

Your themes and plugins will be stored in a composer.json file along, the same way you would manage other PHP dependencies.

134 |

Installation

135 |

Installing as a WP-CLI package (preferred installation method)

136 |
137 |
wp package install rxnlabs/wp-composer-dependencies
138 |
139 |

Installing as a plugin (you need to have Composer installed)

140 |

Clone this repo into plugins/ folder of your WordPress site, run:

141 |
142 |
composer install --no-dev --prefer-dist
143 |
144 |

This installs the plugin dependencies. Then, activate the plugin.

145 |

Requirements

146 |
    147 |
  • PHP 5.4 and up
  • 148 |
  • Requires WP-CLI version 0.24.0 and up.
  • 149 |
150 |

Optional Requirements

151 |
152 |

Note: Only needed if you're using as a plugin and not as a WP-CLI package. Composer is useful in a lot of other scenarios. Learn more about Composer.

153 |
154 | 157 |

After installing as a WP-CLI package or as a plugin, run wp composer --help to see the list of commands and subcommands available. 158 | WP Composer Help Output

159 |

Commands

160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 |
CommandDescription
composer pluginsManage dependencies of installed plugins
composer themesManage dependencies of installed themes
composer pluginManage dependencies of a specific plugin
composer themeManage dependencies of a specific theme
composer addAdd installed plugins and themes to composer.json
composer installInstall the dependencies of third-party themes and plugins
194 | 195 |

Hooks

196 | 197 | List of hooks available for the plugin 198 |
199 | 200 |
201 |
202 | 203 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 223 | 224 | 225 | 226 | -------------------------------------------------------------------------------- /docs/install-command.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Install Command - WP Composer 8 | 9 | 10 | 11 | 12 | 13 | 22 | 33 | 34 | 35 | 36 | 50 | 51 |
52 |
53 | 54 | 55 | 127 | 128 | 129 |
130 |

Install Subcommands

131 |

Install the dependencies of third-party themes and plugins.

132 |
133 |

Note Some commands will generate a composer.json file if one does not currently exist

134 |
135 |

plugins

136 |

Install the Composer dependencies of third-party plugins.

137 |
138 |
wp composer install plugins
139 |
140 |
Example
141 |

Let's say that your site has the plugin bu-versions and that plugin has a composer.json file. You can install that plugin's dependencies, if those dependencies are not currently installed.

142 |
143 |
# Install the dependencies of all of the currently installed plugins
144 | wp composer install plugins
145 |
146 |
147 |

Note This does not currently install dependency plugins needed by other plugins (e.g. an running this command on an Advanced Custom Fields Add-On will not install the Advanced Custom Fields plugin onto a site. This is something I will be working on in the future).

148 |
149 |

themes

150 |

Install the Composer dependencies of third-party themes.

151 |
152 |
wp composer install themes
153 |
154 |
Example
155 |

Let's say that your site has the theme example-theme and that theme has a composer.json file. You can install that theme's dependencies, if those dependencies are not currently installed.

156 |
157 |
# Install the Composer dependencies of all of the currently installed themes
158 | wp composer install themes
159 |
160 |
161 |

Note This does not currently install a parent theme of a Child-theme (e.g. an running this command on a child-theme of twentysixteen will not install the twentysixteen theme onto a site. This is something I will be working on in the future).

162 |
163 |

Options

164 |

No options

165 |
166 | 167 |
168 |
169 | 170 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 190 | 191 | 192 | 193 | -------------------------------------------------------------------------------- /docs/install-command.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Install Command - WP Composer 3 | --- 4 | ##Install Subcommands 5 | Install the dependencies of third-party themes and plugins. 6 | > **Note** Some commands will generate a composer.json file if one does not currently exist 7 | 8 | ###plugins 9 | 10 | Install the dependencies of third-party plugins. 11 | 12 | --- 13 | wp composer install plugins 14 | --- 15 | #####Example 16 | 17 | Let's say that your site has the plugin bu-versions and that plugin has a composer.json file. You can install that plugin's dependencies, if those dependencies are not currently installed. 18 | 19 | --- 20 | # Install the dependencies of all of the currently installed plugins 21 | wp composer install plugins 22 | --- 23 | 24 | > **Note** This does *not* currently install dependency plugins needed by other plugins (e.g. an running this command on an Advanced Custom Fields Add-On will not install the Advanced Custom Fields plugin onto a site. This is something I will be working on in the future). 25 | 26 | ###themes 27 | 28 | Install the dependencies of third-party themes. 29 | 30 | --- 31 | wp composer install themes 32 | --- 33 | #####Example 34 | 35 | Let's say that your site has the theme example-theme and that plugin has a composer.json file. You can install that plugin's dependencies, if those dependencies are not currently installed. 36 | 37 | --- 38 | # Install the dependencies of all of the currently installed themes 39 | wp composer install themes 40 | --- 41 | 42 | > **Note** Note This does **not** currently install a parent theme of a Child-theme (e.g. an running this command on a child-theme of twentysixteen will not install the twentysixteen theme onto a site. This is something I will be working on in the future). 43 | 44 | ####Options 45 | No options 46 | -------------------------------------------------------------------------------- /docs/installation.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Installation - WP Composer 8 | 9 | 10 | 11 | 12 | 13 | 22 | 33 | 34 | 35 | 36 | 50 | 51 |
52 |
53 | 54 | 55 | 127 | 128 | 129 |
130 |

Installation

131 |

Installing as a WP-CLI package (preferred installation method)

132 |
133 |
wp package install rxnlabs/wp-composer-dependencies
134 |
135 |

Installing as a plugin (you need to have Composer installed)

136 |

Clone this repo into plugins/ folder of your WordPress site, run:

137 |
138 |
composer install --no-dev --prefer-dist
139 |
140 | This installs the plugin dependencies. Then, activate the plugin. 141 |

Requirements

142 |

Requires WP-CLI version 0.24.0 and up.

143 |

After installing as a WP-CLI package or as a plugin, run wp composer --help to see the list of commands and subcommands available.

144 |

WP Composer Help Output

145 |
146 | 147 |
148 |
149 | 150 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 170 | 171 | 172 | 173 | -------------------------------------------------------------------------------- /docs/installation.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Installation - WP Composer 3 | --- 4 | # Installation 5 | 6 | ## Installing as a WP-CLI package (preferred installation method) 7 | --- 8 | wp package install rxnlabs/wp-composer-dependencies 9 | --- 10 | 11 | ## Installing as a plugin 12 | 13 | Clone this repo into plugins/ folder of your WordPress site, run: 14 | 15 | --- 16 | composer install --no-dev 17 | --- 18 | 19 | This installs the plugin dependencies. Then, activate the plugin. 20 | 21 | ## Requirements 22 | 23 | Requires WP-CLI version 0.24.0 and up. 24 | 25 | After installing as a WP-CLI package or as a plugin, run `wp composer --help` to see the list of commands and subcommands available. 26 | 27 | ![WP Composer Help Output](images/wp-composer-help.png) -------------------------------------------------------------------------------- /docs/js/app.js: -------------------------------------------------------------------------------- 1 | jQuery(window).ready(function($){ 2 | var result_examples = { 3 | findResults: function(){ 4 | var $h5 = $('h5'); 5 | var results = []; 6 | $.map($h5, function(node, index) { 7 | var element = $(node); 8 | if (element.prop('id').indexOf('result') !== -1) { 9 | results.push(element); 10 | } 11 | }); 12 | 13 | return results; 14 | }, 15 | addCollapseMarkup: function(results){ 16 | $.map(results, function(node, index) { 17 | var element = $(node); 18 | var code = element.nextUntil('pre').last().next(); 19 | 20 | var markup = '
'+ code.clone().html() + '
'; 21 | 22 | $(markup).insertAfter(code); 23 | 24 | if (code.is( 'pre')) { 25 | var button = ''; 26 | $(button).insertAfter(element.next()); 27 | code.remove(); 28 | } 29 | }); 30 | 31 | }, 32 | highlightJS: function() { 33 | hljs.configure({ 34 | tabReplace: ' ' 35 | }); 36 | 37 | $('pre code').each(function(i, block) { 38 | hljs.highlightBlock(block); 39 | }); 40 | } 41 | } 42 | 43 | result_examples.addCollapseMarkup(result_examples.findResults()); 44 | result_examples.highlightJS(); 45 | }); -------------------------------------------------------------------------------- /docs/plugin-command.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Plugin Command - WP Composer 8 | 9 | 10 | 11 | 12 | 13 | 22 | 33 | 34 | 35 | 36 | 50 | 51 |
52 |
53 | 54 | 55 | 127 | 128 | 129 |
130 |

Plugin Subcommands

131 |

Manage dependencies of a specific plugin

132 |
133 |

Note Some commands will generate a composer.json file if one does not currently exist

134 |
135 |

add

136 |

Add the specified plugin to the composer.json file

137 |
138 |
wp composer plugin add
139 |
140 |
Example
141 |
142 |
# Add bbpress plugin to the composer.json file.
143 | wp composer plugin add bbpress
144 | # Add debug-bar as dev dependency
145 | wp composer plugin add debug-bar --dev
146 |
147 |
Result
148 |

A composer.json file will be generated with bbpress added as a dependency and denug-bar added as a dev dependency

149 |
{
150 |     "name": "wp-composer-dependencies",
151 |     "description": "Theme and plugin dependencies for the site http://example.com",
152 |     "repositories": [
153 |         {
154 |             "type": "composer",
155 |             "url": "https://wpackagist.org"
156 |         }
157 |     ],
158 |     "require": {
159 |         "wpackagist-plugin/bbpress": "*"
160 |     },
161 |     "require-dev": {
162 |         "wpackagist-plugin/debug-bar": "*"
163 |     },
164 |     "extra": {
165 |         "installer-paths": {
166 |             "wp-content/themes/{$name}": [
167 |                 "type:wordpress-theme"
168 |             ],
169 |             "wp-content/plugins/{$name}": [
170 |                 "type:wordpress-plugin"
171 |             ],
172 |             "wp-content/mu-plugins/{$name}": [
173 |                 "type:wordpress-muplugin"
174 |             ]
175 |         }
176 |     }
177 | }
178 |

remove

179 |

Remove the specified plugin from the composer.json file

180 |
Example
181 |
182 |
# Remove debug-bar as dev dependency
183 | wp composer plugin remove debug-bar --dev
184 |
185 |
Result
186 |

A composer.json file will be saved with debug-bar removed as a dev dependency

187 |
{
188 |     "name": "wp-composer-dependencies",
189 |     "description": "Theme and plugin dependencies for the site http://example.com",
190 |     "repositories": [
191 |         {
192 |             "type": "composer",
193 |             "url": "https://wpackagist.org"
194 |         }
195 |     ],
196 |         "require": {
197 |             "wpackagist-plugin/bbpress": "*"
198 |     },
199 |     "extra": {
200 |         "installer-paths": {
201 |             "wp-content/themes/{$name}": [
202 |                 "type:wordpress-theme"
203 |             ],
204 |             "wp-content/plugins/{$name}": [
205 |                 "type:wordpress-plugin"
206 |             ],
207 |             "wp-content/mu-plugins/{$name}": [
208 |                 "type:wordpress-muplugin"
209 |             ]
210 |         }
211 |     }
212 | }
213 |

Options

214 |

[<plugin>...]

215 |

    One or more plugins

216 |

[--file]

217 |

    Path to save the composer.json file

218 |

[--version]

219 |

    Add specified version of plugin

220 |

[--latest]

221 |

    Always use the latest version from whatever repo the plugin is coming from

222 |

[--installer-paths] OR [--ip]

223 |

    Set the WordPress plugins and themes installer path

224 |

[--dev]

225 |

    Add plugin as a dev requirement in composer.json

226 |

[--deactivate]

227 |

    Deactivate the plugin before uninstalling it

228 |
229 | 230 |
231 |
232 | 233 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 253 | 254 | 255 | 256 | -------------------------------------------------------------------------------- /docs/plugin-command.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Plugin Command - WP Composer 3 | --- 4 | ##Plugin Subcommands 5 | Manage dependencies of a specific plugin 6 | > **Note** Some commands will generate a composer.json file if one does not currently exist 7 | 8 | ###add 9 | 10 | Add the specified plugin to the composer.json file 11 | 12 | --- 13 | wp composer plugin add 14 | --- 15 | 16 | #####Example 17 | --- 18 | # Add bbpress plugin to the composer.json file. 19 | wp composer plugin add bbpress 20 | # Add debug-bar as dev dependency 21 | wp composer plugin add debug-bar --dev 22 | --- 23 | #####Result 24 | A composer.json file will be generated with bbpress added as a dependency and denug-bar added as a dev dependency 25 | ```json 26 | { 27 | "name": "wp-composer-dependencies", 28 | "description": "Theme and plugin dependencies for the site http://example.com", 29 | "repositories": [ 30 | { 31 | "type": "composer", 32 | "url": "https://wpackagist.org" 33 | } 34 | ], 35 | "require": { 36 | "wpackagist-plugin/bbpress": "*" 37 | }, 38 | "require-dev": { 39 | "wpackagist-plugin/debug-bar": "*" 40 | }, 41 | "extra": { 42 | "installer-paths": { 43 | "wp-content/themes/{$name}": [ 44 | "type:wordpress-theme" 45 | ], 46 | "wp-content/plugins/{$name}": [ 47 | "type:wordpress-plugin" 48 | ], 49 | "wp-content/mu-plugins/{$name}": [ 50 | "type:wordpress-muplugin" 51 | ] 52 | } 53 | } 54 | } 55 | ``` 56 | ###remove 57 | Remove the specified plugin from the composer.json file 58 | 59 | #####Example 60 | --- 61 | # Remove debug-bar as dev dependency 62 | wp composer plugin remove debug-bar --dev 63 | --- 64 | #####Result 65 | A composer.json file will be saved with debug-bar removed as a dev dependency 66 | ```json 67 | { 68 | "name": "wp-composer-dependencies", 69 | "description": "Theme and plugin dependencies for the site http://example.com", 70 | "repositories": [ 71 | { 72 | "type": "composer", 73 | "url": "https://wpackagist.org" 74 | } 75 | ], 76 | "require": { 77 | "wpackagist-plugin/bbpress": "*" 78 | }, 79 | "extra": { 80 | "installer-paths": { 81 | "wp-content/themes/{$name}": [ 82 | "type:wordpress-theme" 83 | ], 84 | "wp-content/plugins/{$name}": [ 85 | "type:wordpress-plugin" 86 | ], 87 | "wp-content/mu-plugins/{$name}": [ 88 | "type:wordpress-muplugin" 89 | ] 90 | } 91 | } 92 | } 93 | ``` 94 | 95 | ####Options 96 | 97 | *[...]* 98 | 99 |     One or more plugins 100 | 101 | *[--file]* 102 | 103 |     Path to save the composer.json file 104 | 105 | *[--version]* 106 | 107 |     Add specified version of plugin 108 | 109 | *[--latest]* 110 | 111 |     Always use the latest version from whatever repo the plugin is coming from 112 | 113 | *[--installer-paths]* OR *[--ip]* 114 | 115 |     Set the WordPress plugins and themes installer path 116 | 117 | *[--dev]* 118 | 119 |     Add plugin as a dev requirement in composer.json 120 | 121 | *[--deactivate]* 122 | 123 |     Deactivate the plugin before uninstalling it 124 | -------------------------------------------------------------------------------- /docs/plugins-command.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Plugins Command - WP Composer 8 | 9 | 10 | 11 | 12 | 13 | 22 | 33 | 34 | 35 | 36 | 50 | 51 |
52 |
53 | 54 | 55 | 127 | 128 | 129 |
130 |

Plugins Subcommands

131 |

Manage dependencies of installed plugins

132 |

add

133 |

Add currently installed plugins to composer.json

134 |
135 |
wp composer plugins add
136 |
137 |

install

138 |

Install plugins listed in composer.json

139 |
140 |
wp composer plugins install
141 |
142 |

uninstall

143 |

Deactivate and uninstall plugins listed in composer.json

144 |
145 |
wp composer plugins uninstall
146 |
147 |

activate

148 |

Activate plugins listed in composer.json

149 |
150 |
wp composer plugins activate
151 |
152 |

deactivate

153 |

Deactivate plugins listed in composer.json

154 |
155 |
wp composer plugins deactivate
156 |
157 |

Options

158 |

[--file]

159 |

    Path to save the composer.json file

160 |

[--all]

161 |

    Add plugins found on wordpress.org and plugins not found on wordpress.org. By default, only plugins available on wordpress.org will be added to the composer.json file

162 |

[--latest]

163 |

    Add current version of plugin installed or specify to always use the latest version from whatever repo the plugin is coming from.

164 |

[--installer-paths] OR [--ip]

165 |

    Set the WordPress plugins and themes installer path

166 |

[--dev]

167 |

    Only apply command to plugins defined as a dev requirement in composer.json

168 |

[--deactivate]

169 |

    Deactivate the plugins before uninstalling them. This only applies when using the command wp plugins uninstall --deactivate

170 |
171 | 172 |
173 |
174 | 175 |
176 |
177 |

178 | Documentation generated using Couscous 179 |

180 |
181 |
182 | 183 | 184 | 185 | 186 | 187 | 188 | 195 | 196 | 197 | 198 | -------------------------------------------------------------------------------- /docs/plugins-command.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Plugins Command - WP Composer 3 | --- 4 | ##Plugins Subcommands 5 | Manage dependencies of installed plugins 6 | 7 | ###add 8 | 9 | Add currently installed plugins to composer.json 10 | 11 | --- 12 | wp composer plugins add 13 | --- 14 | 15 | ###install 16 | Install plugins listed in composer.json 17 | 18 | --- 19 | wp composer plugins install 20 | --- 21 | 22 | ###uninstall 23 | 24 | Deactivate and uninstall plugins listed in composer.json 25 | 26 | --- 27 | wp composer plugins uninstall 28 | --- 29 | 30 | ###activate 31 | 32 | Activate plugins listed in composer.json 33 | 34 | --- 35 | wp composer plugins activate 36 | --- 37 | 38 | ###deactivate 39 | 40 | Deactivate plugins listed in composer.json 41 | 42 | --- 43 | wp composer plugins deactivate 44 | --- 45 | 46 | 47 | ####Options 48 | *[--file]* 49 | 50 |     Path to save the composer.json file 51 | 52 | *[--all]* 53 | 54 |     Add plugins found on wordpress.org and plugins not found on wordpress.org. By default, only plugins available on wordpress.org will be added to the composer.json file 55 | 56 | *[--latest]* 57 | 58 |     Add current version of plugin installed or specify to always use the latest version from whatever repo the plugin is coming from. 59 | 60 | *[--installer-paths]* OR *[--ip]* 61 | 62 |     Set the WordPress plugins and themes installer path 63 | 64 | *[--dev]* 65 | 66 |     Only apply command to plugins defined as a dev requirement in composer.json 67 | 68 | *[--deactivate]* 69 | 70 |     Deactivate the plugins before uninstalling them. This only applies when using the command `wp plugins uninstall --deactivate` 71 | -------------------------------------------------------------------------------- /docs/roadmap.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Roadmap - WP Composer 8 | 9 | 10 | 11 | 12 | 13 | 22 | 33 | 34 | 35 | 36 | 50 | 51 |
52 |
53 | 54 | 55 | 127 | 128 | 129 |
130 |

Roadmap

131 |

Upcoming list of things that would make this project event better:

132 |
    133 |
  • Add support for paid and non-wordpress.org repo pluginss
  • 134 |
  • Create a WordPress plugin for the WordPress dashboard to manage the package settings for better control
  • 135 |
  • Add support for child-themes, so child themes can list their parent themes in a composer.json file or in the style.css. This plugin will read that dependency and install that parent theme in the correct directory
  • 136 |
  • Add support for plugin add-ons, so add-on plugins can list the plugin they need in order to function. E.g. An Advanced Custom Fields add-on can list Advanced Custom Fields as the plugin they need and this plugin/package will install Advanced Custom Fields in the plugin directory
  • 137 |
138 |
139 | 140 |
141 |
142 | 143 |
144 |
145 |

146 | Documentation generated using Couscous 147 |

148 |
149 |
150 | 151 | 152 | 153 | 154 | 155 | 156 | 163 | 164 | 165 | 166 | -------------------------------------------------------------------------------- /docs/roadmap.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Roadmap - WP Composer 3 | --- 4 | #Roadmap 5 | Upcoming list of things that would make this project event better: 6 | * Add support for paid and non-wordpress.org repo pluginss 7 | * Create a WordPress plugin for the WordPress dashboard to manage the package settings for better control 8 | * Add support for child-themes, so child themes can list their parent themes in a composer.json file or in the style.css. This plugin will read that dependency and install that parent theme in the correct directory 9 | * Add support for plugin add-ons, so add-on plugins can list the plugin they need in order to function. E.g. An Advanced Custom Fields add-on can list Advanced Custom Fields as the plugin they need and this plugin/package will install Advanced Custom Fields in the plugin directory -------------------------------------------------------------------------------- /docs/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rxnlabs/wp-composer/29d633e5109dd4bec689af032e70cad3edfa0ff5/docs/screenshot.png -------------------------------------------------------------------------------- /docs/theme-command.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Theme Command - WP Composer 8 | 9 | 10 | 11 | 12 | 13 | 22 | 33 | 34 | 35 | 36 | 50 | 51 |
52 |
53 | 54 | 55 | 127 | 128 | 129 |
130 |

Theme Subcommands

131 |

Manage dependencies of a specific theme

132 |
133 |

Note Some commands will generate a composer.json file if one does not currently exist

134 |
135 |

add

136 |

Add the specified theme to the composer.json file

137 |
138 |
wp composer theme add
139 |
140 |
Example
141 |
142 |
# Add twentysixteen theme to the composer.json file.
143 | wp composer theme add twentysixteen
144 | # Add twentyfourteen as dev dependency
145 | wp composer theme add twentyfourteen --dev
146 | # Install zerif lite and sydney themes
147 | wp composer theme add zerif-lite,sydney
148 |
149 |
Result
150 |

A composer.json file will be generated with twentysixteen added as a dependency and twentyfourteen added as a dev dependency

151 |
{
152 |     "name": "wp-composer-dependencies",
153 |     "description": "Theme and plugin dependencies for the site http://example.com",
154 |     "repositories": [
155 |         {
156 |             "type": "composer",
157 |             "url": "https://wpackagist.org"
158 |         }
159 |     ],
160 |     "require": {
161 |         "wpackagist-theme/twentysixteen": "*",
162 |         "wpackagist-theme/zerif-lite": "*",
163 |         "wpackagist-theme/sydney": "*"
164 |     },
165 |     "require-dev": {
166 |         "wpackagist-theme/twentyfourteen": "*"
167 |     },
168 |     "extra": {
169 |         "installer-paths": {
170 |             "wp-content/themes/{$name}": [
171 |                 "type:wordpress-theme"
172 |             ],
173 |             "wp-content/plugins/{$name}": [
174 |                 "type:wordpress-plugin"
175 |             ],
176 |             "wp-content/mu-plugins/{$name}": [
177 |                 "type:wordpress-muplugin"
178 |             ]
179 |         }
180 |     }
181 | }
182 |

remove

183 |

Remove the specified theme from the composer.json file

184 |
Example
185 |
186 |
# Remove twentyfourteen as dev dependency
187 | wp composer theme remove twentyfourteen --dev
188 |
189 |
Result
190 |

A composer.json file will be saved with twentyfourteen removed as a dev dependency

191 |
{
192 |     "name": "wp-composer-dependencies",
193 |     "description": "Theme and plugin dependencies for the site http://example.com",
194 |     "repositories": [
195 |         {
196 |             "type": "composer",
197 |             "url": "https://wpackagist.org"
198 |         }
199 |     ],
200 |     "require": {
201 |         "wpackagist-theme/twentysixteen": "*"
202 |     },
203 |     "extra": {
204 |         "installer-paths": {
205 |             "wp-content/themes/{$name}": [
206 |                 "type:wordpress-theme"
207 |             ],
208 |             "wp-content/plugins/{$name}": [
209 |                 "type:wordpress-plugin"
210 |             ],
211 |             "wp-content/mu-plugins/{$name}": [
212 |                 "type:wordpress-muplugin"
213 |             ]
214 |         }
215 |     }
216 | }
217 |

Options

218 |

[<theme>...]

219 |

    One or more themes

220 |

[--file]

221 |

    Path to save the composer.json file

222 |

[--latest]

223 |

    Always use the latest version from whatever repo the theme is coming from. default.

224 |
225 |

Note Unlike plugins, themes on wordpress.org don't have specific versions (e.g. v1.0, v2.0, etc...), so the latest version of a theme will always be downloaded

226 |
227 |

[--installer-paths] OR [--ip]

228 |

    Set the WordPress plugins and themes installer path

229 |

[--dev]

230 |

    Add theme as a dev requirement in composer.json

231 |

[--deactivate]

232 |

    Deactivate the theme before uninstalling it

233 |
234 | 235 |
236 |
237 | 238 |
239 |
240 |

241 | Documentation generated using Couscous 242 |

243 |
244 |
245 | 246 | 247 | 248 | 249 | 250 | 251 | 258 | 259 | 260 | 261 | -------------------------------------------------------------------------------- /docs/theme-command.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Theme Command - WP Composer 3 | --- 4 | ##Theme Subcommands 5 | Manage dependencies of a specific theme 6 | > **Note** Some commands will generate a composer.json file if one does not currently exist 7 | 8 | ###add 9 | 10 | Add the specified theme to the composer.json file 11 | 12 | --- 13 | wp composer theme add 14 | --- 15 | 16 | #####Example 17 | --- 18 | # Add twentysixteen theme to the composer.json file. 19 | wp composer theme add twentysixteen 20 | # Add twentyfourteen as dev dependency 21 | wp composer theme add twentyfourteen --dev 22 | # Install zerif lite and sydney themes 23 | wp composer theme add zerif-lite,sydney 24 | --- 25 | #####Result 26 | A composer.json file will be generated with twentysixteen added as a dependency and twentyfourteen added as a dev dependency 27 | ```json 28 | { 29 | "name": "wp-composer-dependencies", 30 | "description": "Theme and plugin dependencies for the site http://example.com", 31 | "repositories": [ 32 | { 33 | "type": "composer", 34 | "url": "https://wpackagist.org" 35 | } 36 | ], 37 | "require": { 38 | "wpackagist-theme/twentysixteen": "*", 39 | "wpackagist-theme/zerif-lite": "*", 40 | "wpackagist-theme/sydney": "*" 41 | }, 42 | "require-dev": { 43 | "wpackagist-theme/twentyfourteen": "*" 44 | }, 45 | "extra": { 46 | "installer-paths": { 47 | "wp-content/themes/{$name}": [ 48 | "type:wordpress-theme" 49 | ], 50 | "wp-content/plugins/{$name}": [ 51 | "type:wordpress-plugin" 52 | ], 53 | "wp-content/mu-plugins/{$name}": [ 54 | "type:wordpress-muplugin" 55 | ] 56 | } 57 | } 58 | } 59 | ``` 60 | ###remove 61 | Remove the specified theme from the composer.json file 62 | 63 | #####Example 64 | --- 65 | # Remove twentyfourteen as dev dependency 66 | wp composer theme remove twentyfourteen --dev 67 | --- 68 | #####Result 69 | A composer.json file will be saved with twentyfourteen removed as a dev dependency 70 | ```json 71 | { 72 | "name": "wp-composer-dependencies", 73 | "description": "Theme and plugin dependencies for the site http://example.com", 74 | "repositories": [ 75 | { 76 | "type": "composer", 77 | "url": "https://wpackagist.org" 78 | } 79 | ], 80 | "require": { 81 | "wpackagist-theme/twentysixteen": "*" 82 | }, 83 | "extra": { 84 | "installer-paths": { 85 | "wp-content/themes/{$name}": [ 86 | "type:wordpress-theme" 87 | ], 88 | "wp-content/plugins/{$name}": [ 89 | "type:wordpress-plugin" 90 | ], 91 | "wp-content/mu-plugins/{$name}": [ 92 | "type:wordpress-muplugin" 93 | ] 94 | } 95 | } 96 | } 97 | ``` 98 | 99 | ####Options 100 | 101 | *[...]* 102 | 103 |     One or more themes 104 | 105 | *[--file]* 106 | 107 |     Path to save the composer.json file 108 | 109 | *[--latest]* 110 | 111 |     Always use the latest version from whatever repo the theme is coming from. **default**. 112 | 113 | > **Note** Unlike plugins, themes on wordpress.org don't have specific versions (e.g. v1.0, v2.0, etc...), so the latest version of a theme will always be downloaded 114 | 115 | *[--installer-paths]* OR *[--ip]* 116 | 117 |     Set the WordPress plugins and themes installer path 118 | 119 | *[--dev]* 120 | 121 |     Add theme as a dev requirement in composer.json 122 | 123 | *[--deactivate]* 124 | 125 |     Deactivate the theme before uninstalling it 126 | -------------------------------------------------------------------------------- /docs/themes-command.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Themes Command - WP Composer 8 | 9 | 10 | 11 | 12 | 13 | 22 | 33 | 34 | 35 | 36 | 50 | 51 |
52 |
53 | 54 | 55 | 127 | 128 | 129 |
130 |

Themes Subcommands

131 |

Manage dependencies of installed themes

132 |

add

133 |

Add currently installed themes to composer.json

134 |
135 |
wp composer themes add
136 |
137 |

install

138 |

Install themes listed in composer.json

139 |
140 |
wp composer themes install
141 |
142 |

uninstall

143 |

Deactivate and uninstall themes listed in composer.json

144 |
145 |
wp composer themes uninstall
146 |
147 |

activate

148 |

Activate themes listed in composer.json

149 |
150 |
wp composer themes activate
151 |
152 |

deactivate

153 |

Deactivate themes listed in composer.json

154 |
155 |
wp composer themes deactivate
156 |
157 |

Options

158 |

[--file]

159 |

    Path to save the composer.json file

160 |

[--all]

161 |

    Add themes found on wordpress.org and themes not found on wordpress.org. By default, only themes available on wordpress.org will be added to the composer.json file

162 |

[--latest]

163 |

    Add current version of themes installed or specify to always use the latest version from whatever repo the themes is coming from.

164 |

[--installer-paths] OR [--ip]

165 |

    Set the WordPress plugins and themes installer path

166 |

[--dev]

167 |

    Only apply command to themes defined as a dev requirement in composer.json

168 |

[--deactivate]

169 |

    Deactivate the themes before uninstalling them. This only applies when using the command wp themes uninstall --deactivate

170 |
171 | 172 |
173 |
174 | 175 |
176 |
177 |

178 | Documentation generated using Couscous 179 |

180 |
181 |
182 | 183 | 184 | 185 | 186 | 187 | 188 | 195 | 196 | 197 | 198 | -------------------------------------------------------------------------------- /docs/themes-command.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Themes Command - WP Composer 3 | --- 4 | ##Themes Subcommands 5 | Manage dependencies of installed themes 6 | 7 | ###add 8 | 9 | Add currently installed themes to composer.json 10 | 11 | --- 12 | wp composer themes add 13 | --- 14 | 15 | ###install 16 | Install themes listed in composer.json 17 | 18 | --- 19 | wp composer themes install 20 | --- 21 | 22 | ###uninstall 23 | 24 | Deactivate and uninstall themes listed in composer.json 25 | 26 | --- 27 | wp composer themes uninstall 28 | --- 29 | 30 | ###activate 31 | 32 | Activate themes listed in composer.json 33 | 34 | --- 35 | wp composer themes activate 36 | --- 37 | 38 | ###deactivate 39 | 40 | Deactivate themes listed in composer.json 41 | 42 | --- 43 | wp composer themes deactivate 44 | --- 45 | 46 | 47 | ####Options 48 | 49 | *[--file]* 50 | 51 |     Path to save the composer.json file 52 | 53 | *[--all]* 54 | 55 |     Add themes found on wordpress.org and themes not found on wordpress.org. By default, only themes available on wordpress.org will be added to the composer.json file 56 | 57 | *[--latest]* 58 | 59 |     Add current version of themes installed or specify to always use the latest version from whatever repo the themes is coming from. 60 | 61 | *[--installer-paths]* OR *[--ip]* 62 | 63 |     Set the WordPress plugins and themes installer path 64 | 65 | *[--dev]* 66 | 67 |     Only apply command to themes defined as a dev requirement in composer.json 68 | 69 | *[--deactivate]* 70 | 71 |     Deactivate the themes before uninstalling them. This only applies when using the command `wp themes uninstall --deactivate` 72 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 8 | Author URI: https://rxnlabs.com 9 | License: GPL2+ 10 | */ 11 | 12 | if (defined('WP_CLI') && WP_CLI && php_sapi_name() === 'cli') { 13 | // Check if installed as WordPress plugin. If so, make sure the composer dependencies have been installed 14 | if (defined('ABSPATH')) { 15 | if (file_exists( __DIR__ . '/vendor/autoload.php')) { 16 | require_once __DIR__ . '/vendor/autoload.php'; 17 | } else { 18 | die( sprintf('Please, run the command composer install --no-dev --working-dir="%s" first before using the plugin wp-composer%s', __DIR__, PHP_EOL) ); 19 | } 20 | } 21 | 22 | $composer_dependencies = new \rxnlabs\Dependencies(); 23 | $composer_dependencies_wp_cli = new \rxnlabs\WPCLI($composer_dependencies); 24 | $composer_dependencies_wp_cli->registerCommands(); 25 | $composer_dependencies_wp_cli->hooks(); 26 | } -------------------------------------------------------------------------------- /wp-composer-dependencies/admin.php: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | namespace rxnlabs; 10 | use League\Flysystem\Filesystem; 11 | use League\Flysystem\Adapter\Local; 12 | 13 | class Dependencies 14 | { 15 | /** 16 | * Store the namespace for the dpendencies namespace from http://wpackagist.org/ 17 | * 18 | * @since 1.0.0 19 | * @version 1.0.0 20 | * 21 | * @var array 22 | */ 23 | public $wp_packagist_namespace = array('plugin'=>'wpackagist-plugin', 'theme'=>'wpackagist-theme'); 24 | 25 | /** 26 | * Secure URL to the WPackagist site 27 | * 28 | * @since 1.0.0 29 | * @version 1.0.0 30 | * 31 | * @var string 32 | */ 33 | public $wp_packagist_repo = 'https://wpackagist.org'; 34 | 35 | /** 36 | * Unsecure URL to the WPackagist site. Composer repositories should ideally use HTTPS since by default composer is 37 | * configured to allow download assets from HTTPS repository. 38 | * 39 | * @since 1.0.0 40 | * @version 1.0.0 41 | * 42 | * @var string 43 | */ 44 | public $wp_packagist_repo_non_https = 'http://wpackagist.org'; 45 | 46 | /** 47 | * Array of dependencies in the composer file. 48 | * 49 | * @since 1.0.0 50 | * @version 1.0.0 51 | * 52 | * @var string 53 | */ 54 | public $composer_dependencies; 55 | 56 | /** 57 | * Path to save the composer.json file 58 | * 59 | * @since 1.0.0 60 | * @version 1.0.0 61 | * 62 | * @var string 63 | */ 64 | public $composer_save_path; 65 | 66 | /** 67 | * Composer file path 68 | * 69 | * @since 1.0.0 70 | * @version 1.0.0 71 | * 72 | * @var string 73 | */ 74 | public $composer_file_location; 75 | 76 | /** 77 | * WordPress assets install path 78 | * 79 | * @since 1.0.0 80 | * @version 1.0.0 81 | * 82 | * @var string 83 | */ 84 | public $assets_install_path; 85 | 86 | /** 87 | * Stop these words from being interpreted as the name of plugins and throwing an error when running the install command. 88 | * 89 | * @since 1.0.1 90 | * @version 1.0.1 91 | * 92 | * @var string 93 | */ 94 | public $reserved_words = array('install', 'uninstall'); 95 | 96 | /** 97 | * Save the composer.json file with tabs or spaces 98 | * 99 | * @since 1.0.2 100 | * @version 1.0.2 101 | * 102 | * @var bool 103 | */ 104 | public $save_as_tabs = true; 105 | 106 | /** 107 | * Dependencies constructor. 108 | * @param string $installer_path Set the default installer path for the WordPress plugins 109 | */ 110 | public function __construct($installer_path = '') { 111 | // set the default installer path for the wordpress assets (we can guess that this plugin is two directories below the wp-content folder or the folder that replaced wp-content) 112 | if (empty($installer_path) && function_exists('plugin_dir_path')) { 113 | $installer_path = basename(dirname(plugin_dir_path(__DIR__), 2)); 114 | } 115 | 116 | $this->setInstallerPath($installer_path); 117 | } 118 | 119 | /** 120 | * Execute WordPress hooks. 121 | * 122 | * @since 1.0.0 123 | * @version 1.0.0 124 | * 125 | * @return void 126 | */ 127 | public function hooks() 128 | { 129 | //register_deactivation_hook(__FILE__, array($this, 'removeThemeDependency')); 130 | //register_uninstall_hook(__FILE__, array($this, 'removeThemeDependency')); 131 | } 132 | 133 | /** 134 | * Write dependencies to composer.json file 135 | * 136 | * Main command that adds and tracks dependencies. 137 | * 138 | * @since 1.0.0 139 | * @version 1.0.0 140 | */ 141 | public function saveComposer($composer_file_name = 'composer.json', $save_path = '') 142 | { 143 | // attempt to extract save path from the passed $composer_file_name path 144 | if (empty($save_path) && !empty($composer_file_name)) { 145 | $save_path = pathinfo($composer_file_name)['dirname']; 146 | } 147 | 148 | if (empty($save_path)) { 149 | if (empty($this->composer_save_path)) { 150 | // read the default composer.json file to set the default save path 151 | $this->readComposerFile(); 152 | } 153 | $save_path = $this->composer_save_path; 154 | } 155 | 156 | $file_extension = new \SplFileInfo($composer_file_name); 157 | if ($file_extension !== 'json') { 158 | $composer_file_name = 'composer.json'; 159 | } 160 | 161 | $this->composer_file_location = sprintf('%s/%s', $save_path, $composer_file_name); 162 | 163 | try { 164 | /* 165 | if we're writing to a local file, Flysystem uses relative paths instead of absolute paths 166 | to write files, so the composer.json file would be saved to the plugin folder instead of 167 | the passed save path. So set the $root to '/' to fix this issue. 168 | @link https://github.com/thephpleague/flysystem/issues/462 169 | */ 170 | $adapter = new Local('/'); 171 | $filesystem = new Filesystem($adapter); 172 | } catch (\LogicException $e) { 173 | error_log($e->getMessage(), 0); 174 | return false; 175 | } 176 | 177 | if (!empty($this->composer_dependencies)) { 178 | $wp_asset = array(); 179 | $other = array(); 180 | 181 | $requires = array('require', 'require-dev'); 182 | $wordpress_types_of_deps = array('plugins', 'themes'); 183 | // loop through composer array and convert each type of dependency to the kind stored in composer.json file 184 | foreach ($requires as $type_of_require) { 185 | if (!empty($this->composer_dependencies[$type_of_require])) { 186 | $composer_dependencies = array(); 187 | foreach ( $wordpress_types_of_deps as $dep ) { 188 | if ( empty( $this->composer_dependencies[ $type_of_require ][ $dep ] ) ) { 189 | continue; 190 | unset( $this->composer_dependencies[ $type_of_require ][ $dep ] ); 191 | } elseif ( isset( $this->composer_dependencies[ $type_of_require ][ $dep ] ) && is_array( $this->composer_dependencies[ $type_of_require ][ $dep ] ) ) { 192 | foreach ( $this->composer_dependencies[ $type_of_require ][ $dep ] as $plugin_or_theme => $version ) { 193 | switch ( $dep ) { 194 | case 'plugins': 195 | $type = 'plugin'; 196 | break; 197 | case 'themes': 198 | $type = 'theme'; 199 | break; 200 | default: 201 | $type = 'plugin'; 202 | } 203 | $plugin_or_theme_namespace = $this->addNameSpace( $plugin_or_theme, $type ); 204 | $wp_asset[ $plugin_or_theme_namespace ] = $version; 205 | } 206 | $composer_dependencies = array_merge( $composer_dependencies, $wp_asset ); 207 | unset( $this->composer_dependencies[ $type_of_require ][ $dep ] ); 208 | } 209 | } 210 | 211 | $this->composer_dependencies[ $type_of_require ] = array_merge( $this->composer_dependencies[ $type_of_require ], $composer_dependencies ); 212 | 213 | } else { 214 | unset($this->composer_dependencies[ $type_of_require ]); 215 | } 216 | } 217 | 218 | $json_pretty = new \Camspiers\JsonPretty\JsonPretty; 219 | 220 | if ($this->save_as_tabs) { 221 | $composer_dependencies = stripslashes($json_pretty->prettify($this->composer_dependencies)); 222 | } else { 223 | $composer_dependencies = stripslashes($json_pretty->prettify($this->composer_dependencies, '\s\s\s\s')); 224 | } 225 | 226 | $composer_file = sprintf('%s/%s', $save_path, $composer_file_name); 227 | $get_real_path = realpath($composer_file); 228 | // if the $composer_file_name doesn't exist 229 | if ($get_real_path === false) { 230 | $composer_file = $this->getAbsolutePathFromRelative($composer_file); 231 | } else { 232 | $composer_file = $get_real_path; 233 | } 234 | $is_success = $filesystem->put($composer_file, $composer_dependencies); 235 | 236 | return $is_success; 237 | } 238 | 239 | 240 | } 241 | 242 | /** 243 | * Read the composer.json file installed. 244 | * 245 | * Read the composer.json file to check for other dependencies. 246 | * 247 | * @since 1.0.0 248 | * @verion 1.0.2 249 | * 250 | * @param string $composer_file File path of composer.json file 251 | */ 252 | public function readComposerFile($composer_file = '') 253 | { 254 | $options = get_option('wp-composer-dependencies'); 255 | 256 | $adapter = new Local('/'); 257 | $filesystem = new Filesystem($adapter); 258 | 259 | // if a specific composer.json file wasn't passed in as parameter, check the current directory for a 260 | if (empty($composer_file)) { 261 | $composer_file = getcwd().'/composer.json'; 262 | } 263 | 264 | $add_packagist_repo = function(array $dependencies){ 265 | if (isset($dependencies['repositories'])) { 266 | $is_object_repo = key($dependencies['repositories']); 267 | if ($is_object_repo !== 0) { 268 | $dependencies['repositories']['wp-composer'] = ['type'=>'composer','url'=>$this->wp_packagist_repo]; 269 | } else { 270 | $dependencies['repositories'] = [['type'=>'composer','url'=>$this->wp_packagist_repo]]; 271 | } 272 | } else { 273 | $dependencies['repositories'] = [['type'=>'composer','url'=>$this->wp_packagist_repo]]; 274 | } 275 | 276 | return $dependencies; 277 | }; 278 | 279 | $add_installer_paths = function(array $dependencies) { 280 | $wordpress_path = $this->getInstallerPath(); 281 | $theme_path = $wordpress_path.'/themes/{$name}/'; 282 | $plugin_path = $wordpress_path.'/plugins/{$name}/'; 283 | $mu_plugin_path = $wordpress_path.'/mu-plugins/{$name}/'; 284 | 285 | $wordpress_install_paths = [ 286 | $theme_path => ["type:wordpress-theme"], 287 | $plugin_path => ["type:wordpress-plugin"], 288 | $mu_plugin_path => ["type:wordpress-muplugin"] 289 | ]; 290 | 291 | if (isset($dependencies['extra']['installer-paths'])) { 292 | $installer_path = $dependencies['extra']['installer-paths']; 293 | } else { 294 | $installer_path = $dependencies['extra']['installer-paths'] = array(); 295 | } 296 | 297 | $dependencies['extra']['installer-paths'] = array_merge( $installer_path, $wordpress_install_paths); 298 | return $dependencies; 299 | }; 300 | 301 | try { 302 | // $parser = new \JsonCollectionParser\Parser(); 303 | $get_real_path = realpath($composer_file); 304 | // if the $composer_file_name doesn't exist 305 | if ($get_real_path === false) { 306 | $composer_file = $this->getAbsolutePathFromRelative($composer_file); 307 | } else { 308 | $composer_file = $get_real_path; 309 | } 310 | 311 | if (!$filesystem->has($composer_file)) { 312 | $composer_file = $this->composer_file_location = ''; 313 | $this->composer_save_path = getcwd(); 314 | $dependencies = [ 315 | 'name'=>'wp-composer-dependencies', 316 | 'description' => sprintf('Theme and plugin dependencies for the site %s', get_bloginfo('url')), 317 | 'require'=>[], 318 | 'require-dev'=>[] 319 | ]; 320 | $dependencies = $add_installer_paths($add_packagist_repo($dependencies)); 321 | } else { 322 | $composer_file_string = $filesystem->read($composer_file); 323 | 324 | $this->save_as_tabs = $this->detectTabs($composer_file_string); 325 | 326 | $dependencies = json_decode($composer_file_string, true); 327 | 328 | if (isset($dependencies['repositories'])) { 329 | $repo_added_already = false; 330 | foreach ($dependencies['repositories'] as &$repo) { 331 | $is_object_repo = key($dependencies['repositories']); 332 | if ($is_object_repo !== 0) { 333 | if ($repo['type'] === 'composer' && $repo['url'] === $this->wp_packagist_repo_non_https) { 334 | $repo['url'] = $this->wp_packagist_repo; 335 | $repo_added_already = true; 336 | break; 337 | } 338 | 339 | if ($repo['type'] === 'composer' && $repo['url'] === $this->wp_packagist_repo) { 340 | $repo_added_already = true; 341 | break; 342 | } 343 | } else { 344 | if ($repo['type'] === 'composer' && $repo['url'] === $this->wp_packagist_repo_non_https) { 345 | $repo['url'] = $this->wp_packagist_repo; 346 | $repo_added_already = true; 347 | break; 348 | } 349 | 350 | if ($repo['type'] === 'composer' && $repo['url'] === $this->wp_packagist_repo) { 351 | $repo_added_already = true; 352 | break; 353 | } 354 | } 355 | } 356 | 357 | if ($repo_added_already === false) { 358 | $dependencies = $add_installer_paths($add_packagist_repo($dependencies)); 359 | } 360 | } else { 361 | $dependencies = $add_installer_paths($add_packagist_repo($dependencies)); 362 | } 363 | 364 | $this->composer_save_path = pathinfo($composer_file)['dirname']; 365 | } 366 | 367 | $this->composer_dependencies = $dependencies; 368 | $this->composer_file_location = sprintf('%s/%s', $this->composer_save_path, 'composer.json'); 369 | 370 | return $dependencies; 371 | } catch (Exception $e) { 372 | return new WP_Error(sprintf('composer.json file does not exist at the path %s', $composer_file)); 373 | } 374 | } 375 | 376 | /** 377 | * Read composer dependencies and extract the ones that WordPress plugins and themes into array 378 | * 379 | * Since wpackagist plugins and themes need to have the package namespaced in a defined format, we need to extract WordPress plugins and themes into their own array 380 | * 381 | * @since 1.0.0 382 | * @version 1.0.0 383 | * 384 | * @param array $dependencies Composer dependencies (i.e. either the "require" key or the "require-dev" key of the composer file) 385 | */ 386 | private function formatComposerDependencies(array $dependencies) 387 | { 388 | foreach($dependencies as $dep) { 389 | $is_wordpress_dependency = false; 390 | } 391 | } 392 | 393 | /** 394 | * Determine of the plugin is available on wordpress.org 395 | * 396 | * @since 1.0.0 397 | * @version 1.0.0 398 | * 399 | * @param string $plugin_slug WordPress plugin slug 400 | * @param string $repo_hosting_service The hosting service where the plugin can be downloaded from (e.g. WordPress.org) 401 | */ 402 | public function isPluginAvailable($plugin_slug, $repo_hosting_service = 'wordpress') { 403 | $object_name = $this->cleanRepoName( $plugin_slug ); 404 | 405 | if ($repo_hosting_service === 'wordpress') { 406 | $url = sprintf('https://api.wordpress.org/plugins/info/1.0/%s.json', $object_name); 407 | 408 | if (isset($url)) { 409 | $plugin_info = wp_remote_post($url); 410 | 411 | if (!is_wp_error($plugin_info) && wp_remote_retrieve_response_code($plugin_info) === 200) { 412 | $response = json_decode( wp_remote_retrieve_body( $plugin_info ) ); 413 | if (empty($response)) { 414 | return false; 415 | } else { 416 | return true; 417 | } 418 | } 419 | } 420 | } 421 | 422 | return false; 423 | } 424 | 425 | /** 426 | * Determine of the theme is available on wordpress.org 427 | * 428 | * @since 1.0.0 429 | * @version 1.0.0 430 | * 431 | * @param string $theme_slug WordPress theme slug 432 | * @param string $repo_hosting_service The hosting service where the theme can be downloaded from (e.g. WordPress.org) 433 | * 434 | * @return bool True if the theme is available, false if not available 435 | */ 436 | public function isThemeAvailable($theme_slug, $repo_hosting_service = 'wordpress') 437 | { 438 | $object_name = $this->cleanRepoName($theme_slug); 439 | 440 | if ($repo_hosting_service === 'wordpress') { 441 | $url = 'https://api.wordpress.org/themes/info/1.1/'; 442 | 443 | $request = array( 444 | 'slug' => $theme_slug, 445 | 'fields' => 'screenshot_url' 446 | ); 447 | 448 | $body = array( 449 | 'action'=>'theme_information', 450 | 'request'=>$request 451 | ); 452 | 453 | $theme_info = wp_remote_post($url,array( 454 | 'body'=> $body 455 | )); 456 | 457 | if (!is_wp_error($theme_info) && wp_remote_retrieve_response_code($theme_info) === 200) { 458 | $response = json_decode(wp_remote_retrieve_body($theme_info)); 459 | if (empty($response)) { 460 | return false; 461 | } else { 462 | return true; 463 | } 464 | 465 | } 466 | } 467 | 468 | return false; 469 | } 470 | 471 | /** 472 | * Get current plugins. 473 | * 474 | * Get the current active and inactive plugins. 475 | * 476 | * @since 1.0.0 477 | * @version 1.0.0 478 | * 479 | * @param string $status Get active, inactive, or all installed plugins. 480 | */ 481 | public function getPlugins($status = 'active') 482 | { 483 | $plugins = get_plugins(); 484 | if ($status === 'active') { 485 | 486 | } elseif ($status === 'inactive') { 487 | 488 | } elseif ($status === 'all') { 489 | 490 | } 491 | } 492 | 493 | /** 494 | * Get the current themes. 495 | * 496 | * Get the current active and inactive themes. 497 | * 498 | * @since 1.0.0 499 | * @version 1.0.0 500 | * 501 | * @param strng $status Get active, inactive, or all installed themes. 502 | */ 503 | public function getThemes($status = 'active') 504 | { 505 | $themes = wp_get_themes(); 506 | if ($status === 'active') { 507 | 508 | } elseif ($status === 'inactive') { 509 | 510 | } elseif ($status === 'all') { 511 | 512 | } 513 | } 514 | 515 | /** 516 | * Add the WordPress plugin as a dependency 517 | * 518 | * @since 1.0.0 519 | * @version 1.0.0 520 | * 521 | * @param string $plugin_name Name of the plugin to add as a dependency (e.g. slug, folder name) 522 | * @param string $version The plugin version number 523 | */ 524 | public function addPluginDependency($plugin_name, $version = '*') 525 | { 526 | $plugin_name = $this->stripSpecialChars($plugin_name); 527 | 528 | if (!in_array( $plugin_name, $this->reserved_words)) { 529 | $this->composer_dependencies['require']['plugins'][$plugin_name] = $version; 530 | } 531 | 532 | return $plugin_name; 533 | } 534 | 535 | /** 536 | * Add the WordPress plugin as a dev dependency 537 | * 538 | * @since 1.0.0 539 | * @version 1.0.0 540 | * 541 | * @param string $plugin_name Name of the plugin to add as a dependency (e.g. slug, folder name) 542 | * @param string $version The plugin version number 543 | */ 544 | public function addDevPluginDependency($plugin_name, $version = '*') 545 | { 546 | $plugin_name = $this->stripSpecialChars($plugin_name); 547 | 548 | if (!in_array( $plugin_name, $this->reserved_words)) { 549 | $this->composer_dependencies['require-dev']['plugins'][$plugin_name] = $version; 550 | } 551 | 552 | return $plugin_name; 553 | } 554 | 555 | /** 556 | * Remove the WordPress plugin as a dependency 557 | * 558 | * @since 1.0.0 559 | * @version 1.0.0 560 | * 561 | * @param string $plugin_name Name of the plugin to remove as a dependency (e.g. slug, folder name) 562 | */ 563 | public function removePluginDependency($plugin_name) 564 | { 565 | $namespaced_plugin_name = $this->addNameSpace( $plugin_name, 'plugin' ); 566 | unset($this->composer_dependencies['require'][$namespaced_plugin_name]); 567 | } 568 | 569 | /** 570 | * Remove the WordPress plugin as a dev dependency 571 | * 572 | * @since 1.0.0 573 | * @version 1.0.0 574 | * 575 | * @param string $plugin_name Name of the plugin to remove as a dependency (e.g. slug, folder name) 576 | */ 577 | public function removeDevPluginDependency($plugin_name) 578 | { 579 | $namespaced_plugin_name = $this->addNameSpace( $plugin_name, 'plugin' ); 580 | unset($this->composer_dependencies['require-dev'][$namespaced_plugin_name]); 581 | } 582 | 583 | /** 584 | * Add specified theme as a dependency 585 | * 586 | * @since 1.0.0 587 | * @version 1.0.0 588 | * 589 | * @param string $theme_name Name of the theme to add as a dependency (e.g. slug, folder name) 590 | */ 591 | public function addThemeDependency($theme_name, $version = "*") 592 | { 593 | $this->composer_dependencies['require']['themes'][$theme_name] = $version; 594 | } 595 | 596 | /** 597 | * Add specified theme as a dev dependency 598 | * 599 | * @since 1.0.0 600 | * @version 1.0.0 601 | * 602 | * @param string $theme_name Name of the theme to add as a dependency (e.g. slug, folder name) 603 | */ 604 | public function addDevThemeDependency($theme_name, $version = "*") 605 | { 606 | $this->composer_dependencies['require-dev']['themes'][$theme_name] = $version; 607 | } 608 | 609 | /** 610 | * Remove the WordPress theme as a dependency 611 | * 612 | * @since 1.0.0 613 | * @version 1.0.0 614 | * 615 | * @param string $theme_name Name of the theme to remove as a dependency 616 | */ 617 | public function removeThemeDependency($theme_name) 618 | { 619 | $namespaced_theme_name = $this->addNameSpace( $theme_name, 'theme' ); 620 | unset($this->composer_dependencies['require'][$namespaced_theme_name]); 621 | 622 | return $this->composer_dependencies; 623 | } 624 | 625 | /** 626 | * Remove the WordPress theme as a dev dependency 627 | * 628 | * @since 1.0.0 629 | * @version 1.0.0 630 | * 631 | * @param string $theme_name Name of the theme to remove as a dependency 632 | */ 633 | public function removeDevThemeDependency($theme_name) 634 | { 635 | $namespaced_theme_name = $this->addNameSpace( $theme_name, 'theme' ); 636 | unset($this->composer_dependencies['require-dev'][$namespaced_theme_name]); 637 | 638 | return $this->composer_dependencies; 639 | } 640 | 641 | /** 642 | * Add other dependencies to composer.json that aren't WordPress plugins or themes. 643 | * 644 | * @since 1.0.0 645 | * @version 1.0.0 646 | * 647 | * @param string $other Composer package or vendor. 648 | */ 649 | public function addOtherDependency($other, $version) 650 | { 651 | $this->composer_dependencies['other'][$other] = $version; 652 | } 653 | 654 | /** 655 | * Load WordPress core as a dependency. 656 | * 657 | * @since 1.0.0 658 | * @version 1.0.0 659 | * 660 | * @param string $version WordPress version 661 | */ 662 | public function addWordPressDependency($version = 'latest') 663 | { 664 | 665 | } 666 | 667 | /** 668 | * Add inactive plugins as dependencies 669 | * 670 | * @since 1.0.0 671 | * @version 1.0.0 672 | */ 673 | public function addInactivePlugins() 674 | { 675 | 676 | } 677 | 678 | /** 679 | * Add inactive themes as dependencies 680 | * 681 | * @since 1.0.0 682 | * @version 1.0.0 683 | */ 684 | public function addInactiveThemes() 685 | { 686 | 687 | } 688 | 689 | /** 690 | * Sort dependencies in alphabetical order. 691 | * 692 | * Sort dependencies either by ascending alphabetical order or descending alphabetical order. 693 | * 694 | * @since 1.0.0 695 | * @version 1.0.0 696 | * 697 | * @param boolean Sort Ascending If true, sort by ascending order. If false, sort by descending alphabetical order. 698 | */ 699 | public function sortDependencies($ascending = true) 700 | { 701 | 702 | } 703 | 704 | /** 705 | * Remove forward slashes and backslashes from the theme or plugin slug. 706 | * 707 | * @since 1.0.0 708 | * @version 1.0.0 709 | * 710 | * @param string $object_name Slug of the theme or plugin 711 | * @return string Plugin or theme slug with slashes stripped from the name. 712 | */ 713 | public function cleanRepoName($object_name) 714 | { 715 | if (strpos($object_name, '/') !== false) { 716 | list($vendor, $object_name) = explode('/', $object_name); 717 | } 718 | 719 | return stripcslashes($object_name); 720 | } 721 | 722 | /** 723 | * Add the plugin and theme wpackagist namespace to the plugin and theme name 724 | * 725 | * @param string $plugin_or_theme_name tTeme or plugin slug name/folder 726 | * @param string $theme_or_plugin Is this a plugin or theme. Valid values are "plugin", and "theme" 727 | * @return string Plugin with wpackagist namespace or theme with wpackagist namespace 728 | */ 729 | public function addNameSpace($plugin_or_theme_name, $theme_or_plugin = 'plugin') 730 | { 731 | switch($theme_or_plugin) { 732 | case 'plugin': $namespace = sprintf('%s/%s', $this->wp_packagist_namespace['plugin'], $plugin_or_theme_name); 733 | break; 734 | case 'theme': $namespace = sprintf('%s/%s', $this->wp_packagist_namespace['theme'], $plugin_or_theme_name); 735 | break; 736 | default: $namespace = $plugin_or_theme_name; 737 | } 738 | 739 | return $namespace; 740 | } 741 | 742 | /** 743 | * Remove the plugin and theme wpackagist namespace from the plugin and theme name 744 | * 745 | * @param string $plugin_or_theme_name Theme or plugin slug name/folder 746 | * @param string $theme_or_plugin Is this a plugin or theme. Valid values are "plugin", and "theme" 747 | * 748 | * @return string Theme or plugin name without the wpackagist namespace 749 | */ 750 | public function removeNamespace($plugin_or_theme_name, $theme_or_plugin = 'plugin') 751 | { 752 | $count_limit = 1; 753 | switch($theme_or_plugin) { 754 | case 'plugin': $namespace = str_replace($this->wp_packagist_namespace['plugin'].'/', '', $plugin_or_theme_name, $count_limit); 755 | break; 756 | case 'theme': $namespace = str_replace( $this->wp_packagist_namespace['theme'].'/', '', $plugin_or_theme_name, $count_limit); 757 | break; 758 | default: $namespace = $plugin_or_theme_name; 759 | } 760 | return $namespace; 761 | } 762 | 763 | /** 764 | * Check if a package listed in composer.json is a WordPress theme or plugin 765 | * 766 | * @param string $plugin_or_theme_name Theme or plugin slug name/folder 767 | * 768 | * @return bool True if package is a WordPress plugin or theme. False, if not. 769 | */ 770 | public function isWordPressPackage($plugin_or_theme_name) 771 | { 772 | foreach ($this->wp_packagist_namespace as $asset) { 773 | if (strpos($plugin_or_theme_name, $asset) !== false) { 774 | return true; 775 | } 776 | } 777 | 778 | return false; 779 | } 780 | 781 | /** 782 | * Check if a package listed in composer.json is a WordPress plugin based on it's key 783 | * 784 | * @param string $plugin_slug Plugin slug name/folder 785 | * 786 | * @return bool True if package is a WordPress plugin. False, if not. 787 | */ 788 | public function isWordPressPlugin($plugin_slug) 789 | { 790 | if (strpos($plugin_slug, $this->wp_packagist_namespace['plugin']) !== false) { 791 | 792 | return true; 793 | } 794 | 795 | return false; 796 | } 797 | 798 | /** 799 | * Check if a package listed in composer.json is a WordPress theme based on it's key 800 | * 801 | * @param string $theme_slug Theme slug name/folder 802 | * 803 | * @return bool True if package is a WordPress theme. False, if not. 804 | */ 805 | public function isWordPressTheme($theme_slug) 806 | { 807 | if (strpos($theme_slug, $this->wp_packagist_namespace['theme']) !== false) { 808 | return true; 809 | } 810 | 811 | return false; 812 | } 813 | 814 | /** 815 | * Convert an absolute path to a relative path. 816 | * 817 | * Convert an absolute path to a relative path so we can save the composer.json file in the correct 818 | * directory instead of getting saved to the plugin folder. 819 | * 820 | * @link http://stackoverflow.com/questions/2637945/getting-relative-path-from-absolute-path-in-php#answer-2638272 821 | * @param $from_path 822 | * @param $to_path 823 | * @return string 824 | */ 825 | protected function getRelativePath($from_path, $to_path) 826 | { 827 | // some compatibility fixes for Windows paths 828 | $from_path = is_dir($from_path) ? rtrim($from_path, '\/') . '/' : $from_path; 829 | $to_path = is_dir($to_path) ? rtrim($to_path, '\/') . '/' : $to_path; 830 | $from_path = str_replace('\\', '/', $from_path); 831 | $to_path = str_replace('\\', '/', $to_path); 832 | 833 | $from_path = explode('/', $from_path); 834 | $to_path = explode('/', $to_path); 835 | $relPath = $to_path; 836 | 837 | foreach($from_path as $depth => $dir) { 838 | // find first non-matching dir 839 | if($dir === $to_path[$depth]) { 840 | // ignore this directory 841 | array_shift($relPath); 842 | } else { 843 | // get number of remaining dirs to $from 844 | $remaining = count($from_path) - $depth; 845 | if($remaining > 1) { 846 | // add traversals up to first matching dir 847 | $padLength = (count($relPath) + $remaining - 1) * -1; 848 | $relPath = array_pad($relPath, $padLength, '..'); 849 | break; 850 | } else { 851 | $relPath[0] = './' . $relPath[0]; 852 | } 853 | } 854 | } 855 | return implode('/', $relPath); 856 | } 857 | 858 | /** 859 | * Convert relative directory path to absolute path. 860 | * 861 | * Needed since the Flysystem library doesn't create directories when we pass it relative paths. 862 | * 863 | * @since 1.0.0 864 | * @version 1.0.0 865 | * @link http://proger.i-forge.net/%D0%9C%D0%BE%D0%B8%20%D0%BF%D1%80%D0%BE%D0%B3%D0%B8/%D0%92%D0%B5%D0%B1/Real%20realpath.html 866 | * @param string $path Relative path to use 867 | * @param string|null $cwd Current working directory 868 | * @return string Absolute path to file 869 | */ 870 | public function getAbsolutePathFromRelative($path, $cwd = null) 871 | { 872 | $path = self::expandLeaveLinks($path, $cwd); 873 | 874 | if (function_exists('readlink')) { // prior to PHP 5.3 it only works for *nix. 875 | while (is_link($path) and ($target = readlink($path)) !== false) { $path = $target; } 876 | } 877 | 878 | return $path; 879 | } 880 | 881 | 882 | public function expandLeaveLinks($path, $cwd = null) 883 | { 884 | if (!is_scalar($path) and $path !== null) { return; } 885 | 886 | $cwd === null and $cwd = getcwd(); 887 | $cwd = static::pathize($cwd); 888 | 889 | $path = strtr($path, DIRECTORY_SEPARATOR === '\\' ? '/' : '\\', DIRECTORY_SEPARATOR); 890 | $firstIsSlash = (isset($path[0]) and strpbrk($path[0], '\\/')); 891 | 892 | if ($path === '' or (!$firstIsSlash and isset($path[1]) and $path[1] !== ':')) { 893 | $path = $cwd.DIRECTORY_SEPARATOR.$path; 894 | } elseif ($firstIsSlash and isset($cwd[1]) and $cwd[1] === ':') { 895 | // when a drive is specified in CWD then \ or / refers to that drive's root. 896 | $path = substr($cwd, 0, 2).$path; 897 | } 898 | 899 | if ($path !== '' and ($path[0] === DIRECTORY_SEPARATOR or (isset($path[1]) and $path[1] === ':'))) { 900 | list($prefix, $path) = explode(DIRECTORY_SEPARATOR, $path, 2); 901 | $prefix .= DIRECTORY_SEPARATOR; 902 | } else { 903 | $prefix = ''; 904 | } 905 | 906 | $expanded = array(); 907 | foreach (explode(DIRECTORY_SEPARATOR, $path) as $dir) { 908 | if ($dir === '..') { 909 | array_pop($expanded); 910 | } elseif ($dir !== '' and $dir !== '.') { 911 | $expanded[] = $dir; 912 | } 913 | } 914 | 915 | return $prefix.join(DIRECTORY_SEPARATOR, $expanded); 916 | } 917 | 918 | /** 919 | * @link https://github.com/ProgerXP/HTMLki/blob/master/start.php#L82 920 | * @param $path 921 | * @return string 922 | */ 923 | static function pathize($path) { 924 | return rtrim(str_replace('\\', '/', $path), '/').'/'; 925 | } 926 | 927 | /** 928 | * Set the path to install WordPress plugins and themes into 929 | * 930 | * Not all WordPress websites use the default WordPress directory structure. Some sites don't use wp-content to store their assets (e.g. Bedrock, https://github.com/roots/bedrock), some use subdirectories for their wordpress installs but manage composer assets in an ancestor directory. Allow thiose sites to set their own path to install their WordPress assets. 931 | * @param string $path Path to install the WordPres composer packages (i.e. themes and plugins) 932 | * 933 | * @return void 934 | */ 935 | public function setInstallerPath($path = 'wp-content') 936 | { 937 | if (empty($path)) { 938 | $path = 'wp-content'; 939 | } 940 | 941 | $this->assets_install_path = $path; 942 | } 943 | 944 | /** 945 | * Get the path to install WordPress plugins and themes into 946 | * 947 | * @see \rxnlabs\Dependencies\setInstallPath For why we need this 948 | * 949 | * @since 1.0.0 950 | * @version 1.0.0 951 | * 952 | * @return string Path to install the site plugins and themes 953 | */ 954 | public function getInstallerPath() 955 | { 956 | return $this->assets_install_path; 957 | } 958 | 959 | /** 960 | * Strip all non-alphanumeric characters from theme and plugin name 961 | * 962 | * @since 1.0.0 963 | * @version 1.0.0 964 | * 965 | * @return string Plugin or theme slug without special chars 966 | */ 967 | public function stripSpecialChars($string) 968 | { 969 | return preg_replace('/[^\w-]/', '', $string); 970 | } 971 | 972 | /** 973 | * Detect if line is indented with tabs 974 | * 975 | * @since 1.0.2 976 | * @version 1.0.2 977 | * 978 | * @param $line Input line to test against 979 | * 980 | * @return bool True if line is indented with tabs. False if not indented with tabs. 981 | */ 982 | public function detectTabs($line) 983 | { 984 | $is_tab = false; 985 | if (preg_match("/\t/", $line)) { 986 | $is_tab = true; 987 | } 988 | 989 | return $is_tab; 990 | } 991 | } 992 | --------------------------------------------------------------------------------