3
votes

I want to get the parameters of a module which is not assigned to the the current page. The helper class JModuleHelper has a getModule method but as defined here: http://docs.joomla.org/JModuleHelper/getModule, the module must be assigned to the current menu item or all menu items.

Obviously I can just go into the database and pull out the parameters myself, but I wanted to do it in a neater Joomla way.

What I'm trying to do is write a library, but the library requires some parametrization and its own database tables (two things that libraries cannot do), so I'm trying to use a module to fill the gaps. I need to access the module parameters from the library code (which could be called from any page on the site).

Thanks for any help


The solution I've gone with is to add the following code to my library:

$db = JFactory::getDbo();
$query = $db->getQuery(true);

$query->select('m.params')
    ->from('#__modules AS m')
    ->where('m.module=' . $db->quote('mod_my_module_name'));
$db->setQuery($query);
$module = $db->loadObject();

$module_params = new JRegistry();
$module_params->loadString($module->params);

I've not added this as an answer to this question because I think there should be a better solution which doesn't directly query the core database. However I think that the above is the best solution for now.


Update

Based on an answer to this question on the Joomla! developer group I've implemented a library/plugin solution. Plugins can have parameters which can be pulled from anywhere using the code:

$plugin = JPluginHelper::getPlugin('plugin_type', 'plugin_name');
$parameteres = new JRegistry($plugin->params);
$param =$parameteres->get('parameter');

The advantage of plugins over modules is that there is no requirement to assign the plugin to all item id's as their is with modules.

The more I've looked into it, the more confident I am that no elegant solution to my original question, of getting the parameters of modules not assigned to the current item id. So if you have found this question because you want to do something similar then I would recommend my solution above or cppl's solution below. Both will work and there probably isn't much to choose between them

1
You might want to circumvent the problem by assigning the module to all menu items but putting it in a position that doesn't exist in the template. Then getModule would find it, I think. If you need to display it sometimes though this would be a hassle.David Fritsch

1 Answers

3
votes

To get around that you can get the current document and then load the module renderer. e.g. if I wanted the Latest news module I had setup with a title of "Sport News" I could use this:

$module    = 'mod_articles_latest';
$title     = 'Sport News';

$document  = JFactory::getDocument();
$renderer  = $document->loadRenderer('module');
$theModule = JModuleHelper::getModule($module, $title);

So, to handle the case where modules aren't assigned to the current or all menu items you could possibly create your own helper that inherits from JModuleHelper and override just the protected function _load().

class MyModuleHelper extends JModuleHelper
{
    protected static function &_load()
    {
        static $clean;

        if (isset($clean))
        {
            return $clean;
        }

        $Itemid = JRequest::getInt('Itemid');
        $app = JFactory::getApplication();
        $user = JFactory::getUser();
        $groups = implode(',', $user->getAuthorisedViewLevels());
        $lang = JFactory::getLanguage()->getTag();
        $clientId = (int) $app->getClientId();

        $cache = JFactory::getCache('com_modules', '');
        $cacheid = md5(serialize(array($Itemid, $groups, $clientId, $lang)));

        if (!($clean = $cache->get($cacheid)))
        {
            $db = JFactory::getDbo();

            $query = $db->getQuery(true);
            $query->select('m.id, m.title, m.module, m.position,    m.content, m.showtitle, m.params, mm.menuid');
            $query->from('#__modules AS m');
            $query->join('LEFT', '#__modules_menu AS mm ON mm.moduleid =    m.id');
            $query->where('m.published = 1');

            $query->join('LEFT', '#__extensions AS e ON e.element =     m.module AND e.client_id = m.client_id');
            $query->where('e.enabled = 1');

            $date = JFactory::getDate();
            $now = $date->toSql();
            $nullDate = $db->getNullDate();
            $query->where('(m.publish_up = ' . $db->Quote($nullDate) . '    OR m.publish_up <= ' . $db->Quote($now) . ')');
            $query->where('(m.publish_down = ' . $db->Quote($nullDate) . '  OR m.publish_down >= ' . $db->Quote($now) . ')');

            $query->where('m.access IN (' . $groups . ')');
            $query->where('m.client_id = ' . $clientId);
            // Disable this line in your override class's _load()...
            // $query->where('(mm.menuid = ' . (int) $Itemid . ' OR     mm.menuid <= 0)');

            // Filter by language
            if ($app->isSite() && $app->getLanguageFilter())
            {
                $query->where('m.language IN (' . $db->Quote($lang) .   ',' . $db->Quote('*') . ')');
            }

            $query->order('m.position, m.ordering');

            // Set the query
            $db->setQuery($query);
            $modules = $db->loadObjectList();
            $clean = array();

            if ($db->getErrorNum())
            {
                JError::raiseWarning(500,   JText::sprintf('JLIB_APPLICATION_ERROR_MODULE_LOAD', $db->getErrorMsg()));
                return $clean;
            }

            // Apply negative selections and eliminate duplicates
            $negId = $Itemid ? -(int) $Itemid : false;
            $dupes = array();
            for ($i = 0, $n = count($modules); $i < $n; $i++)
            {
                $module = &$modules[$i];

                // The module is excluded if there is an explicit   prohibition
                $negHit = ($negId === (int) $module->menuid);

                if (isset($dupes[$module->id]))
                {
                    // If this item has been excluded, keep the     duplicate flag set,
                    // but remove any item from the cleaned array.
                    if ($negHit)
                    {
                        unset($clean[$module->id]);
                    }
                    continue;
                }

                $dupes[$module->id] = true;

                // Only accept modules without explicit exclusions.
                if (!$negHit)
                {
                    // Determine if this is a 1.0 style custom  module (no mod_ prefix)
                    // This should be eliminated when the class is  refactored.
                    // $module->user is deprecated.
                    $file = $module->module;
                    $custom = substr($file, 0, 4) == 'mod_' ?  0 :  1;
                    $module->user = $custom;
                    // 1.0 style custom module name is given by     the title field, otherwise strip off "mod_"
                    $module->name = $custom ? $module->module :     substr($file, 4);
                    $module->style = null;
                    $module->position = strtolower($module- >position);
                    $clean[$module->id] = $module;
                }
            }

            unset($dupes);

            // Return to simple indexing that matches the query order.
            $clean = array_values($clean);

            $cache->store($clean, $cacheid);
        }

        return $clean;
    }
}