<?php
namespace Wpupgrader\Libraries\WordPress\Plugins\Core\Hooks;

/**
 * Plug'n'play trait for use in your Class. Use WpHooksTrait, to enable Auto-hooks for Actions and Filters
 *
 * @see \registerWpHooks()
 * @author Wpupgrader, Patrick Weijtenburg
 */
trait WpHooksTrait
{
    /**
     * Register Wordpress Action- and Filter Hooks from a Class (e.g. \action_init(), \action_wp_head(), \filter_plugins_api())
     * ---
     * Action hooks (or actions) are triggered when something takes place, such as loading a page, a user
     * logging in, or a custom action that you define in your theme or plugin.
     * ---
     * Filter hooks, or filters, control how something happens or change something that's already being output.
     * You could use a filter to output metadata in a specific format, to override text output by your plugin,
     * or to prevent something from being displayed at all.
     *
     * @param bool $unregister When TRUE this will unregister the hooks, instead of registering them.
     */
    static public function registerWpHooks($unregister = false)
    {
        $r = new \ReflectionClass(static::class);

        foreach ($r->getMethods(\ReflectionMethod::IS_STATIC | \ReflectionMethod::IS_PUBLIC) as $method) {
            /**
             * =============================
             * Wordpress Core - Action Hooks
             * =============================
             */
            if (\substr($method->getName(), 0, 7) === 'action_') {
                $hook = \substr($method->getName(), 7);
                $priority = 10;
                $arguments = 1;

                if (\preg_match('~^(.+?)[_-](\d+)(?:[_-](\d+))?$~', $hook, $match)) {
                    $hook = (string)$match[1];
                    $priority = (int)$match[2];

                    if (isset($match[3])) {
                        $arguments = (int)$match[3];
                    }
                }

                if ($unregister) {
                    \remove_action($hook, [static::class, $method->getName()], $priority);
                }
                else {
                    \add_action($hook, [static::class, $method->getName()], $priority, $arguments);
                }
            }

            /**
             * =============================
             * Wordpress Core - Filter Hooks
             * =============================
             */
            if (\substr($method->getName(), 0, 7) === 'filter_') {
                $hook = \substr($method->getName(), 7);
                $priority = 10;
                $arguments = 1;

                if (\preg_match('~^(.+?)[_-](\d+)(?:[_-](\d+))?$~', $hook, $match)) {
                    $hook = (string)$match[1];
                    $priority = (int)$match[2];

                    if (isset($match[3])) {
                        $arguments = (int)$match[3];
                    }
                }
                if ($unregister) {
                    \remove_filter($hook, [static::class, $method->getName()], $priority);
                }
                else {
                    \add_filter($hook, [static::class, $method->getName()], $priority, $arguments);
                }
            }
        }
    }

    /**
     * Unregister Wordpress Action- and Filter Hooks from a Class
     */
    static public function unregisterWpHooks()
    {
        static::registerWpHooks(true);
    }
}