Fixed update of box to page assignments
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / data / page / PageAction.class.php
1 <?php
2 namespace wcf\data\page;
3 use wcf\data\page\content\PageContent;
4 use wcf\data\page\content\PageContentEditor;
5 use wcf\data\AbstractDatabaseObjectAction;
6 use wcf\data\ISearchAction;
7 use wcf\data\IToggleAction;
8 use wcf\system\exception\PermissionDeniedException;
9 use wcf\system\exception\UserInputException;
10 use wcf\system\html\simple\HtmlSimpleParser;
11 use wcf\system\message\embedded\object\MessageEmbeddedObjectManager;
12 use wcf\system\page\handler\ILookupPageHandler;
13 use wcf\system\WCF;
14
15 /**
16 * Executes page related actions.
17 *
18 * @author Marcel Werk
19 * @copyright 2001-2016 WoltLab GmbH
20 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
21 * @package WoltLabSuite\Core\Data\Page
22 * @since 3.0
23 *
24 * @method PageEditor[] getObjects()
25 * @method PageEditor getSingleObject()
26 */
27 class PageAction extends AbstractDatabaseObjectAction implements ISearchAction, IToggleAction {
28 /**
29 * @inheritDoc
30 */
31 protected $className = PageEditor::class;
32
33 /**
34 * @var PageEditor
35 */
36 protected $pageEditor;
37
38 /**
39 * @inheritDoc
40 */
41 protected $permissionsCreate = ['admin.content.cms.canManagePage'];
42
43 /**
44 * @inheritDoc
45 */
46 protected $permissionsDelete = ['admin.content.cms.canManagePage'];
47
48 /**
49 * @inheritDoc
50 */
51 protected $permissionsUpdate = ['admin.content.cms.canManagePage'];
52
53 /**
54 * @inheritDoc
55 */
56 protected $requireACP = ['create', 'delete', 'getSearchResultList', 'search', 'toggle', 'update'];
57
58 /**
59 * @inheritDoc
60 * @return Page
61 */
62 public function create() {
63 /** @var Page $page */
64 $page = parent::create();
65
66 // save page content
67 if (!empty($this->parameters['content'])) {
68 foreach ($this->parameters['content'] as $languageID => $content) {
69 if (!empty($content['htmlInputProcessor'])) {
70 /** @noinspection PhpUndefinedMethodInspection */
71 $content['content'] = $content['htmlInputProcessor']->getHtml();
72 }
73
74 /** @var PageContent $pageContent */
75 $pageContent = PageContentEditor::create([
76 'pageID' => $page->pageID,
77 'languageID' => $languageID ?: null,
78 'title' => $content['title'],
79 'content' => $content['content'],
80 'metaDescription' => $content['metaDescription'],
81 'metaKeywords' => $content['metaKeywords'],
82 'customURL' => $content['customURL']
83 ]);
84 $pageContentEditor = new PageContentEditor($pageContent);
85
86 // save embedded objects
87 if (!empty($content['htmlInputProcessor'])) {
88 /** @noinspection PhpUndefinedMethodInspection */
89 $content['htmlInputProcessor']->setObjectID($pageContent->pageContentID);
90 if (MessageEmbeddedObjectManager::getInstance()->registerObjects($content['htmlInputProcessor'])) {
91 $pageContentEditor->update(['hasEmbeddedObjects' => 1]);
92 }
93 }
94 else if ($page->pageType == 'html' || $page->pageType == 'tpl') {
95 HtmlSimpleParser::getInstance()->parse('com.woltlab.wcf.page.content', $pageContent->pageContentID, $pageContent->content);
96 }
97 }
98 }
99
100 // save box to page assignments
101 if (!empty($this->parameters['boxToPage'])) {
102 $sql = "INSERT INTO wcf".WCF_N."_box_to_page
103 (boxID, pageID, visible)
104 VALUES (?, ?, ?)";
105 $statement = WCF::getDB()->prepareStatement($sql);
106
107 foreach ($this->parameters['boxToPage'] as $boxData) {
108 $statement->execute([
109 $boxData['boxID'],
110 $page->pageID,
111 $boxData['visible']
112 ]);
113 }
114 }
115
116 // save template
117 if ($page->pageType == 'tpl') {
118 if (!empty($this->parameters['content'])) {
119 foreach ($this->parameters['content'] as $languageID => $content) {
120 file_put_contents(WCF_DIR . 'templates/' . $page->getTplName(($languageID ?: null)) . '.tpl', $content['content']);
121 }
122 }
123 }
124
125 return $page;
126 }
127
128 /**
129 * @inheritDoc
130 */
131 public function update() {
132 parent::update();
133
134 // update page content
135 if (!empty($this->parameters['content'])) {
136 foreach ($this->getObjects() as $page) {
137 foreach ($this->parameters['content'] as $languageID => $content) {
138 if (!empty($content['htmlInputProcessor'])) {
139 /** @noinspection PhpUndefinedMethodInspection */
140 $content['content'] = $content['htmlInputProcessor']->getHtml();
141 }
142
143 $pageContent = PageContent::getPageContent($page->pageID, ($languageID ?: null));
144 $pageContentEditor = null;
145 if ($pageContent !== null) {
146 // update
147 $pageContentEditor = new PageContentEditor($pageContent);
148 $pageContentEditor->update([
149 'title' => $content['title'],
150 'content' => $content['content'],
151 'metaDescription' => $content['metaDescription'],
152 'metaKeywords' => $content['metaKeywords'],
153 'customURL' => $content['customURL']
154 ]);
155 $pageContent = PageContent::getPageContent($page->pageID, ($languageID ?: null));
156 }
157 else {
158 /** @var PageContent $pageContent */
159 $pageContent = PageContentEditor::create([
160 'pageID' => $page->pageID,
161 'languageID' => $languageID ?: null,
162 'title' => $content['title'],
163 'content' => $content['content'],
164 'metaDescription' => $content['metaDescription'],
165 'metaKeywords' => $content['metaKeywords'],
166 'customURL' => $content['customURL']
167 ]);
168 $pageContentEditor = new PageContentEditor($pageContent);
169 }
170
171 // save embedded objects
172 if (!empty($content['htmlInputProcessor'])) {
173 /** @noinspection PhpUndefinedMethodInspection */
174 $content['htmlInputProcessor']->setObjectID($pageContent->pageContentID);
175 if ($pageContent->hasEmbeddedObjects != MessageEmbeddedObjectManager::getInstance()->registerObjects($content['htmlInputProcessor'])) {
176 $pageContentEditor->update(['hasEmbeddedObjects' => $pageContent->hasEmbeddedObjects ? 0 : 1]);
177 }
178 }
179 else if ($page->pageType == 'html' || $page->pageType == 'tpl') {
180 HtmlSimpleParser::getInstance()->parse('com.woltlab.wcf.page.content', $pageContent->pageContentID, $pageContent->content);
181 }
182 }
183
184 // save template
185 if ($page->pageType == 'tpl') {
186 foreach ($this->parameters['content'] as $languageID => $content) {
187 file_put_contents(WCF_DIR . 'templates/' . $page->getTplName(($languageID ?: null)) . '.tpl', $content['content']);
188 }
189 }
190 }
191 }
192
193 // save box to page assignments
194 if (isset($this->parameters['boxToPage'])) {
195 $sql = "DELETE FROM wcf".WCF_N."_box_to_page
196 WHERE pageID = ?";
197 $deleteStatement = WCF::getDB()->prepareStatement($sql);
198
199 $sql = "INSERT INTO wcf".WCF_N."_box_to_page
200 (boxID, pageID, visible)
201 VALUES (?, ?, ?)";
202 $insertStatement = WCF::getDB()->prepareStatement($sql);
203
204 foreach ($this->getObjects() as $page) {
205 $deleteStatement->execute([$page->pageID]);
206
207 if (!empty($this->parameters['boxToPage'])) {
208 foreach ($this->parameters['boxToPage'] as $boxData) {
209 $insertStatement->execute([
210 $boxData['boxID'],
211 $page->pageID,
212 $boxData['visible']
213 ]);
214 }
215 }
216 }
217 }
218 }
219
220 /**
221 * @inheritDoc
222 */
223 public function validateDelete() {
224 parent::validateDelete();
225
226 foreach ($this->getObjects() as $object) {
227 if (!$object->canDelete()) {
228 throw new PermissionDeniedException();
229 }
230 }
231 }
232
233 /**
234 * @inheritDoc
235 */
236 public function validateToggle() {
237 parent::validateUpdate();
238
239 foreach ($this->getObjects() as $object) {
240 if (!$object->canDisable()) {
241 throw new PermissionDeniedException();
242 }
243 }
244 }
245
246 /**
247 * @inheritDoc
248 */
249 public function toggle() {
250 foreach ($this->getObjects() as $object) {
251 $object->update(['isDisabled' => $object->isDisabled ? 0 : 1]);
252 }
253 }
254
255 /**
256 * @inheritDoc
257 */
258 public function validateGetSearchResultList() {
259 $this->pageEditor = $this->getSingleObject();
260 if ($this->pageEditor->getHandler() === null || !($this->pageEditor->getHandler() instanceof ILookupPageHandler)) {
261 throw new UserInputException('objectIDs');
262 }
263
264 $this->readString('searchString', false, 'data');
265 }
266
267 /**
268 * @inheritDoc
269 */
270 public function getSearchResultList() {
271 /** @noinspection PhpUndefinedMethodInspection */
272 return $this->pageEditor->getHandler()->lookup($this->parameters['data']['searchString']);
273 }
274
275 /**
276 * Validates parameters to search for a page by its internal name.
277 */
278 public function validateSearch() {
279 $this->readString('searchString');
280 }
281
282 /**
283 * Searches for a page by its internal name.
284 *
285 * @return array list of matching pages
286 */
287 public function search() {
288 $sql = "SELECT pageID
289 FROM wcf".WCF_N."_page
290 WHERE name LIKE ?
291 AND requireObjectID = ?
292 ORDER BY name";
293 $statement = WCF::getDB()->prepareStatement($sql, 5);
294 $statement->execute([
295 '%' . $this->parameters['searchString'] . '%',
296 0
297 ]);
298
299 $pages = [];
300 while ($pageID = $statement->fetchColumn()) {
301 $page = PageCache::getInstance()->getPage($pageID);
302 $pages[] = [
303 'displayLink' => $page->getDisplayLink(),
304 'name' => $page->name,
305 'pageID' => $pageID
306 ];
307 }
308
309 return $pages;
310 }
311
312 /**
313 * @inheritDoc
314 */
315 public function delete() {
316 foreach ($this->getObjects() as $page) {
317 if ($page->pageType == 'tpl') {
318 foreach ($page->getPageContents() as $languageID => $content) {
319 $file = WCF_DIR . 'templates/' . $page->getTplName(($languageID ?: null)) . '.tpl';
320 if (file_exists($file)) {
321 @unlink($file);
322 }
323 }
324 }
325 }
326
327 parent::delete();
328 }
329 }