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

**URL:** https://discourse.getcockpit.com/t/create-links-to-all-tags-and-create-new-tags-if-not-exist-via-cockpit-php-bootstrap/698
**Category:** General
**Created:** [April 1, 2019, 10:09am UTC](https://discourse.getcockpit.com/t/create-links-to-all-tags-and-create-new-tags-if-not-exist-via-cockpit-php-bootstrap/698 "2019-04-01T10:09:22Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![dubaua](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.getcockpit.com/dubaua/32/291_2.png) [@dubaua](https://discourse.getcockpit.com/u/dubaua)
#### Post date: [April 1, 2019, 10:09am UTC](https://discourse.getcockpit.com/t/create-links-to-all-tags-and-create-new-tags-if-not-exist-via-cockpit-php-bootstrap/698/1 "2019-04-01T10:09:22Z")

</div>

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.

```php
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?

---

<div class="post-metadata">

### Author: ![dubaua](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.getcockpit.com/dubaua/32/291_2.png) [@dubaua](https://discourse.getcockpit.com/u/dubaua)
#### Post date: [April 3, 2019, 8:02am UTC](https://discourse.getcockpit.com/t/create-links-to-all-tags-and-create-new-tags-if-not-exist-via-cockpit-php-bootstrap/698/2 "2019-04-03T08:02:46Z")

</div>

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

````auto
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)
  );
}```
````
