AJ asked me to post snippets of my "hook" system.

Well, I try to keep this simple:

My Bootstrap class (defined by Zend_Application) has following static
method.
I'm sure it can be made better but it seems to work for me.

/**
 * Call hook in modules (Note! methods must be static!)
 * 
 * @param string $hook Class, where method is defined. Eg.
Modulex_Bootstrap, Moduley_Model_Foobar
 * @param string $method Method to call
 * @param array $args [optional] Method arguments to pass
 * @param string $only_module [optional] Restict call to distinct module
 * @return void invoke method does not return anything. Modify variables
passed as arguments in hook method
 */
public static function invoke($hook, $method, array $args = null,
$only_module = null)
{
        $hook = ucfirst($hook);
                
        foreach (self::$modules as $module => $directory)
        {
                if (null === $only_module || $only_module == $module)
                {
                        $className = ucfirst($module) ."_{$hook}";
                                
                        if (!class_exists($className))
                        {
                                $classFile = dirname($directory) . 
DIRECTORY_SEPARATOR ."{$hook}.php";
                                        
                                if (file_exists($classFile))
                                {
                                        require_once $classFile;
                                }
                        }
                                
                        if (class_exists($className))
                        {
                                if (method_exists($className, $method))
                                {
                                        call_user_func_array(array($className, 
$method), $args);
                                }
                        }
                }
        }
}

Ok, now I have thos module called "content" and it's responsible for giving
the user
possibility to create different kinds of content like "story", "link" and
"file". I have few
content types defined in content module itself. But I wanted that other
modules can
define new types (when dropped into the modules folder).

For getting these content type definitions, I have method
getTypeDefinitions() in my Content_Model_Content
model. It lists those few predefined types and then calls a hook, see next
example:

public static function getTypeDefinitions()
{
        $types = self::$type_definitions;
                
        $other_types = array();
                
        // HOOK CALL: Ask other modules for additional content type definitions
        // this calls {Module}_Bootstrap class and method
"getContentTypeDefinitions" and passes
        // the the array as method arguments. Does someone know another way to 
do
this?
        Bootstrap::invoke("Bootstrap", "getContentTypeDefinitions",
array(&$other_types));
                
        return array_merge($types, $other_types);
}

So here we have simple Hook, which gives me possibility to define new
content types by other modules.

My hook call works so that first argument states the name of the class in
module, in my example I call
{Module}_Bootstrap class. The second argument gives the method to be called.
And the third gives the arguments as array to be passes to the method.

My solution was inspired by Drupal's node/hook system I had used in few
customer cases.

br, Marko


Marko78 wrote:
> 
> Hi,
> 
> I have the following setup:
> 
> 1. My application, has the usual stuff, "core" modules, controllers etc
> etc.
> 2. Library, Zend, ZendX, PHPExcel etc. and my own library-level classes.
> 3. site-specific folder. this one has application.ini, cache folder,
> search index. etc.
>    everything to do with the current instance of my application.
>    In this folder I also have my site specific or "external" modules
> 
> I have just added this modules folder to frontcontroller so it knows that
> there is a
> second modules folder. Of course you can put this folder anywhere.
> 
> In my bootstrap I just do the following ( _initSiteModules() ):
> // Add site specific modules
> if (file_exists(SITE_PATH ."/modules"))
> {
>       $this->getResource("frontController")->addModuleDirectory(SITE_PATH
> ."/modules");
> }
> 
> And well, you can keep this directory information for example in your
> configs or where ever.
> 
> I also made "hook" system, which allows me to extend behaviour of my
> "core" modules.
> For example, my "tag" module adds tag field to form in "user" module...
> I can post more about that, if someone is interested in.
> 
> br,
> Marko
> 

-- 
View this message in context: 
http://n4.nabble.com/External-Modules-tp977596p978008.html
Sent from the Zend Framework mailing list archive at Nabble.com.

Reply via email to