Bookmark Tutorial buildtags explanation needed

In version 3 bookmarks tutorial the method _buildTags takes the submitted comma separated list of tags, then (according to comments) “Remove existing tags from the list of new tags.”; “Add existing tags.” and then “Add new tags.”. This appears to generate in $out the same list of tags as those posted, as calculated in the initial value of $newTags. Why are these 3 steps performed?

protected function _buildTags($tagString)
{
    // Trim tags
    $newTags = array_map('trim', explode(',', $tagString));
    // Remove all empty tags
    $newTags = array_filter($newTags);
    // Reduce duplicated tags
    $newTags = array_unique($newTags);

    $out = [];
    $query = $this->Tags->find()
        ->where(['Tags.title IN' => $newTags]);

    // Remove existing tags from the list of new tags.
    foreach ($query->extract('title') as $existing) {
        $index = array_search($existing, $newTags);
        if ($index !== false) {
            unset($newTags[$index]);
        }
    }
    // Add existing tags.
    foreach ($query as $tag) {
        $out[] = $tag;
    }
    // Add new tags.
    foreach ($newTags as $tag) {
        $out[] = $this->Tags->newEntity(['title' => $tag]);
    }
    return $out;
}

Thanks!

Yeah, this does seem a bit odd. Normally, something like this should be all that’s needed (not tested though):

protected function _buildTags($tagString)
{
    // Trim tags
    $newTags = array_map('trim', explode(',', $tagString));
    // Remove all empty tags
    $newTags = array_filter($newTags);
    // Reduce duplicated tags
    $newTags = array_unique($newTags);

    $out = [];
    $query = $this->Tags->find()
        ->where(['Tags.title IN' => $newTags]);

    // Add the tag entities to the $out array
    foreach ($query as $tag) {
        $out[] = $tag;
    }
    return $out;
}

Since $newTags should contain the same tags as are found in $query, there shouldn’t be a need to do anything else.

I suspect the other stuff was just to demonstrate what you can do, but it ends up being a little confusing…

1 Like

@ali: Thanks for your help.

It appears that tags not already in the Tags table, are created from within the bookmarks maintenance rather than having to create them in tags maintenance, so that’s why the existing ones are removed so the new ones remain. I still don’t see why the initial $newtags isn’t used as it’s the new definitive list of tags - new and existing.

Edit: Beginning to figure it out now: $out must be an array of entities not a simple array of string tag names. I’m new to frameworks.

Edit2: I think I’ve answered my own question: $out is built up from a list of entities - existing ones, new ones but excluding deleted ones.