Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I've built a small hooks class for adding some capabilities of basic plug-in functionality.

Is there room for improvement? I am just beginning to learn OOP, so don't be too harsh. I have two methods for manually adding execution points and deleting them:

  • autoloading method for plugins in a specific folder
  • method for execution

defined('BASE_PATH') || (header("HTTP/1.1 403 Forbidden") & die('403 - Acces direct interzis.'));
class hooks
{
private  static $hooks = [];
private static $instance;

    /**
     * @param null $plugin_dir
     * @return hooks
     * @desc ne asiguram ca avem o singura instanta globala
     */
    public static function init($plugin_dir = null)
    {
        if(self::$instance == null)
            self::$instance = new self($plugin_dir);
        return self::$instance;
    }

    /**
     * @param $plugin_dir
     * @desc instantierea efectiva, nu cred ca e nevoie de descriere si rulam load_action
     */
    private function __construct($plugin_dir)
    {
        self::load_action($plugin_dir);
    }

    /**
     * @desc ne aisguram ca obiectul nu poate fi clonat
     */
    private function __clone(){}

    /**
     * @param $plugin_dir
     * @return bool
     * @desc incarcarea dinamica de pluginuri (se efectueaza doar daca clasa este instantiata)
     * cautam directorul pt pluginuri le includem si le inregistram cu self::add_action
     */
    private static function load_action($plugin_dir)
    {
        if($plugin_dir == null)
            return null;
        $hooks = new GlobIterator($plugin_dir.DIRECTORY_SEPARATOR.'*.php', FilesystemIterator::KEY_AS_FILENAME);
        foreach($hooks as $hook => $file)
        {
            require_once $file;
            (empty($priority)) ? self::add_action($where, $callback) : self::add_action($where, $callback, $priority);
        }
        return null;
    }

    /**
     * @param $where punctul de executie
     * @param $callback metoda chemata poate fi functie sau metoda
     * @ex add_action('punct executie',[SomeClass, 'someStaticMethod']);
     * @param int $priority ordinea in care sant executate callbackurile pt fiecare pct de executie
     * @desc inregistram pluginuri
     */
    public static function add_action($where, $callback, $priority = 50)
    {
        if(!isset(self::$hooks[$where]))
            self::$hooks[$where] = [];
        self::$hooks[$where][$callback] = $priority;
    }

    /**
     * @param $where
     * @param $callback
     * @desc stergem un callback pt un pct de executie
     */
    public static function remove_action($where, $callback)
    {
        if(isset(self::$hooks[$where][$callback]))
            unset(self::$hooks[$where][$callback]);
    }

    /**
     * @param $where
     * @param array $args
     * @desc executam callbackurile pt un pct de executie si ai dam parametri necesari (optionali)
     */
    public static function execute_action($where, $args = [])
    {
        if(isset(self::$hooks[$where]) && is_array(self::$hooks[$where]))
        {
            arsort(self::$hooks[$where]);
            foreach(self::$hooks[$where] as $callback => &$priority)
                call_user_func_array($callback, $args);
        }
    }
}

index.php

define('BASE_PATH', realpath(__DIR__).DIRECTORY_SEPARATOR);
require_once BASE_PATH.'hooks.php';
hooks::init(BASE_PATH.'plugin'.DIRECTORY_SEPARATOR);
$array_pt_test = [
    'Home' => 'Home.php',
    'Top' => 'Top.php',
    'Hello' => 'Hello.php'
];
function render_nav($array =[])
{
    $output = '';
    foreach($array as $key => $value)
    {
        $output .= '<li>';
        $output .= '<a href="'.$value.'">'.$key.'</a>';
        $output .= '</li>';
    }
    echo $output;
}
hooks::add_action('nav', 'render_nav');

<nav id="nav">
                <ul>
                    <?php
                    hooks::execute_action('nav', [$array_pt_test]);
                    ?>
                </ul>
                <br class="clear" />
            </nav>

This is a simple example of displaying a navigation menu. We register a default function (action) to process the array. In overwrite.php(plugin directory) we register another function and give the overwrite_nav function a higher priority to be processed, and then call the hooks::remove_action method to unregister the default one. Just play with the priority ($priority) value in overwrite.php to see the effects. You can have multiple actions tied to the same execution point.

overwrite.php

 defined('BASE_PATH') || (header("HTTP/1.1 403 Forbidden") & die('403 - Acces direct interzis.'));
$where = 'nav';
$callback = 'overwrite_nav';
$priority = 57 ;

function overwrite_nav($array = [])
{
    hooks::remove_action('nav','render_nav');
        $output = '';
        foreach($array as $key => $value)
        {
            $output .= '<li>';
            $output .= '<a href="'.$value.'">'.strtolower($key).'</a>';
            $output .= '</li>';
        }
        echo $output;
}
share|improve this question
    
Two suggestions immediately comes to my mind: don't use Singletons (they are just disguised globals) and always write in English both comments and code. –  Jefffrey Feb 10 '13 at 2:09
    
Can you provide some example calling code? –  Rob Apodaca Feb 10 '13 at 13:45
    
Offcourse, but first sorry for my bad enghlish. I hope you can understand the exemple. I'll edit original post. –  danutz0501 Feb 10 '13 at 20:39
    
Please, do not tag question with OOP tag, when there is no OOP in them. This is purely procedural code with some camouflage oo-related keywords. –  tereško Feb 10 '13 at 21:21
    
Sorry about that. I removed the oop tag. But it uses one of the basic principles in oop "encapsulation" :D –  danutz0501 Feb 10 '13 at 21:34

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.