Skip to content

Commit d711ab3

Browse files
authored
Merge pull request #6650 from WoltLab/62-attachment-list-related-content
Fix several issues caused by the switch to grid view of the attachment list
2 parents 1c9cf40 + a3b619c commit d711ab3

5 files changed

Lines changed: 94 additions & 31 deletions

File tree

wcfsetup/install/files/lib/acp/page/AttachmentListPage.class.php

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
namespace wcf\acp\page;
44

5+
use wcf\data\object\type\ObjectTypeCache;
56
use wcf\page\AbstractGridViewPage;
7+
use wcf\system\database\util\PreparedStatementConditionBuilder;
68
use wcf\system\gridView\admin\AttachmentGridView;
79
use wcf\system\WCF;
810

@@ -48,14 +50,34 @@ public function assignVariables()
4850
*/
4951
private function getAttachmentStats(): array
5052
{
51-
$sql = "SELECT COUNT(*) AS count,
52-
COALESCE(SUM(file.fileSize), 0) AS size,
53-
COALESCE(SUM(downloads), 0) AS downloads
54-
FROM wcf1_attachment attachment
53+
$objectTypeIDs = [];
54+
foreach (ObjectTypeCache::getInstance()->getObjectTypes('com.woltlab.wcf.attachment.objectType') as $objectType) {
55+
if (!$objectType->private) {
56+
$objectTypeIDs[] = $objectType->objectTypeID;
57+
}
58+
}
59+
60+
if ($objectTypeIDs === []) {
61+
return [
62+
'count' => 0,
63+
'size' => 0,
64+
'downloads' => 0,
65+
];
66+
}
67+
68+
$conditionBuilder = new PreparedStatementConditionBuilder();
69+
$conditionBuilder->add('attachment.objectTypeID IN (?)', [$objectTypeIDs]);
70+
$conditionBuilder->add('attachment.tmpHash = ?', ['']);
71+
72+
$sql = "SELECT COUNT(*) AS count,
73+
COALESCE(SUM(file.fileSize), 0) AS size,
74+
COALESCE(SUM(downloads), 0) AS downloads
75+
FROM wcf1_attachment attachment
5576
LEFT JOIN wcf1_file file
56-
ON (file.fileID = attachment.fileID)";
77+
ON (file.fileID = attachment.fileID)
78+
" . $conditionBuilder;
5779
$statement = WCF::getDB()->prepare($sql);
58-
$statement->execute();
80+
$statement->execute($conditionBuilder->getParameters());
5981

6082
return $statement->fetchArray();
6183
}

wcfsetup/install/files/lib/system/gridView/admin/AttachmentGridView.class.php

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@
66
use wcf\data\attachment\AdministrativeAttachment;
77
use wcf\data\attachment\AdministrativeAttachmentList;
88
use wcf\data\DatabaseObject;
9+
use wcf\data\object\type\ObjectTypeCache;
910
use wcf\event\gridView\admin\AttachmentGridViewInitialized;
11+
use wcf\system\database\util\PreparedStatementConditionBuilder;
1012
use wcf\system\gridView\AbstractGridView;
1113
use wcf\system\gridView\GridViewColumn;
1214
use wcf\system\gridView\GridViewRowLink;
1315
use wcf\system\gridView\renderer\AbstractColumnRenderer;
16+
use wcf\system\gridView\renderer\DefaultColumnRenderer;
1417
use wcf\system\gridView\renderer\FilesizeColumnRenderer;
1518
use wcf\system\gridView\renderer\ILinkColumnRenderer;
1619
use wcf\system\gridView\renderer\NumberColumnRenderer;
@@ -92,6 +95,27 @@ public function getClasses(): string
9295
->unsafeDisableEncoding()
9396
->renderer(new TruncatedTextColumnRenderer())
9497
->sortable(sortByDatabaseColumn: 'file_table.filename'),
98+
GridViewColumn::for('container')
99+
->label('wcf.acp.attachment.content')
100+
->renderer(
101+
new class extends DefaultColumnRenderer implements ILinkColumnRenderer {
102+
#[\Override]
103+
public function render(mixed $value, DatabaseObject $row): string
104+
{
105+
\assert($row instanceof AdministrativeAttachment);
106+
107+
if ($row->getContainerObject() === null) {
108+
return '';
109+
}
110+
111+
return \sprintf(
112+
'<a href="%s">%s</a>',
113+
StringUtil::encodeHTML($row->getContainerObject()->getLink()),
114+
StringUtil::encodeHTML($row->getContainerObject()->getTitle())
115+
);
116+
}
117+
}
118+
),
95119
GridViewColumn::for('username')
96120
->label('wcf.user.username')
97121
->filter(new UserFilter('username', 'wcf.user.username', 'user_table.userID'))
@@ -168,13 +192,23 @@ public function render(mixed $value, DatabaseObject $row): string
168192
*/
169193
private function getAvailableFileTypes(): array
170194
{
195+
$objectTypeIDs = $this->getAvailableObjectTypeIDs();
196+
if ($objectTypeIDs === []) {
197+
return [];
198+
}
199+
200+
$conditionBuilder = new PreparedStatementConditionBuilder();
201+
$conditionBuilder->add('attachment.fileID IS NOT NULL');
202+
$conditionBuilder->add('attachment.objectTypeID IN (?)', [$objectTypeIDs]);
203+
$conditionBuilder->add('attachment.tmpHash = ?', ['']);
204+
171205
$sql = "SELECT DISTINCT file_table.mimeType
172206
FROM wcf1_attachment attachment
173207
LEFT JOIN wcf1_file file_table
174208
ON (file_table.fileID = attachment.fileID)
175-
WHERE attachment.fileID IS NOT NULL";
209+
" . $conditionBuilder;
176210
$statement = WCF::getDB()->prepare($sql);
177-
$statement->execute();
211+
$statement->execute($conditionBuilder->getParameters());
178212
$fileTypes = $statement->fetchAll(\PDO::FETCH_COLUMN);
179213

180214
\sort($fileTypes);
@@ -191,12 +225,37 @@ public function isAccessible(): bool
191225
#[\Override]
192226
protected function createObjectList(): AdministrativeAttachmentList
193227
{
194-
return new AdministrativeAttachmentList();
228+
$list = new AdministrativeAttachmentList();
229+
230+
$objectTypeIDs = $this->getAvailableObjectTypeIDs();
231+
if ($objectTypeIDs !== []) {
232+
$list->getConditionBuilder()->add('attachment.objectTypeID IN (?)', [$objectTypeIDs]);
233+
} else {
234+
$list->getConditionBuilder()->add('1=0');
235+
}
236+
$list->getConditionBuilder()->add('attachment.tmpHash = ?', ['']);
237+
238+
return $list;
195239
}
196240

197241
#[\Override]
198242
protected function getInitializedEvent(): AttachmentGridViewInitialized
199243
{
200244
return new AttachmentGridViewInitialized($this);
201245
}
246+
247+
/**
248+
* @return list<int>
249+
*/
250+
private function getAvailableObjectTypeIDs(): array
251+
{
252+
$objectTypeIDs = [];
253+
foreach (ObjectTypeCache::getInstance()->getObjectTypes('com.woltlab.wcf.attachment.objectType') as $objectType) {
254+
if (!$objectType->private) {
255+
$objectTypeIDs[] = $objectType->objectTypeID;
256+
}
257+
}
258+
259+
return $objectTypeIDs;
260+
}
202261
}

wcfsetup/install/files/lib/system/interaction/admin/AttachmentInteractions.class.php

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,10 @@
33
namespace wcf\system\interaction\admin;
44

55
use wcf\data\attachment\AdministrativeAttachment;
6-
use wcf\data\DatabaseObject;
76
use wcf\event\interaction\admin\AttachmentInteractionCollecting;
87
use wcf\system\event\EventHandler;
9-
use wcf\system\interaction\AbstractInteraction;
108
use wcf\system\interaction\AbstractInteractionProvider;
119
use wcf\system\interaction\DeleteInteraction;
12-
use wcf\system\WCF;
13-
use wcf\util\StringUtil;
1410

1511
/**
1612
* Interaction provider for attachments.
@@ -26,22 +22,6 @@ public function __construct()
2622
{
2723
$this->addInteractions([
2824
new DeleteInteraction('core/attachments/%s'),
29-
new class(
30-
'goToContent',
31-
static fn(AdministrativeAttachment $object) => $object->getContainerObject() !== null
32-
) extends AbstractInteraction {
33-
#[\Override]
34-
public function render(DatabaseObject $object): string
35-
{
36-
\assert($object instanceof AdministrativeAttachment);
37-
38-
return \sprintf(
39-
'<a href="%s">%s</a>',
40-
StringUtil::encodeHTML($object->getContainerObject()->getLink()),
41-
WCF::getLanguage()->get('wcf.acp.attachment.button.goToContent')
42-
);
43-
}
44-
}
4525
]);
4626

4727
EventHandler::getInstance()->fire(

wcfsetup/install/lang/de.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@
113113
<category name="wcf.acp.attachment">
114114
<item name="wcf.acp.attachment.list"><![CDATA[Dateianhänge]]></item>
115115
<item name="wcf.acp.attachment.stats"><![CDATA[<ul class="inlineList dotSeparated"><li>{#$stats.count} {if $stats.count == 1}Dateianhang{else}Dateianhänge{/if}</li><li>{@$stats.size|filesize}</li><li>{#$stats.downloads} Download{if $stats.downloads != 1}s{/if}</li></ul>]]></item>
116-
<item name="wcf.acp.attachment.button.goToContent"><![CDATA[Zum Inhalt gehen]]></item>
116+
<item name="wcf.acp.attachment.content"><![CDATA[Inhalt]]></item>
117117
</category>
118118
<category name="wcf.acp.bbcode">
119119
<item name="wcf.acp.bbcode.add"><![CDATA[BBCode hinzufügen]]></item>
@@ -5731,5 +5731,6 @@ Erlaubte Dateiendungen: {', '|implode:$allowedFileExtensions}]]></item>
57315731
<item name="wcf.user.profileHits.hitsPerDay"/>
57325732
<item name="wcf.user.avatar.type.none"/>
57335733
<item name="wcf.user.avatar.type.custom"/>
5734+
<item name="wcf.acp.attachment.button.goToContent"/>
57345735
</delete>
57355736
</language>

wcfsetup/install/lang/en.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@
113113
<category name="wcf.acp.attachment">
114114
<item name="wcf.acp.attachment.list"><![CDATA[Attachments]]></item>
115115
<item name="wcf.acp.attachment.stats"><![CDATA[<ul class="inlineList dotSeparated"><li>{#$stats.count} Attachment{if $stats.count != 1}s{/if}</li><li>{@$stats.size|filesize}</li><li>{#$stats.downloads} Download{if $stats.downloads != 1}s{/if}</li></ul>]]></item>
116-
<item name="wcf.acp.attachment.button.goToContent"><![CDATA[Go to Related Content]]></item>
116+
<item name="wcf.acp.attachment.content"><![CDATA[Related Content]]></item>
117117
</category>
118118
<category name="wcf.acp.bbcode">
119119
<item name="wcf.acp.bbcode.add"><![CDATA[Add BBCode]]></item>
@@ -5733,5 +5733,6 @@ Allowed extensions: {', '|implode:$allowedFileExtensions}]]></item>
57335733
<item name="wcf.user.profileHits.hitsPerDay"/>
57345734
<item name="wcf.user.avatar.type.none"/>
57355735
<item name="wcf.user.avatar.type.custom"/>
5736+
<item name="wcf.acp.attachment.button.goToContent"/>
57365737
</delete>
57375738
</language>

0 commit comments

Comments
 (0)