2

How can I make few global php functions which can be called from any Joomla custom module? E.g I wish to make a global function executing a select database query:

function select($row,$table_name,$where,$equals) {

$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select($row)
      ->from($db->quoteName($table_name))
      ->where($db->quoteName($where) . "=" . $db->q($equals));
$db->setQuery($query);
$result = $db->loadResult();
$row = $db->loadAssoc();
return $row[$row];

}

and then call it from any module:

$result = select('id','#__table','name','john');

what would be the best way to achieve this?

  • re your code example: return $row[$row]; -- I don't think that's right. You've got clashing variable names. Change the name of the function argument to $rowNumber and do return $row[$rowNumber]. – Simba Feb 9 '17 at 10:28
  • 1
    This might be useful as well (if it's not a duplicate) joomla.stackexchange.com/questions/16557/… – FFrewin Feb 9 '17 at 10:50
2
  1. To add a global function you just need to declare a function early in the lifecycle where you are not in a class - all functions per se are global in php. A reasonable place to do so that would not get overridden would be outside the class declaration in a system plugin. Any functions there will be added to the global space during the joomla initialisation - disabling the plugin will stop the functions being loaded. If you are going to do that then you should make sure your functions are called something that will not collide with other functions. This is not a good practice but whatever.

  2. What I would recommend is that you use static methods instead and register your class in the libraries folder with jloader. The doc is here: https://docs.joomla.org/Using_own_library_in_your_extensions

In short if I call my lib Pf then I will have a file called /libraries/pf/helper.php

<?php
class PfHelper
{
    public static function sayWooh()
    {
        return "wooh!";
    }
}

And a system plugin that registers the library - this will autoload all the classes in the library that follow the naming convention as detailed in the doc linked above.

A system plugin requires a minimum 2 files. /plugins/system/loadcustomlibrary.xml

<?xml version="1.0" encoding="utf-8"?>
<extension version="3.1" type="plugin" group="system">
    <name>Load Custom Library</name>
    <version>1.0</version>
    <description>Register custom library with Joomla's autoloader</description>
    <files>
        <filename plugin="loadcustomlibrary">loadcustomlibrary.php</filename>
    </files>
</extension>

/plugins/system/loadcustomlibrary.php

<?php
class plgSystemLoadcustomlibrary extends JPlugin
{
    public function onAfterInitialise()
    {
        JLoader::registerPrefix('Pf', JPATH_LIBRARIES . '/pf');
    }
}

Now anywhere in Joomla I can use any of my functions from the helper like this:

echo PfHelper::sayWooh();

The benefits are that you only need to make sure your library name isn't a copy of one of the things already in the Joomla libraries folder. Joomla will only load the helper class if you are using it because it is autoloaded. You still get the simplicity of being able to call you function/method anywhere without having to import something each time. You can break your functions up into classes if you have a lot of them which may help with reusability and maintainability etc. Having your own library is a nice technique to know if you want to use some code all over the place.

  • Can you post the full code for system plugin file and where to place it? – saibbyweb Feb 11 '17 at 11:27
  • I have edited the answer above with the full code of the system plugin. – jamesgarrett Feb 13 '17 at 8:52
1

I would suggest avoiding writing a "global" function. Yes it would be very easy to write one, but you'll be going against Joomla's architectural design.

My suggested way of doing this would be to implement the shared functionality as a plugin, with the function written as an event listener. Don't worry, its easier than it sounds.

  1. Write a plugin like this:

    class PlgXyzMyPlugin extends JPlugin    // <-- replace 'xyz' with whatever you want; ie a relevant and unique plugin type name.
    {
        public function onMyEvent()         // <-- it's an event listener, so name should start with 'on'.
        {
            //...your code here
        }
    }
    
  2. Wherever you want to call the function, write the following:

    JPluginHelper::importPlugin('xyz');  // <-- 'xyz' here is the same as in the plugin classname above.
    $dispatcher = JEventDispatcher::getInstance();
    $results = $dispatcher->trigger('onMyEvent', $args);  //event name is the function name. $args is an array of the parameters.
    

$results will now contain an array of the results from your function, and any others with the same plugin type.

This makes your function available wherever you need it, but without it being global.

It also has additional benefits; if you find a bug in the function, or want to improve it, you can upgrade the plugin without needing to touch all your other modules.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.