diff --git a/composer.json b/composer.json index 0c7f077..829da74 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "johnbillion/wp-hooks-generator", + "name": "wp-hooks/generator", "description": "Generates a JSON representation of the WordPress actions and filters in your code", "type": "library", "license": "GPL-3.0-or-later", @@ -21,10 +21,20 @@ ], "require": { "php": ">=7", + "ext-libxml": "*", "johnbillion/wp-parser-lib": "^1.3.0" }, "require-dev": { "oomphinc/composer-installers-extender": "^2", "opis/json-schema": "^1" + }, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/johnbillion" + } + ], + "replace": { + "johnbillion/wp-hooks-generator": "*" } } diff --git a/interface/index.d.ts b/interface/index.d.ts index 2ce8a58..6a8b962 100644 --- a/interface/index.d.ts +++ b/interface/index.d.ts @@ -32,6 +32,10 @@ export interface Hook { * The hook name */ name: string; + /** + * Aliases of the hook name + */ + aliases?: string[]; /** * The relative name of the file containing the hook */ diff --git a/package-lock.json b/package-lock.json index 7634e51..3cd76a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { - "name": "@johnbillion/wp-hooks-generator", - "version": "0.7.3", + "name": "wp-hooks/generator", + "version": "0.9.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index c43a070..ad6eb0d 100644 --- a/package.json +++ b/package.json @@ -1,16 +1,16 @@ { "name": "@johnbillion/wp-hooks-generator", - "version": "0.7.3", - "description": "Scans the WordPress actions and filters in your code and saves them as JSON.", + "version": "0.9.0", + "description": "Generates a JSON representation of the WordPress actions and filters in your code", "private": true, "repository": { "type": "git", - "url": "git+https://github.com/johnbillion/wp-hooks-generator.git" + "url": "git+https://github.com/wp-hooks/generator.git" }, "author": "John Blackbourn", "license": "GPL-3.0-or-later", "bugs": { - "url": "https://github.com/johnbillion/wp-hooks-generator/issues" + "url": "https://github.com/wp-hooks/generator/issues" }, "dependencies": { "json-schema-to-typescript": "^7.1" @@ -18,5 +18,5 @@ "scripts": { "generate-interfaces": "json2ts --input schema.json --output=interface/index.d.ts" }, - "homepage": "https://github.com/johnbillion/wp-hooks-generator#readme" + "homepage": "https://github.com/wp-hooks/generator#readme" } diff --git a/readme.md b/readme.md index 37a78bd..4e65d53 100644 --- a/readme.md +++ b/readme.md @@ -1,25 +1,29 @@ -# wp-hooks-generator +# WP Hooks Generator Generates a JSON representation of the WordPress actions and filters in your code. Can be used with WordPress plugins, themes, and core. Note: If you just want the hook files without generating them yourself, use the following packages instead: -* [johnbillion/wp-hooks](https://github.com/johnbillion/wp-hooks) for WordPress core +* [wp-hooks/wordpress-core](https://github.com/wp-hooks/wordpress-core) for WordPress core ## Installation - composer require johnbillion/wp-hooks-generator +```shell +composer require wp-hooks/generator +``` ## Generating the Hook Files - ./bin/wp-hooks-generator --input=src --output=hooks +```shell +./bin/wp-hooks-generator --input=src --output=hooks +``` ## Usage of the Generated Hook Files in PHP ```php // Get hooks as JSON: -$actions_json = file_get_contents( 'hook/actions.json' ); -$filters_json = file_get_contents( 'hook/filters.json' ); +$actions_json = file_get_contents( 'hooks/actions.json' ); +$filters_json = file_get_contents( 'hooks/filters.json' ); // Convert hooks to PHP: $actions = json_decode( $actions_json, true )['hooks']; diff --git a/schema.json b/schema.json index c892a3a..da0abed 100644 --- a/schema.json +++ b/schema.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "https://github.com/johnbillion/wp-hooks-generator/blob/0.7.3/schema.json", + "$id": "https://github.com/wp-hooks/generator/blob/0.9.0/schema.json", "title": "HooksContainer", "description": "The container for the list of hooks", "type": "object", @@ -41,6 +41,13 @@ "init" ] }, + "aliases": { + "description": "Aliases of the hook name", + "type": "array", + "items": { + "type": "string" + } + }, "file": { "description": "The relative name of the file containing the hook", "type": "string", diff --git a/src/generate.php b/src/generate.php index ab4b4a3..75f7805 100755 --- a/src/generate.php +++ b/src/generate.php @@ -4,7 +4,9 @@ namespace JohnBillion\WPHooksGenerator; -require_once 'vendor/autoload.php'; +use DOMDocument; + +require_once file_exists( 'vendor/autoload.php' ) ? 'vendor/autoload.php' : dirname( __DIR__, 4 ) . '/vendor/autoload.php'; $options = getopt( '', [ "input:", @@ -103,12 +105,22 @@ function hooks_parse_files( array $files, string $root, array $ignore_hooks ) : $output = array(); foreach ( $files as $filename ) { + if ( !is_readable( $filename ) ) { + continue; + } $file = new \WP_Parser\File_Reflector( $filename ); $file_hooks = []; $path = ltrim( substr( $filename, strlen( $root ) ), DIRECTORY_SEPARATOR ); $file->setFilename( $path ); + // should throw things, but for some reason returns errors instead, so we just collect them manually + ob_start(); $file->process(); + $processing_errors = ob_get_clean(); + if ( !empty( $processing_errors ) ) { + fwrite( STDERR, $filename . PHP_EOL ); + fwrite( STDERR, $processing_errors . PHP_EOL ); + } if ( ! empty( $file->uses['hooks'] ) ) { $file_hooks = array_merge( $file_hooks, export_hooks( $file->uses['hooks'], $path ) ); @@ -267,12 +279,7 @@ function( array $matches ) : string { foreach ( $docblock->getTags() as $i => $tag ) { $content = ''; - if ( method_exists( $tag, 'getVersion' ) ) { - $version = $tag->getVersion(); - if ( ! empty( $version ) ) { - $content = $version; - } - } else { + if ( ! method_exists( $tag, 'getVersion' ) ) { $content = $tag->getDescription(); $content = \WP_Parser\format_description( preg_replace( '#\n\s+#', ' ', $content ) ); } @@ -287,18 +294,52 @@ function( array $matches ) : string { $doc['long_description'] = ''; } - $out[] = array( - 'name' => $hook->getName(), - 'file' => $path, - 'type' => $hook->getType(), - 'doc' => $doc, - 'args' => count( $hook->getNode()->args ) - 1, - ); + $aliases = parse_aliases( $doc['long_description_html'] ); + + $result = []; + + $result['name'] = $hook->getName(); + + if ( $aliases ) { + $result['aliases'] = $aliases; + } + + $result['file'] = $path; + $result['type'] = $hook->getType(); + $result['doc'] = $doc; + $result['args'] = count( $hook->getNode()->args ) - 1; + + $out[] = $result; } return $out; } +/** + * @return array + */ +function parse_aliases( string $html ) : array { + if ( false === strpos( $html, 'Possible hook names include' ) ) { + return []; + } + + $aliases = []; + + $html = explode( 'Possible hook names include', $html, 2 ); + $html = explode( '', end( $html ) ); + + $dom = new DOMDocument(); + $dom->loadHTML( reset( $html ) ); + + foreach ( $dom->getElementsByTagName( 'li' ) as $li ) { + $aliases[] = $li->nodeValue; + } + + sort( $aliases ); + + return $aliases; +} + $output = hooks_parse_files( $files, $source_dir, $ignore_hooks ); // Actions @@ -307,7 +348,7 @@ function( array $matches ) : string { } ) ); $actions = [ - '$schema' => 'https://raw.githubusercontent.com/johnbillion/wp-hooks-generator/0.7.3/schema.json', + '$schema' => 'https://raw.githubusercontent.com/wp-hooks/generator/0.9.0/schema.json', 'hooks' => $actions, ]; @@ -319,7 +360,7 @@ function( array $matches ) : string { } ) ); $filters = [ - '$schema' => 'https://raw.githubusercontent.com/johnbillion/wp-hooks-generator/0.7.3/schema.json', + '$schema' => 'https://raw.githubusercontent.com/wp-hooks/generator/0.9.0/schema.json', 'hooks' => $filters, ]; diff --git a/src/validate.php b/src/validate.php index 809ee4a..47e0243 100755 --- a/src/validate.php +++ b/src/validate.php @@ -3,7 +3,7 @@ namespace JohnBillion\WPHooksGenerator; -require_once 'vendor/autoload.php'; +require_once file_exists( 'vendor/autoload.php' ) ? 'vendor/autoload.php' : dirname( __DIR__, 4 ) . '/vendor/autoload.php'; use Opis\JsonSchema\{ Validator, ValidationResult, ValidationError, Schema