Combine together correlated tags of several tags

This is a help method for method combine_tags()

@param core_tag_tag[] $tags
541010
protected function combine_correlated_tags($tags) {
        global $DB;
        $ids = array_map(function($t) {
            return $t->id;
        }, $tags);

        // Retrieve the correlated tags of this tag and correlated tags of all tags to be merged in one query
        // but store them separately. Calculate the list of correlated tags that need to be added to the current.
        list($sql, $params) = $DB->get_in_or_equal($ids);
        $params[] = $this->id;
        $records = $DB->get_records_select('tag_correlation', 'tagid '.$sql.' OR tagid = ?',
            $params, '', 'tagid, id, correlatedtags');
        $correlated = array();
        $mycorrelated = array();
        foreach ($records as $record) {
            $taglist = preg_split('/\s*,\s*/', trim($record->correlatedtags), -1, PREG_SPLIT_NO_EMPTY);
            if ($record->tagid == $this->id) {
                $mycorrelated = $taglist;
            } else {
                $correlated = array_merge($correlated, $taglist);
            }
        }
        array_unique($correlated);
        // Strip out from $correlated the ids of the tags that are already in $mycorrelated
        // or are one of the tags that are going to be combined.
        $correlated = array_diff($correlated, [$this->id], $ids, $mycorrelated);

        if (empty($correlated)) {
            // Nothing to do, ignore situation when current tag is correlated to one of the merged tags - they will
            // be deleted later and get_tag_correlation() will not return them. Next cron will clean everything up.
            return;
        }

        // Update correlated tags of this tag.
        $newcorrelatedlist = join(',', array_merge($mycorrelated, $correlated));
        if (isset($records[$this->id])) {
            $DB->update_record('tag_correlation', array('id' => $records[$this->id]->id, 'correlatedtags' => $newcorrelatedlist));
        } else {
            $DB->insert_record('tag_correlation', array('tagid' => $this->id, 'correlatedtags' => $newcorrelatedlist));
        }

        // Add this tag to the list of correlated tags of each tag in $correlated.
        list($sql, $params) = $DB->get_in_or_equal($correlated);
        $records = $DB->get_records_select('tag_correlation', 'tagid '.$sql, $params, '', 'tagid, id, correlatedtags');
        foreach ($correlated as $tagid) {
            if (isset($records[$tagid])) {
                $newcorrelatedlist = $records[$tagid]->correlatedtags . ',' . $this->id;
                $DB->update_record('tag_correlation', array('id' => $records[$tagid]->id, 'correlatedtags' => $newcorrelatedlist));
            } else {
                $DB->insert_record('tag_correlation', array('tagid' => $tagid, 'correlatedtags' => '' . $this->id));
            }
        }
    }
663030
public function tag($tags)
    {
        foreach ($this->prepareTags($tags) as $tag) {
            $this->addTag($tag);
        }

        return true;
    }
434969
protected function insertTag(Tag $tag)
	{
		if (!$this->tagStackIsSorted)
		{
			$this->tagStack[] = $tag;
		}
		else
		{
			// Scan the stack and copy every tag to the next slot until we find the correct index
			$i = count($this->tagStack);
			while ($i > 0 && self::compareTags($this->tagStack[$i - 1], $tag) > 0)
			{
				$this->tagStack[$i] = $this->tagStack[$i - 1];
				--$i;
			}
			$this->tagStack[$i] = $tag;
		}
	}
1192014
public function _processTags(&$tags)
    {
        $tagString = '';
        foreach ($tags as $key => $tag) {
            if ($key != '@text') {
                if (is_array($tag)) {
                    $hasText = FALSE;
                    foreach ($tag as $key => $tagFromGroup) {
                        if ($tagFromGroup->text($this->_doclet) != '') {
                            $hasText = TRUE;
                        }
                    }
                    if ($hasText) {
                        $tagString .= '<dt>'.$tag[0]->displayName().":</dt>\n";
                        foreach ($tag as $tagFromGroup) {
                            $tagString .= '<dd>'.$tagFromGroup->text($this->_doclet)."</dd>\n";
                        }
                    }
                } else {
                    $text = $tag->text($this->_doclet);
                    if ($text != '') {
                        $tagString .= '<dt>'.$tag->displayName().":</dt>\n";
                        $tagString .= '<dd>'.$text."</dd>\n";
                    } elseif ($tag->displayEmpty()) {
                        $tagString .= '<dt>'.$tag->displayName().".</dt>\n";
                    }
                }
            }
        }
        if ($tagString) {
            echo "<dl>\n", $tagString, "</dl>\n";
        }
    }
1368921
public function addTags(): void
    {
        $tags = $this->getTags();
        $currentStructureUuid = $this->getCurrentStructureUuid();
        if ($currentStructureUuid && !in_array($currentStructureUuid, $tags)) {
            $tags[] = $currentStructureUuid;
        }

        if (count($tags) <= 0) {
            return;
        }

        $this->symfonyResponseTagger->addTags($tags);
    }
593450
public function syncTags($tags)
    {
        /** @var Tag $className */
        $className = static::getTagClassName();

        $tags = collect($className::findOrCreate($tags));

        $this->tags()->sync($tags->pluck('id')->toArray());

        return $this;
    }
1170938
public static Tags concat(@Nullable Iterable<? extends Tag> tags, @Nullable Iterable<Tag> otherTags) {
        return Tags.of(tags).and(otherTags);
    }
157139
public void setTags(java.util.Collection<Tag> tags) {
        if (tags == null) {
            this.tags = null;
            return;
        }

        this.tags = new java.util.ArrayList<Tag>(tags);
    }
202858
public function setTags($tags)
    {
        $this->_tags = $tags;
        $this->_tagsDirty = true;
        $this->_currentTags = null;
    }
308269
public function MetaTags(&$tags)
    {
        // Only attempt to replace <title> tag if it has been included, as it won't
        // be included if called via $MetaTags(false)
        if (preg_match("/<title>(.+)<\/title>/i", $tags)) {
            $format = Config::inst()->get(static::class, 'title_format');

            $data = ArrayData::create([
                'MetaTitle' => $this->owner->MetaTitle ? $this->owner->obj('MetaTitle') : $this->owner->obj('Title')
            ]);

            $newTitleTag = HTML::createTag('title', [], SSViewer::execute_string($format, $data));
            $tags = preg_replace("/<title>(.+)<\/title>/i", $newTitleTag, $tags);
        }
    }
782651
@SuppressWarnings("unchecked")
	public T tags(final Collection<String> tags) {
		if (this.tags == null) {
			this.tags = new HashSet<>();
		}

		this.tags.addAll(tags);

		return (T) this;
	}
17286
public void setTags( Collection<String> tags ) {

		synchronized( this.tags ) {
			this.tags.clear();
			if( tags != null )
				this.tags.addAll( tags );
		}
	}
1266244
public function tag($tagNames)
    {
        $tagNames = static::$taggingUtility->makeTagArray($tagNames);

        foreach($tagNames as $tagName) {
            $this->addTag($tagName);
        }
    }
806243
def set_tags(self, tags):
        
        for key, value in tags.items():
            self.set_tag(key, value)
925146
public function untag($tags = null)
    {
        if ($tags === null) {
            $this->removeAllTags();

            return;
        }

        $this->removeTags(
            $this->getWorkableTags($tags)
        );
    }
389023
public function tag($tag, array $keys)
	{
		foreach ($keys as $key)
		{
			$resolvedKey = $this->resolveAlias($key);

			if (!isset($this->tags[$tag]))
			{
				$this->tags[$tag] = array();
			}

			$this->tags[$tag][] = $resolvedKey;
		}

		// Prune duplicates
		$this->tags[$tag] = array_unique($this->tags[$tag]);

		return $this;
	}
561210
public function flushByTags(array $tags)
    {
        $this->throwExceptionIfFrontendDoesNotExist();

        if (empty($tags)) {
            return;
        }

        $this->logger->debug('SFC flushByTags', [$tags]);

        $identifiers = [];
        foreach ($tags as $tag) {
            $identifiers = \array_merge($identifiers, $this->findIdentifiersByTagIncludingExpired($tag));
        }

        if ($this->isBoostMode()) {
            $this->getQueue()->addIdentifiers($identifiers);

            return;
        }

        foreach ($identifiers as $identifier) {
            $this->removeStaticFiles($identifier);
        }

        parent::flushByTags($tags);
    }