phpjoomla

joomla tag form loads whole list from db


I noticed that joomla tag input field is quite stupid. It loads everything from db, in this case 9K tags. Obviously ui becomes so slow.

Any ideas how to fix it? it seems there is already an ajax functionality present, so why not rely on that completely? J ways are crazy.

enter image description here

1 idea is to modify getOption method, and load only the tags that are related to current article editor is editing.

But in this context I don't seem to have article id.

Any ideas how to solve situation? I'm sure some of you've run into this :S

/**
 * Method to get a list of tags
 *
 * @return  array  The field option objects.
 *
 * @since   3.1
 */
protected function getOptions()
{
    $published = $this->element['published']? $this->element['published'] : array(0,1);

    $db    = JFactory::getDbo();
    $query = $db->getQuery(true)
        ->select('DISTINCT a.id AS value, a.path, a.title AS text, a.level, a.published, a.lft')
        ->from('#__tags AS a')
        ->join('LEFT', $db->qn('#__tags') . ' AS b ON a.lft > b.lft AND a.rgt < b.rgt');

    // Filter language
    if (!empty($this->element['language']))
    {
        $query->where('a.language = ' . $db->q($this->element['language']));
    }

    $query->where($db->qn('a.lft') . ' > 0');

    // Filter on the published state
    if (is_numeric($published))
    {
        $query->where('a.published = ' . (int) $published);
    }
    elseif (is_array($published))
    {
        JArrayHelper::toInteger($published);
        $query->where('a.published IN (' . implode(',', $published) . ')');
    }

    $query->order('a.lft ASC');

    // Get the options.
    $db->setQuery($query);

    try
    {
        $options = $db->loadObjectList();
    }
    catch (RuntimeException $e)
    {
        return false;
    }

    // Block the possibility to set a tag as it own parent
    if ($this->form->getName() == 'com_tags.tag')
    {
        $id   = (int) $this->form->getValue('id', 0);

        foreach ($options as $option)
        {
            if ($option->value == $id)
            {
                $option->disable = true;
            }
        }
    }

    // Merge any additional options in the XML definition.
    $options = array_merge(parent::getOptions(), $options);

    // Prepare nested data
    if ($this->isNested())
    {
        $this->prepareOptionsNested($options);
    }
    else
    {
        $options = JHelperTags::convertPathsToNames($options);
    }

    return $options;
}

Solution

  • So I've modified list that gets preloaded, only to load tags that are present in the article (saved as belonging to article). Autocomplete still works with ajax so no loss of functionality there.

    enter image description here