Create links to all tags (and create new tags if not exist) via cockpit php bootstrap

#1

I accept string contains hashtags. Then I extract hashtags from string and unique them. So I have string and array of hashtags.
Before I post it I want to check for existance hashtags in database and create not existing tags, and then link all my tags to my new post.

function getHashtags($string) {
  preg_match_all('/#(\w+)/', $string, $matches);
  foreach ($matches[1] as $match) {
    $keywords[] = $match;
  }
  return array_unique($keywords);
}

function getTagLinks($postContent, $collectionName) {
  return array_map(function($tag) {
    $collectionName = 'postTags';
  
    $link = cockpit('collections')->findOne($collectionName, [
      'title' => $tag,
    ]);
  
    if (empty($link)) {
      $link = cockpit('collections')->save($collectionName, ['title' => $tag] );
    }
    return [
      '_id' => $link['_id'],
      'link' => $collectionName,
      'display' => $link['title'],
    ];
  }, getHashtags($postContent));
}

It is simple to iterate through my tags, find if item exist, get link to it otherwise create it and get link. But this method is overthinking and cause a lot of requests. Can you suggest more native way?

0 Likes

#2

I’ve got this solution. It more efficent, because it make only 2 requests.

function getTagLinks($postContent, $collectionName, $fieldName) {
  $hashtags = getHashtags($postContent);

  $existingTagLinks = cockpit('collections')->find($collectionName, [
    'filter' => [
      $fieldName => [
        '$in' => $hashtags
      ]
    ]
  ]);

  $lackingTagList = array_map(
    function ($tag) use ($fieldName) {return [ $fieldName => $tag];},
    array_values(
      array_diff(
        $hashtags,
        array_map(
          function($tag) use ($fieldName) {return $tag[$fieldName];},
          $existingTagLinks
        )
      )
    )
  );

  $newTagLinks = array();

  if (!empty($lackingTagList)) {
    $saveResponse = cockpit('collections')->save($collectionName, $lackingTagList);
    // in case when only one new tag saved it return tag, not list of tags
    if (isset($saveResponse['_id'])) {
      $newTagLinks = [ '0' => $saveResponse];
    } else {
      $newTagLinks = $saveResponse;
    }
  }

  return array_map(
    function($tag) use ($collectionName, $fieldName) {
      return [
        '_id' => $tag['_id'],
        'link' => $collectionName,
        'display' => $tag[$fieldName],
      ];
    },
    array_merge($existingTagLinks, $newTagLinks)
  );
}```
0 Likes