Commit | Line | Data |
---|---|---|
04c06e85 | 1 | <?php |
a9229942 | 2 | |
04c06e85 | 3 | namespace wcf\data\tag; |
a9229942 | 4 | |
04c06e85 MW |
5 | use wcf\data\AbstractDatabaseObjectAction; |
6 | use wcf\data\ISearchAction; | |
ea3185a0 | 7 | use wcf\system\clipboard\ClipboardHandler; |
04c06e85 MW |
8 | use wcf\system\database\util\PreparedStatementConditionBuilder; |
9 | use wcf\system\exception\UserInputException; | |
10 | use 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 |
23 | class 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 | } |