From 48fae60ace2210e0a37f79803d5b526d55b1807d Mon Sep 17 00:00:00 2001 From: Peter Lohse Date: Sat, 2 Nov 2024 12:50:40 +0100 Subject: [PATCH 1/7] fix formation for missing category --- acptemplates/faqQuestionAdd.tpl | 6 +- .../lib/acp/form/FaqQuestionAddForm.class.php | 66 +++++++++++-------- package.xml | 10 +-- templates/faqQuestionAdd.tpl | 6 +- 4 files changed, 55 insertions(+), 33 deletions(-) diff --git a/acptemplates/faqQuestionAdd.tpl b/acptemplates/faqQuestionAdd.tpl index bb32bcf..268c56b 100644 --- a/acptemplates/faqQuestionAdd.tpl +++ b/acptemplates/faqQuestionAdd.tpl @@ -14,6 +14,10 @@ -{unsafe:$form->getHtml()} +{if $categories|count} + {unsafe:$form->getHtml()} +{else} + {lang}wcf.acp.faq.question.error.noCategory{/lang} +{/if} {include file='footer'} \ No newline at end of file diff --git a/files/lib/acp/form/FaqQuestionAddForm.class.php b/files/lib/acp/form/FaqQuestionAddForm.class.php index ea2f4a5..0eceaab 100644 --- a/files/lib/acp/form/FaqQuestionAddForm.class.php +++ b/files/lib/acp/form/FaqQuestionAddForm.class.php @@ -11,7 +11,6 @@ use wcf\data\IStorableObject; use wcf\data\language\item\LanguageItemList; use wcf\form\AbstractFormBuilderForm; -use wcf\system\exception\NamedUserException; use wcf\system\form\builder\container\FormContainer; use wcf\system\form\builder\container\TabFormContainer; use wcf\system\form\builder\container\TabMenuFormContainer; @@ -60,6 +59,8 @@ class FaqQuestionAddForm extends AbstractFormBuilderForm protected array $multiLingualAnswers = []; + protected array $categories; + #[Override] public function readParameters() { @@ -102,31 +103,6 @@ protected function createForm() { parent::createForm(); - $categoryTree = new FaqCategoryNodeTree('dev.tkirch.wsc.faq.category'); - $categoryTree->setMaxDepth(0); - $categoryList = $categoryTree->getIterator(); - - $categories = []; - foreach ($categoryList as $category) { - $categories[$category->categoryID] = $category; - - $childCategories = $category->getAllChildCategories(); - if (!\count($childCategories)) { - continue; - } - - foreach ($childCategories as $childCategory) { - $childCategory->setPrefix(); - $categories[$childCategory->categoryID] = $childCategory; - } - } - - if (!\count($categories)) { - throw new NamedUserException( - WCF::getLanguage()->getDynamicVariable('wcf.acp.faq.question.error.noCategory') - ); - } - $tabContent = []; if ($this->isMultilingual) { foreach ($this->availableLanguages as $language) { @@ -148,7 +124,7 @@ protected function createForm() ->appendChildren([ SingleSelectionFormField::create('categoryID') ->label('wcf.acp.faq.category') - ->options($categories) + ->options($this->getCategories()) ->required(), TextFormField::create('question') ->label('wcf.acp.faq.question.question') @@ -239,4 +215,40 @@ protected function setFormAction() $this->form->action(LinkHandler::getInstance()->getControllerLink(static::class, $parameters)); } + + #[Override] + public function assignVariables() + { + parent::assignVariables(); + + WCF::getTPL()->assign([ + 'categories' => $this->getCategories(), + ]); + } + + protected function getCategories(): array + { + if (!isset($this->categories)) { + $categoryTree = new FaqCategoryNodeTree('dev.tkirch.wsc.faq.category'); + $categoryTree->setMaxDepth(0); + $categoryList = $categoryTree->getIterator(); + + $this->categories = []; + foreach ($categoryList as $category) { + $this->categories[$category->categoryID] = $category; + + $childCategories = $category->getAllChildCategories(); + if (!\count($childCategories)) { + continue; + } + + foreach ($childCategories as $childCategory) { + $childCategory->setPrefix(); + $this->categories[$childCategory->categoryID] = $childCategory; + } + } + } + + return $this->categories; + } } diff --git a/package.xml b/package.xml index 88ae5c1..55c3573 100644 --- a/package.xml +++ b/package.xml @@ -6,8 +6,8 @@ Simple FAQ A simple and powerful FAQ for your WSC. Ein simples und leistungsstarkes FAQ für Ihr WSC. - 2.2.4 - 2024-10-29 + 2.2.5 + 2024-11-03 Hanashi Development, Titus Kirch @@ -36,8 +36,10 @@ acp/database/install_dev.tkirch.wsc.faq.php - - + + + + diff --git a/templates/faqQuestionAdd.tpl b/templates/faqQuestionAdd.tpl index 67ac013..4ac3e8d 100644 --- a/templates/faqQuestionAdd.tpl +++ b/templates/faqQuestionAdd.tpl @@ -18,6 +18,10 @@ {include file='header' contentHeader=$__contentHeader} -{unsafe:$form->getHtml()} +{if $categories|count} + {unsafe:$form->getHtml()} +{else} + {lang}wcf.acp.faq.question.error.noCategory{/lang} +{/if} {include file='footer'} From fea6bc398582a254bd566dd8c3754b3c576b7270 Mon Sep 17 00:00:00 2001 From: Peter Lohse Date: Sat, 2 Nov 2024 12:53:08 +0100 Subject: [PATCH 2/7] show category box only if categories exists --- files/lib/system/box/FaqCategoriesBoxController.class.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/files/lib/system/box/FaqCategoriesBoxController.class.php b/files/lib/system/box/FaqCategoriesBoxController.class.php index 9b282f5..13eb871 100644 --- a/files/lib/system/box/FaqCategoriesBoxController.class.php +++ b/files/lib/system/box/FaqCategoriesBoxController.class.php @@ -46,6 +46,9 @@ protected function getResetFilterLink(): string #[Override] public function hasContent() { - return SIMPLE_FAQ_VIEW !== 'gallery'; + $categoryTree = $this->getNodeTree(); + $categoryList = $categoryTree->getIterator(); + + return SIMPLE_FAQ_VIEW !== 'gallery' && \iterator_count($categoryList); } } From ec08364d405af83052a690a694fcd745ee6e8278 Mon Sep 17 00:00:00 2001 From: Peter Lohse Date: Sat, 2 Nov 2024 13:09:13 +0100 Subject: [PATCH 3/7] fix category view --- files/lib/page/FaqQuestionListPage.class.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/files/lib/page/FaqQuestionListPage.class.php b/files/lib/page/FaqQuestionListPage.class.php index 6bc2cb1..0666a9a 100644 --- a/files/lib/page/FaqQuestionListPage.class.php +++ b/files/lib/page/FaqQuestionListPage.class.php @@ -73,16 +73,13 @@ public function assignVariables() $questionList->getConditionBuilder()->add('categoryID = ?', [$category->categoryID]); $questionList->readObjects(); - if (!\count($questionList)) { - continue; - } - $faq = [ 'id' => $category->categoryID, 'title' => WCF::getLanguage()->get($category->title), - 'attachments' => $questionList->getAttachmentList(), + 'attachments' => count($questionList) ? $questionList->getAttachmentList() : [], 'icon24' => $category->getIcon(24), 'icon64' => $category->getIcon(64), + 'questions' => [], ]; foreach ($questionList->getObjects() as $question) { From 2fff444b9e26f73eb30571558ffe90d091cd6872 Mon Sep 17 00:00:00 2001 From: Peter Lohse Date: Sat, 2 Nov 2024 13:34:31 +0100 Subject: [PATCH 4/7] performance verbesserung --- files/lib/data/faq/QuestionEditor.class.php | 11 ++++- files/lib/data/faq/QuestionList.class.php | 21 -------- files/lib/page/FaqQuestionListPage.class.php | 48 +++++++++++++------ .../FaqQuestionListCacheBuilder.class.php | 23 +++++++++ 4 files changed, 67 insertions(+), 36 deletions(-) create mode 100644 files/lib/system/cache/builder/FaqQuestionListCacheBuilder.class.php diff --git a/files/lib/data/faq/QuestionEditor.class.php b/files/lib/data/faq/QuestionEditor.class.php index 8f19153..c6dedc9 100644 --- a/files/lib/data/faq/QuestionEditor.class.php +++ b/files/lib/data/faq/QuestionEditor.class.php @@ -2,7 +2,10 @@ namespace wcf\data\faq; +use Override; use wcf\data\DatabaseObjectEditor; +use wcf\data\IEditableCachedObject; +use wcf\system\cache\builder\FaqQuestionListCacheBuilder; use wcf\system\WCF; /** @@ -10,13 +13,19 @@ * @method Question getDecoratedObject() * @mixin Question */ -final class QuestionEditor extends DatabaseObjectEditor +final class QuestionEditor extends DatabaseObjectEditor implements IEditableCachedObject { /** * @inheritDoc */ protected static $baseClass = Question::class; + #[Override] + public static function resetCache() + { + FaqQuestionListCacheBuilder::getInstance()->reset(); + } + /** * Returns the new show order for a object */ diff --git a/files/lib/data/faq/QuestionList.class.php b/files/lib/data/faq/QuestionList.class.php index 30afecc..f35f243 100644 --- a/files/lib/data/faq/QuestionList.class.php +++ b/files/lib/data/faq/QuestionList.class.php @@ -2,7 +2,6 @@ namespace wcf\data\faq; -use wcf\data\attachment\GroupedAttachmentList; use wcf\data\DatabaseObjectList; /** @@ -18,24 +17,4 @@ final class QuestionList extends DatabaseObjectList * @inheritDoc */ public $sqlOrderBy = 'showOrder, questionID'; - - private GroupedAttachmentList $attachmentList; - - public function readAttachments() - { - if (!empty($this->objectIDs)) { - $this->attachmentList = new GroupedAttachmentList('dev.tkirch.wsc.faq.question'); - $this->attachmentList->getConditionBuilder()->add('attachment.objectID IN (?)', [$this->objectIDs]); - $this->attachmentList->readObjects(); - } - } - - public function getAttachmentList() - { - if (!isset($this->attachmentList)) { - $this->readAttachments(); - } - - return $this->attachmentList; - } } diff --git a/files/lib/page/FaqQuestionListPage.class.php b/files/lib/page/FaqQuestionListPage.class.php index 0666a9a..c03bd7b 100644 --- a/files/lib/page/FaqQuestionListPage.class.php +++ b/files/lib/page/FaqQuestionListPage.class.php @@ -4,10 +4,11 @@ use CuyZ\Valinor\Mapper\MappingError; use Override; +use wcf\data\attachment\GroupedAttachmentList; use wcf\data\faq\category\FaqCategory; use wcf\data\faq\category\FaqCategoryNodeTree; -use wcf\data\faq\QuestionList; use wcf\http\Helper; +use wcf\system\cache\builder\FaqQuestionListCacheBuilder; use wcf\system\exception\IllegalLinkException; use wcf\system\message\embedded\object\MessageEmbeddedObjectManager; use wcf\system\WCF; @@ -19,6 +20,8 @@ class FaqQuestionListPage extends AbstractPage */ public $neededPermissions = ['user.faq.canViewFAQ']; + protected array $faqs = []; + protected int $showFaqAddDialog = 0; protected ?FaqCategory $category; @@ -49,14 +52,15 @@ public function readParameters() } #[Override] - public function assignVariables() + public function readData() { - parent::assignVariables(); + parent::readData(); //get categories - $faqs = []; $embedObjectIDs = []; $categoryTree = new FaqCategoryNodeTree('dev.tkirch.wsc.faq.category'); + [$questionList, $questionIDs] = FaqQuestionListCacheBuilder::getInstance()->getData(); + $attachmentList = $this->getAttachmentList($questionIDs); foreach ($categoryTree->getIterator() as $category) { if (!$category->isAccessible()) { continue; @@ -69,20 +73,17 @@ public function assignVariables() continue; } - $questionList = new QuestionList(); - $questionList->getConditionBuilder()->add('categoryID = ?', [$category->categoryID]); - $questionList->readObjects(); - $faq = [ 'id' => $category->categoryID, 'title' => WCF::getLanguage()->get($category->title), - 'attachments' => count($questionList) ? $questionList->getAttachmentList() : [], + 'attachments' => $attachmentList, 'icon24' => $category->getIcon(24), 'icon64' => $category->getIcon(64), 'questions' => [], ]; - foreach ($questionList->getObjects() as $question) { + $questions = $questionList[$category->categoryID] ?? []; + foreach ($questions as $question) { if ($question->isAccessible()) { $faq['questions'][] = $question; if ($question->hasEmbeddedObjects) { @@ -92,22 +93,41 @@ public function assignVariables() } if ($category->getParentNode() && $category->getParentNode()->categoryID) { - $faqs[$category->getParentNode()->categoryID]['sub'][$category->categoryID] = $faq; + $this->faqs[$category->getParentNode()->categoryID]['sub'][$category->categoryID] = $faq; } else { - $faqs[$category->categoryID] = $faq; + $this->faqs[$category->categoryID] = $faq; } } - if (\count($embedObjectIDs)) { + if ($embedObjectIDs !== []) { MessageEmbeddedObjectManager::getInstance()->loadObjects( 'dev.tkirch.wsc.faq.question', $embedObjectIDs ); } + } + + #[Override] + public function assignVariables() + { + parent::assignVariables(); WCF::getTPL()->assign([ - 'faqs' => $faqs, + 'faqs' => $this->faqs, 'showFaqAddDialog' => $this->showFaqAddDialog, ]); } + + protected function getAttachmentList(array $questionIDs): array|GroupedAttachmentList + { + if ($questionIDs === []) { + return []; + } + + $attachmentList = new GroupedAttachmentList('dev.tkirch.wsc.faq.question'); + $attachmentList->getConditionBuilder()->add('attachment.objectID IN (?)', [$questionIDs]); + $attachmentList->readObjects(); + + return $attachmentList; + } } diff --git a/files/lib/system/cache/builder/FaqQuestionListCacheBuilder.class.php b/files/lib/system/cache/builder/FaqQuestionListCacheBuilder.class.php new file mode 100644 index 0000000..bc23312 --- /dev/null +++ b/files/lib/system/cache/builder/FaqQuestionListCacheBuilder.class.php @@ -0,0 +1,23 @@ +readObjects(); + + $questions = []; + foreach ($questionList as $question) { + $questions[$question->categoryID][] = $question; + } + + return [$questions, $questionList->getObjectIDs()]; + } +} From b54220a51b3aa219e798bad8ed47825eb9736dfd Mon Sep 17 00:00:00 2001 From: Peter Lohse Date: Sat, 2 Nov 2024 13:55:06 +0100 Subject: [PATCH 5/7] fix icon wurde nicht gespeichert --- files/lib/acp/form/FaqCategoryAddForm.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/files/lib/acp/form/FaqCategoryAddForm.class.php b/files/lib/acp/form/FaqCategoryAddForm.class.php index 2089bd0..b994f85 100644 --- a/files/lib/acp/form/FaqCategoryAddForm.class.php +++ b/files/lib/acp/form/FaqCategoryAddForm.class.php @@ -39,8 +39,6 @@ protected function createForm() #[Override] protected function finalizeForm() { - parent::finalizeForm(); - $this->form->getDataHandler()->addProcessor( new CustomFormDataProcessor( 'icon', @@ -59,5 +57,7 @@ function (IFormDocument $document, array $data, IStorableObject $object) { } ) ); + + parent::finalizeForm(); } } From 0a40ab5f2e146673b401c11b79f515dc727aab48 Mon Sep 17 00:00:00 2001 From: Peter Lohse Date: Sat, 2 Nov 2024 14:10:32 +0100 Subject: [PATCH 6/7] =?UTF-8?q?Kategorien=20k=C3=B6nnen=20nun=20eine=20Bes?= =?UTF-8?q?chreibung=20haben?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/faq/category/FaqCategory.class.php | 17 ++++++++++++- files/lib/page/FaqQuestionListPage.class.php | 5 +--- .../system/category/FaqCategoryType.class.php | 9 ++++++- files/style/faq.scss | 18 ++++++++------ templates/faqQuestionList.tpl | 24 ++++++++++--------- 5 files changed, 49 insertions(+), 24 deletions(-) diff --git a/files/lib/data/faq/category/FaqCategory.class.php b/files/lib/data/faq/category/FaqCategory.class.php index 2c79195..02a2ac7 100644 --- a/files/lib/data/faq/category/FaqCategory.class.php +++ b/files/lib/data/faq/category/FaqCategory.class.php @@ -13,6 +13,7 @@ use wcf\system\request\LinkHandler; use wcf\system\style\FontAwesomeIcon; use wcf\system\WCF; +use wcf\util\StringUtil; /** * @method FaqCategory[] getChildCategories() @@ -86,7 +87,17 @@ public function getLink(): string ]); } - public function getIcon(int $size = 24): string + public function getDescription(): string + { + return WCF::getLanguage()->get($this->description); + } + + public function getDescriptionHtml(): string + { + return $this->descriptionUseHtml ? $this->getDescription() : StringUtil::encodeHTML($this->getDescription()); + } + + public function getIcon(int $size = 24, bool $defaultIcon = false): string { if ( isset($this->additionalData['faqIcon']) @@ -95,6 +106,10 @@ public function getIcon(int $size = 24): string return FontAwesomeIcon::fromString($this->additionalData['faqIcon'])->toHtml($size); } + if ($defaultIcon) { + return FontAwesomeIcon::fromString('circle-question;false')->toHtml($size); + } + return ''; } } diff --git a/files/lib/page/FaqQuestionListPage.class.php b/files/lib/page/FaqQuestionListPage.class.php index c03bd7b..38a6d1c 100644 --- a/files/lib/page/FaqQuestionListPage.class.php +++ b/files/lib/page/FaqQuestionListPage.class.php @@ -74,11 +74,8 @@ public function readData() } $faq = [ - 'id' => $category->categoryID, - 'title' => WCF::getLanguage()->get($category->title), + 'category' => $category, 'attachments' => $attachmentList, - 'icon24' => $category->getIcon(24), - 'icon64' => $category->getIcon(64), 'questions' => [], ]; diff --git a/files/lib/system/category/FaqCategoryType.class.php b/files/lib/system/category/FaqCategoryType.class.php index fb663c4..dcb924d 100644 --- a/files/lib/system/category/FaqCategoryType.class.php +++ b/files/lib/system/category/FaqCategoryType.class.php @@ -14,7 +14,7 @@ final class FaqCategoryType extends AbstractCategoryType /** * @inheritDoc */ - protected $hasDescription = false; + protected $hasDescription = true; /** * @inheritDoc @@ -42,7 +42,14 @@ final class FaqCategoryType extends AbstractCategoryType protected function init() { $this->maximumNestingLevel = SIMPLE_FAQ_VIEW === 'gallery' ? 0 : 1; + $this->hasDescription = SIMPLE_FAQ_VIEW === 'gallery' ? false : true; parent::init(); } + + #[Override] + public function supportsHtmlDescription() + { + return SIMPLE_FAQ_VIEW === 'gallery' ? false : true; + } } diff --git a/files/style/faq.scss b/files/style/faq.scss index 926fd7a..0572943 100644 --- a/files/style/faq.scss +++ b/files/style/faq.scss @@ -43,18 +43,22 @@ } .faq { - > h2 { - font-size: 1.5rem; - border-bottom: 1px solid currentColor; - padding-bottom: 10px + > .sectionHeader { + h2 { + font-size: 1.5rem !important; + } + border-bottom: 1px solid currentColor !important; + padding-bottom: 10px; } > .sub { margin-top: 16px; margin-bottom: 8px; margin-left: 16px; - > h2 { - font-size: 1.3rem; - border-bottom: 1px solid currentColor; + .sectionHeader { + h2 { + font-size: 1.3rem !important; + } + border-bottom: 1px solid currentColor !important; padding-bottom: 10px; } } diff --git a/templates/faqQuestionList.tpl b/templates/faqQuestionList.tpl index 98555db..9538d0d 100644 --- a/templates/faqQuestionList.tpl +++ b/templates/faqQuestionList.tpl @@ -23,13 +23,9 @@
{foreach from=$faqs item=faq} {if ($faq['questions']|isset && $faq['questions']|count)} - {/if} {/foreach} @@ -46,8 +42,8 @@ {if ($faq['questions']|isset && $faq['questions']|count)} {assign var='attachmentList' value=$faq['attachments']} -