Fixed deactive_extension hook execution on extension deactivation.
[fa-stable.git] / includes / hooks.inc
index d89c1d3e677c3e30fe7b8f5ad8beffa497ef81a8..6f15d0b0b7138c7a8f3542b89d4e55144fab7bec 100644 (file)
@@ -66,24 +66,46 @@ class hooks {
        //
        //      Install additional tabs provided by extension
        //
-       function install_tabs($app) {
-//             set_ext_domain('modules/example');        // set text domain for gettext
+       function install_tabs($app)
+       {
 //             $app->add_application(new example_class); // add menu tab defined by example_class
-//             set_ext_domain();
        }
        //
        //      Install additonal menu options provided by extension
        //
-       function install_options($app) {
+       function install_options($app)
+       {
 //             global $path_to_root;
-//             set_ext_domain('modules/example');
+//
 //             switch($app->id) {
 //                     case 'orders':
 //                             $app->add_rapp_function( 0, _("&Example option"), 
 //                                     $path_to_root.'/modules/example/example.php?', 'SA_OPEN');
 //             }
-//             set_ext_domain();
        }
+       
+       function install_access()
+       {
+//             $security_areas['SA_EXAMPLE'] = array(SS_EXAMPLE|100, _("Example security area."));
+//
+//             $security_sections = array(SS_EXAMPLE => _("Example module implementation"));
+//
+//             return array($security_areas, $security_sections);
+       }
+
+       //
+       //      Invoked for all modules before page header is displayed
+       //
+       function pre_header($fun_args)
+       {
+       }
+       //
+       //      Invoked for all modules before page footer is displayed
+       //
+       function pre_footer($fun_args)
+       {
+       }
+
        //
        // Price in words. $doc_type is set to document type and can be used to suppress 
        // price in words printing for selected document types.
@@ -94,7 +116,6 @@ class hooks {
        function price_in_words($amount, $doc_type)
        {
        }
-
        //
        // Exchange rate currency $curr as on date $date.
        // Keep in mind FA has internally implemented 3 exrate providers
@@ -109,6 +130,12 @@ class hooks {
                return null;
        }
 
+       // External authentication
+       // If used should return true after successfull athentication, false otherwise.
+       function authenticate($login, $password)
+       {
+               return null;
+       }
        // Generic function called at the end of Tax Report (report 709)
        // Can be used e.g. for special database updates on every report printing
        // or to print special tax report footer 
@@ -163,28 +190,45 @@ class hooks {
        {
                return true;
        }
-}
-//
-// include all extensions hook files.
-//
-foreach ($installed_extensions as $ext)
-{
-       if (file_exists($path_to_root.'/'.$ext['path'].'/hooks.php'))
-               include_once($path_to_root.'/'.$ext['path'].'/hooks.php');
+
+       /*
+        * Returns the quantity allowed to be dispatched for a particular item 
+        * and a status (which can be used to style the row).
+        * This quantity would be the default value on the delivery note.
+        * The usual use case for this is when a item is in stock,
+        * but has been reserved by someone else.
+        * This allows extensions to implements its own priority algorithm.
+        * This function is by detail_id and not item in case the item is present
+        * more than one in  the cart.
+        */
+       /* Default behavior check if there is enough quantity on hand and change the css
+ * class if needed */
+       static function  default_get_dispatchable_quantity($line_item, $location, $date, $qoh) {
+    global $SysPrefs;
+
+               if ($SysPrefs->allow_negative_stock() || ($line_item->qty_dispatched <= $qoh)) {
+                       return true;
+               }
+               return array($qoh, 'stockmankobg');
+               return array($line_item->qty_dispatched, 'stockmankobg');
+       }
+
 }
 
 /*
        Installs hooks provided by extension modules
 */
-function install_hooks() {
+function install_hooks()
+{
        global $path_to_root, $Hooks, $installed_extensions;
 
        $Hooks = array();
        
        // include current language related $Hooks object if locale file exists
-       if (file_exists($path_to_root . "/lang/".$_SESSION['language']->code."/locale.inc"))
+       $lang_code  = clean_file_name($_SESSION['language']->code);
+       if (file_exists($path_to_root . "/lang/" . $lang_code . "/locale.inc"))
        {
-               include_once($path_to_root . "/lang/".$_SESSION['language']->code."/locale.inc");
+               include_once($path_to_root . "/lang/" . $lang_code . "/locale.inc");
                $code = $_SESSION['language']->code;
                $hook_class = 'hooks_'.$code;
                $Hooks[$code] = new $hook_class;
@@ -202,7 +246,8 @@ function install_hooks() {
        Non active hooks are not included in $Hooks array, so we can use special function to 
        activate.
 */
-function activate_hooks($ext, $comp) {
+function activate_hooks($ext, $comp, $on=true)
+{
        global $Hooks;
        
        $hooks = @$Hooks[$ext];
@@ -215,13 +260,16 @@ function activate_hooks($ext, $comp) {
        }
        if (!$hooks)
                return false;
-       else
+       elseif ($on)
                return $hooks->activate_extension($comp, false);
+       else
+               return $hooks->deactivate_extension($comp, false);
 }
 /*
        Calls hook $method defined in extension $ext (if any)
 */
-function hook_invoke($ext, $method, &$data, $opts=null) {
+function hook_invoke($ext, $method, &$data, $opts=null)
+{
 
        global $Hooks;
 
@@ -237,28 +285,33 @@ function hook_invoke($ext, $method, &$data, $opts=null) {
 /*
        Calls hook $methods defined in all extensions (if any)
 */
-function hook_invoke_all($method, &$data, $opts=null) {
+function hook_invoke_all($method, &$data, $opts=null)
+{
 
        global $Hooks;
        
-       $result = array();
-       foreach($Hooks as $ext => $hook)
-               if (method_exists($hook, $method)) {
-                       set_ext_domain('modules/'.$ext);
-                       $result = $hook->$method($data, $opts);
-                       if (isset($result) && is_array($result)) {
-                               $return = array_merge_recursive($return, $result);
-                       } else if (isset($result)) {
-                               $return[] = $result;
-                               }
-               }
-       set_ext_domain();
-       return $result;
+       $return = array();
+       if (isset($Hooks))
+       {
+               foreach($Hooks as $ext => $hook)
+                       if (method_exists($hook, $method)) {
+                               set_ext_domain('modules/'.$ext);
+                               $result = $hook->$method($data, $opts);
+                               if (isset($result) && is_array($result)) {
+                                       $return = array_merge_recursive($return, $result);
+                               } else if (isset($result)) {
+                                       $return[] = $result;
+                                       }
+                               set_ext_domain();
+                       }
+       }
+       return $return;
 }
 /*
        Returns first non-null result returned from hook.
 */
-function hook_invoke_first($method, &$data, $opts=null) {
+function hook_invoke_first($method, &$data, $opts=null)
+{
 
        global $Hooks;
        
@@ -267,35 +320,34 @@ function hook_invoke_first($method, &$data, $opts=null) {
                if (method_exists($hook, $method)) {
                        set_ext_domain('modules/'.$ext);
                        $result = $hook->$method($data, $opts);
+                       set_ext_domain();
                        if (isset($result))
                                break;
                }
        }
-       set_ext_domain();
        return $result;
 }
 /*
-       Returns result of last hook installed. Helps implement hooks overriding by 
+       Returns last non-null result returned from modules method. Helps implement hooks overriding by 
        extensions installed later.
-       
 */
-function hook_invoke_last($method, &$data, $opts=null) {
+function hook_invoke_last($method, &$data, $opts=null)
+{
 
        global $Hooks;
 
-       $found = false;
-       foreach($Hooks as $ext => $hook) {
+       $result = null;
+       $Reverse = array_reverse($Hooks);
+       foreach($Reverse as $ext => $hook) {
                if (method_exists($hook, $method)) {
-                       $found = $ext;
+                       set_ext_domain('modules/'.$ext);
+                       $result = $hook->$method($data, $opts);
+                       set_ext_domain();
+                       if (isset($result))
+                               break;
                }
        }
-       $ret = null;
-       if ($found) {
-               set_ext_domain('modules/'.$found);
-               $ret = $Hooks[$found]->$method($data, $opts);
-               set_ext_domain();
-       }
-       return $ret;
+       return $result;
 }
 //------------------------------------------------------------------------------------------
 //     Database transaction hooks.
@@ -381,3 +433,27 @@ function hook_session_start($company)
        }
        return false;
 }
+//
+//     Third party authentication modules.
+//     Returns true after successfull authentication, false otherwise, null if no login hook is defined.
+//
+function hook_authenticate($login, $password)
+{
+       return hook_invoke_last('authenticate', $login, $password);
+}
+
+       /*
+        * Returns the quantity allowed to be dispatched for a particular item 
+        * and a "reason" (css classes).
+        * This quantity would be the default value on the delivery note.
+        * The usual use case for this is when a item is in stock,
+        * but has been reserved by someone else.
+        * This allows extensions to implements its own priority algorithm.
+        * This function is by detail_id and not item in case the item is present
+        * more than one in  the cart.
+        * If 'skip' is returned, the line will be skipped and not displayed
+        */
+function hook_get_dispatchable_quantity($line_item, $location, $date, $qoh) {
+               $result =  hook_invoke_first('get_dispatchable_quantity', $line_item, array($location, $date, $qoh));
+               return $result !== null ? $result : hooks::default_get_dispatchable_quantity($line_item, $location, $date, $qoh);
+}