Back to TagField class

Method getOptions

protected array
getOptions
()
Method to get a list of tags
Returns
  • array The field option objects.
Since
  • 3.1
Class: TagField
Project: Joomla

Method getOptions - Source code

/**
 * Method to get a list of tags
 *
 * @return  array  The field option objects.
 *
 * @since   3.1
 */
protected function getOptions()
{
    $published = (string) $this->element['published'] ?: array(0, 1);
    $app = Factory::getApplication();
    $language = null;
    $options = [];
    // This limit is only used with isRemoteSearch
    $prefillLimit = 30;
    $isRemoteSearch = $this->isRemoteSearch();
    $db = Factory::getDbo();
    $query = $db->getQuery(true)->select([$db->quoteName('a.id', 'value'), $db->quoteName('a.path'), $db->quoteName('a.title', 'text'), $db->quoteName('a.level'), $db->quoteName('a.published'), $db->quoteName('a.lft')])->from($db->quoteName('#__tags', 'a'));
    // Limit Options in multilanguage
    if ($app->isClient('site') && Multilanguage::isEnabled()) {
        if (ComponentHelper::getParams('com_tags')->get('tag_list_language_filter') === 'current_language') {
            $language = [$app->getLanguage()->getTag(), '*'];
        }
    } elseif (!empty($this->element['language'])) {
        if (strpos($this->element['language'], ',') !== false) {
            $language = explode(',', $this->element['language']);
        } else {
            $language = [$this->element['language']];
        }
    }
    if ($language) {
        $query->whereIn($db->quoteName('a.language'), $language, ParameterType::STRING);
    }
    $query->where($db->quoteName('a.lft') . ' > 0');
    // Filter on the published state
    if (is_numeric($published)) {
        $published = (int) $published;
        $query->where($db->quoteName('a.published') . ' = :published')->bind(':published', $published, ParameterType::INTEGER);
    } elseif (\is_array($published)) {
        $published = ArrayHelper::toInteger($published);
        $query->whereIn($db->quoteName('a.published'), $published);
    }
    $query->order($db->quoteName('a.lft') . ' ASC');
    // Preload only active values and 30 most used tags or fill up
    if ($isRemoteSearch) {
        // Load the most $prefillLimit used tags
        $topQuery = $db->getQuery(true)->select($db->quoteName('tag_id'))->from($db->quoteName('#__contentitem_tag_map'))->group($db->quoteName('tag_id'))->order('count(*)')->setLimit($prefillLimit);
        $db->setQuery($topQuery);
        $topIds = $db->loadColumn();
        // Merge the used values into the most used tags
        if (!empty($this->value) && is_array($this->value)) {
            $topIds = array_merge($topIds, $this->value);
            $topIds = array_keys(array_flip($topIds));
        }
        // Set the default limit for the main query
        $query->setLimit($prefillLimit);
        if (!empty($topIds)) {
            // Filter the ids to the most used tags and the selected tags
            $preQuery = clone $query;
            $preQuery->whereIn($db->quoteName('a.id'), $topIds);
            $db->setQuery($preQuery);
            try {
                $options = $db->loadObjectList();
            } catch (\RuntimeException $e) {
                return array();
            }
            // Limit the main query to the missing amount of tags
            $count = count($options);
            $prefillLimit = $prefillLimit - $count;
            $query->setLimit($prefillLimit);
            // Exclude the already loaded tags from the main query
            if ($count > 0) {
                $query->whereNotIn($db->quoteName('a.id'), ArrayHelper::getColumn($options, 'value'));
            }
        }
    }
    // Only execute the query if we need more tags not already loaded by the $preQuery query
    if (!$isRemoteSearch || $prefillLimit > 0) {
        // Get the options.
        $db->setQuery($query);
        try {
            $options = array_merge($options, $db->loadObjectList());
        } catch (\RuntimeException $e) {
            return array();
        }
    }
    // 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 = TagsHelper::convertPathsToNames($options);
    }
    return $options;
}