From ea8857a41d91499b0a719a4b52f1d82c4ca21544 Mon Sep 17 00:00:00 2001 From: Damian Taggart <4309872+attackant@users.noreply.github.com> Date: Fri, 8 Mar 2024 14:50:52 -0700 Subject: [PATCH] Remove CI pipeline and unnecessary PHP files, add `wp-404-caching` plugin The commit removes defunct CI pipeline configuration and obsolete PHP class files. This helps to clean up the project layout. Moreover, the `wp-404-caching` WordPress plugin and the associated PHP class has been added, as well as a configuration file to tweak the plugin as per requirements. --- .../workflows/merge-develop-to-scaffold.yml | 40 - .github/workflows/unit-test.yml | 1 + .../workflows/upgrade-wordpress-plugin.yml | 2 +- .phpcs.xml | 8 +- CHANGELOG.md | 2 +- Makefile | 4 - README.md | 51 +- blocks/README.md | 4 +- buddy.yml | 174 ---- composer.json | 18 +- configure.php | 836 ------------------ entries/README.md | 2 +- package-lock.json | 4 +- package.json | 10 +- phpstan.neon | 2 +- phpunit.xml | 4 +- scaffold/config.json | 4 +- src/assets.php | 8 +- src/class-example-plugin.php | 15 - src/class-feature-manager.php | 4 +- src/class-wp-404-caching.php | 15 + src/features/README.md | 14 +- src/meta.php | 8 +- tests/Feature/ExampleFeatureTest.php | 8 +- tests/TestCase.php | 8 +- tests/Unit/ExampleUnitTest.php | 6 +- tests/bootstrap.php | 8 +- plugin.php => wp-404-caching.php | 26 +- 28 files changed, 100 insertions(+), 1186 deletions(-) delete mode 100644 .github/workflows/merge-develop-to-scaffold.yml delete mode 100644 Makefile delete mode 100644 buddy.yml delete mode 100644 configure.php delete mode 100644 src/class-example-plugin.php create mode 100644 src/class-wp-404-caching.php rename plugin.php => wp-404-caching.php (62%) diff --git a/.github/workflows/merge-develop-to-scaffold.yml b/.github/workflows/merge-develop-to-scaffold.yml deleted file mode 100644 index 4f6b2f22..00000000 --- a/.github/workflows/merge-develop-to-scaffold.yml +++ /dev/null @@ -1,40 +0,0 @@ -# This workflow is used on alleyinteractive/create-wordpress-plugin to merge the -# develop branch into the scaffold branch and is NOT meant to be used on other -# repositories. This workflow will be deleted automatically when the -# configuration script is run. - -name: Merge Develop to Scaffold Branch - -on: - push: - branches: - - develop - - remove-scaffold - -jobs: - merge-develop-to-scaffold: - name: merge develop to scaffold - if: ${{ github.repository == 'alleyinteractive/create-wordpress-plugin' }} - runs-on: ubuntu-latest - - steps: - - name: Merge develop to scaffold - shell: bash - env: - DEVELOP_BRANCH: develop - SCAFFOLD_BRANCH: scaffold - - TOKEN: ${{ secrets.GH_TOKEN }} - run: | - git config --global user.name "$GITHUB_ACTOR" - git config --global user.email "$GITHUB_ACTOR@users.noreply.github.com" - - echo "Cloning alleyinteractive/create-wordpress-plugin..." - git clone --recursive --quiet https://$TOKEN@github.com/alleyinteractive/create-wordpress-plugin.git create-wordpress-plugin -b $SCAFFOLD_BRANCH - cd create-wordpress-plugin - - git fetch origin $DEVELOP_BRANCH - git fetch origin $SCAFFOLD_BRANCH - - git merge origin/$DEVELOP_BRANCH --no-edit - git push -u origin $SCAFFOLD_BRANCH diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 12b7eb1d..721ba730 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -17,5 +17,6 @@ jobs: wordpress: ["latest"] uses: alleyinteractive/.github/.github/workflows/php-tests.yml@main with: + database: '' php: ${{ matrix.php }} wordpress: ${{ matrix.wordpress }} diff --git a/.github/workflows/upgrade-wordpress-plugin.yml b/.github/workflows/upgrade-wordpress-plugin.yml index 9fdf3c6f..97b61293 100644 --- a/.github/workflows/upgrade-wordpress-plugin.yml +++ b/.github/workflows/upgrade-wordpress-plugin.yml @@ -15,5 +15,5 @@ jobs: - uses: actions/checkout@v4 - uses: alleyinteractive/action-update-wordpress-plugin@v1.2.1 with: - plugin-file: 'plugin.php' + plugin-file: 'wp-404-caching.php' upgrade-npm-dependencies: "true" diff --git a/.phpcs.xml b/.phpcs.xml index ca3aa55f..3e6848f7 100644 --- a/.phpcs.xml +++ b/.phpcs.xml @@ -1,6 +1,6 @@ - - PHP_CodeSniffer standard for create-wordpress-plugin. + + PHP_CodeSniffer standard for wp-404-caching. @@ -36,8 +36,8 @@ - - + + diff --git a/CHANGELOG.md b/CHANGELOG.md index f91d2c0a..5851ce3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -All notable changes to `Create WordPress Plugin` will be documented in this file. +All notable changes to `WP 404 Caching` will be documented in this file. ## 0.1.0 - 202X-XX-XX diff --git a/Makefile b/Makefile deleted file mode 100644 index d9e033f8..00000000 --- a/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -setup: - php ./configure.php - -.PHONY: setup diff --git a/README.md b/README.md index 853b9fe4..584df9f9 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,8 @@ - -# Create WordPress Plugin +# WP 404 Caching -This is a skeleton WordPress plugin that can scaffold a WordPress plugin. This -template includes a base plugin file, autoloaded PHP files, unit tests powered -by [Mantle](https://mantle.alley.com/), front-end assets compiled via Webpack, -and Continuous Integration [via GitHub Actions](.github/workflows). Actions are -configured to test the plugin and also build it for releases. A built tag -workflow will create `*-built` branches as well as a built release workflow that -will build and tag/release the plugin automatically. The built branches and -releases will include any compiled front-end assets (if using them). +Contributors: alleyinteractive -The plugin supports front-end assets which can be enqueued inside -`src/assets.php` or from within an entry points `index.php` file. For plugins -that don't require front-end assets, the configuration script below will prompt -you to delete the front-end files if you don't wish to use them. - -## Getting Started - -Follow these steps to get started: - -1. Press the "Use template" button at the top of this repo to create a new repo - with the contents of this skeleton. -2. Run `make` (or `php ./configure.php`) to run a script that will replace all - placeholders throughout all the files. -3. Have fun creating your plugin! 🎊 - - - -# Create WordPress Plugin - -Contributors: author_username - -Tags: vendor_name, create-wordpress-plugin +Tags: alleyinteractive, wp-404-caching Stable tag: 0.0.0 @@ -43,17 +14,17 @@ Requires PHP: 8.1 License: GPL v2 or later -[![Coding Standards](https://github.com/alleyinteractive/create-wordpress-plugin/actions/workflows/coding-standards.yml/badge.svg)](https://github.com/alleyinteractive/create-wordpress-plugin/actions/workflows/coding-standards.yml) -[![Testing Suite](https://github.com/alleyinteractive/create-wordpress-plugin/actions/workflows/unit-test.yml/badge.svg)](https://github.com/alleyinteractive/create-wordpress-plugin/actions/workflows/unit-test.yml) +[![Coding Standards](https://github.com/alleyinteractive/wp-404-caching/actions/workflows/coding-standards.yml/badge.svg)](https://github.com/alleyinteractive/wp-404-caching/actions/workflows/coding-standards.yml) +[![Testing Suite](https://github.com/alleyinteractive/wp-404-caching/actions/workflows/unit-test.yml/badge.svg)](https://github.com/alleyinteractive/wp-404-caching/actions/workflows/unit-test.yml) -A skeleton WordPress plugin. +Full Page Cache for WordPress 404s. ## Installation You can install the package via composer: ```bash -composer require alleyinteractive/create-wordpress-plugin +composer require alleyinteractive/wp-404-caching ``` ## Usage @@ -61,10 +32,10 @@ composer require alleyinteractive/create-wordpress-plugin Activate the plugin in WordPress and use it like so: ```php -$plugin = Create_WordPress_Plugin\Skeleton\Example_Plugin(); +$plugin = Alley\WP\WP_404_Caching\WP_404_Caching\WP_404_Caching(); $plugin->perform_magic(); ``` - + ## Testing Run `npm run test` to run Jest tests against JavaScript files. Run @@ -156,9 +127,9 @@ This project is actively maintained by [Alley Interactive](https://github.com/alleyinteractive). Like what you see? [Come work with us](https://alley.co/careers/). -- [author_name](https://github.com/author_name) +- [Alley](https://github.com/Alley) - [All Contributors](../../contributors) ## License -The GNU General Public License (GPL) license. Please see [License File](LICENSE) for more information. +The GNU General Public License (GPL) license. Please see [License File](LICENSE) for more information. \ No newline at end of file diff --git a/blocks/README.md b/blocks/README.md index e747f97c..156e07ca 100644 --- a/blocks/README.md +++ b/blocks/README.md @@ -10,7 +10,7 @@ Custom blocks in this directory can be created by running the `create-block` scr The `create-block` script will create the block files in a the block directory using the `slug` field entered from the prompts when scaffolding the block. -The script uses the [@alleyinteractive/create-block](https://github.com/alleyinteractive/alley-scripts/tree/main/packages/create-block) script with the `--namespace` flag for scaffolding block files with the plugin namespace of `create-wordpress-plugin`. See the `create-block` script in `package.json`. +The script uses the [@alleyinteractive/create-block](https://github.com/alleyinteractive/alley-scripts/tree/main/packages/create-block) script with the `--namespace` flag for scaffolding block files with the plugin namespace of `wp-404-caching`. See the `create-block` script in `package.json`. For **dynmanic blocks** the following files will be generated: @@ -30,4 +30,4 @@ The `index.php` contains the PHP block registration and will be autoloaded with Block attributes should be defined in the `block.json` file. [Learn more about block.json in the block editor handbook.](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/) -Running `npm run build` will compile the JavaScript and copy the PHP files to a directory in the `build` folder using `@wordpress/scripts`. The blocks will be enqueued via `block.json` after block registration. The block `index.php` file will be read by the `load_scripts()` function found in the `src/assets.php` file. +Running `npm run build` will compile the JavaScript and copy the PHP files to a directory in the `build` folder using `@wordpress/scripts`. The blocks will be enqueued via `block.json` after block registration. The block `index.php` file will be read by the `load_scripts()` function found in the `src/assets.php` file. \ No newline at end of file diff --git a/buddy.yml b/buddy.yml deleted file mode 100644 index ee5a0e06..00000000 --- a/buddy.yml +++ /dev/null @@ -1,174 +0,0 @@ -- pipeline: "Pull Request Tests" - trigger_mode: "ON_EVERY_PUSH" - ref_name: "refs/pull/*" - ref_type: "WILDCARD" - priority: "NORMAL" - target_site_url: "https://github.com/alleyinteractive/create-wordpress-plugin" - fetch_all_refs: true - fail_on_prepare_env_warning: true - trigger_condition: "ALWAYS" - actions: - - action: "Gitignored files check" - type: "BUILD" - working_directory: "/buddy/create-wordpress-plugin" - docker_image_name: "alleyops/ci-resources" - docker_image_tag: "8.2-fpm-wp" - execute_commands: - - "if [[ ! -z $(git ls-files -i --exclude-standard) ]]; then exit 1; fi" - volume_mappings: - - "/:/buddy/create-wordpress-plugin" - trigger_condition: "ALWAYS" - shell: "BASH" - run_next_parallel: true - - action: "Check for git conflicts" - type: "BUILD" - working_directory: "/buddy/create-wordpress-plugin" - docker_image_name: "alleyops/ci-resources" - docker_image_tag: "8.2-fpm-wp" - execute_commands: - - "! git grep -E '<<<<<<< |>>>>>>> ' -- './*' ':(exclude)buddy.yml' ':(exclude).buddy/*'" - volume_mappings: - - "/:/buddy/create-wordpress-plugin" - trigger_condition: "ALWAYS" - shell: "BASH" - - action: "Composer install" - type: "BUILD" - working_directory: "/buddy/create-wordpress-plugin" - docker_image_name: "alleyops/ci-resources" - docker_image_tag: "8.2-fpm-wp" - execute_commands: - - "composer install -q" - volume_mappings: - - "/:/buddy/create-wordpress-plugin" - trigger_condition: "ALWAYS" - shell: "BASH" - - action: "phpunit" - type: "BUILD" - working_directory: "/buddy/create-wordpress-plugin" - docker_image_name: "alleyops/ci-resources" - docker_image_tag: "8.2-fpm-wp" - execute_commands: - - "composer phpunit" - setup_commands: - - "echo \"extension=memcache.so\" >> /usr/local/etc/php/conf.d/buddy.ini" - services: - - type: "MYSQL" - version: "8.0" - connection: - host: "mysql" - port: 3306 - user: "root" - password: "root" - db: "wordpress_unit_tests" - - type: "MEMCACHED" - version: "1.6.21" - connection: - host: "memcached" - port: 11211 - volume_mappings: - - "/:/buddy/create-wordpress-plugin" - trigger_condition: "ALWAYS" - shell: "BASH" - run_next_parallel: true - - action: "composer phpcs" - type: "BUILD" - working_directory: "/buddy/create-wordpress-plugin" - docker_image_name: "alleyops/ci-resources" - docker_image_tag: "8.2-fpm-wp" - execute_commands: - - "composer phpcs" - volume_mappings: - - "/:/buddy/create-wordpress-plugin" - trigger_condition: "ALWAYS" - shell: "BASH" - - action: "npm audit" - type: "BUILD" - working_directory: "/buddy/create-wordpress-plugin" - docker_image_name: "library/node" - docker_image_tag: "16" - execute_commands: - - "npm audit --audit-level=high --production --cache /buddy/create-wordpress-plugin/.npm" - volume_mappings: - - "/:/buddy/create-wordpress-plugin" - trigger_condition: "ALWAYS" - shell: "BASH" - - action: "npm ci" - type: "BUILD" - working_directory: "/buddy/create-wordpress-plugin" - docker_image_name: "library/node" - docker_image_tag: "16" - execute_commands: - - "npm ci --cache /buddy/create-wordpress-plugin/.npm" - volume_mappings: - - "/:/buddy/create-wordpress-plugin" - trigger_condition: "ALWAYS" - shell: "BASH" - - action: "npm run lint" - type: "BUILD" - working_directory: "/buddy/create-wordpress-plugin" - docker_image_name: "library/node" - docker_image_tag: "16" - execute_commands: - - "npm run lint" - volume_mappings: - - "/:/buddy/create-wordpress-plugin" - trigger_condition: "ALWAYS" - shell: "BASH" - run_next_parallel: true - - action: "npm run stylelint" - type: "BUILD" - working_directory: "/buddy/create-wordpress-plugin" - docker_image_name: "library/node" - docker_image_tag: "16" - execute_commands: - - "npm run stylelint" - volume_mappings: - - "/:/buddy/create-wordpress-plugin" - trigger_condition: "ALWAYS" - shell: "BASH" - - action: "npm run test" - type: "BUILD" - working_directory: "/buddy/create-wordpress-plugin" - docker_image_name: "library/node" - docker_image_tag: "16" - execute_commands: - - "npm run test" - volume_mappings: - - "/:/buddy/create-wordpress-plugin" - trigger_condition: "ALWAYS" - shell: "BASH" - - action: "npm run build" - type: "BUILD" - working_directory: "/buddy/create-wordpress-plugin" - docker_image_name: "library/node" - docker_image_tag: "16" - execute_commands: - - "npm run build" - volume_mappings: - - "/:/buddy/create-wordpress-plugin" - trigger_condition: "ALWAYS" - shell: "BASH" - variables: - - key: "CACHEDIR" - value: "/tmp/test-cache" - type: "VAR" - description: "Cache folder for remote requests." - - key: "SKIP_DISCOVERY" - value: "true" - type: "VAR" - - key: "WP_CORE_DIR" - value: "/tmp/wordpress" - type: "VAR" - description: "WordPress checkout folder." - - key: "WP_VERSION" - value: "latest" - type: "VAR" - - key: "WP_DB_PASSWORD" - value: "root" - type: "VAR" - - key: "WP_DB_HOST" - value: "mysql" - type: "VAR" - - key: "WP_SKIP_DB_CREATE" - value: "true" - type: "VAR" diff --git a/composer.json b/composer.json index 56b9f681..cad0fe1f 100644 --- a/composer.json +++ b/composer.json @@ -1,17 +1,17 @@ { - "name": "alleyinteractive/create-wordpress-plugin", - "description": "A skeleton WordPress plugin", + "name": "alleyinteractive/wp-404-caching", + "description": "Full Page Cache for WordPress 404s", "type": "wordpress-plugin", "keywords": [ "alleyinteractive", - "create-wordpress-plugin" + "wp-404-caching" ], - "homepage": "https://github.com/alleyinteractive/create-wordpress-plugin", + "homepage": "https://github.com/alleyinteractive/wp-404-caching", "license": "GPL-2.0-or-later", "authors": [ { - "name": "author_name", - "email": "email@domain.com" + "name": "Alley", + "email": "info@alley.com" } ], "require": { @@ -34,16 +34,16 @@ }, "autoload-dev": { "psr-4": { - "Create_WordPress_Plugin\\Tests\\": "tests" + "Alley\WP\WP_404_Caching\\Tests\\": "tests" } }, "extra": { "wordpress-autoloader": { "autoload": { - "Create_WordPress_Plugin\\": "src" + "Alley\\WP\\WP_404_Caching": "src" }, "autoload-dev": { - "Create_WordPress_Plugin\\Tests\\": "tests" + "Alley\\WP\\WP_404_Caching\\Tests": "tests" } } }, diff --git a/configure.php b/configure.php deleted file mode 100644 index c845ab62..00000000 --- a/configure.php +++ /dev/null @@ -1,836 +0,0 @@ -#!/usr/bin/env php -] - * : The author name. - * - * [--author_email=] - * : The author email. - * - * phpcs:disable - */ - -namespace Create_WordPress_Plugin\Configure; - -if ( ! defined( 'STDIN' ) ) { - die( 'Not in CLI mode.' ); -} - -if ( 0 === strpos( strtoupper( PHP_OS ), 'WIN' ) ) { - die( 'Not supported in Windows. 🪟' ); -} - -if ( version_compare( PHP_VERSION, '8.1.0', '<' ) ) { - die( 'PHP 8.1.0 or greater is required.' ); -} - -// Parse the command line arguments from $argv. -$args = []; -$previous_key = null; - -foreach ( $argv as $value ) { - if ( str_starts_with( $value, '--' ) ) { - if ( false !== strpos( $value, '=' ) ) { - [ $arg, $value ] = explode( '=', substr( $value, 2 ), 2 ); - - $args[ $arg ] = trim( $value ); - - $previous_key = null; - } else { - $args[ substr( $value, 2 ) ] = true; - - $previous_key = substr( $value, 2 ); - } - } elseif ( ! empty( $previous_key ) ) { - $args[ $previous_key ] = trim( $value ); - } else { - $previous_key = trim( $value ); - } -} - -$terminal_width = (int) exec( 'tput cols' ); - -function write( string $text ): void { - global $terminal_width; - echo wordwrap( $text, $terminal_width - 1 ) . PHP_EOL; -} - -function ask( string $question, string $default = '', bool $allow_empty = true ): string { - while ( true ) { - write( $question . ( $default ? " [{$default}]" : '' ) . ': ' ); - $answer = readline( '> ' ); - - $value = $answer ?: $default; - - if ( ! $allow_empty && empty( $value ) ) { - echo "This value can't be empty." . PHP_EOL; - continue; - } - - return $value; - } -} - -function confirm( string $question, bool $default = false ): bool { - write( "{$question} (yes/no) [" . ( $default ? 'yes' : 'no' ) . ']: ' ); - - $answer = readline( '> ' ); - - if ( ! $answer ) { - return $default; - } - - return in_array( strtolower( trim( $answer ) ), [ 'y', 'yes', 'true', '1' ], true ); -} - -function run( string $command, string $dir = null ): string { - $command = $dir ? "cd {$dir} && {$command}" : $command; - - return trim( (string) shell_exec( $command ) ); -} - -function str_after( string $subject, string $search ): string { - $pos = strrpos( $subject, $search ); - - if ( $pos === false ) { - return $subject; - } - - return substr( $subject, $pos + strlen( $search ) ); -} - -function slugify( string $subject ): string { - return strtolower( trim( (string) preg_replace( '/[^A-Za-z0-9-]+/', '-', $subject ), '-' ) ); -} - -function title_case( string $subject ): string { - return ensure_capitalp( str_replace( ' ', '_', ucwords( str_replace( [ '-', '_' ], ' ', $subject ) ) ) ); -} - -function ensure_capitalp( string $text ): string { - return str_replace( 'Wordpress', 'WordPress', $text ); -} - -/** - * @param string $file - * @param array $replacements - */ -function replace_in_file( string $file, array $replacements ): void { - $contents = file_get_contents( $file ); - - if ( empty( $contents ) ) { - return; - } - - file_put_contents( - $file, - str_replace( - array_keys( $replacements ), - array_values( $replacements ), - $contents, - ) - ); -} - -function remove_readme_paragraphs( string $file ): void { - $contents = file_get_contents( $file ); - - if ( empty( $contents ) ) { - return; - } - - file_put_contents( - $file, - trim( (string) preg_replace( '/.*/s', '', $contents ) ?: $contents ), - ); -} - -function remove_composer_require(): void { - global $plugin_file; - - $contents = file_get_contents( $plugin_file ); - - if ( empty( $contents ) ) { - return; - } - - file_put_contents( - $plugin_file, - trim( (string) preg_replace( '/\n\/\* Start Composer Loader \*\/.*\/\* End Composer Loader \*\/\n/s', '', $contents ) ?: $contents ) . PHP_EOL, - ); - - echo "Removed Composer's vendor/autoload.php from {$plugin_file}" . PHP_EOL; -} - -function remove_composer_wrapper_comments(): void { - global $plugin_file; - - $contents = file_get_contents( $plugin_file ); - - if ( empty( $contents ) ) { - return; - } - - file_put_contents( - $plugin_file, - trim( preg_replace( '/\n\/\* (Start|End) Composer Loader \*\/\n/', '', $contents ) ?: $contents ) . PHP_EOL, - ); - - echo "Removed Composer's wrapper comments from {$plugin_file}" . PHP_EOL; -} - -function remove_composer_files(): void { - $file_list = [ - 'composer.json', - 'composer.lock', - 'vendor/', - ]; - - delete_files( $file_list ); - - write( sprintf( 'Removed %s files.', implode( ', ', $file_list ) ) ); -} - -function remove_project_files(): void { - $file_list = [ - '.buddy', - 'buddy.yml', - 'CHANGELOG.md', - '.deployignore', - '.editorconfig', - '.gitignore', - '.gitattributes', - '.github', - 'LICENSE', - ]; - - delete_files( $file_list ); - - write( sprintf( 'Removed %s files.', implode( ', ', $file_list ) ) ); -} - -function rollup_phpcs_to_parent( string $parent_file, string $local_file, string $plugin_name, string $plugin_domain ): void { - $config = ' - - PHP_CodeSniffer standard for ' . $plugin_name . ' - - - - - - - - - - - - - - - - - - -'; - - if ( file_put_contents( $local_file, $config ) ) { - delete_files( '.phpcs' ); - - echo "Updated {$local_file}.\n"; - } -} - -function remove_assets_readme( bool $keep_contents, string $file = 'README.md' ): void { - $contents = file_get_contents( $file ); - - if ( empty( $contents ) ) { - return; - } - - if ( $keep_contents ) { - $contents = str_replace( '', '', $contents ); - $contents = str_replace( '', '', $contents ); - - file_put_contents( $file, $contents ); - } else { - file_put_contents( - $file, - trim( (string) preg_replace( '/.*/s', '', $contents ) ?: $contents ), - ); - } -} - -function remove_assets_require(): void { - global $plugin_file; - - $contents = file_get_contents( $plugin_file ); - - if ( empty( $contents ) ) { - return; - } - - file_put_contents( - $plugin_file, - trim( (string) preg_replace( '/require_once __DIR__ \. \'\/src\/assets.php\';\\n/s', '', $contents ) ?: $contents ) . PHP_EOL, - ); -} - -function remove_assets_buddy( string $file = 'buddy.yml' ): void { - $contents = file_get_contents( $file ); - - if ( empty( $contents ) ) { - return; - } - - $contents = trim( preg_replace( '/(- action: "npm audit".*)variables:/s', 'variables:', $contents ) ?: $contents ); - $contents = str_replace( ' variables:', ' variables:', $contents ); - - file_put_contents( $file, $contents ); -} - -function determine_separator( string $path ): string { - return str_replace( '/', DIRECTORY_SEPARATOR, $path ); -} - -/** - * @return array - */ -function list_all_files_for_replacement(): array { - $exclude = [ - 'LICENSE', - 'configure.php', - '.phpunit.result.cache', - '.phpcs', - 'composer.lock', - ]; - - $exclude_dirs = [ - '.git', - 'pantheon-mu-plugin', - 'vendor', - 'node_modules', - '.phpcs', - '.scaffolder', - ]; - - $exclude = array_map( - fn ( string $file ) => "--exclude {$file}", - $exclude, - ); - - $exclude_dirs = array_map( - fn ( string $dir ) => "--exclude-dir {$dir}", - $exclude_dirs, - ); - - return explode( - PHP_EOL, - run( - "grep -R -l . " . implode( ' ', $exclude_dirs ) . ' ' . implode( ' ', $exclude ), - ), - ); -} - -/** - * @param string|array $paths - */ -function delete_files( string|array $paths ): void { - if ( ! is_array( $paths ) ) { - $paths = [ $paths ]; - } - - foreach ( $paths as $path ) { - $path = determine_separator( $path ); - - if ( is_dir( $path ) ) { - run( "rm -rf {$path}" ); - } elseif ( file_exists( $path ) ) { - @unlink( $path ); - } - } -} - -function remove_phpstan(): void { - delete_files( 'phpstan.neon' ); - - // Manually patch the Composer.json file. - if ( file_exists( 'composer.json' ) ) { - $composer_json = (array) json_decode( (string) file_get_contents( 'composer.json' ), true ); - - if ( isset( $composer_json['scripts']['phpstan'] ) ) { // @phpstan-ignore-line - unset( $composer_json['scripts']['phpstan'] ); // @phpstan-ignore-line - - $composer_json['scripts']['test'] = [ // @phpstan-ignore-line - '@phpcs', - '@phpunit', - ]; - - file_put_contents( 'composer.json', json_encode( $composer_json, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES ) ); - } - } -} - -function contributing_message( string $message ): void { - write( "\n{$message}\n" ); - echo "\t\e]8;;https://github.com/alleyinteractive/.github/blob/main/CONTRIBUTING.md#best-practices\e\\CONTRIBUTING.md\e]8;;\e\\\n\n"; -} - -function enable_sqlite_testing(): void { - if ( ! file_exists( __DIR__ . '/phpunit.xml' ) ) { - return; - } - - file_put_contents( - __DIR__ . '/phpunit.xml', - str_replace( - [ - '', - '', - ], - [ - '', - '', - ], - (string) file_get_contents( __DIR__ . '/phpunit.xml' ), - ), - ); - - if ( file_exists( __DIR__ . '/.github/workflows/unit-test.yml' ) ) { - file_put_contents( - __DIR__ . '/.github/workflows/unit-test.yml', - str_replace( - 'with:', - "with:\n database: ''", - (string) file_get_contents( __DIR__ . '/.github/workflows/unit-test.yml' ), - ), - ); - } -} - -// --------------------------------------------------------- -// Start of the script. Above this line are the functions. -// --------------------------------------------------------- - -echo "\nWelcome friend to alleyinteractive/create-wordpress-plugin! 😀\nLet's setup your WordPress Plugin 🚀\n\n"; - -// Always delete the 'merge-develop-to-scaffold.yml' file (this is never used in -// a scaffolded plugins). -delete_files( '.github/workflows/merge-develop-to-scaffold.yml' ); - -$current_dir = getcwd(); - -if ( ! $current_dir ) { - echo "Could not determine current directory.\n"; - exit( 1 ); -} - -$folder_name = ensure_capitalp( basename( $current_dir ) ); - -$author_email = ask( - question: 'Author email?', - default: (string) ( $args['author_email'] ?? run( 'git config user.email' ) ), - allow_empty: false, -); - -$username_guess = explode( ':', run( 'git config remote.origin.url' ) )[1] ?? ''; -$username_guess = dirname( $username_guess ); -$username_guess = basename( $username_guess ); -$author_username = ask( - question: 'Author username?', - default: $username_guess, - allow_empty: false, -); - -$author_name = ask( - question: 'Author name?', - default: (string) ( $args['author_name'] ?? run( 'git config user.name' ) ), - allow_empty: false, -); - -$vendor_name = ask( - question: 'Vendor name (usually the Github Organization)?', - default: $username_guess, - allow_empty: false, -); - -$vendor_slug = slugify( $vendor_name ); -$is_alley_plugin = 'alleyinteractive' === $vendor_slug; - -$plugin_name = ask( - question: 'Plugin name?', - default: (string) ( $args['plugin_name'] ?? str_replace( '_', ' ', title_case( $folder_name ) ) ), - allow_empty: false, -); - -while ( true ) { - $plugin_name_slug = slugify( ask( - question: 'Plugin slug?', - default: slugify( $plugin_name ), - allow_empty: false, - ) ); - - // Suggest a different plugin name if this is an Alley plugin. - if ( $is_alley_plugin && 0 !== strpos( $plugin_name_slug, 'wp-' ) ) { - $example_slug = "wp-{$plugin_name_slug}"; - - contributing_message( "Alley WordPress plugin slugs should be prefixed with \"wp-\". For example, {$example_slug} would be a great slug. If this plugin isn't meant to be published anywhere, this is fine to ignore. See our CONTRIBUTING.md for more details." ); - - if ( ! confirm( 'Do you wish to continue anyway?', false ) ) { - continue; - } - } - - break; -} - -while ( true ) { - $namespace = ask( - question: 'Plugin namespace?', - default: $is_alley_plugin ? 'Alley\\WP\\' . title_case( $plugin_name ) : title_case( $plugin_name ), - allow_empty: false, - ); - - // Check if the namespace is valid. - if ( ! preg_match( '/^[a-zA-Z0-9_\\\\]+$/', $namespace ) ) { - echo "Invalid namespace, please try again.\n"; - continue; - } - - // Offer to fix the namespace if this is an Alley plugin. - if ( $is_alley_plugin && 0 !== strpos( $namespace, 'Alley\\WP\\' ) ) { - $example_namespace = 'Alley\\WP\\' . title_case( $plugin_name ); - contributing_message( "Alley WordPress plugins should be prefixed with \"Alley\\WP\\\". A namespace such as \"{$example_namespace}\" would work well. If this plugin isn't meant to be published anywhere, this is fine to ignore. See our CONTRIBUTING.md for more details." ); - - if ( confirm( 'Do you wish to continue anyway?', false ) ) { - break; - } - } - - break; -} - -$class_name = ask( 'Base class name for plugin?', title_case( $plugin_name ) ); -$description = ask( 'Plugin description?', "This is my plugin {$plugin_name}" ); - -while ( true ) { - $plugin_file = ask( 'Main plugin file?', "{$plugin_name_slug}.php" ); - - // Validate that plugin file is a valid file name. - if ( ! preg_match( '/^[a-zA-Z0-9-_\.]+\.php$/', $plugin_file ) ) { - echo "Invalid plugin file name. Please try again.\n"; - continue; - } - - // Validate that plugin file does not already exist. - if ( file_exists( $plugin_file ) ) { - echo "Plugin file already exists. Please try again.\n"; - continue; - } - - break; -} - -write( '------' ); -write( "Plugin : {$plugin_name} <{$plugin_name_slug}>" ); -write( "Author : {$author_name} ({$author_email})" ); -write( "Vendor : {$vendor_name} ({$vendor_slug})" ); -write( "Description : {$description}" ); -write( "Namespace : {$namespace}" ); -write( "Main File : {$plugin_file}" ); -write( "Main Class : {$class_name}" ); -write( '------' ); - -write( 'This script will replace the above values in all relevant files in the project directory.' ); - -if ( ! confirm( 'Modify files?', true ) ) { - exit( 1 ); -} - -$search_and_replace = [ - 'author_name' => $author_name, - 'author_username' => $author_username, - 'email@domain.com' => $author_email, - - 'A skeleton WordPress plugin' => $description, - - // Escape the namespace used in composer.json. - '"Create_WordPress_Plugin\\"' => (string) json_encode( $namespace ), - '"Create_WordPress_Plugin\\Tests\\"' => (string) json_encode( $namespace . '\\Tests' ), - - 'Create_WordPress_Plugin' => $namespace, - 'Example_Plugin' => $class_name, - - 'create_wordpress_plugin' => str_replace( '-', '_', $plugin_name_slug ), - 'plugin_name' => $plugin_name, - - 'create-wordpress-plugin' => $plugin_name_slug, - 'Create WordPress Plugin' => $plugin_name, - - 'CREATE_WORDPRESS_PLUGIN' => strtoupper( str_replace( '-', '_', $plugin_name_slug ) ), - 'Skeleton' => $class_name, - 'vendor_name' => $vendor_name, - 'alleyinteractive' => $vendor_slug, - 'plugin.php' => $plugin_file, -]; - -// Patch the Composer.json namespace first before search and replace. -run( - 'composer config extra.wordpress-autoloader.autoload --json \'' . json_encode( [ - $namespace => 'src', - ] ) . '\'', -); - -run( - 'composer config extra.wordpress-autoloader.autoload-dev --json \'' . json_encode( [ - $namespace . '\\Tests' => 'tests', - ] ) . '\'', -); - -foreach ( list_all_files_for_replacement() as $path ) { - echo "Updating $path...\n"; - - replace_in_file( $path, $search_and_replace ); - - if ( str_contains( $path, determine_separator( 'src/class-example-plugin.php' ) ) ) { - rename( $path, determine_separator( './src/class-' . str_replace( '_', '-', strtolower( $class_name ) ) . '.php' ) ); - } - - if ( str_contains( $path, 'README.md' ) ) { - remove_readme_paragraphs( $path ); - } -} - -// Attempt to rename the main plugin file. -if ( 'plugin.php' !== $plugin_file ) { - rename( 'plugin.php', $plugin_file ); - - replace_in_file( './.github/workflows/upgrade-wordpress-plugin.yml', $search_and_replace ); - - echo "Renamed plugin.php to {$plugin_file}\n"; -} - -echo "Done!\n\n"; - -$needs_built_assets = false; -$uses_composer = false; - -if ( confirm( 'Will this plugin be compiling front-end assets (Node)?', true ) ) { - $needs_built_assets = true; - - if ( confirm( 'Do you want to run `npm install` and `npm run build`?', true ) ) { - echo run( 'npm install && npm run build' ); - echo "\n\n\n"; - } - - remove_assets_readme( true ); -} elseif ( confirm( 'Do you want to delete the front-end files? (Such as package.json, etc.)', true ) ) { - echo "Deleting...\n"; - - delete_files( - [ - '.github/workflows/node-tests.yml', - '.eslintignore', - '.eslintrc.json', - '.nvmrc', - '.stylelintrc.json', - 'babel.config.js', - 'jest.config.js', - 'jsconfig.json', - 'package.json', - 'package-lock.json', - 'tsconfig.json', - 'entries/', - 'blocks/', - 'build/', - 'bin/', - 'node_modules/', - 'scaffold', - 'src/assets.php', - ] - ); - - remove_assets_readme( false ); - remove_assets_require(); - remove_assets_buddy(); -} - -if ( confirm( 'Will this plugin be using Composer? (WordPress Composer Autoloader already included! phpcs and phpunit also rely on Composer being installed for testing.)', true ) ) { - $uses_composer = true; - $needs_built_assets = true; - - remove_composer_wrapper_comments(); - - if ( confirm( 'Do you want to run `composer install`?', true ) ) { - if ( file_exists( __DIR__ . '/composer.lock' ) ) { - echo run( 'composer update' ); - } else { - echo run( 'composer install' ); - } - - echo "\n\n"; - } -} elseif ( confirm( 'Do you want to remove the vendor/autoload.php dependency from your main plugin file and the composer.json file?' ) ) { - remove_composer_require(); - - // Prompt the user to delete the composer.json file. Plugins often still - // keep this around for development and Packagist. - if ( confirm( 'Do you want to delete the composer.json and composer.lock files? (This will prevent you from using PHPCS/PHPStan/Composer entirely).', false ) ) { - remove_composer_files(); - } -} - -if ( file_exists( 'composer.json') && ! confirm(' Using PHPStan? (PHPStan is a great static analyzer to help find bugs in your code.)', true) ) { - remove_phpstan(); -} - -$standalone = true; - -// Check if the plugin will be use standalone (as a single repository) or as a -// part of larger project (such as a wp-content-rooted project). Assumes that -// the parent project is located at /wp-content/ and this plugin is located at -// /wp-content/plugins/:plugin/. -if ( - file_exists( '../../.git/index' ) - && ! confirm( - 'Will this be a standalone plugin, not located within a larger project? For example, a standalone plugin will have a separate repository and will be distributed independently.', - false, - ) -) { - $standalone = false; - - $needs_built_assets = false; - - if ( confirm( 'Do you want to remove project-based files, such as GitHub actions? (If this is a standalone plugin, these are probably in the root directory.)', true ) ) { - remove_project_files(); - } - - // Offer to roll up this plugin's dependencies to the parent project's composer. - if ( $uses_composer && file_exists( '../../composer.json' ) ) { - $parent_composer = (string) realpath( '../../composer.json' ); - $parent_folder = dirname( $parent_composer ); - - if ( confirm( "Do you want to rollup the plugin's Composer dependencies to the parent project's composer.json file ({$parent_composer})? This will copy this plugin's dependencies to the parent project and delete the local composer.json file.", true ) ) { - $composer = (array) json_decode( (string) file_get_contents( $parent_composer ), true ); - $plugin_composer = (array) json_decode( (string) file_get_contents( 'composer.json' ), true ); - - $original = $composer; - - $composer['require'] = array_merge( - (array) ( $composer['require'] ?? [] ), - (array) ( $plugin_composer['require'] ?? [] ), - ); - - $composer['require-dev'] = array_merge( - (array) ( $composer['require-dev'] ?? [] ), - (array) ( $plugin_composer['require-dev'] ?? [] ), - ); - - $composer['config']['allow-plugins']['alleyinteractive/composer-wordpress-autoloader'] = true; - - ksort( $composer['require'] ); - ksort( $composer['require-dev'] ); - ksort( $composer['config']['allow-plugins'] ); - - if ( $composer !== $original ) { - file_put_contents( $parent_composer, json_encode( $composer, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES ) ); - echo "Updated {$parent_composer} with the plugin's composer dependencies.\n"; - - remove_composer_require(); - remove_composer_files(); - - echo "\n\n"; - - if ( confirm( "Do you want to run `composer update` in {$parent_folder}?", true ) ) { - echo run( 'composer update', $parent_folder ); - echo "\n\n"; - } - } - - $parent_files = [ - $parent_folder . '/phpcs.xml', - $parent_folder . '/phpcs.xml.dist', - $parent_folder . '/.phpcs.xml', - ]; - - if ( file_exists( __DIR__ . '/.phpcs.xml' ) ) { - foreach ( $parent_files as $parent_file ) { - if ( ! file_exists( $parent_file ) ) { - continue; - } - - if ( confirm( "Do you want to roll up the phpcs configuration to the parent? (This will change the plugin's phpcs configuration to inherit the parent configuration from {$parent_file}.)" ) ) { - rollup_phpcs_to_parent( - parent_file: '../../' . basename( $parent_file ), - local_file: __DIR__ . '/.phpcs.xml', - plugin_name: $plugin_name, - plugin_domain: $plugin_name_slug, - ); - - break; - } - } - } - } - } - - if ( confirm( 'Do you want to remove the git repository for the plugin?', true ) ) { - delete_files( '.git' ); - } -} - -if ( $standalone && confirm( 'Do you want to use SQLite for unit testing? (This is a great way to speed up your tests!)', true ) ) { - enable_sqlite_testing(); -} - -// Offer to delete the built asset workflows if built assets aren't needed. -if ( ! $needs_built_assets && file_exists( '.github/workflows/built-release.yml' ) && confirm( 'Delete the Github actions for built assets?', true ) ) { - delete_files( - [ - '.github/workflows/built-branch.yml', - '.github/workflows/built-release.yml', - ] - ); -} - -if ( - $standalone && file_exists( __DIR__ . '/buddy.yml' ) && ! confirm( 'Do you need the Buddy CI configuration? (Alley devs only -- if the plugin is open-source it will not be needed)', false ) -) { - delete_files( [ '.buddy', 'buddy.yml' ] ); -} - -if ( confirm( 'Let this script delete itself?', true ) ) { - delete_files( - [ - 'Makefile', - __FILE__, - ] - ); -} - -echo "\n\nWe're done! 🎉\n\n"; - -// Offer some information about built releases if the workflow still exists. -if ( file_exists( '.github/workflows/built-release.yml' ) ) { - echo << - - + + diff --git a/scaffold/config.json b/scaffold/config.json index 0e5a9002..da6d9e91 100644 --- a/scaffold/config.json +++ b/scaffold/config.json @@ -1,7 +1,7 @@ { "core_term_meta": true, - "domain": "create-wordpress-plugin", + "domain": "wp-404-caching", "folder": "src", - "namespace": "Create_WordPress_Plugin", + "namespace": "Alley\WP\WP_404_Caching", "require_path": "__DIR__" } diff --git a/src/assets.php b/src/assets.php index f544dbcb..f7f09a8a 100644 --- a/src/assets.php +++ b/src/assets.php @@ -4,10 +4,10 @@ * * phpcs:disable phpcs:ignore Squiz.PHP.CommentedOutCode.Found * - * @package create-wordpress-plugin + * @package wp-404-caching */ -namespace Create_WordPress_Plugin; +namespace Alley\WP\WP_404_Caching; /** * Validate file paths to prevent a PHP error if a file doesn't exist. @@ -31,7 +31,7 @@ function get_entry_dir_path( string $dir_entry_name, bool $dir = false ): string // The relative path from the plugin root. $asset_build_dir = "/build/{$dir_entry_name}/"; // Set the absolute file path from the root directory. - $asset_dir_path = CREATE_WORDPRESS_PLUGIN_DIR . $asset_build_dir; + $asset_dir_path = WP_404_CACHING_DIR . $asset_build_dir; if ( validate_path( $asset_dir_path ) ) { // Negotiate the base path. @@ -115,7 +115,7 @@ function get_entry_asset_url( string $dir_entry_name, $filename = 'index.js' ) { * Load the php index files from the build directory for blocks, slotfills, and any other scripts with an index.php file. */ function load_scripts(): void { - $files = glob( CREATE_WORDPRESS_PLUGIN_DIR . '/build/**/index.php' ); + $files = glob( WP_404_CACHING_DIR . '/build/**/index.php' ); if ( ! empty( $files ) ) { foreach ( $files as $path ) { diff --git a/src/class-example-plugin.php b/src/class-example-plugin.php deleted file mode 100644 index 198311ca..00000000 --- a/src/class-example-plugin.php +++ /dev/null @@ -1,15 +0,0 @@ - [ 'lyrics' => $lyrics ], + 'Alley\WP\WP_404_Caching\Features\Hello' => [ 'lyrics' => $lyrics ], ]; Feature_Manager::add_features( $features ); @@ -34,16 +34,16 @@ Feature_Manager::add_features( $features ); > 💡 If you `apply_filters` to the features array before passing it to `add_features`, you can modify it with a filter. ``` -$features = apply_filters( 'create_wordpress_plugin_features', $features ); +$features = apply_filters( 'wp_404_caching_features', $features ); ``` ### Add a feature using the `add_feature` method ``` -Feature_Manager::add_feature( 'Create_WordPress_Plugin\Features\Hello', [ 'lyrics' => $lyrics ] ); +Feature_Manager::add_feature( 'Alley\WP\WP_404_Caching\Features\Hello', [ 'lyrics' => $lyrics ] ); ``` ## Get the instance of an added feature with the `get_feature` method ``` -$hello_feature = Feature_Manager::get_feature( 'Create_WordPress_Plugin\Features\Hello' ); +$hello_feature = Feature_Manager::get_feature( 'Alley\WP\WP_404_Caching\Features\Hello' ); ``` ## Once we have the instance, we can remove hooks from inside the instance ``` @@ -57,10 +57,10 @@ This is a port of the infamous WordPress `hello.php` plugin to a feature. The ly /** * Feature implementation of hello.php * - * @package Create_WordPress_Plugin + * @package Alley\WP\WP_404_Caching */ -namespace Create_WordPress_Plugin\Features; +namespace Alley\WP\WP_404_Caching\Features; use Alley\WP\Types\Feature; diff --git a/src/meta.php b/src/meta.php index a49d51a9..fe94010e 100644 --- a/src/meta.php +++ b/src/meta.php @@ -2,10 +2,10 @@ /** * Contains functions for working with meta. * - * @package create-wordpress-plugin + * @package wp-404-caching */ -namespace Create_WordPress_Plugin; +namespace Alley\WP\WP_404_Caching; // Register custom meta fields. register_post_meta_from_defs(); @@ -36,7 +36,7 @@ function register_meta_helper( throw new \InvalidArgumentException( esc_html__( 'Object type must be one of "post", "term".', - 'create-wordpress-plugin' + 'wp-404-caching' ) ); } @@ -72,7 +72,7 @@ function register_meta_helper( * @param string $meta_key The meta key to register. */ $args = apply_filters( - 'create_wordpress_plugin_register_meta_helper_args', // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound + 'wp_404_caching_register_meta_helper_args', // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound wp_parse_args( $args, [ diff --git a/tests/Feature/ExampleFeatureTest.php b/tests/Feature/ExampleFeatureTest.php index aaad99db..708b12d3 100644 --- a/tests/Feature/ExampleFeatureTest.php +++ b/tests/Feature/ExampleFeatureTest.php @@ -1,13 +1,13 @@ maybe_rsync_plugin() // Load the main file of the plugin. - ->loaded( fn () => require_once __DIR__ . '/../plugin.php' ) + ->loaded( fn () => require_once __DIR__ . '/../wp-404-caching.php' ) ->install(); diff --git a/plugin.php b/wp-404-caching.php similarity index 62% rename from plugin.php rename to wp-404-caching.php index 11793e97..107a5f8a 100644 --- a/plugin.php +++ b/wp-404-caching.php @@ -1,21 +1,21 @@
-

+