Merge pull request #5989 from WoltLab/wsc-rpc-api-const
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / data / tag / TagAction.class.php
CommitLineData
04c06e85 1<?php
a9229942 2
04c06e85 3namespace wcf\data\tag;
a9229942 4
04c06e85
MW
5use wcf\data\AbstractDatabaseObjectAction;
6use wcf\data\ISearchAction;
ea3185a0 7use wcf\system\clipboard\ClipboardHandler;
04c06e85
MW
8use wcf\system\database\util\PreparedStatementConditionBuilder;
9use wcf\system\exception\UserInputException;
10use wcf\system\WCF;
11
12/**
13 * Executes tagging-related actions.
a9229942
TD
14 *
15 * @author Alexander Ebert
16 * @copyright 2001-2019 WoltLab GmbH
17 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
a9229942
TD
18 *
19 * @method Tag create()
20 * @method TagEditor[] getObjects()
21 * @method TagEditor getSingleObject()
04c06e85 22 */
a9229942
TD
23class TagAction extends AbstractDatabaseObjectAction implements ISearchAction
24{
25 /**
26 * @inheritDoc
27 */
28 protected $allowGuestAccess = ['getSearchResultList'];
29
30 /**
31 * @inheritDoc
32 */
33 protected $className = TagEditor::class;
34
35 /**
36 * @inheritDoc
37 */
38 protected $permissionsDelete = ['admin.content.tag.canManageTag'];
39
40 /**
41 * @inheritDoc
42 */
43 protected $permissionsUpdate = ['admin.content.tag.canManageTag'];
44
45 /**
46 * @inheritDoc
47 */
48 protected $requireACP = ['delete', 'update'];
49
50 /**
51 * tag for which other tags will be used as synonyms
52 * @var TagEditor
53 */
54 public $tagEditor;
55
56 /**
57 * @inheritDoc
58 */
59 public function validateGetSearchResultList()
60 {
61 $this->readString('searchString', false, 'data');
42f2a585 62 $this->readInteger('languageID', true);
a9229942
TD
63
64 if (isset($this->parameters['data']['excludedSearchValues']) && !\is_array($this->parameters['data']['excludedSearchValues'])) {
65 throw new UserInputException('excludedSearchValues');
66 }
67 }
68
69 /**
70 * @inheritDoc
71 */
72 public function getSearchResultList()
73 {
74 $excludedSearchValues = [];
75 if (isset($this->parameters['data']['excludedSearchValues'])) {
76 $excludedSearchValues = $this->parameters['data']['excludedSearchValues'];
77 }
78 $list = [];
79
80 $conditionBuilder = new PreparedStatementConditionBuilder();
81 $conditionBuilder->add("name LIKE ?", [$this->parameters['data']['searchString'] . '%']);
82 if (!empty($excludedSearchValues)) {
83 $conditionBuilder->add("name NOT IN (?)", [$excludedSearchValues]);
84 }
85
42f2a585
MW
86 if ($this->parameters['languageID']) {
87 $conditionBuilder->add("languageID = ?", [$this->parameters['languageID']]);
88 }
89
a9229942
TD
90 // find tags
91 $sql = "SELECT tagID, name
92 FROM wcf" . WCF_N . "_tag
93 " . $conditionBuilder;
94 $statement = WCF::getDB()->prepareStatement($sql, 5);
95 $statement->execute($conditionBuilder->getParameters());
96 while ($row = $statement->fetchArray()) {
97 $list[] = [
98 'label' => $row['name'],
99 'objectID' => $row['tagID'],
100 ];
101 }
102
103 return $list;
104 }
105
106 /**
107 * @inheritDoc
108 */
109 public function delete()
110 {
111 $returnValue = parent::delete();
112
113 $this->unmarkItems();
114
115 return $returnValue;
116 }
117
118 /**
119 * Validates the 'setAsSynonyms' action.
120 *
121 * @since 3.0
122 */
123 public function validateSetAsSynonyms()
124 {
125 WCF::getSession()->checkPermissions(['admin.content.tag.canManageTag']);
126 if (empty($this->objects)) {
127 $this->readObjects();
128
129 if (\count($this->objects) < 2) {
130 throw new UserInputException('objectIDs');
131 }
132 }
133
134 $this->readInteger('tagID');
135 $this->tagEditor = new TagEditor(new Tag($this->parameters['tagID']));
136 if (!$this->tagEditor->tagID) {
137 throw new UserInputException('tagID');
138 }
139 }
140
141 /**
142 * Sets a number of tags as a synonyms of another tag.
143 *
144 * @since 3.0
145 */
146 public function setAsSynonyms()
147 {
148 // the "main" tag may not be a synonym itself
149 if ($this->tagEditor->synonymFor) {
150 $this->tagEditor->update([
151 'synonymFor' => null,
152 ]);
153 }
154
155 foreach ($this->getObjects() as $tagEditor) {
156 $this->tagEditor->addSynonym($tagEditor->getDecoratedObject());
157 }
158
159 $this->unmarkItems();
160 }
161
162 /**
163 * Unmarks tags.
164 *
165 * @param int[] $tagIDs
166 * @since 3.0
167 */
168 protected function unmarkItems(array $tagIDs = [])
169 {
170 if (empty($tagIDs)) {
171 $tagIDs = $this->objectIDs;
172 }
173
174 if (!empty($tagIDs)) {
175 ClipboardHandler::getInstance()->unmark(
176 $tagIDs,
177 ClipboardHandler::getInstance()->getObjectTypeID('com.woltlab.wcf.tag')
178 );
179 }
180 }
04c06e85 181}