From 038c41136602669314ba977dcbf2515fa160ba05 Mon Sep 17 00:00:00 2001 From: Sami Mokaddem Date: Fri, 12 Apr 2024 15:58:19 +0200 Subject: [PATCH] new: [feed:pullEvents] Added support of tag collection in feed configuration This allow to specify a tag collection for which all the tags will be applied on the pulled Events --- app/Controller/FeedsController.php | 50 +++++++++++++- app/Model/AppModel.php | 5 +- app/Model/Feed.php | 68 +++++++++++++++---- .../IndexTable/Fields/tags.ctp | 24 +++++++ app/View/Feeds/index.ctp | 3 +- 5 files changed, 131 insertions(+), 19 deletions(-) diff --git a/app/Controller/FeedsController.php b/app/Controller/FeedsController.php index 5eafbf435..d634bf65c 100644 --- a/app/Controller/FeedsController.php +++ b/app/Controller/FeedsController.php @@ -74,6 +74,8 @@ class FeedsController extends AppController ); } } + $loggedUser = $this->Auth->user(); + $this->loadModel('TagCollection'); $this->CRUD->index([ 'filters' => [ @@ -92,7 +94,7 @@ class FeedsController extends AppController 'source_format' ], 'conditions' => $conditions, - 'afterFind' => function (array $feeds) { + 'afterFind' => function (array $feeds) use ($loggedUser) { if ($this->_isSiteAdmin()) { $feeds = $this->Feed->attachFeedCacheTimestamps($feeds); } @@ -106,6 +108,22 @@ class FeedsController extends AppController } } + foreach ($feeds as &$feed) { + if (!empty($feed['Feed']['tag_id'])) { + if (substr($feed['Feed']['tag_id'], 0, 11) == 'collection_') { + $tagCollectionID = intval(substr($feed['Feed']['tag_id'], 11)); + $tagCollection = $this->TagCollection->fetchTagCollection($loggedUser, [ + 'conditions' => [ + 'TagCollection.id' => $tagCollectionID, + ] + ]); + if (!empty($tagCollection)) { + $feed['TagCollection'] = $tagCollection; + } + } + } + } + return $feeds; } ]); @@ -292,7 +310,20 @@ class FeedsController extends AppController if (empty(Configure::read('Security.disable_local_feed_access'))) { $inputSources['local'] = 'Local'; } - $tags = $this->Event->EventTag->Tag->find('list', array('fields' => array('Tag.name'), 'order' => array('lower(Tag.name) asc'))); + $tags = $this->Event->EventTag->Tag->find('all', [ + 'recursive' => -1, + 'fields' => ['Tag.name', 'Tag.id'], + 'order' => ['lower(Tag.name) asc'] + ]); + $tags = Hash::combine($tags, '{n}.Tag.id', '{n}.Tag.name'); + $tagCollections = $this->TagCollection->fetchTagCollection($this->Auth->user()); + $tagCollections = Hash::combine($tagCollections, '{n}.TagCollection.id', '{n}.TagCollection.name'); + foreach ($tagCollections as $id => $name) { + $newID = "collection_{$id}"; + $tagCollections[$newID] = sprintf('%s :: %s', __('Tag Collection'), $name); + unset($tagCollections[$id]); + } + $tags = array_merge($tags, $tagCollections); $tags[0] = 'None'; $this->loadModel('Server'); @@ -442,7 +473,20 @@ class FeedsController extends AppController if (empty(Configure::read('Security.disable_local_feed_access'))) { $inputSources['local'] = 'Local'; } - $tags = $this->Event->EventTag->Tag->find('list', array('fields' => array('Tag.name'), 'order' => array('lower(Tag.name) asc'))); + $tags = $this->Event->EventTag->Tag->find('all', [ + 'recursive' => -1, + 'fields' => ['Tag.name', 'Tag.id'], + 'order' => ['lower(Tag.name) asc'] + ]); + $tags = Hash::combine($tags, '{n}.Tag.id', '{n}.Tag.name'); + $this->loadModel('TagCollection'); + $tagCollections = $this->TagCollection->fetchTagCollection($this->Auth->user()); + $tagCollections = Hash::combine($tagCollections, '{n}.TagCollection.id', '{n}.TagCollection.name'); + foreach ($tagCollections as $id => $name) { + $newID = "collection_{$id}"; + $tags[$newID] = sprintf('%s :: %s', __('Tag Collection'), $name); + } + unset($tagCollections); $tags[0] = 'None'; $this->loadModel('Server'); diff --git a/app/Model/AppModel.php b/app/Model/AppModel.php index 738c4d3d8..f91cdadc7 100644 --- a/app/Model/AppModel.php +++ b/app/Model/AppModel.php @@ -91,7 +91,7 @@ class AppModel extends Model 105 => false, 106 => false, 107 => false, 108 => false, 109 => false, 110 => false, 111 => false, 112 => false, 113 => true, 114 => false, 115 => false, 116 => false, 117 => false, 118 => false, 119 => false, 120 => false, 121 => false, 122 => false, - 123 => false, 124 => false, + 123 => false, 124 => false, 125 => false, ); const ADVANCED_UPDATES_DESCRIPTION = array( @@ -2176,6 +2176,9 @@ class AppModel extends Model INDEX `org_name` (`org_name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;'; break; + case 125: + $sqlArray[] = "ALTER TABLE `feeds` MODIFY `tag_id` VARCHAR(40) NOT NULL DEFAULT '0';"; + break; case 'fixNonEmptySharingGroupID': $sqlArray[] = 'UPDATE `events` SET `sharing_group_id` = 0 WHERE `distribution` != 4;'; $sqlArray[] = 'UPDATE `attributes` SET `sharing_group_id` = 0 WHERE `distribution` != 4;'; diff --git a/app/Model/Feed.php b/app/Model/Feed.php index 74acee2ae..862985686 100644 --- a/app/Model/Feed.php +++ b/app/Model/Feed.php @@ -1041,23 +1041,42 @@ class Feed extends AppModel 'recursive' => -1, 'fields' => ['Tag.name', 'Tag.colour', 'Tag.id'] ]); - $feed['Tag'] = $feed_tag['Tag']; + if (!empty($feed_tag)) { + $feed['Tag'] = $feed_tag['Tag']; + } } if (!isset($event['Event']['Tag'])) { $event['Event']['Tag'] = array(); } - $feedTag = $this->Tag->find('first', array('conditions' => array('Tag.id' => $feed['Feed']['tag_id']), 'recursive' => -1, 'fields' => array('Tag.name', 'Tag.colour', 'Tag.exportable'))); - if (!empty($feedTag)) { - $found = false; - foreach ($event['Event']['Tag'] as $tag) { - if (strtolower($tag['name']) === strtolower($feedTag['Tag']['name'])) { - $found = true; - break; - } + if (substr($feed['Feed']['tag_id'], 0, 11) == 'collection_') { // Tag is actually a tag collection + $this->TagCollection = ClassRegistry::init('TagCollection'); + $tagCollectionID = intval(substr($feed['Feed']['tag_id'], 11)); + $tagCollection = $this->TagCollection->find('first', [ + 'recursive' => -1, + 'conditions' => [ + 'TagCollection.id' => $tagCollectionID, + ], + 'contain' => [ + 'TagCollectionTag' => ['Tag'], + ] + ]); + foreach ($tagCollection['TagCollectionTag'] as $collectionTag) { + $event['Event']['Tag'][] = $collectionTag['Tag']; } - if (!$found) { - $event['Event']['Tag'][] = $feedTag['Tag']; + } else { + $feedTag = $this->Tag->find('first', array('conditions' => array('Tag.id' => $feed['Feed']['tag_id']), 'recursive' => -1, 'fields' => array('Tag.name', 'Tag.colour', 'Tag.exportable'))); + if (!empty($feedTag)) { + $found = false; + foreach ($event['Event']['Tag'] as $tag) { + if (strtolower($tag['name']) === strtolower($feedTag['Tag']['name'])) { + $found = true; + break; + } + } + if (!$found) { + $event['Event']['Tag'][] = $feedTag['Tag']; + } } } } @@ -1131,9 +1150,13 @@ class Feed extends AppModel */ private function __updateEventFromFeed(HttpSocket $HttpSocket = null, $feed, $uuid, $user, $filterRules) { - $event = $this->downloadAndParseEventFromFeed($feed, $uuid, $HttpSocket); + $event = $this->downloadAndParseEventFromFeed($feed, $uuid, $HttpSocket); $event = $this->__prepareEvent($event, $feed, $filterRules); - return $this->Event->_edit($event, $user, $uuid, $jobId = null); + if (is_array($event)) { + return $this->Event->_edit($event, $user, $uuid, $jobId = null); + } else { + return $event; + } } public function addDefaultFeeds($newFeeds) @@ -1378,7 +1401,24 @@ class Feed extends AppModel $this->Event->publishRouter($event['Event']['id'], null, $user); } if ($feed['Feed']['tag_id']) { - $this->Event->EventTag->attachTagToEvent($event['Event']['id'], ['id' => $feed['Feed']['tag_id']]); + if (substr($feed['Feed']['tag_id'], 0, 11) == 'collection_') { // Tag is actually a tag collection + $this->TagCollection = ClassRegistry::init('TagCollection'); + $tagCollectionID = intval(substr($feed['Feed']['tag_id'], 11)); + $tagCollection = $this->TagCollection->find('first', [ + 'recursive' => -1, + 'conditions' => [ + 'TagCollection.id' => $tagCollectionID, + ], + 'contain' => [ + 'TagCollectionTag', + ] + ]); + foreach ($tagCollection['TagCollectionTag'] as $collectionTag) { + $this->Event->EventTag->attachTagToEvent($event['Event']['id'], ['id' => $collectionTag['tag_id']]); + } + } else { + $this->Event->EventTag->attachTagToEvent($event['Event']['id'], ['id' => $feed['Feed']['tag_id']]); + } } return true; } diff --git a/app/View/Elements/genericElements/IndexTable/Fields/tags.ctp b/app/View/Elements/genericElements/IndexTable/Fields/tags.ctp index 859f6fc06..1cb0a9523 100644 --- a/app/View/Elements/genericElements/IndexTable/Fields/tags.ctp +++ b/app/View/Elements/genericElements/IndexTable/Fields/tags.ctp @@ -25,5 +25,29 @@ 'hide_global_scope' => isset($field['hide_global_scope']) ? $field['hide_global_scope'] : false ] ); + } else if (!empty($field['includeTagCollection']) && empty($tags)) { + if (!empty($row['TagCollection'])) { + echo sprintf('%s :: %s', + __('Tag Collection'), + '/tag_collections/view/' . h($row['TagCollection'][0]['TagCollection']['id']), + __('Tag Collection'), + h($row['TagCollection'][0]['TagCollection']['name']) + ); + echo '
'; + echo $this->element( + 'ajaxTags', + [ + 'scope' => '', + 'attributeId' => 0, + 'tags' => Hash::extract($row['TagCollection'][0]['TagCollectionTag'], '{n}.Tag'), + 'tagAccess' => false, + 'localTagAccess' => false, + 'static_tags_only' => 1, + 'scope' => isset($field['scope']) ? $field['scope'] : 'event', + 'hide_global_scope' => isset($field['hide_global_scope']) ? $field['hide_global_scope'] : false + ] + ); + echo '
'; + } } ?> diff --git a/app/View/Feeds/index.ctp b/app/View/Feeds/index.ctp index 9736841ec..965d13971 100644 --- a/app/View/Feeds/index.ctp +++ b/app/View/Feeds/index.ctp @@ -193,7 +193,8 @@ 'class' => 'short', 'data_path' => 'Tag', 'element' => 'tags', - 'scope' => 'feeds' + 'scope' => 'feeds', + 'includeTagCollection' => true, ), array( 'name' => __('Visible'),