├── .gitattributes ├── .editorconfig ├── .github └── workflows │ ├── test.yml │ ├── stable.yml │ └── release.yml ├── src ├── Helper │ └── AnnotationTest.php ├── HookAnnotations.php ├── Helper.php ├── Hooks.php └── HookTrait.php ├── bin ├── dump-hooks └── dump-hooks.php ├── composer.json ├── CHANGELOG.md ├── LICENSE ├── phpcs.xml ├── .gitignore ├── README.md └── composer.lock /.gitattributes: -------------------------------------------------------------------------------- 1 | * text eol=lf 2 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | trim_trailing_whitespace = true 8 | indent_style = tab 9 | 10 | [{*.txt,wp-config-sample.php}] 11 | end_of_line = crlf 12 | 13 | [*.yml] 14 | indent_style = space 15 | indent_size = 2 16 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: ['pull_request', 'push'] 4 | 5 | jobs: 6 | phpcs: 7 | name: WordPress Coding Standards 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Checkout 11 | uses: actions/checkout@v2 12 | - name: Install dependencies 13 | run: composer install --no-progress 14 | - name: Coding Standards 15 | run: composer phpcs 16 | -------------------------------------------------------------------------------- /src/Helper/AnnotationTest.php: -------------------------------------------------------------------------------- 1 | = 2 ? $_SERVER['argv'][1] : null; 12 | 13 | if ( $output_file ) { 14 | $output_file = realpath( __DIR__ . '../../../../../' . $output_file ); 15 | } 16 | 17 | echo shell_exec( "wp eval-file {$file} {$output_file}" ); 18 | -------------------------------------------------------------------------------- /src/HookAnnotations.php: -------------------------------------------------------------------------------- 1 | changelog.txt 22 | truncate -s-3 changelog.txt 23 | sed -i '1d' changelog.txt 24 | - name: Release 25 | uses: softprops/action-gh-release@v1 26 | with: 27 | body_path: changelog.txt 28 | env: 29 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 30 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "micropackage/dochooks", 3 | "description": "DocHooks - annotated WordPress hooks", 4 | "license": "GPL-3.0-or-later", 5 | "authors": [ 6 | { 7 | "name": "Jakub Mikita", 8 | "email": "jakub@bracketspace.com" 9 | } 10 | ], 11 | "scripts": { 12 | "phpcs": "phpcs", 13 | "phpcbf": "phpcbf" 14 | }, 15 | "require": { 16 | "php": ">=5.6", 17 | "micropackage/singleton": "^1.1" 18 | }, 19 | "require-dev": { 20 | "dealerdirect/phpcodesniffer-composer-installer": "^0.7", 21 | "phpcompatibility/php-compatibility": "^9.3", 22 | "wp-coding-standards/wpcs": "^2.3" 23 | }, 24 | "autoload": { 25 | "psr-4" : { 26 | "Micropackage\\DocHooks\\" : "src" 27 | } 28 | }, 29 | "bin": ["bin/dump-hooks"], 30 | "config": { 31 | "allow-plugins": { 32 | "dealerdirect/phpcodesniffer-composer-installer": true 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | ## 1.1.4 5 | 6 | ### Changed: 7 | - Upgraded dependencies 8 | 9 | ## 1.1.3 10 | 11 | ### Changed: 12 | - License from GPL to MIT 13 | 14 | ## 1.1.2 15 | 16 | ### Changed 17 | - Regex pattern to match hook name containing any character, except space 18 | 19 | ## 1.1.1 20 | 21 | ### Fixed 22 | - Invalid context for objects hooked using Helper 23 | - Missing objects for dumped hooks 24 | 25 | ## 1.1.0 26 | 27 | ### Added 28 | - Central Hooks class storing hooked objects 29 | - `dump-hooks` binary 30 | 31 | ## 1.0.2 32 | 33 | ### Added 34 | - HookTrait Trait 35 | 36 | ### Changed 37 | - HookAnnotations now uses HookTrait 38 | 39 | ## 1.0.1 40 | 41 | ### Fixed 42 | - AnnotationTest class giving a fatal error because of a wrong file name, issue #1 43 | 44 | ## 1.0.0 45 | 46 | Initial release 47 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Micropackage 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/Helper.php: -------------------------------------------------------------------------------- 1 | getMethods() as $method ) { 27 | $doc = $method->getDocComment(); 28 | return (bool) strpos( $doc, '@action' ); 29 | } 30 | } 31 | 32 | /** 33 | * Hooks object methods. 34 | * 35 | * @since 1.0.0 36 | * @param mixed $object The class object or null. 37 | * @return mixed Subject object. 38 | */ 39 | public static function hook( $object ) { 40 | $dochooks = new HookAnnotations(); 41 | return $dochooks->add_hooks( $object ); 42 | } 43 | 44 | /** 45 | * Loads dumped hooks. 46 | * 47 | * @param string $file File with hooks. 48 | * @return void 49 | */ 50 | public static function load_hooks( $file ) { 51 | Hooks::get()->load_hooks( $file ); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | new_version: 7 | description: 'New version' 8 | required: true 9 | 10 | jobs: 11 | release: 12 | name: Release 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Checkout master 16 | uses: actions/checkout@v1 17 | with: 18 | ref: 'master' 19 | - name: Checkout develop 20 | uses: actions/checkout@v1 21 | with: 22 | ref: 'develop' 23 | clean: false 24 | - name: Install git-flow 25 | run: sudo apt-get install git-flow -y 26 | - name: Configure commiter 27 | run: | 28 | git config --local user.email "${{ secrets.WORKER_EMAIL }}" 29 | git config --local user.name "${{ secrets.WORKER_NAME }}" 30 | - name: Init git-flow 31 | run: git flow init -d 32 | - name: Start release 33 | run: git flow release start ${{ github.event.inputs.new_version }} 34 | - name: Replace 1.1.2 tags with new version number 35 | uses: jacobtomlinson/gha-find-replace@master 36 | with: 37 | find: "(?i)\\[Next\\]" 38 | replace: "${{ github.event.inputs.new_version }}" 39 | - name: Commit version bump 40 | run: git commit -am "Version bump" --allow-empty 41 | - name: Finish release 42 | run: git flow release finish ${{ github.event.inputs.new_version }} -m "v${{ github.event.inputs.new_version }}" 43 | - name: Push develop and tags 44 | uses: ad-m/github-push-action@master 45 | with: 46 | github_token: ${{ secrets.WORKER_TOKEN }} 47 | branch: 'develop' 48 | - name: Push master 49 | uses: ad-m/github-push-action@master 50 | with: 51 | github_token: ${{ secrets.WORKER_TOKEN }} 52 | branch: 'master' 53 | -------------------------------------------------------------------------------- /bin/dump-hooks.php: -------------------------------------------------------------------------------- 1 | get_hooked_objects(); 23 | 24 | $hook_functions = []; 25 | 26 | // Loop over each class who added own hooks. 27 | foreach ( $objects as $class_name => $data ) { 28 | $count = 0; 29 | 30 | $callback_object_name = '$this->objects[\'' . $class_name . '\'][\'instance\']'; 31 | 32 | foreach ( $data['hooks'] as $hook ) { 33 | $hook_functions[] = sprintf( 34 | "add_%s( '%s', [ %s, '%s' ], %d, %d );", 35 | $hook['type'], 36 | $hook['name'], 37 | $callback_object_name, 38 | $hook['callback'], 39 | $hook['priority'], 40 | $hook['arg_count'] 41 | ); 42 | 43 | $count++; 44 | } 45 | 46 | WP_CLI::log( "{$class_name} added {$count} hooks" ); 47 | } 48 | 49 | // // Clear the hooks file. 50 | // $hooks_file = EW_DIR_PATH . '/src/inc/hooks.php'; 51 | 52 | if ( file_exists( $hooks_file ) ) { 53 | unlink( $hooks_file ); 54 | } 55 | 56 | $hook_functions = implode( "\n", $hook_functions ); 57 | 58 | // Save the content. 59 | $file_content = << 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | . 37 | 38 | 39 | 40 | 41 | tests/* 42 | vendor/* 43 | 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### Project ### 2 | *.log 3 | /vendor/ 4 | 5 | ### Windows ### 6 | # Windows image file caches 7 | Thumbs.db 8 | ehthumbs.db 9 | 10 | # Folder config file 11 | Desktop.ini 12 | 13 | # Recycle Bin used on file shares 14 | $RECYCLE.BIN/ 15 | 16 | # Windows Installer files 17 | *.cab 18 | *.msi 19 | *.msm 20 | *.msp 21 | 22 | # Windows shortcuts 23 | *.lnk 24 | 25 | 26 | ### macOS ### 27 | *.DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Icon must end with two \r 32 | Icon 33 | 34 | 35 | # Thumbnails 36 | ._* 37 | 38 | # Files that might appear in the root of a volume 39 | .DocumentRevisions-V100 40 | .fseventsd 41 | .Spotlight-V100 42 | .TemporaryItems 43 | .Trashes 44 | .VolumeIcon.icns 45 | .com.apple.timemachine.donotpresent 46 | 47 | # Directories potentially created on remote AFP share 48 | .AppleDB 49 | .AppleDesktop 50 | Network Trash Folder 51 | Temporary Items 52 | .apdisk 53 | 54 | 55 | ### Sass ### 56 | .sass-cache/ 57 | *.css.map 58 | 59 | 60 | ### SublimeText ### 61 | # cache files for sublime text 62 | *.tmlanguage.cache 63 | *.tmPreferences.cache 64 | *.stTheme.cache 65 | 66 | # workspace files are user-specific 67 | *.sublime-workspace 68 | .vscode 69 | 70 | # project files should be checked into the repository, unless a significant 71 | # proportion of contributors will probably not be using SublimeText 72 | # *.sublime-project 73 | 74 | # sftp configuration file 75 | sftp-config.json 76 | 77 | # postcss sorting config file 78 | settings.json 79 | 80 | # Package control specific files 81 | Package Control.last-run 82 | Package Control.ca-list 83 | Package Control.ca-bundle 84 | Package Control.system-ca-bundle 85 | Package Control.cache/ 86 | Package Control.ca-certs/ 87 | bh_unicode_properties.cache 88 | 89 | # Sublime-github package stores a github token in this file 90 | # https://packagecontrol.io/packages/sublime-github 91 | GitHub.sublime-settings 92 | 93 | 94 | ### Vim ### 95 | # swap 96 | [._]*.s[a-w][a-z] 97 | [._]s[a-w][a-z] 98 | # session 99 | Session.vim 100 | # temporary 101 | .netrwhist 102 | *~ 103 | # auto-generated tag files 104 | tags 105 | -------------------------------------------------------------------------------- /src/Hooks.php: -------------------------------------------------------------------------------- 1 | objects[ $class_name ] ) ) { 35 | $this->objects[ $class_name ] = [ 36 | 'instance' => $object, 37 | 'hooks' => [], 38 | ]; 39 | } 40 | } 41 | 42 | /** 43 | * Checks if given object already has been added. 44 | * 45 | * @param object $object Object to check. 46 | * @return boolean `True` if object has been added, `false` otherwise. 47 | */ 48 | public function has_object( $object ) { 49 | $class_name = get_class( $object ); 50 | 51 | return isset( $this->objects[ $class_name ] ); 52 | } 53 | 54 | /** 55 | * Adds hook. 56 | * 57 | * @param object $object Object. 58 | * @param array $data Hook data. 59 | * @return void 60 | */ 61 | public function add_hook( $object, $data ) { 62 | $class_name = get_class( $object ); 63 | 64 | if ( ! isset( $this->objects[ $class_name ] ) ) { 65 | $this->add_object( $object ); 66 | } 67 | 68 | $this->objects[ $class_name ]['hooks'][] = $data; 69 | } 70 | 71 | /** 72 | * Gets hooked objects. 73 | * 74 | * @return array 75 | */ 76 | public function get_hooked_objects() { 77 | return $this->objects; 78 | } 79 | 80 | /** 81 | * Returns hooks registered for given object. 82 | * 83 | * @since 1.1.0 84 | * @param object $object Object to get the hooks for. 85 | * @return array Hooks registered for given object. 86 | */ 87 | public function get_hooks_for_object( $object ) { 88 | $class_name = get_class( $object ); 89 | 90 | return isset( $this->objects[ $class_name ] ) ? $this->objects[ $class_name ] : []; 91 | } 92 | 93 | /** 94 | * Loads dumped hooks.. 95 | * 96 | * @param string $file File with hooks. 97 | * @return void 98 | */ 99 | public function load_hooks( $file ) { 100 | if ( file_exists( $file ) ) { 101 | include_once $file; 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DocHooks 2 | 3 | [![BracketSpace Micropackage](https://img.shields.io/badge/BracketSpace-Micropackage-brightgreen)](https://bracketspace.com) 4 | [![Latest Stable Version](https://poser.pugx.org/micropackage/dochooks/v/stable)](https://packagist.org/packages/micropackage/dochooks) 5 | [![PHP from Packagist](https://img.shields.io/packagist/php-v/micropackage/dochooks.svg)](https://packagist.org/packages/micropackage/dochooks) 6 | [![Total Downloads](https://poser.pugx.org/micropackage/dochooks/downloads)](https://packagist.org/packages/micropackage/dochooks) 7 | [![License](https://poser.pugx.org/micropackage/dochooks/license)](https://packagist.org/packages/micropackage/dochooks) 8 | 9 |

10 | Micropackage logo 11 |

12 | 13 | ## 🧬 About DocHooks 14 | 15 | The Laravel or Symfony projects are using method annotations for various things. This helps to have the project organized without too much code. WordPress has no implementation of such concept and this package is a remedy. 16 | 17 | DocHooks package allows you to do: 18 | 19 | ```php 20 | class Example extends HookAnnotations { 21 | 22 | /** 23 | * @action test 24 | */ 25 | public function test_action() {} 26 | 27 | /** 28 | * @filter test 5 29 | */ 30 | public function test_filter( $val, $arg ) { 31 | return $val; 32 | } 33 | 34 | /** 35 | * @shortcode test 36 | */ 37 | public function test_shortcode( $atts, $content ) { 38 | return 'This is test'; 39 | } 40 | 41 | } 42 | 43 | $example = new Example(); 44 | $example->add_hooks(); 45 | ``` 46 | 47 | Instead of old: 48 | 49 | ```php 50 | $example = new Example(); 51 | 52 | add_action( 'test', [ $example, 'test_action' ] ); 53 | add_filter( 'test', [ $example, 'test_filter' ], 5, 2 ); 54 | add_shortcode( 'test', [ $example, 'test_shortcode' ] ); 55 | ``` 56 | 57 | ## 💾 Installation 58 | 59 | ``` bash 60 | composer require micropackage/dochooks 61 | ``` 62 | 63 | ## 🕹 Usage 64 | 65 | ### Annotations 66 | 67 | ``` 68 | @action 69 | @filter 70 | @shortcode 71 | ``` 72 | 73 | The hook and shortcode name is required while default priority is `10`. 74 | 75 | You don't provide the argument count, the class will figure it out. Just use the callback params you want. 76 | 77 | ### Test if DocHooks are working 78 | 79 | When OPCache has the `save_comments` and `load_comments` disabled, this package won't work, because the comments are stripped down. [See the fallback solution](#fallback). 80 | 81 | ```php 82 | use Micropackage\DocHooks\Helper; 83 | 84 | (bool) Helper::is_enabled(); 85 | ``` 86 | 87 | ### Using within the class 88 | 89 | You can extend the HookAnnotations class: 90 | 91 | ```php 92 | use Micropackage\DocHooks\HookAnnotations; 93 | 94 | class Example extends HookAnnotations { 95 | 96 | /** 97 | * @action test 98 | */ 99 | public function test_action() {} 100 | 101 | } 102 | 103 | $example = new Example(); 104 | $example->add_hooks(); 105 | ``` 106 | 107 | Or use the Trait: 108 | 109 | ```php 110 | use Micropackage\DocHooks\HookTrait; 111 | 112 | class Example { 113 | 114 | use HookTrait; 115 | 116 | /** 117 | * @action test 118 | */ 119 | public function test_action() {} 120 | 121 | } 122 | 123 | $example = new Example(); 124 | $example->add_hooks(); 125 | ``` 126 | 127 | ### Using as a standalone object 128 | 129 | ```php 130 | use Micropackage\DocHooks\Helper; 131 | 132 | class Example { 133 | 134 | /** 135 | * @action test 136 | */ 137 | public function test_action() {} 138 | 139 | } 140 | 141 | $example = Helper::hook( new Example() ); 142 | ``` 143 | 144 | ### Fallback 145 | 146 | Because the HookAnnotations object stores the called hooks in `_called_doc_hooks` property, you are able to pull them out and parse them into a list of old `add_action`, `add_filter` and `add_shortcode` functions. 147 | 148 | For this you'll need a central "repository" of all objects with hooks ie. Runtime class. [See the example of this approach](https://github.com/BracketSpace/Notification/blob/master/src/Cli/DumpHooks.php) in the Notification plugin, which uses the WP CLI to dump all the hooks into separate file. 149 | 150 | ## 📦 About the Micropackage project 151 | 152 | Micropackages - as the name suggests - are micro packages with a tiny bit of reusable code, helpful particularly in WordPress development. 153 | 154 | The aim is to have multiple packages which can be put together to create something bigger by defining only the structure. 155 | 156 | Micropackages are maintained by [BracketSpace](https://bracketspace.com). 157 | 158 | ## 📖 Changelog 159 | 160 | [See the changelog file](./CHANGELOG.md). 161 | 162 | ## 📃 License 163 | 164 | This software is released under MIT license. See the [LICENSE](./LICENSE) file for more information. 165 | -------------------------------------------------------------------------------- /src/HookTrait.php: -------------------------------------------------------------------------------- 1 | filter|action|shortcode)\s+(?P[^\s]+)(\s+(?P\d+))?#'; 29 | 30 | /** 31 | * Add actions/filters from the method of a class based on DocBlock 32 | * 33 | * @since 1.0.0 34 | * @param mixed $object The class object or null. 35 | * @return mixed The subject. 36 | */ 37 | public function add_hooks( $object = null ) { 38 | if ( is_null( $object ) ) { 39 | $object = $this; 40 | } 41 | 42 | $hooks = Hooks::get(); 43 | 44 | if ( $hooks->has_object( $object ) ) { 45 | // Don't add the hooks twice. 46 | return; 47 | } 48 | 49 | $hooks->add_object( $object ); 50 | 51 | $reflector = new \ReflectionObject( $object ); 52 | 53 | foreach ( $reflector->getMethods() as $method ) { 54 | $doc = $method->getDocComment(); 55 | $arg_count = $method->getNumberOfParameters(); 56 | 57 | if ( preg_match_all( self::$pattern, $doc, $matches, PREG_SET_ORDER ) ) { 58 | 59 | foreach ( $matches as $match ) { 60 | 61 | $type = $match['type']; 62 | $name = $match['name']; 63 | 64 | $priority = empty( $match['priority'] ) ? 10 : intval( $match['priority'] ); 65 | $callback = [ $object, $method->getName() ]; 66 | 67 | call_user_func( [ $this, "add_{$type}" ], $name, $callback, compact( 'priority', 'arg_count' ) ); 68 | 69 | $hooks->add_hook( $object, [ 70 | 'name' => $name, 71 | 'type' => $type, 72 | 'callback' => $method->getName(), 73 | 'priority' => $priority, 74 | 'arg_count' => $arg_count, 75 | ] ); 76 | } 77 | } 78 | } 79 | 80 | return $object; 81 | } 82 | 83 | /** 84 | * Hooks a function on to a specific filter 85 | * 86 | * @since 1.0.0 87 | * @param atring $name The hook name. 88 | * @param array $callback The class object and method. 89 | * @param array $args An array with priority and arg_count. 90 | * @return mixed 91 | */ 92 | public function add_filter( $name, $callback, $args = [] ) { 93 | return $this->_add_hook( 'filter', $name, $callback, $this->_args( $args ) ); 94 | } 95 | 96 | /** 97 | * Hooks a function on to a specific action 98 | * 99 | * @since 1.0.0 100 | * @param string $name The hook name. 101 | * @param array $callback The class object and method. 102 | * @param array $args An array with priority and arg_count. 103 | * @return mixed 104 | */ 105 | public function add_action( $name, $callback, $args = [] ) { 106 | return $this->_add_hook( 'action', $name, $callback, $this->_args( $args ) ); 107 | } 108 | 109 | /** 110 | * Hooks a function on to a specific shortcode 111 | * 112 | * @since 1.0.0 113 | * @param string $name The shortcode name. 114 | * @param array $callback The class object and method. 115 | * @return mixed 116 | */ 117 | public function add_shortcode( $name, $callback ) { 118 | return $this->_add_hook( 'shortcode', $name, $callback ); 119 | } 120 | 121 | /** 122 | * Gets hook calls 123 | * 124 | * @since 1.0.2 125 | * @param mixed $object The class object or null. 126 | * @return array 127 | */ 128 | public function get_calls( $object = null ) { 129 | if ( is_null( $object ) ) { 130 | $object = $this; 131 | } 132 | 133 | return Hooks::get()->get_hooks_for_object( $object ); 134 | } 135 | 136 | /** 137 | * Hooks a function on to a specific action/filter 138 | * 139 | * @since 1.0.0 140 | * @param string $type The hook type. Options are action/filter. 141 | * @param string $name The hook name. 142 | * @param array $callback Callback. 143 | * @param array $args An array with priority and arg_count. 144 | * @return mixed 145 | */ 146 | protected function _add_hook( $type, $name, $callback, $args = [] ) { 147 | $priority = isset( $args['priority'] ) ? $args['priority'] : 10; 148 | $arg_count = isset( $args['arg_count'] ) ? $args['arg_count'] : PHP_INT_MAX; 149 | 150 | $function = sprintf( 'add_%s', $type ); 151 | 152 | return call_user_func( $function, $name, $callback, $priority, $arg_count ); 153 | } 154 | 155 | /** 156 | * Merges the hook args with defaults 157 | * 158 | * @since 1.0.0 159 | * @param array $args Arguments. 160 | * @return array 161 | */ 162 | protected function _args( $args ) { 163 | return array_merge( [ 164 | 'priority' => 10, 165 | 'arg_count' => PHP_INT_MAX, 166 | ], $args ); 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "b056515b13ce4c69a81535aeb37663ad", 8 | "packages": [ 9 | { 10 | "name": "micropackage/singleton", 11 | "version": "1.1.1", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/micropackage/singleton.git", 15 | "reference": "594b5a857ee42149e6b01e8a353e5aaee52e726d" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/micropackage/singleton/zipball/594b5a857ee42149e6b01e8a353e5aaee52e726d", 20 | "reference": "594b5a857ee42149e6b01e8a353e5aaee52e726d", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "php": ">=5.6" 25 | }, 26 | "require-dev": { 27 | "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0", 28 | "phpcompatibility/php-compatibility": "^9.1", 29 | "wp-coding-standards/wpcs": "^2.0" 30 | }, 31 | "type": "library", 32 | "autoload": { 33 | "psr-4": { 34 | "Micropackage\\Singleton\\": "src" 35 | } 36 | }, 37 | "notification-url": "https://packagist.org/downloads/", 38 | "license": [ 39 | "GPL-3.0-or-later" 40 | ], 41 | "authors": [ 42 | { 43 | "name": "Jakub Mikita", 44 | "email": "jakub@bracketspace.com" 45 | } 46 | ], 47 | "description": "Singleton implementation", 48 | "support": { 49 | "issues": "https://github.com/micropackage/singleton/issues", 50 | "source": "https://github.com/micropackage/singleton/tree/1.1.1" 51 | }, 52 | "time": "2022-01-25T19:59:48+00:00" 53 | } 54 | ], 55 | "packages-dev": [ 56 | { 57 | "name": "dealerdirect/phpcodesniffer-composer-installer", 58 | "version": "v0.7.2", 59 | "source": { 60 | "type": "git", 61 | "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", 62 | "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db" 63 | }, 64 | "dist": { 65 | "type": "zip", 66 | "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", 67 | "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", 68 | "shasum": "" 69 | }, 70 | "require": { 71 | "composer-plugin-api": "^1.0 || ^2.0", 72 | "php": ">=5.3", 73 | "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" 74 | }, 75 | "require-dev": { 76 | "composer/composer": "*", 77 | "php-parallel-lint/php-parallel-lint": "^1.3.1", 78 | "phpcompatibility/php-compatibility": "^9.0" 79 | }, 80 | "type": "composer-plugin", 81 | "extra": { 82 | "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" 83 | }, 84 | "autoload": { 85 | "psr-4": { 86 | "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" 87 | } 88 | }, 89 | "notification-url": "https://packagist.org/downloads/", 90 | "license": [ 91 | "MIT" 92 | ], 93 | "authors": [ 94 | { 95 | "name": "Franck Nijhof", 96 | "email": "franck.nijhof@dealerdirect.com", 97 | "homepage": "http://www.frenck.nl", 98 | "role": "Developer / IT Manager" 99 | }, 100 | { 101 | "name": "Contributors", 102 | "homepage": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer/graphs/contributors" 103 | } 104 | ], 105 | "description": "PHP_CodeSniffer Standards Composer Installer Plugin", 106 | "homepage": "http://www.dealerdirect.com", 107 | "keywords": [ 108 | "PHPCodeSniffer", 109 | "PHP_CodeSniffer", 110 | "code quality", 111 | "codesniffer", 112 | "composer", 113 | "installer", 114 | "phpcbf", 115 | "phpcs", 116 | "plugin", 117 | "qa", 118 | "quality", 119 | "standard", 120 | "standards", 121 | "style guide", 122 | "stylecheck", 123 | "tests" 124 | ], 125 | "support": { 126 | "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues", 127 | "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer" 128 | }, 129 | "time": "2022-02-04T12:51:07+00:00" 130 | }, 131 | { 132 | "name": "phpcompatibility/php-compatibility", 133 | "version": "9.3.5", 134 | "source": { 135 | "type": "git", 136 | "url": "https://github.com/PHPCompatibility/PHPCompatibility.git", 137 | "reference": "9fb324479acf6f39452e0655d2429cc0d3914243" 138 | }, 139 | "dist": { 140 | "type": "zip", 141 | "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/9fb324479acf6f39452e0655d2429cc0d3914243", 142 | "reference": "9fb324479acf6f39452e0655d2429cc0d3914243", 143 | "shasum": "" 144 | }, 145 | "require": { 146 | "php": ">=5.3", 147 | "squizlabs/php_codesniffer": "^2.3 || ^3.0.2" 148 | }, 149 | "conflict": { 150 | "squizlabs/php_codesniffer": "2.6.2" 151 | }, 152 | "require-dev": { 153 | "phpunit/phpunit": "~4.5 || ^5.0 || ^6.0 || ^7.0" 154 | }, 155 | "suggest": { 156 | "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically.", 157 | "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." 158 | }, 159 | "type": "phpcodesniffer-standard", 160 | "notification-url": "https://packagist.org/downloads/", 161 | "license": [ 162 | "LGPL-3.0-or-later" 163 | ], 164 | "authors": [ 165 | { 166 | "name": "Wim Godden", 167 | "homepage": "https://github.com/wimg", 168 | "role": "lead" 169 | }, 170 | { 171 | "name": "Juliette Reinders Folmer", 172 | "homepage": "https://github.com/jrfnl", 173 | "role": "lead" 174 | }, 175 | { 176 | "name": "Contributors", 177 | "homepage": "https://github.com/PHPCompatibility/PHPCompatibility/graphs/contributors" 178 | } 179 | ], 180 | "description": "A set of sniffs for PHP_CodeSniffer that checks for PHP cross-version compatibility.", 181 | "homepage": "http://techblog.wimgodden.be/tag/codesniffer/", 182 | "keywords": [ 183 | "compatibility", 184 | "phpcs", 185 | "standards" 186 | ], 187 | "support": { 188 | "issues": "https://github.com/PHPCompatibility/PHPCompatibility/issues", 189 | "source": "https://github.com/PHPCompatibility/PHPCompatibility" 190 | }, 191 | "time": "2019-12-27T09:44:58+00:00" 192 | }, 193 | { 194 | "name": "squizlabs/php_codesniffer", 195 | "version": "3.7.2", 196 | "source": { 197 | "type": "git", 198 | "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", 199 | "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879" 200 | }, 201 | "dist": { 202 | "type": "zip", 203 | "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ed8e00df0a83aa96acf703f8c2979ff33341f879", 204 | "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879", 205 | "shasum": "" 206 | }, 207 | "require": { 208 | "ext-simplexml": "*", 209 | "ext-tokenizer": "*", 210 | "ext-xmlwriter": "*", 211 | "php": ">=5.4.0" 212 | }, 213 | "require-dev": { 214 | "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" 215 | }, 216 | "bin": [ 217 | "bin/phpcs", 218 | "bin/phpcbf" 219 | ], 220 | "type": "library", 221 | "extra": { 222 | "branch-alias": { 223 | "dev-master": "3.x-dev" 224 | } 225 | }, 226 | "notification-url": "https://packagist.org/downloads/", 227 | "license": [ 228 | "BSD-3-Clause" 229 | ], 230 | "authors": [ 231 | { 232 | "name": "Greg Sherwood", 233 | "role": "lead" 234 | } 235 | ], 236 | "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", 237 | "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", 238 | "keywords": [ 239 | "phpcs", 240 | "standards", 241 | "static analysis" 242 | ], 243 | "support": { 244 | "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", 245 | "source": "https://github.com/squizlabs/PHP_CodeSniffer", 246 | "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" 247 | }, 248 | "time": "2023-02-22T23:07:41+00:00" 249 | }, 250 | { 251 | "name": "wp-coding-standards/wpcs", 252 | "version": "2.3.0", 253 | "source": { 254 | "type": "git", 255 | "url": "https://github.com/WordPress/WordPress-Coding-Standards.git", 256 | "reference": "7da1894633f168fe244afc6de00d141f27517b62" 257 | }, 258 | "dist": { 259 | "type": "zip", 260 | "url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/7da1894633f168fe244afc6de00d141f27517b62", 261 | "reference": "7da1894633f168fe244afc6de00d141f27517b62", 262 | "shasum": "" 263 | }, 264 | "require": { 265 | "php": ">=5.4", 266 | "squizlabs/php_codesniffer": "^3.3.1" 267 | }, 268 | "require-dev": { 269 | "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || ^0.6", 270 | "phpcompatibility/php-compatibility": "^9.0", 271 | "phpcsstandards/phpcsdevtools": "^1.0", 272 | "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" 273 | }, 274 | "suggest": { 275 | "dealerdirect/phpcodesniffer-composer-installer": "^0.6 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically." 276 | }, 277 | "type": "phpcodesniffer-standard", 278 | "notification-url": "https://packagist.org/downloads/", 279 | "license": [ 280 | "MIT" 281 | ], 282 | "authors": [ 283 | { 284 | "name": "Contributors", 285 | "homepage": "https://github.com/WordPress/WordPress-Coding-Standards/graphs/contributors" 286 | } 287 | ], 288 | "description": "PHP_CodeSniffer rules (sniffs) to enforce WordPress coding conventions", 289 | "keywords": [ 290 | "phpcs", 291 | "standards", 292 | "wordpress" 293 | ], 294 | "support": { 295 | "issues": "https://github.com/WordPress/WordPress-Coding-Standards/issues", 296 | "source": "https://github.com/WordPress/WordPress-Coding-Standards", 297 | "wiki": "https://github.com/WordPress/WordPress-Coding-Standards/wiki" 298 | }, 299 | "time": "2020-05-13T23:57:56+00:00" 300 | } 301 | ], 302 | "aliases": [], 303 | "minimum-stability": "stable", 304 | "stability-flags": [], 305 | "prefer-stable": false, 306 | "prefer-lowest": false, 307 | "platform": { 308 | "php": ">=5.6" 309 | }, 310 | "platform-dev": [], 311 | "plugin-api-version": "2.3.0" 312 | } 313 | --------------------------------------------------------------------------------