Skip to content

Commit 026d63b

Browse files
authored
Merge pull request #6367 from WoltLab/6.2-list-view-box-controller
Add abstract implementation for box controllers that are based on list views
2 parents 63295a1 + 2850bd4 commit 026d63b

File tree

9 files changed

+160
-27
lines changed

9 files changed

+160
-27
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<div class="{$containerCssClassName}">
2+
{unsafe:$listView->render()}
3+
</div>

com.woltlab.wcf/templates/shared_listView.tpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
</div>
5555
</div>
5656

57-
<div class="listView__footer" id="{$view->getID()}_footer">
57+
<div class="listView__footer" id="{$view->getID()}_footer"{if $view->countPages() < 2} hidden{/if}>
5858
{if $view->hasBulkInteractions()}
5959
<div id="{$view->getID()}_selectionBar" class="listView__selectionBar dropdown" hidden>
6060
<button type="button" id="{$view->getID()}_bulkInteractionButton" class="button small listView__bulkInteractionButton dropdownToggle"></button>

ts/WoltLabSuite/Core/Component/ListView/Selection.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ export class Selection extends EventTarget {
5151
this.#restoreSelection();
5252
}
5353

54+
selectionBarVisible(): boolean {
55+
return this.#selectionBar !== null && this.getSelectedIds().length > 0;
56+
}
57+
5458
refresh(): void {
5559
this.#restoreSelection();
5660
}

ts/WoltLabSuite/Core/Component/ListView/State.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ export class State extends EventTarget {
186186
}
187187

188188
#updateListViewFooter(): void {
189-
this.#listViewFooter.hidden = this.#pagination.count < 2 && this.#selection.getSelectedIds().length === 0;
189+
this.#listViewFooter.hidden = this.#pagination.count < 2 && !this.#selection.selectionBarVisible();
190190
}
191191

192192
setBulkInteractionContextMenuOptions(options: string): void {

wcfsetup/install/files/js/WoltLabSuite/Core/Component/ListView/Selection.js

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

wcfsetup/install/files/js/WoltLabSuite/Core/Component/ListView/State.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
<?php
2+
3+
namespace wcf\system\box;
4+
5+
use wcf\system\condition\IObjectListCondition;
6+
use wcf\system\event\EventHandler;
7+
use wcf\system\listView\AbstractListView;
8+
use wcf\system\WCF;
9+
10+
/**
11+
* Default implementation of a box controller based on a list view.
12+
*
13+
* @author Marcel Werk
14+
* @copyright 2001-2025 WoltLab GmbH
15+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
16+
* @since 6.2
17+
*
18+
* @template TListView of AbstractListView
19+
*/
20+
abstract class AbstractListViewBoxController extends AbstractDatabaseObjectListBoxController
21+
{
22+
/**
23+
* @var TListView
24+
*/
25+
protected AbstractListView $listView;
26+
27+
/**
28+
* @return TListView
29+
*/
30+
protected function getListView(): AbstractListView
31+
{
32+
if (!isset($this->listView)) {
33+
$this->listView = $this->createListView();
34+
$this->listView->setAllowFiltering(false);
35+
$this->listView->setAllowSorting(false);
36+
$this->listView->setAllowBulkInteractions(false);
37+
}
38+
39+
return $this->listView;
40+
}
41+
42+
/**
43+
* @return TListView
44+
*/
45+
protected abstract function createListView(): AbstractListView;
46+
47+
#[\Override]
48+
public function hasContent()
49+
{
50+
EventHandler::getInstance()->fireAction($this, 'hasContent');
51+
52+
if ($this->objectList === null) {
53+
$this->loadContent();
54+
}
55+
56+
return $this->getListView()->countItems() > 0;
57+
}
58+
59+
#[\Override]
60+
protected function loadContent()
61+
{
62+
EventHandler::getInstance()->fireAction($this, 'beforeLoadContent');
63+
64+
if ($this->limit) {
65+
$this->getListView()->setFixedNumberOfItems($this->limit);
66+
}
67+
68+
if ($this->sortOrder && $this->sortField) {
69+
$this->getListView()->setSortField($this->sortField);
70+
$this->getListView()->getSortOrder($this->sortOrder);
71+
}
72+
73+
$this->objectList = $this->getObjectList();
74+
75+
if ($this->conditionDefinition) {
76+
foreach ($this->box->getControllerConditions() as $condition) {
77+
$processor = $condition->getObjectType()->getProcessor();
78+
if ($processor instanceof IObjectListCondition) {
79+
$processor->addObjectListCondition($this->objectList, $condition->conditionData);
80+
}
81+
}
82+
}
83+
84+
$this->content = $this->getTemplate();
85+
86+
EventHandler::getInstance()->fireAction($this, 'afterLoadContent');
87+
}
88+
89+
#[\Override]
90+
protected function getObjectList()
91+
{
92+
return $this->getListView()->getObjectList();
93+
}
94+
95+
#[\Override]
96+
protected function getTemplate()
97+
{
98+
return WCF::getTPL()->render('wcf', 'boxListView', [
99+
'listView' => $this->listView,
100+
'containerCssClassName' => $this->getContainerCssClassName(),
101+
]);
102+
}
103+
104+
public function getContainerCssClassName(): string
105+
{
106+
return '';
107+
}
108+
109+
#[\Override]
110+
protected function readObjects()
111+
{
112+
// Does nothing.
113+
}
114+
}

wcfsetup/install/files/lib/system/box/ArticleListBoxController.class.php

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace wcf\system\box;
44

5-
use wcf\data\article\AccessibleArticleList;
5+
use wcf\system\listView\user\ArticleListView;
66
use wcf\system\WCF;
77

88
/**
@@ -13,9 +13,9 @@
1313
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
1414
* @since 3.0
1515
*
16-
* @extends AbstractDatabaseObjectListBoxController<AccessibleArticleList>
16+
* @extends AbstractListViewBoxController<ArticleListView>
1717
*/
18-
class ArticleListBoxController extends AbstractDatabaseObjectListBoxController
18+
class ArticleListBoxController extends AbstractListViewBoxController
1919
{
2020
/**
2121
* @inheritDoc
@@ -51,12 +51,8 @@ class ArticleListBoxController extends AbstractDatabaseObjectListBoxController
5151
public $validSortFields = [
5252
'time',
5353
'views',
54-
'random',
5554
];
5655

57-
/**
58-
* @inheritDoc
59-
*/
6056
public function __construct()
6157
{
6258
if (!empty($this->validSortFields) && MODULE_LIKE) {
@@ -66,35 +62,42 @@ public function __construct()
6662
parent::__construct();
6763
}
6864

69-
/**
70-
* @inheritDoc
71-
*/
65+
#[\Override]
7266
protected function getObjectList()
7367
{
74-
$objectList = new AccessibleArticleList();
68+
$objectList = $this->getListView()->getObjectList();
7569

7670
switch ($this->sortField) {
7771
case 'views':
7872
$objectList->getConditionBuilder()->add('article.views > ?', [0]);
7973
break;
8074
}
8175

82-
if ($this->sortField === 'random') {
83-
$this->sortField = 'RAND()';
84-
}
85-
8676
return $objectList;
8777
}
8878

89-
/**
90-
* @inheritDoc
91-
*/
79+
#[\Override]
80+
protected function createListView(): ArticleListView
81+
{
82+
return new ArticleListView();
83+
}
84+
85+
#[\Override]
86+
public function getContainerCssClassName(): string
87+
{
88+
return 'entryCardList__container';
89+
}
90+
91+
#[\Override]
9292
protected function getTemplate()
9393
{
94-
return WCF::getTPL()->render('wcf', 'boxArticleList', [
95-
'boxArticleList' => $this->objectList,
96-
'boxSortField' => $this->sortField,
97-
'boxPosition' => $this->box->position,
98-
]);
94+
return match ($this->box->position) {
95+
'top', 'bottom', 'contentTop', 'contentBottom' => parent::getTemplate(),
96+
default => WCF::getTPL()->render('wcf', 'boxArticleList', [
97+
'boxArticleList' => $this->getListView()->getItems(),
98+
'boxSortField' => $this->sortField,
99+
'boxPosition' => $this->box->position,
100+
])
101+
};
99102
}
100103
}

wcfsetup/install/files/lib/system/listView/AbstractListView.class.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ abstract class AbstractListView
4242
private bool $allowFiltering = true;
4343
private bool $allowSorting = true;
4444
private bool $allowInteractions = true;
45+
private bool $allowBulkInteractions = true;
4546
private int $fixedNumberOfItems = 0;
4647

4748
/**
@@ -479,7 +480,7 @@ public function getBulkInteractionProvider(): ?IBulkInteractionProvider
479480
*/
480481
public function hasBulkInteractions(): bool
481482
{
482-
return $this->allowInteractions
483+
return $this->allowBulkInteractions
483484
&& $this->getBulkInteractionProvider() !== null
484485
&& $this->getBulkInteractionProvider()->getInteractions() !== [];
485486
}
@@ -498,6 +499,11 @@ public function setAllowInteractions(bool $allowInteractions): void
498499
$this->allowInteractions = $allowInteractions;
499500
}
500501

502+
public function setAllowBulkInteractions(bool $allowBulkInteractions): void
503+
{
504+
$this->allowBulkInteractions = $allowBulkInteractions;
505+
}
506+
501507
/**
502508
* Returns true, if this list view has interactions.
503509
*/

0 commit comments

Comments
 (0)