1<?php
2
3/**
4 * Autosave handler.
5 *
6 * This Source Code Form is subject to the terms of the Mozilla Public License,
7 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
8 * obtain one at http://mozilla.org/MPL/2.0/.
9 *
10 * @package phpMyFAQ
11 * @author Anatoliy Belsky <ab@php.net>
12 * @copyright 2003-2020 phpMyFAQ Team
13 * @license http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
14 * @link https://www.phpmyfaq.de
15 * @since 2012-07-07
16 */
17
18use phpMyFAQ\Category;
19use phpMyFAQ\Changelog;
20use phpMyFAQ\Filter;
21use phpMyFAQ\Helper\HttpHelper;
22use phpMyFAQ\Tags;
23use phpMyFAQ\User\CurrentUser;
24use phpMyFAQ\Visits;
25
26if (!defined('IS_VALID_PHPMYFAQ')) {
27    http_response_code(400);
28    exit();
29}
30
31$do = Filter::filterInput(INPUT_GET, 'do', FILTER_SANITIZE_STRING);
32
33$http = new HttpHelper();
34$http->setContentType('application/json');
35$http->addHeader();
36
37if ('insertentry' === $do &&
38    ($user->perm->checkRight($user->getUserId(), 'edit_faq') || $user->perm->checkRight($user->getUserId(),
39            'add_faq')) ||
40    'saveentry' === $do && $user->perm->checkRight($user->getUserId(), 'edit_faq')) {
41    $user = CurrentUser::getFromCookie($faqConfig);
42    if (!$user instanceof CurrentUser) {
43        $user = CurrentUser::getFromSession($faqConfig);
44    }
45
46    $dateStart = Filter::filterInput(INPUT_POST, 'dateStart', FILTER_SANITIZE_STRING);
47    $dateEnd = Filter::filterInput(INPUT_POST, 'dateEnd', FILTER_SANITIZE_STRING);
48    $question = Filter::filterInput(INPUT_POST, 'question', FILTER_SANITIZE_STRING);
49    $categories = Filter::filterInputArray(INPUT_POST, [
50        'rubrik' => [
51            'filter' => FILTER_VALIDATE_INT,
52            'flags' => FILTER_REQUIRE_ARRAY,
53        ]
54    ]
55    );
56    $recordLang = Filter::filterInput(INPUT_POST, 'lang', FILTER_SANITIZE_STRING);
57    $tags = Filter::filterInput(INPUT_POST, 'tags', FILTER_SANITIZE_STRING);
58    $active = Filter::filterInput(INPUT_POST, 'active', FILTER_SANITIZE_STRING);
59    $sticky = Filter::filterInput(INPUT_POST, 'sticky', FILTER_SANITIZE_STRING);
60    $content = Filter::filterInput(INPUT_POST, 'answer', FILTER_SANITIZE_SPECIAL_CHARS);
61    $keywords = Filter::filterInput(INPUT_POST, 'keywords', FILTER_SANITIZE_STRING);
62    $author = Filter::filterInput(INPUT_POST, 'author', FILTER_SANITIZE_STRING);
63    $email = Filter::filterInput(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
64    $comment = Filter::filterInput(INPUT_POST, 'comment', FILTER_SANITIZE_STRING);
65    $recordId = Filter::filterInput(INPUT_POST, 'recordId', FILTER_VALIDATE_INT);
66    $solutionId = Filter::filterInput(INPUT_POST, 'solutionId', FILTER_VALIDATE_INT);
67    $revisionId = Filter::filterInput(INPUT_POST, 'revisionId', FILTER_VALIDATE_INT);
68    $changed = '';
69
70    $user_permission = Filter::filterInput(INPUT_POST, 'userpermission', FILTER_SANITIZE_STRING);
71    $restrictedUsers = ('all' == $user_permission) ? -1 : Filter::filterInput(INPUT_POST, 'restrictedUsers',
72                                                                              FILTER_VALIDATE_INT);
73    $group_permission = Filter::filterInput(INPUT_POST, 'grouppermission', FILTER_SANITIZE_STRING);
74    $restrictedGroups = ('all' == $group_permission) ? -1 : Filter::filterInput(INPUT_POST, 'restrictedGroups',
75                                                                                FILTER_VALIDATE_INT);
76
77    if (!is_null($question) && !is_null($categories)) {
78        $tagging = new Tags($faqConfig);
79        $category = new Category($faqConfig, [], false);
80        $category->setUser($currentAdminUser);
81        $category->setGroups($currentAdminGroups);
82
83        if (!isset($categories['rubrik'])) {
84            $categories['rubrik'] = [];
85        }
86
87        $recordData = [
88            'id' => $recordId,
89            'lang' => $recordLang,
90            'revisionId' => $revisionId,
91            'active' => $active,
92            'sticky' => (!is_null($sticky) ? 1 : 0),
93            'thema' => html_entity_decode($question),
94            'content' => html_entity_decode($content),
95            'keywords' => $keywords,
96            'author' => $author,
97            'email' => $email,
98            'comment' => (!is_null($comment) ? 'y' : 'n'),
99            'date' => empty($date) ? date('YmdHis') : str_replace(['-', ':', ' '], '', $date),
100            'dateStart' => (empty($dateStart) ? '00000000000000' : str_replace('-', '', $dateStart) . '000000'),
101            'dateEnd' => (empty($dateEnd) ? '99991231235959' : str_replace('-', '', $dateEnd) . '235959'),
102            'linkState' => '',
103            'linkDateCheck' => 0,
104            'notes' => ''
105        ];
106
107        if ('saveentry' == $do || $recordId) {
108            /* Create a revision anyway, it's autosaving */
109            $faq->addNewRevision($recordId, $recordLang);
110            ++$revisionId;
111
112            $changelog = new Changelog($faqConfig);
113            $changelog->addEntry($recordId, $user->getUserId(), nl2br($changed), $recordLang, $revisionId);
114
115            $visits = new Visits($faqConfig);
116            $visits->logViews($recordId);
117
118            if ($faq->hasTranslation($recordId, $recordLang)) {
119                $faq->updateRecord($recordData);
120            } else {
121                $recordId = $faq->addRecord($recordData, false);
122            }
123
124            $faq->deleteCategoryRelations($recordId, $recordLang);
125            $faq->addCategoryRelations($categories['rubrik'], $recordId, $recordLang);
126
127            if ($tags != '') {
128                $tagging->saveTags($recordId, explode(',', $tags));
129            } else {
130                $tagging->deleteTagsFromRecordId($recordId);
131            }
132
133            $faq->deletePermission('user', $recordId);
134            $faq->addPermission('user', $recordId, [$restrictedUsers]);
135            $category->deletePermission('user', $categories['rubrik']);
136            $category->addPermission('user', $categories['rubrik'], [$restrictedUsers]);
137            if ($faqConfig->get('security.permLevel') !== 'basic') {
138                $faq->deletePermission('group', $recordId);
139                $faq->addPermission('group', $recordId, [$restrictedGroups]);
140                $category->deletePermission('group', $categories['rubrik']);
141                $category->addPermission('group', $categories['rubrik'], [$restrictedGroups]);
142            }
143        } elseif ('insertentry' == $do) {
144            unset($recordData['id']);
145            unset($recordData['revisionId']);
146            $revisionId = 1;
147            $recordId = $faq->addRecord($recordData);
148            if ($recordId) {
149                $changelog = new Changelog($faqConfig);
150                $changelog->addEntry($recordId, $user->getUserId(), nl2br($changed), $recordData['lang']);
151                $visits = new Visits($faqConfig);
152                $visits->add($recordId);
153
154                $faq->addCategoryRelations($categories['rubrik'], $recordId, $recordData['lang']);
155
156                if ($tags != '') {
157                    $tagging->saveTags($recordId, explode(',', $tags));
158                }
159
160                $faq->addPermission('user', $recordId, [$restrictedUsers]);
161                $category->addPermission('user', $categories['rubrik'], [$restrictedUsers]);
162
163                if ($faqConfig->get('security.permLevel') !== 'basic') {
164                    $faq->addPermission('group', $recordId, [$restrictedGroups]);
165                    $category->addPermission('group', $categories['rubrik'], [$restrictedGroups]);
166                }
167            }
168        }
169
170        $out = [
171            'msg' => sprintf('Item auto-saved at revision %d', $revisionId),
172            'revisionId' => $revisionId,
173            'recordId' => $recordId,
174        ];
175
176        $http->sendJsonWithHeaders($out);
177    }
178} else {
179    $http->setStatus(401);
180    $http->sendJsonWithHeaders(['msg' => 'Missing article rights']);
181}
182