diff --git a/app/Controller/FeedsController.php b/app/Controller/FeedsController.php index 5eafbf435..954bf95f6 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,19 @@ class FeedsController extends AppController } } + foreach ($feeds as &$feed) { + if (!empty($feed['Feed']['tag_collection_id'])) { + $tagCollection = $this->TagCollection->fetchTagCollection($loggedUser, [ + 'conditions' => [ + 'TagCollection.id' => $feed['Feed']['tag_collection_id'], + ] + ]); + if (!empty($tagCollection)) { + $feed['TagCollection'] = $tagCollection; + } + } + } + return $feeds; } ]); @@ -294,6 +309,10 @@ class FeedsController extends AppController } $tags = $this->Event->EventTag->Tag->find('list', array('fields' => array('Tag.name'), 'order' => array('lower(Tag.name) asc'))); $tags[0] = 'None'; + $this->loadModel('TagCollection'); + $tagCollections = $this->TagCollection->fetchTagCollection($this->Auth->user()); + $tagCollections = Hash::combine($tagCollections, '{n}.TagCollection.id', '{n}.TagCollection.name'); + $tagCollections[0] = 'None'; $this->loadModel('Server'); $allTypes = $this->Server->getAllTypes(); @@ -304,6 +323,7 @@ class FeedsController extends AppController 'order' => 'LOWER(name)' )), 'tags' => $tags, + 'tag_collections' => $tagCollections, 'feedTypes' => $this->Feed->getFeedTypesOptions(), 'sharingGroups' => $sharingGroups, 'distributionLevels' => $distributionLevels, @@ -340,6 +360,7 @@ class FeedsController extends AppController 'distribution', 'sharing_group_id', 'tag_id', + 'tag_collection_id', 'event_id', 'publish', 'delta_merge', @@ -442,8 +463,17 @@ class FeedsController extends AppController if (empty(Configure::read('Security.disable_local_feed_access'))) { $inputSources['local'] = 'Local'; } + $tags = $this->Event->EventTag->Tag->find('all', [ + 'recursive' => -1, + 'fields' => ['Tag.name', 'Tag.id'], + 'order' => ['lower(Tag.name) asc'] + ]); $tags = $this->Event->EventTag->Tag->find('list', array('fields' => array('Tag.name'), 'order' => array('lower(Tag.name) asc'))); $tags[0] = 'None'; + $this->loadModel('TagCollection'); + $tagCollections = $this->TagCollection->fetchTagCollection($this->Auth->user()); + $tagCollections = Hash::combine($tagCollections, '{n}.TagCollection.id', '{n}.TagCollection.name'); + $tagCollections[0] = 'None'; $this->loadModel('Server'); $allTypes = $this->Server->getAllTypes(); @@ -457,6 +487,7 @@ class FeedsController extends AppController 'order' => 'LOWER(name)' )), 'tags' => $tags, + 'tag_collections' => $tagCollections, 'feedTypes' => $this->Feed->getFeedTypesOptions(), 'sharingGroups' => $sharingGroups, 'distributionLevels' => $distributionLevels, diff --git a/app/Model/AppModel.php b/app/Model/AppModel.php index 738c4d3d8..cb8232d2e 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` ADD COLUMN `tag_collection_id` INT(11) 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..e17fa4b45 100644 --- a/app/Model/Feed.php +++ b/app/Model/Feed.php @@ -1032,7 +1032,7 @@ class Feed extends AppModel } } } - if ($feed['Feed']['tag_id']) { + if ($feed['Feed']['tag_id'] || $feed['Feed']['tag_collection_id']) { if (empty($feed['Tag']['name'])) { $feed_tag = $this->Tag->find('first', [ 'conditions' => [ @@ -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 (!empty($feed['Feed']['tag_collection_id'])) { + $this->TagCollection = ClassRegistry::init('TagCollection'); + $tagCollectionID = $feed['Feed']['tag_collection_id']; + $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) @@ -1377,8 +1400,25 @@ class Feed extends AppModel if ($feed['Feed']['publish']) { $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 ($feed['Feed']['tag_id'] || $feed['Feed']['tag_collection_id']) { + if (!empty($feed['Feed']['tag_collection_id'])) { + $this->TagCollection = ClassRegistry::init('TagCollection'); + $tagCollectionID = $feed['Feed']['tag_collection_id']; + $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/add.ctp b/app/View/Feeds/add.ctp index f1032c8c0..6000130d7 100755 --- a/app/View/Feeds/add.ctp +++ b/app/View/Feeds/add.ctp @@ -166,6 +166,14 @@ echo $this->element('genericElements/Form/genericForm', [ 'type' => 'dropdown', 'searchable' => 1 ], + [ + 'field' => 'tag_collection_id', + 'label' => __('Default Tag Collection'), + 'options' => $dropdownData['tag_collections'], + 'selected' => isset($entity['Feed']['tag_collection_id']) ? $entity['Feed']['tag_collection_id'] : '0', + 'type' => 'dropdown', + 'searchable' => 1 + ], [ 'field' => 'rules', 'label' => __('Filter rules'), 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'), diff --git a/db_schema.json b/db_schema.json index e720ef18c..e2c975312 100644 --- a/db_schema.json +++ b/db_schema.json @@ -3206,6 +3206,17 @@ "column_type": "int(11)", "column_default": "0", "extra": "" + }, + { + "column_name": "tag_collection_id", + "is_nullable": "NO", + "data_type": "int", + "character_maximum_length": null, + "numeric_precision": "10", + "collation_name": null, + "column_type": "int(11)", + "column_default": "0", + "extra": "" } ], "fuzzy_correlate_ssdeep": [ @@ -10603,5 +10614,5 @@ "uuid": false } }, - "db_version": "124" + "db_version": "125" } \ No newline at end of file