CiviCRM Community Forums (archive)

*

News:

Have a question about CiviCRM?
Get it answered quickly at the new
CiviCRM Stack Exchange Q+A site

This forum was archived on 25 November 2017. Learn more.
How to get involved.
What to do if you think you've found a bug.



  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Developer Discussion »
  • APIs and Hooks (Moderator: Donald Lobo) »
  • Making hooks easier in Joomla
Pages: [1]

Author Topic: Making hooks easier in Joomla  (Read 5405 times)

mcsmom

  • I post frequently
  • ***
  • Posts: 266
  • Karma: 23
    • Official Joomla! Book
  • CiviCRM version: 4 and 3.4
  • CMS version: Joomla!
Making hooks easier in Joomla
November 05, 2009, 05:55:58 am
I've been working on making hooks easier to implement in Joomla. What I'd like to propose is that this file civicrmhooks.php be added to com_civicrm/helpers folders. The default hooks folder could then be pointed there.  Unless a new hook is added this file would never need to be changed.


Here's the code for the file:

Quote
<?
/**
 * @version      $Id: route.php 10752 2008-08-23 01:53:31Z eddieajau $
 * @package      CiviCRM + Joomla
 * @copyright   Copyright (C) 2009 Open Source Matters. All rights reserved.
 * @license      GNU/GPL, see LICENSE.php
 * Joomla! is free software. This version may have been modified pursuant to the
 * GNU General Public License, and as distributed it includes or is derivative
 * of works licensed under the GNU General Public License or other free or open
 * source software licenses. See COPYRIGHT.php for copyright notices and
 * details.
 */

// no direct access

if(!defined('_JEXEC')) { return false; }
// Helper to load civicrm hooks


function joomla_civicrm_pre($op, $objectName, $objectId, & $objectRef)
{
      // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('pre', Array($op, $objectName, $objectId, & $objectRef));

}

function joomla_civicrm_post($op, $objectName, $objectId, & $objectRef)
{
   // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('post', Array($op, $objectName, $objectId, & $objectRef));   
   }

function joomla_civicrm_links( $op, $objectName, $objectId )
{
   // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('links', Array($op, $objectName, $objectId ));   
}
function joomla_civicrm_validate( $formName, &$fields, &$files, &$form )
{
   // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('validate', Array($formName, &$fields, &$files, &$form));   
}
function joomla_civicrm_buildForm( $formName, &$form )
{
   // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('buildForm', Array( $formName, &$form ));   
}
function joomla_civicrm_postProcess( $formName, &$form )
{
      // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('postProcess', Array( $formName, &$form ));   
}
function joomla_civicrm_custom( $op, $groupID, $entityID, &$params )
{
         // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('custom', Array( $op, $groupID, $entityID, &$params ));   
}
function joomla_civicrm_aclWhereClause( $type, &$tables, &$whereTables, &$contactID, &$where )
{
         // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('custom', Array($type, &$tables, &$whereTables, &$contactID, &$where));   
}
function joomla_civicrm_aclGroup( $type, $contactID, $tableName, &$allGroups, &$currentGroups )
{
         // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('aclGroup', Array( $type, $contactID, $tableName, &$allGroups, &$currentGroups));
}
function joomla_civicrm_dashboard( $contactID, &$contentPlacement = self::DASHBOARD_BELOW )
{      
      // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('dashboard', Array( $contactID, &$contentPlacement = self::DASHBOARD_BELOW));
}
function joomla_civicrm_xmlMenu( &$files )
{
         // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('files', Array(&$files));
}
function joomla_civicrm_pageRun( &$page )
{
         // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('pageRun', Array(&$page));

}
function joomla_civicrm_tokens( &$tokens )
{
         // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('tokens', Array(&$tokens));
}
function joomla_civicrm_tokenValues( &$details, &$contactIDs )
{
         // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('tokenValues', Array( &$details, &$contactIDs ));

}
function joomla_civicrm_buildAmount( $pageType, &$form, &$amount )
{
         // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('buildAmount', Array( $pageType, &$form, &$amount));

}   
function joomla_civicrm_tabs( &$tabs, $contactID )
{
            // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('tabs', Array(&$tabs, $contactID ));

}   
function joomla_civicrm_mailingGroups( &$form, &$groups, &$mailings )
{
            // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('mailingGroups', Array(&$form, &$groups, &$mailings));   
}   
function joomla_civicrm_shortcuts( &$options )
{
            // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('shortcuts', Array(&$options));   
}   
function joomla_civicrm_summary( $contactID, &$content, &$contentPlacement = CRM_Utils_Hook::SUMMARY_BELOW )
{
            // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('summary', Array($contactID, &$content, &$contentPlacement = CRM_Utils_Hook::SUMMARY_BELOW));      
)   
function joomla_civicrm_contactListQuery( &$query, $name, $context, $id )
{
            // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('ListQuery', Array( &$query, $name, $context, $id));      
}   
function joomla_civicrm_membershipTypeValues( &$form, &$membershipTypeValues )
{
            // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('membershipTypeValues', Array(&$form, &$membershipTypeValues));      
}



Then each custom hook type can be created and installed as a Joomla plugin. For example, this could be one:
Quote
<?php

/**
 * @version
 * @package      JCivicrm
 * @subpackage   plugins
 * @copyright   Copyright (C) 2005 - 2008 Open Source Matters. All rights reserved.
 * @license      GNU/GPL, see LICENSE.php
 * Joomla! is free software. This version may have been modified pursuant
 * to the GNU General Public License, and as distributed it includes or
 * is derivative of works licensed under the GNU General Public License or
 * other free or open source software licenses.
 * See COPYRIGHT.php for copyright notices and details.
 */
//See http://wiki.civicrm.org/confluence/display/CRMDOC/CiviCRM+hook+specification for details on how to write custom hooks.
// Check to ensure this file is included in Joomla!
defined('_JEXEC') or die('Restricted access');

jimport('joomla.plugin.plugin');

/**
 *  Civicrm Plugin
 *
 * @package   Civivrm
 * @subpackage  Joomla
 * @since       1.5
 */

/**
 * This is an example of how to make a plugin for implementing hooks from civicrm.
 *
 * It implements an example found here http://wiki.civicrm.org/confluence/display/CRMDOC/CiviCRM+hook+specification
 *
 *
 * @access public
 */

class plgCiviCRMHooksExample extends JPlugin {
    function civitest_civicrm_summary( $contactID, &$content, &$contentPlacement ) {
      // REPLACE default Contact Summary with your customized content
      $contentPlacement = 3;
      $content = "
         <table>
         <tr><th>Hook Data</th></tr>
         <tr><td>Data 1</td></tr>
         <tr><td>Data 2</td></tr>
         </table>
         ";

   }

}



Donald Lobo

  • Administrator
  • I’m (like) Lobo ;)
  • *****
  • Posts: 15963
  • Karma: 470
    • CiviCRM site
  • CiviCRM version: 4.2+
  • CMS version: Drupal 7, Joomla 2.5+
  • MySQL version: 5.5.x
  • PHP version: 5.4.x
Re: Making hooks easier in Joomla
November 05, 2009, 06:46:35 am

lets fix this during the joomla developer camp :) (joomla developers: do plan on attending and helping out during the code sprint)

Any specific reason we need to keep that file? the civicrm hooks can just fire the joomla trigger directly and hence avoid having another file

thoughts?

lobo





A new CiviCRM Q&A resource needs YOUR help to get started. Visit our StackExchange proposed site, sign up and vote on 5 questions

mcsmom

  • I post frequently
  • ***
  • Posts: 266
  • Karma: 23
    • Official Joomla! Book
  • CiviCRM version: 4 and 3.4
  • CMS version: Joomla!
Re: Making hooks easier in Joomla
November 05, 2009, 10:18:41 am
Even better to fire directly, I don't see a downside to that.  I just usually try to work above the civicrm folder. :)

I think we should also incorporate firing of civicrm triggers into  /com_covicrm/civicrm.php. That makes it possible for plugins that aren't hooks to work.


mcsmom

  • I post frequently
  • ***
  • Posts: 266
  • Karma: 23
    • Official Joomla! Book
  • CiviCRM version: 4 and 3.4
  • CMS version: Joomla!
Re: Making hooks easier in Joomla
November 06, 2009, 08:17:03 am
here's an updated and working version of the civicrmhooks.php file.

Quote
<?
/**
 * @version      $Id: route.php 10752 2008-08-23 01:53:31Z eddieajau $
 * @package      CiviCRM + Joomla
 * @copyright   Copyright (C) 2009 Open Source Matters. All rights reserved.
 * @license      GNU/GPL, see LICENSE.php
 * Joomla! is free software. This version may have been modified pursuant to the
 * GNU General Public License, and as distributed it includes or is derivative
 * of works licensed under the GNU General Public License or other free or open
 * source software licenses. See COPYRIGHT.php for copyright notices and
 * details.
 */

// no direct access
if(!defined('_JEXEC')) { return false; }
// Helper to load civicrm hooks

function joomla_civicrm_pre($op, $objectName, $objectId, & $objectRef)
{
      // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('civicrm_pre', Array($op, $objectName, $objectId, & $objectRef));

}
function joomla_civicrm_post($op, $objectName, $objectId, & $objectRef)
{
   // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('civicrm_post', Array($op, $objectName, $objectId, & $objectRef));   
   }
function joomla_civicrm_links( $op, $objectName, $objectId )
{
   // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('civicrm_links', Array($op, $objectName, $objectId ));   
}
function joomla_civicrm_validate( $formName, &$fields, &$files, &$form )
{
   // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('civicrm_validate', Array($formName, &$fields, &$files, &$form));   
}
function joomla_civicrm_buildForm( $formName, &$form )
{
   // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('civicrm_buildForm', Array( $formName, &$form ));   
}
function joomla_civicrm_postProcess( $formName, &$form )
{
      // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('civicrm_postProcess', Array( $formName, &$form ));   
}
function joomla_civicrm_custom( $op, $groupID, $entityID, &$params )
{
         // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('civicrm_custom', Array( $op, $groupID, $entityID, &$params ));   
}
function joomla_civicrm_aclWhereClause( $type, &$tables, &$whereTables, &$contactID, &$where )
{
         // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('civicrm_custom', Array($type, &$tables, &$whereTables, &$contactID, &$where));   
}
function joomla_civicrm_aclGroup( $type, $contactID, $tableName, &$allGroups, &$currentGroups )
{
         // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('civicrm_aclGroup', Array( $type, $contactID, $tableName, &$allGroups, &$currentGroups));
}
function joomla_civicrm_dashboard( $contactID, &$contentPlacement = self::DASHBOARD_BELOW )
{      
      // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('civicrm_dashboard', Array( $contactID, &$contentPlacement));
}
function joomla_civicrm_xmlMenu( &$files )
{
         // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('civicrm_files', Array(&$files));
}
function joomla_civicrm_pageRun( &$page )
{
         // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('civicrm_pageRun', Array(&$page));

}
function joomla_civicrm_tokens( &$tokens )
{
         // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('civicrm_tokens', Array(&$tokens));
}
function joomla_civicrm_tokenValues( &$details, &$contactIDs )
{
         // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('civicrm_tokenValues', Array( &$details, &$contactIDs ));

}
function joomla_civicrm_buildAmount( $pageType, &$form, &$amount )
{
         // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('civicrm_buildAmount', Array( $pageType, &$form, &$amount));

}   
function joomla_civicrm_tabs( &$tabs, $contactID )
{
            // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('civicrm_tabs', Array(&$tabs, $contactID ));

}   
function joomla_civicrm_mailingGroups( &$form, &$groups, &$mailings )
{
            // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('civicrm_mailingGroups', Array(&$form, &$groups, &$mailings));   
}   
function joomla_civicrm_shortcuts( &$options )
{
            // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('civicrm_shortcuts', Array(&$options));   
}   
function joomla_civicrm_contactListQuery( &$query, $name, $context, $id )
{
            // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('civicrm_ListQuery', Array( &$query, $name, $context, $id));      
}   
function joomla_civicrm_membershipTypeValues( &$form, &$membershipTypeValues )
{
            // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('civicrm_membershipTypeValues', Array(&$form, &$membershipTypeValues));      
}

function joomla_civicrm_summary( $contactID, &$content, &$contentPlacement = CRM_Utils_Hook::SUMMARY_BELOW )
{
            // Import the civicrm plugin group
   JPluginHelper::importPlugin('civicrm');
   $dispatcher =& JDispatcher::getInstance();
   $dispatcher->trigger('civicrm_summary', Array($contactID, &$content, &$contentPlacement ));      
}   


And of the example plugin

hooksexample.php

Quote
<?php

/**
 * @version
 * @package      JCivicrm
 * @subpackage   plugins
 * @copyright   Copyright (C) 2005 - 2008 Open Source Matters. All rights reserved.
 * @license      GNU/GPL, see LICENSE.php
 * Joomla! is free software. This version may have been modified pursuant
 * to the GNU General Public License, and as distributed it includes or
 * is derivative of works licensed under the GNU General Public License or
 * other free or open source software licenses.
 * See COPYRIGHT.php for copyright notices and details.
 */
//See http://wiki.civicrm.org/confluence/display/CRMDOC/CiviCRM+hook+specification for details on how to write custom hooks.
// Check to ensure this file is included in Joomla!
defined('_JEXEC') or die('Restricted access');

jimport('joomla.plugin.plugin');

/**
 *  Civicrm Plugin
 *
 * @package   Civivrm
 * @subpackage  Joomla
 * @since       1.5
 */

/**
 * This is an example of how to make a plugin for implementing hooks from civicrm.
 *
 * It implements an example found here http://wiki.civicrm.org/confluence/display/CRMDOC/CiviCRM+hook+specification
 *
 *
 * @access public
 */
//die('hello');
class plgCiviCRMHooksExample extends JPlugin {

function civicrm_summary( $contactID, &$content, &$contentPlacement ) {

    // REPLACE default Contact Summary with your customized content
    $contentPlacement = 3;
    $content = "
<table>
<tr><th>Hook Data</th></tr>
<tr><td>Data 1</td></tr>
<tr><td>Data 2</td></tr>
</table>
";

}
}


and the corresponding hoosexample.xml

Quote
<?xml version="1.0" encoding="utf-8"?>
<install version="1.5" type="plugin" group="civicrm">
   <name>CiviCRM - Hook-Example</name>
   <author>Joomla! Project</author>
   <creationDate>November 2009</creationDate>
   <copyright>Copyright (C) 2005 - 2009 Open Source Matters. All rights reserved.</copyright>
   <license>http://www.gnu.org GNU/GPL</license>
   <authorEmail>elin.waring@opensourcematters.org</authorEmail>
   <authorUrl>www.joomla.org</authorUrl>
   <version>1.5</version>
   <description>A civicrm plugin implementing generic hooks</description>
   <files>
      <filename plugin="event">hooksexample.php</filename>
   </files>
   <languages></languages>
   <params/>
</install>

aspagarino

  • I post occasionally
  • **
  • Posts: 89
  • Karma: 10
  • San Diego Joomla
    • California Center for Sustainable Energy
  • CiviCRM version: CiviCRM 4.3
  • CMS version: Drupal 7
Re: Making hooks easier in Joomla
December 18, 2009, 10:59:43 am
The plugin version sound interesting.

So I guess this will be a way to custom hook for any exiting function of CiviCRM? If we put input fields like Contribution ID, Event ID, etc then administrators would be able to modify existing forms/fields just with hooks right?

I will start playing with this... hopefully will have something to report soon.
Andres

Open Source is Green

johng

  • Guest
Re: Making hooks easier in Joomla
January 09, 2010, 02:22:48 pm
Hello, I am new to Civi/Joomla but I am experienced with PHP. I'm trying to understand this whole process and wondering if I can get some input from the original poster and/or moderator/developers of Civi. I am using Joomla 1.5.15 and Civi 3.0.3. Here are the step I have taken, I am sure I am missing something small.

1. I setup the civicrmHooks.php file as specified above and placed it within ROOT/civicrm
2. Under Administer > Configure > Global Settings > Directories I pointed Custom PHP Path Directory to that folder.
3. I created hooksexample.php and hooksexample.xml and stuck them in a Zip file... the hooksexample.php file I made contained the following code (instead of the included function):
Quote
class plgCiviCRMHooksExample extends JPlugin {

     function civicrm_pageRun(&$page) {
          die('hello');
     }
}

4. I installed them via Joomla Extensions > Install > Upload Package File
5. I enabled the plugin via Joomla Extensions > Plugin Manager

Now if I understand correctly, this should fire before a Civi Page is loaded. However, when I view say an information request form on the front end (created via profile) the page loads. What step in the process am I missing or messing up? Thanks!

johng

  • Guest
Re: Making hooks easier in Joomla
January 11, 2010, 07:23:03 am
Anyone have any input on this?

johng

  • Guest
Re: Making hooks easier in Joomla
January 11, 2010, 09:28:47 am
Alright after taking some time to do some serious debugging/var_dumping I figured out what the problem was.

For some reason on the install the line in the xml file:

Quote
<filename plugin="event">hooksexample.php</filename>

Was making Joomla think that the plugin file was named event.php. I simply changed the file to hooksexample.php within the Joomla admin and it corrected the problem. Updating that line in the xml file to:

Quote
<filename>hooksexample.php</filename>

Should fix the problem if I am not mistaken.

jugrecarya

  • Guest
Re: Making hooks easier in Joomla
June 30, 2010, 03:33:56 pm
Hi, sorry my english.

i need make a civicrmhook.php with custom_19 = custom_17 - custom_18
please helpme

Tanks

Donald Lobo

  • Administrator
  • I’m (like) Lobo ;)
  • *****
  • Posts: 15963
  • Karma: 470
    • CiviCRM site
  • CiviCRM version: 4.2+
  • CMS version: Drupal 7, Joomla 2.5+
  • MySQL version: 5.5.x
  • PHP version: 5.4.x
Re: Making hooks easier in Joomla
June 30, 2010, 10:29:11 pm

1. please create a new topic in future rather than piggy backing on an older topic

2. check http://en.flossmanuals.net/CiviCRM/DevelopIntro

3. if still does not make a lot of sense but u r good with php/mysql chat with other developers on IRC

4. else hire someone from http://civicrm.org/professional/

lobo
A new CiviCRM Q&A resource needs YOUR help to get started. Visit our StackExchange proposed site, sign up and vote on 5 questions

Pages: [1]
  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Developer Discussion »
  • APIs and Hooks (Moderator: Donald Lobo) »
  • Making hooks easier in Joomla

This forum was archived on 2017-11-26.