1<?php 2/** 3 * The FAQ record editor. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public License, 6 * v. 2.0. If a copy of the MPL was not distributed with this file, You can 7 * obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * @package phpMyFAQ 10 * @author Thorsten Rinne <thorsten@phpmyfaq.de> 11 * @copyright 2003-2020 phpMyFAQ Team 12 * @license http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0 13 * @link https://www.phpmyfaq.de 14 * @since 2003-02-23 15 */ 16 17use phpMyFAQ\Attachment\AttachmentFactory; 18use phpMyFAQ\Category; 19use phpMyFAQ\Category\CategoryRelation; 20use phpMyFAQ\Changelog; 21use phpMyFAQ\Database; 22use phpMyFAQ\Date; 23use phpMyFAQ\Faq; 24use phpMyFAQ\Filter; 25use phpMyFAQ\Helper\CategoryHelper; 26use phpMyFAQ\Helper\LanguageHelper; 27use phpMyFAQ\Link; 28use phpMyFAQ\Logging; 29use phpMyFAQ\Question; 30use phpMyFAQ\Strings; 31use phpMyFAQ\Tags; 32use phpMyFAQ\User; 33 34if (!defined('IS_VALID_PHPMYFAQ')) { 35 http_response_code(400); 36 exit(); 37} 38 39$currentUserId = $user->getUserId(); 40 41if (($user->perm->checkRight($currentUserId, 'edit_faq') || 42 $user->perm->checkRight($currentUserId, 'add_faq')) && !Database::checkOnEmptyTable('faqcategories')) { 43 $category = new Category($faqConfig, [], false); 44 45 if ($faqConfig->get('main.enableCategoryRestrictions')) { 46 $category = new Category($faqConfig, $currentAdminGroups, true); 47 } 48 49 $category->setUser($currentAdminUser); 50 $category->setGroups($currentAdminGroups); 51 $category->buildTree(); 52 53 $categoryRelation = new CategoryRelation($faqConfig); 54 55 $categoryHelper = new CategoryHelper(); 56 $categoryHelper->setCategory($category); 57 58 $faq = new Faq($faqConfig); 59 60 $questionObject = new Question($faqConfig); 61 62 $changelog = new Changelog($faqConfig); 63 64 $selectedCategory = ''; 65 $categories = []; 66 $faqData = [ 67 'id' => 0, 68 'lang' => $faqLangCode, 69 'revision_id' => 0, 70 'title' => '', 71 'dateStart' => '', 72 'dateEnd' => '', 73 ]; 74 75 $tagging = new Tags($faqConfig); 76 $date = new Date($faqConfig); 77 78 if ('takequestion' === $action) { 79 $questionId = Filter::filterInput(INPUT_GET, 'id', FILTER_VALIDATE_INT); 80 $question = $questionObject->getQuestion($questionId); 81 $selectedCategory = $question['category_id']; 82 $faqData['title'] = $question['question']; 83 $notifyUser = $question['username']; 84 $notifyEmail = $question['email']; 85 $categories = [ 86 'category_id' => $selectedCategory, 87 'category_lang' => $faqData['lang'], 88 ]; 89 } else { 90 $questionId = 0; 91 $notifyUser = ''; 92 $notifyEmail = ''; 93 } 94 95 if ('editpreview' === $action) { 96 $faqData['id'] = Filter::filterInput(INPUT_POST, 'id', FILTER_VALIDATE_INT); 97 if (!is_null($faqData['id'])) { 98 $queryString = 'saveentry&id=' . $faqData['id']; 99 } else { 100 $queryString = 'insertentry'; 101 } 102 103 $faqData['lang'] = Filter::filterInput(INPUT_POST, 'lang', FILTER_SANITIZE_STRING); 104 $selectedCategory = Filter::filterInputArray( 105 INPUT_POST, 106 [ 107 'rubrik' => [ 108 'filter' => FILTER_VALIDATE_INT, 109 'flags' => FILTER_REQUIRE_ARRAY, 110 ], 111 ] 112 ); 113 if (is_array($selectedCategory)) { 114 foreach ($selectedCategory as $cats) { 115 $categories[] = ['category_id' => $cats, 'category_lang' => $faqData['lang']]; 116 } 117 } 118 $faqData['active'] = Filter::filterInput(INPUT_POST, 'active', FILTER_SANITIZE_STRING); 119 $faqData['keywords'] = Filter::filterInput(INPUT_POST, 'keywords', FILTER_SANITIZE_STRING); 120 $faqData['title'] = Filter::filterInput(INPUT_POST, 'thema', FILTER_SANITIZE_STRING); 121 $faqData['content'] = Filter::filterInput(INPUT_POST, 'content', FILTER_SANITIZE_SPECIAL_CHARS); 122 $faqData['author'] = Filter::filterInput(INPUT_POST, 'author', FILTER_SANITIZE_STRING); 123 $faqData['email'] = Filter::filterInput(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL); 124 $faqData['comment'] = Filter::filterInput(INPUT_POST, 'comment', FILTER_SANITIZE_STRING); 125 $faqData['solution_id'] = Filter::filterInput(INPUT_POST, 'solution_id', FILTER_VALIDATE_INT); 126 $faqData['revision_id'] = Filter::filterInput(INPUT_POST, 'revision_id', FILTER_VALIDATE_INT, 0); 127 $faqData['sticky'] = Filter::filterInput(INPUT_POST, 'sticky', FILTER_VALIDATE_INT); 128 $faqData['tags'] = Filter::filterInput(INPUT_POST, 'tags', FILTER_SANITIZE_STRING); 129 $faqData['changed'] = Filter::filterInput(INPUT_POST, 'changed', FILTER_SANITIZE_STRING); 130 $faqData['dateStart'] = Filter::filterInput(INPUT_POST, 'dateStart', FILTER_SANITIZE_STRING); 131 $faqData['dateEnd'] = Filter::filterInput(INPUT_POST, 'dateEnd', FILTER_SANITIZE_STRING); 132 $faqData['content'] = html_entity_decode($faqData['content']); 133 } elseif ('editentry' === $action) { 134 $id = Filter::filterInput(INPUT_GET, 'id', FILTER_VALIDATE_INT); 135 $lang = Filter::filterInput(INPUT_GET, 'lang', FILTER_SANITIZE_STRING); 136 $translateTo = Filter::filterInput(INPUT_GET, 'translateTo', FILTER_SANITIZE_STRING); 137 $categoryId = Filter::filterInput(INPUT_GET, 'cat', FILTER_VALIDATE_INT); 138 139 if (!is_null($translateTo)) { 140 $faqData['lang'] = $lang = $translateTo; 141 } 142 143 if ((!isset($selectedCategory) && !isset($faqData['title'])) || !is_null($id)) { 144 $logging = new Logging($faqConfig); 145 $logging->logAdmin($user, 'admin-edit-faq, ' . $id); 146 147 $categories = $categoryRelation->getCategories($id, $lang); 148 149 $faq->getRecord($id, null, true); 150 $faqData = $faq->faqRecord; 151 $faqData['tags'] = implode(', ', $tagging->getAllTagsById($faqData['id'])); 152 $queryString = 'saveentry&id=' . $faqData['id']; 153 } else { 154 $queryString = 'insertentry'; 155 if (isset($categoryId)) { 156 $categories = ['category_id' => $categoryId, 'category_lang' => $lang]; 157 } 158 } 159 } elseif ('copyentry' === $action) { 160 $faqData['id'] = Filter::filterInput(INPUT_GET, 'id', FILTER_VALIDATE_INT); 161 $faqData['lang'] = Filter::filterInput(INPUT_GET, 'lang', FILTER_SANITIZE_STRING); 162 $categories = $categoryRelation->getCategories($faqData['id'], $faqData['lang']); 163 164 $faq->getRecord($faqData['id'], null, true); 165 166 $faqData = $faq->faqRecord; 167 $queryString = 'insertentry'; 168 } else { 169 $logging = new Logging($faqConfig); 170 $logging->logAdmin($user, 'admin-add-faq'); 171 $queryString = 'insertentry'; 172 if (!is_array($categories)) { 173 $categories = []; 174 } 175 } 176 177 // Revisions 178 $selectedRevisionId = Filter::filterInput(INPUT_POST, 'revisionid_selected', FILTER_VALIDATE_INT); 179 if (is_null($selectedRevisionId)) { 180 $selectedRevisionId = $faqData['revision_id']; 181 } 182 183 // User permissions 184 $userPermission = $faq->getPermission('user', $faqData['id']); 185 if (count($userPermission) == 0 || $userPermission[0] == -1) { 186 $allUsers = true; 187 $restrictedUsers = false; 188 $userPermission[0] = -1; 189 } else { 190 $allUsers = false; 191 $restrictedUsers = true; 192 } 193 194 // Group permissions 195 $groupPermission = $faq->getPermission('group', $faqData['id']); 196 if (count($groupPermission) == 0 || $groupPermission[0] == -1) { 197 $allGroups = true; 198 $restrictedGroups = false; 199 $groupPermission[0] = -1; 200 } else { 201 $allGroups = false; 202 $restrictedGroups = true; 203 } 204 205 // Set data for forms 206 $faqData['title'] = (isset($faqData['title']) ? Strings::htmlspecialchars($faqData['title']) : ''); 207 $faqData['content'] = (isset($faqData['content']) ? trim(Strings::htmlentities($faqData['content'])) : ''); 208 $faqData['tags'] = (isset($faqData['tags']) ? Strings::htmlspecialchars($faqData['tags']) : ''); 209 $faqData['keywords'] = (isset($faqData['keywords']) ? Strings::htmlspecialchars($faqData['keywords']) : ''); 210 $faqData['author'] = (isset($faqData['author']) ? Strings::htmlspecialchars( 211 $faqData['author'] 212 ) : $user->getUserData('display_name')); 213 $faqData['email'] = (isset($faqData['email']) ? Strings::htmlspecialchars($faqData['email']) : $user->getUserData( 214 'email' 215 )); 216 $faqData['isoDate'] = (isset($faqData['date']) ? $faqData['date'] : date('Y-m-d H:i')); 217 $faqData['date'] = (isset($faqData['date']) ? $date->format($faqData['date']) : $date->format(date('Y-m-d H:i'))); 218 $faqData['changed'] = (isset($faqData['changed']) ? $faqData['changed'] : ''); 219 220 if (isset($faqData['comment']) && $faqData['comment'] == 'y') { 221 $faqData['comment'] = ' checked'; 222 } elseif ($faqConfig->get('records.defaultAllowComments')) { 223 $faqData['comment'] = ' checked'; 224 } else { 225 $faqData['comment'] = ''; 226 } 227 228 // Header 229 if (0 !== $faqData['id'] && 'copyentry' !== $action) { 230 $currentRevision = sprintf('%s 1.%d', $PMF_LANG['ad_entry_revision'], $selectedRevisionId); 231 $faqUrl = sprintf( 232 '%sindex.php?action=faq&cat=%s&id=%d&artlang=%s', 233 $faqConfig->getDefaultUrl(), 234 array_values($categories)[0]['category_id'], 235 $faqData['id'], 236 $faqData['lang'] 237 ); 238 $link = new Link($faqUrl, $faqConfig); 239 $link->itemTitle = $faqData['title']; 240 ?> 241 <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"> 242 <h1 class="h2"> 243 <i aria-hidden="true" class="fa fa-edit"></i> 244 <?= $PMF_LANG['ad_entry_edit_1'] ?> 245 <?= $PMF_LANG['ad_entry_edit_2'] ?> 246 </h1> 247 <div class="btn-toolbar mb-2 mb-md-0"> 248 <div class="btn-group mr-2"> 249 <span class="btn btn-sm btn-info"> 250 <i class="fa fa-hashtag" aria-hidden="true"></i> 251 <?= $currentRevision ?> 252 </span> 253 <a href="<?= $link->toString() ?>" class="btn btn-sm btn-success"> 254 <i class="fa fa-arrow-alt-circle-right" aria-hidden="true"></i> 255 <?= $PMF_LANG['ad_view_faq'] ?> 256 </a> 257 </div> 258 </div> 259 </div> 260 261 <?php } else { ?> 262 <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"> 263 <h1 class="h2"> 264 <i aria-hidden="true" class="fa fa-edit"></i> 265 <?= $PMF_LANG['ad_entry_add'] ?> 266 </h1> 267 </div> 268 269 <?php } ?> 270 271 <div class="row"> 272 <div class="col-lg-9"> 273 <div class="card mb-4"> 274 <div class="card-header"> 275 <ul class="nav nav-tabs card-header-tabs" id="nav-tab" role="tablist"> 276 <li class="nav-item"> 277 <a class="nav-link active" data-toggle="tab" href="#tab-question-answer" role="tab"> 278 <i class="fa fa-pencil-square-o"></i> <?= $PMF_LANG['ad_record_faq'] ?> 279 </a> 280 </li> 281 <li class="nav-item"> 282 <a class="nav-link" data-toggle="tab" href="#tab-meta-data" role="tab"> 283 <i class="fa fa-database"></i> <?= $PMF_LANG['ad_menu_faq_meta'] ?> 284 </a> 285 </li> 286 <li class="nav-item"> 287 <a class="nav-link" data-toggle="tab" href="#tab-permissions" role="tab"> 288 <i class="fa fa-unlock-alt"></i> <?= $PMF_LANG['ad_record_permissions'] ?> 289 </a> 290 </li> 291 <li class="nav-item"> 292 <a class="nav-link" data-toggle="tab" href="#tab-notes-changelog" role="tab"> 293 <i class="fa fa-sticky-note-o"></i> <?= $PMF_LANG['ad_admin_notes'] . ' / ' . $PMF_LANG['ad_entry_changelog'] ?> 294 </a> 295 </li> 296 </ul> 297 </div> 298 <div class="card-body"> 299 <div class="tab-content"> 300 <div class="tab-pane active" id="tab-question-answer"> 301 <!-- Revision --> 302 <?php 303 if ($user->perm->checkRight($currentUserId, 'changebtrevs')) { 304 $revisions = $faq->getRevisionIds($faqData['id'], $faqData['lang'], $faqData['author']); 305 if (count($revisions)) { ?> 306 <div class="form-group"> 307 <form id="selectRevision" name="selectRevision" method="post" 308 action="?action=editentry&id=<?= $faqData['id'] ?>&lang=<?= $faqData['lang'] ?>"> 309 <select name="revisionid_selected" onchange="this.form.submit();" 310 class="form-control"> 311 <option value="<?= $faqData['revision_id'] ?>"> 312 <?= $PMF_LANG['ad_changerev'] ?> 313 </option> 314 <?php foreach ($revisions as $revisionId => $revisionData) { ?> 315 <option value="<?= $revisionData['revision_id'] ?>" <?php if ($selectedRevisionId == $revisionData['revision_id']) { 316 echo 'selected'; 317 } 318 ?>> 319 <?php printf( 320 '%s 1.%d: %s - %s', 321 $PMF_LANG['ad_entry_revision'], 322 $revisionData['revision_id'], 323 Date::createIsoDate($revisionData['updated']), 324 $revisionData['author'] 325 ); 326 ?> 327 </option> 328 <?php 329 } 330 ?> 331 </select> 332 </form> 333 </div> 334 <?php } 335 if (isset($selectedRevisionId) && 336 isset($faqData['revision_id']) && 337 $selectedRevisionId !== $faqData['revision_id']) { 338 $faq->language = $faqData['lang']; 339 $faq->getRecord($faqData['id'], $selectedRevisionId, true); 340 $faqData = $faq->faqRecord; 341 $faqData['tags'] = implode(', ', $tagging->getAllTagsById($faqData['id'])); 342 $faqData['revision_id'] = $selectedRevisionId; 343 } 344 } ?> 345 346 <form id="faqEditor" action="?action=<?= $queryString ?>" method="post"> 347 <input type="hidden" name="revision_id" id="revision_id" value="<?= $faqData['revision_id'] ?>"> 348 <input type="hidden" name="record_id" id="record_id" value="<?= $faqData['id'] ?>"> 349 <input type="hidden" name="csrf" id="csrf" value="<?= $user->getCsrfTokenFromSession() ?>"> 350 <input type="hidden" name="openQuestionId" id="openQuestionId" value="<?= $questionId ?>"> 351 <input type="hidden" name="notifyUser" id="notifyUser" value="<?= $notifyUser ?>"> 352 <input type="hidden" name="notifyEmail" id="notifyEmail" value="<?= $notifyEmail ?>"> 353 354 <!-- Question --> 355 <div class="form-group"> 356 <input type="text" name="question" id="question" 357 class="form-control form-control-lg" 358 placeholder="<?= $PMF_LANG['ad_entry_theme'] ?>" 359 value="<?= htmlspecialchars($faqData['title']) ?>"> 360 </div> 361 362 <!-- Answer --> 363 <?php if ($faqConfig->get('main.enableWysiwygEditor')): ?> 364 <div class="form-group row"> 365 <div class="col-lg-12"> 366 <noscript>Please enable JavaScript to use the WYSIWYG editor!</noscript> 367 <textarea id="answer" name="answer" class="form-control" rows="7" 368 placeholder="<?= $PMF_LANG['ad_entry_content'] ?>" 369 ><?= $faqData['content'] ?></textarea> 370 </div> 371 </div> 372 <?php endif; ?> 373 <?php if ($faqConfig->get('main.enableMarkdownEditor')): ?> 374 <div class="form-group row"> 375 <div class="col-lg-12"> 376 <ul class="nav nav-tabs markdown-tabs mb-2"> 377 <li class="nav-item"> 378 <a class="nav-link active" data-toggle="tab" href="#text">Text</a> 379 </li> 380 <li class="nav-item"> 381 <a class="nav-link" data-toggle="tab" href="#preview" data-markdown-tab="preview">Preview</a> 382 </li> 383 </ul> 384 <div class="tab-content"> 385 <div class="tab-pane active" id="text"> 386 <div class="form-group row"> 387 <div class="col-lg-12"> 388 <textarea id="answer-markdown" name="answer" class="form-control" 389 rows="7" placeholder="<?= $PMF_LANG['ad_entry_content'] ?>" 390 ><?= $faqData['content'] ?></textarea> 391 </div> 392 </div> 393 </div> 394 <div class="tab-pane" id="preview"> 395 <article class="markdown-preview"></article> 396 </div> 397 </div> 398 </div> 399 </div> 400 <?php endif; ?> 401 </div> 402 <div class="tab-pane" id="tab-meta-data"> 403 <!-- Categories --> 404 <div class="form-group row"> 405 <label class="col-lg-2 col-form-label" for="phpmyfaq-categories"> 406 <?= $PMF_LANG['ad_entry_category'] ?> 407 </label> 408 <div class="col-lg-10"> 409 <select name="rubrik[]" id="phpmyfaq-categories" size="5" multiple 410 class="form-control"> 411 <?= $categoryHelper->renderOptions($categories) ?> 412 </select> 413 </div> 414 </div> 415 416 <!-- Language --> 417 <div class="form-group row"> 418 <label class="col-lg-2 col-form-label" for="lang"> 419 <?= $PMF_LANG['ad_entry_locale'] ?>: 420 </label> 421 <div class="col-lg-10"> 422 <?= LanguageHelper::renderSelectLanguage($faqData['lang'], false, [], 'lang') ?> 423 </div> 424 </div> 425 426 <!-- Attachments --> 427 <?php if ($user->perm->checkRight($currentUserId, 'addattachment')): ?> 428 <div class="form-group row"> 429 <label class="col-lg-2 col-form-label"> 430 <?= $PMF_LANG['ad_menu_attachments'] ?>: 431 </label> 432 <div class="col-lg-10"> 433 <ul class="list-unstyled adminAttachments"> 434 <?php 435 $attList = AttachmentFactory::fetchByRecordId( 436 $faqConfig, 437 $faqData['id'] 438 ); 439 foreach ($attList as $att) { 440 printf( 441 '<li><a href="../%s">%s</a> ', 442 $att->buildUrl(), 443 $att->getFilename() 444 ); 445 if ($user->perm->checkRight($currentUserId, 'delattachment')) { 446 printf( 447 '<a class="badge badge-danger" href="?action=delatt&record_id=%d&id=%d&lang=%s"><i aria-hidden="true" class="fa fa-trash"></i></a>', 448 $faqData['id'], 449 $att->getId(), 450 $faqData['lang'] 451 ); 452 } 453 echo "</li>\n"; 454 } 455 ?> 456 </ul> 457 <?php 458 printf( 459 '<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#attachmentModal">%s</button>', 460 $PMF_LANG['ad_att_add'] 461 ); 462 ?> 463 </div> 464 </div> 465 <?php endif; ?> 466 467 <!-- Tags --> 468 <div class="form-group row"> 469 <label class="col-lg-2 col-form-label" for="tags"> 470 <?= $PMF_LANG['ad_entry_tags'] ?>: 471 </label> 472 <div class="col-lg-10"> 473 <input type="text" name="tags" id="tags" value="<?= $faqData['tags'] ?>" 474 autocomplete="off" 475 class="form-control pmf-tags-autocomplete" 476 data-tag-list="<?= $faqData['tags'] ?>"> 477 <small id="tagsHelp" 478 class="form-text text-muted"><?= $PMF_LANG['msgShowHelp'] ?></small> 479 </div> 480 </div> 481 482 <!-- Keywords --> 483 <div class="form-group row"> 484 <label class="col-lg-2 col-form-label" for="keywords"> 485 <?= $PMF_LANG['ad_entry_keywords'] ?>: 486 </label> 487 <div class="col-lg-10"> 488 <input type="text" name="keywords" id="keywords" maxlength="255" 489 class="form-control" 490 value="<?= $faqData['keywords'] ?>"> 491 <small id="keywordsHelp" 492 class="form-text text-muted"><?= $PMF_LANG['msgShowHelp'] ?></small> 493 </div> 494 </div> 495 496 <!-- Author --> 497 <div class="form-group row"> 498 <label class="col-lg-2 col-form-label" for="author"> 499 <?= $PMF_LANG['ad_entry_author'] ?> 500 </label> 501 <div class="col-lg-10"> 502 <input type="text" name="author" id="author" value="<?= $faqData['author'] ?>" 503 class="form-control"> 504 </div> 505 </div> 506 507 <!-- E-Mail --> 508 <div class="form-group row"> 509 <label class="col-lg-2 col-form-label" for="email"> 510 <?= $PMF_LANG['ad_entry_email'] ?> 511 </label> 512 <div class="col-lg-10"> 513 <input type="email" name="email" id="email" value="<?= $faqData['email'] ?>" 514 class="form-control"> 515 </div> 516 </div> 517 </div> 518 519 <div class="tab-pane" id="tab-permissions"> 520 <!-- Permissions --> 521 <?php if ($faqConfig->get('security.permLevel') !== 'basic'): ?> 522 <fieldset class="form-group"> 523 <div class="row"> 524 <legend class="col-lg-2 col-form-label pt-0"> 525 <?= $PMF_LANG['ad_entry_grouppermission'] ?> 526 </legend> 527 <div class="col-lg-10"> 528 <div class="form-check"> 529 <input type="radio" id="allgroups" name="grouppermission" 530 value="all" class="form-check-input" 531 <?php echo($allGroups ? 'checked' : ''); ?>> 532 <label class="form-check-label" for="allgroups"> 533 <?= $PMF_LANG['ad_entry_all_groups'] ?> 534 </label> 535 </div> 536 <div class="form-check"> 537 <input type="radio" id="restrictedgroups" name="grouppermission" 538 class="form-check-input" 539 value="restricted" <?php echo($restrictedGroups ? 'checked' : ''); ?>> 540 <label for="selected-groups" class="form-check-label" 541 for="restrictedgroups"> 542 <?= $PMF_LANG['ad_entry_restricted_groups'] ?> 543 </label> 544 <select id="selected-groups" name="restricted_groups[]" size="3" 545 class="form-control" multiple> 546 <?= $user->perm->getAllGroupsOptions($groupPermission, $user) ?> 547 </select> 548 </div> 549 </div> 550 </div> 551 </fieldset> 552 <?php else: ?> 553 <input type="hidden" name="grouppermission" value="all"> 554 <?php endif; ?> 555 556 <fieldset class="form-group"> 557 <div class="row"> 558 <legend class="col-lg-2 col-form-label pt-0"><?= $PMF_LANG['ad_entry_userpermission'] ?></legend> 559 <div class="col-lg-10"> 560 <div class="form-check"> 561 <input type="radio" id="allusers" name="userpermission" value="all" 562 class="form-check-input" 563 <?= $allUsers ? 'checked' : '' ?>> 564 <label class="form-check-label" for="allusers"> 565 <?= $PMF_LANG['ad_entry_all_users'] ?> 566 </label> 567 </div> 568 <div class="form-check"> 569 <input type="radio" id="restrictedusers" name="userpermission" 570 class="form-check-input" 571 value="restricted" <?= $restrictedUsers ? 'checked' : '' ?>> 572 <label class="form-check-label" for="restrictedusers"> 573 <?= $PMF_LANG['ad_entry_restricted_users'] ?> 574 </label> 575 <select name="restricted_users" class="form-control"> 576 <?= $user->getAllUserOptions($userPermission[0], false) ?> 577 </select> 578 </div> 579 </div> 580 </div> 581 </fieldset> 582 583 </div> 584 585 <div class="tab-pane" id="tab-notes-changelog"> 586 <h6 class="card-title sr-only"> 587 <?= $PMF_LANG['ad_entry_changelog'] ?> 588 </h6> 589 <div class="form-group row"> 590 <label class="col-lg-2 col-form-label" for="changelog-date"> 591 <?= $PMF_LANG['ad_entry_date'] ?> 592 </label> 593 <div class="col-lg-10"> 594 <input type="text" readonly class="form-control-plaintext" id="changelog-date" 595 value="<?= $faqData['date'] ?>"> 596 </div> 597 </div> 598 <div class="form-group row"> 599 <label class="col-lg-2 col-form-label" for="changed"> 600 <?= $PMF_LANG['ad_entry_changed'] ?> 601 </label> 602 <div class="col-lg-10"> 603 <textarea name="changed" id="changed" rows="3" class="form-control" 604 ><?= $faqData['changed'] ?></textarea> 605 </div> 606 </div> 607 608 <h6 class="card-title"> 609 <label for="notes"> 610 <?php printf($PMF_LANG['ad_admin_notes_hint'], $PMF_LANG['ad_admin_notes']) ?> 611 </label> 612 </h6> 613 <div class="form-group row"> 614 <div class="col-lg-10 offset-lg-2"> 615 <textarea id="notes" name="notes" class="form-control" rows="3" 616 ><?= isset($faqData['notes']) ? $faqData['notes'] : '' ?></textarea> 617 </div> 618 </div> 619 620 <div class="row"> 621 <div class="col-lg-2"> 622 <h6 class="card-title"> 623 <?= $PMF_LANG['ad_entry_changelog_history'] ?> 624 </h6> 625 </div> 626 <div class="col-lg-10"> 627 <ul> 628 <?php foreach ($changelog->getChangeEntries($faqData['id']) as $entry) { 629 $entryUser = new User($faqConfig); 630 $entryUser->getUserById($entry['user']); 631 ?> 632 <li class="small pt-0"> 633 <?php printf( 634 '<i class="fa fa-hand-o-right"></i> %s 1.%d <i class="fa fa-calendar"></i> %s <i class="fa fa-user"></i> %s', 635 $PMF_LANG['ad_entry_revision'], 636 $entry['revision_id'], 637 $date->format(date('Y-m-d H:i', $entry['date'])), 638 $entryUser->getUserData('display_name') 639 ); 640 ?> 641 <br> 642 <?= $entry['changelog'] ?> 643 </li> 644 <?php } ?> 645 </ul> 646 </div> 647 </div> 648 </div> 649 </div> 650 </div> 651 </div> 652 </div> 653 654 <!-- Sidebar --> 655 <div class="col-lg-3"> 656 <div id="accordion" role="tablist"> 657 <div class="card mb-4"> 658 <div class="card-header text-center" role="tab" id="pmf-heading-date"> 659 <?php if ($selectedRevisionId === $faqData['revision_id']): ?> 660 <button class="btn btn-lg btn-info" type="reset"> 661 <?= $PMF_LANG['ad_gen_reset'] ?> 662 </button> 663 <button class="btn btn-lg btn-primary" type="submit"> 664 <?= $PMF_LANG['ad_entry_save'] ?> 665 </button> 666 <?php endif ?> 667 668 </div> 669 <div class="card-body"> 670 <h5 class="mb-0"> 671 <?= $PMF_LANG['ad_entry_date'] ?> 672 </h5> 673 <div class="form-group"> 674 <div class="form-check"> 675 <input type="radio" id="dateActualize" checked name="recordDateHandling" 676 class="form-check-input" 677 onchange="setRecordDate(this.id);"> 678 <label class="form-check-label" for="dateActualize"> 679 <?= $PMF_LANG['msgUpdateFaqDate'] ?> 680 </label> 681 </div> 682 <div class="form-check"> 683 <input type="radio" id="dateKeep" name="recordDateHandling" class="form-check-input" 684 onchange="setRecordDate(this.id);"> 685 <label class="form-check-label" for="dateKeep"> 686 <?= $PMF_LANG['msgKeepFaqDate'] ?> 687 </label> 688 </div> 689 <div class="form-check"> 690 <input type="radio" id="dateCustomize" name="recordDateHandling" 691 class="form-check-input" 692 onchange="setRecordDate(this.id);"> 693 <label class="form-check-label" for="dateCustomize"> 694 <?= $PMF_LANG['msgEditFaqDat'] ?> 695 </label> 696 </div> 697 <div id="recordDateInputContainer" class="form-group invisible"> 698 <input type="datetime-local" name="date" id="date" class="form-control" 699 placeholder="<?= $faqData['date'] ?>"> 700 </div> 701 </div> 702 <h5 class="mb-0"> 703 <?= $PMF_LANG['ad_entry_status'] ?> 704 </h5> 705 <div class="form-group"> 706 <!-- active or not --> 707 <?php if ($user->perm->checkRight($currentUserId, 'approverec')): 708 if (isset($faqData['active']) && $faqData['active'] == 'yes') { 709 $suf = ' checked'; 710 $sul = null; 711 } elseif ($faqConfig->get('records.defaultActivation')) { 712 $suf = ' checked'; 713 $sul = null; 714 } else { 715 $suf = null; 716 $sul = ' checked'; 717 } 718 ?> 719 <div class="form-check"> 720 <input type="radio" id="active" name="active" value="yes" 721 class="form-check-input" 722 <?php if (isset($suf)) { 723 echo $suf; 724 } ?>> 725 <label class="form-check-label" 726 for="active"><?= $PMF_LANG['ad_entry_visibility'] ?></label> 727 </div> 728 <div class="form-check"> 729 <input type="radio" id="inactive" name="active" value="no" 730 class="form-check-input" 731 <?php if (isset($sul)) { 732 echo $sul; 733 } ?>> 734 <label class="form-check-label" 735 for="inactive"><?= $PMF_LANG['ad_gen_no'] ?></label> 736 </div> 737 <?php else: ?> 738 <div class="form-check"> 739 <input type="radio" id="inactive" name="active" value="no" 740 class="form-check-input" checked> 741 <label class="form-check-label" 742 for="inactive"><?= $PMF_LANG['ad_gen_no'] ?></label> 743 </div> 744 <?php endif; ?> 745 </div> 746 747 <?php if ($queryString != 'insertentry' && !$faqConfig->get('records.enableAutoRevisions')): ?> 748 <h5 class="mb-0"> 749 <?= $PMF_LANG['ad_entry_new_revision'] ?> 750 </h5> 751 <div class="form-group"> 752 <div class="form-check"> 753 <input type="radio" name="revision" id="revision" value="yes" 754 class="form-check-input"> 755 <label class="form-check-label" 756 for="revision"><?= $PMF_LANG['ad_gen_yes'] ?></label> 757 </div> 758 <div class="form-check"> 759 <input type="radio" name="revision" id="no-revision" value="no" 760 checked class="form-check-input"> 761 <label class="form-check-label" 762 for="no-revision"><?= $PMF_LANG['ad_gen_no'] ?></label> 763 </div> 764 </div> 765 <?php endif ?> 766 767 <div class="form-group"> 768 <!-- sticky or not --> 769 <div class="form-check"> 770 <input type="checkbox" id="sticky" name="sticky" class="form-check-input" 771 <?php echo(isset($faqData['sticky']) && $faqData['sticky'] ? 'checked' : '') ?>> 772 <label class="form-check-label" 773 for="sticky"><?= $PMF_LANG['ad_entry_sticky'] ?></label> 774 </div> 775 776 <!-- comments allowed or not --> 777 <div class="form-check"> 778 <input type="checkbox" name="comment" id="comment" value="y" 779 class="form-check-input" 780 <?= $faqData['comment'] ?>> 781 <label class="form-check-label" 782 for="comment"><?= $PMF_LANG['ad_entry_allowComments'] ?></label> 783 </div> 784 </div> 785 786 <div class="form-group"> 787 <!-- solution id --> 788 <label class="col-form-label" for="solution_id"> 789 <?= $PMF_LANG['ad_entry_solution_id'] ?>: 790 </label> 791 <input type="number" name="solution_id" id="solution_id" size="5" class="form-control" 792 readonly 793 value="<?= isset($faqData['solution_id']) ? $faqData['solution_id'] : $faq->getSolutionId( 794 ) ?>"> 795 </div> 796 </div> 797 </div> 798 </div> 799 </div> 800 </div> 801 802 </form> 803 804 <!-- Attachment Upload Dialog --> 805 <?php 806 if (0 === $faqData['id']) { 807 $faqData['id'] = $faqConfig->getDb()->nextId( 808 Database::getTablePrefix() . 'faqdata', 809 'id' 810 ); 811 } 812 ?> 813 <div class="modal fade" id="attachmentModal" tabindex="-1" role="dialog" aria-labelledby="attachmentModalLabel" 814 aria-hidden="true"> 815 <div class="modal-dialog" role="document"> 816 <div class="modal-content"> 817 <div class="modal-header"> 818 <h5 class="modal-title" id="attachmentModalLabel"> 819 <?= $PMF_LANG['ad_att_addto'] . ' ' . $PMF_LANG['ad_att_addto_2'] ?> 820 (max <?= round($faqConfig->get('records.maxAttachmentSize') / pow(1024, 2), 2) ?> MB) 821 </h5> 822 <button type="button" class="close" data-dismiss="modal" aria-label="Close"> 823 <span aria-hidden="true">×</span> 824 </button> 825 </div> 826 <div class="modal-body"> 827 <form action="ajax.attachment.php?action=upload" enctype="multipart/form-data" method="post" 828 id="attachmentForm" novalidate> 829 <fieldset> 830 <input type="hidden" name="MAX_FILE_SIZE" 831 value="<?= $faqConfig->get('records.maxAttachmentSize') ?>"> 832 <input type="hidden" name="record_id" id="attachment_record_id" 833 value="<?= $faqData['id'] ?>"> 834 <input type="hidden" name="record_lang" id="attachment_record_lang" 835 value="<?= $faqData['lang'] ?>"> 836 <input type="hidden" name="save" value="true"> 837 <input type="hidden" name="csrf" value="<?= $user->getCsrfTokenFromSession() ?>"> 838 839 <div class="custom-file"> 840 <input type="file" class="custom-file-input" name="filesToUpload[]" id="filesToUpload" multiple> 841 <label class="custom-file-label" for="filesToUpload"> 842 <?= $PMF_LANG['ad_att_att'] ?> 843 </label> 844 <div class="invalid-feedback"> 845 The file is too big. 846 </div> 847 </div> 848 849 <div class="form-group pmf-attachment-upload-files invisible"> 850 <?= $PMF_LANG['msgAttachmentsFilesize'] ?>: 851 <output id="filesize"></output> 852 </div> 853 <div class="progress invisible"> 854 <div class="progress-bar progress-bar-striped bg-success progress-bar-animated" 855 role="progressbar" aria-valuemin="0" aria-valuemax="100"></div> 856 </div> 857 858 </fieldset> 859 </form> 860 </div> 861 <div class="modal-footer"> 862 <button type="reset" class="btn btn-primary" data-dismiss="modal" id="pmf-attachment-modal-close"> 863 <?= $PMF_LANG['ad_att_close'] ?> 864 </button> 865 <button type="button" class="btn btn-primary" id="pmf-attachment-modal-upload"> 866 <?= $PMF_LANG['ad_att_butt'] ?> 867 </button> 868 </div> 869 </div> 870 </div> 871 </div> 872 873 <script src="assets/js/record.js"></script> 874 <script> 875 function setRecordDate(how) { 876 if ('dateActualize' === how) { 877 $('#date').val(''); 878 } else if ('dateKeep' === how) { 879 $('#date').val('<?= $faqData['isoDate'] ?>'); 880 } else if ('dateCustomize' === how) { 881 $('#recordDateInputContainer').removeClass('invisible'); 882 $('#date').val(''); 883 } 884 } 885 </script> 886 <?php 887} elseif ($user->perm->checkRight($currentUserId, 'edit_faq') !== 1 && !Database::checkOnEmptyTable('faqcategories')) { 888 echo $PMF_LANG['err_NotAuth']; 889} elseif ($user->perm->checkRight($currentUserId, 'edit_faq') && Database::checkOnEmptyTable('faqcategories')) { 890 echo $PMF_LANG['no_cats']; 891} 892