Skip to content

Commit bc94d77

Browse files
committed
Assign attachments to article contents instead of articles
1 parent d3862c0 commit bc94d77

15 files changed

Lines changed: 237 additions & 120 deletions

com.woltlab.wcf/objectType.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,11 @@
171171
<definitionname>com.woltlab.wcf.attachment.objectType</definitionname>
172172
<classname>wcf\system\attachment\ArticleAttachmentObjectType</classname>
173173
</type>
174+
<type>
175+
<name>com.woltlab.wcf.article.content</name>
176+
<definitionname>com.woltlab.wcf.attachment.objectType</definitionname>
177+
<classname>wcf\system\attachment\ArticleAttachmentObjectType</classname>
178+
</type>
174179
<type>
175180
<name>com.woltlab.wcf.comment</name>
176181
<definitionname>com.woltlab.wcf.message</definitionname>

com.woltlab.wcf/templates/article.tpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@
116116

117117
{include file='entryTags' objectType='com.woltlab.wcf.article'}
118118

119-
{include file='entryAttachments' attachments=$article->getAttachments()}
119+
{include file='entryAttachments' attachments=$articleContent->getAttachments()}
120120

121121
<footer class="entry__footer">
122122
{if MODULE_LIKE && ARTICLE_ENABLE_LIKE && $__wcf->session->getPermission('user.like.canViewLike')}

wcfsetup/install/files/acp/database/update_com.woltlab.wcf_6.3_step1.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,19 @@
1717
use wcf\system\database\table\PartialDatabaseTable;
1818

1919
return [
20+
PartialDatabaseTable::create('wcf1_article')
21+
->columns([
22+
SmallintDatabaseTableColumn::create('attachments')
23+
->notNull()
24+
->defaultValue(0)
25+
->drop()
26+
]),
27+
PartialDatabaseTable::create('wcf1_article_content')
28+
->columns([
29+
SmallintDatabaseTableColumn::create('attachments')
30+
->notNull()
31+
->defaultValue(0),
32+
]),
2033
PartialDatabaseTable::create('wcf1_label_group')
2134
->columns([
2235
DefaultFalseBooleanDatabaseTableColumn::create('sortAlphabetically')

wcfsetup/install/files/lib/acp/form/ArticleAddForm.class.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ protected function createMonolingualForm(): void
299299
WysiwygFormContainer::create('content')
300300
->label('wcf.acp.article.content')
301301
->messageObjectType('com.woltlab.wcf.article.content')
302-
->attachmentData('com.woltlab.wcf.article', objectID: $this->getAttachmentObjectID())
302+
->attachmentData('com.woltlab.wcf.article.content', objectID: $this->getAttachmentObjectID())
303303
->required(),
304304
]);
305305
}
@@ -348,7 +348,7 @@ protected function createMultilingualForm(): void
348348
->label('wcf.acp.article.content')
349349
->messageObjectType('com.woltlab.wcf.article.content')
350350
->attachmentData(
351-
'com.woltlab.wcf.article',
351+
'com.woltlab.wcf.article.content',
352352
objectID: $this->getAttachmentObjectID($language->languageID)
353353
)
354354
->required()
@@ -412,6 +412,9 @@ function (IFormDocument $document, array $parameters) {
412412
'metaTitle' => $parameters['data']["metaTitle_{$lc}"] ?? '',
413413
'metaDescription' => $parameters['data']["metaDescription_{$lc}"] ?? '',
414414
];
415+
if (isset($parameters["content_{$lc}_attachmentHandler"])) {
416+
$parameters['content'][$lid]['attachmentHandler'] = $parameters["content_{$lc}_attachmentHandler"];
417+
}
415418

416419
unset(
417420
$parameters['data']["title_{$lc}"],
@@ -440,7 +443,7 @@ function (IFormDocument $document, array $parameters) {
440443
];
441444

442445
if (isset($parameters['content_attachmentHandler'])) {
443-
$parameters['attachmentHandler'] = $parameters['content_attachmentHandler'];
446+
$parameters['content'][0]['attachmentHandler'] = $parameters['content_attachmentHandler'];
444447
}
445448

446449
unset(

wcfsetup/install/files/lib/data/article/Article.class.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
* @property-read 0|1 $enableComments is `1` if comments are enabled for the article, otherwise `0`
4141
* @property-read int $views number of times the article has been viewed
4242
* @property-read int $cumulativeLikes cumulative result of likes for the article
43-
* @property-read int $attachments number of attachments in the article descriptions
4443
* @property-read 0|1 $isDeleted is 1 if the article is in trash bin, otherwise 0
4544
* @property-read 0|1 $hasLabels is `1` if labels are assigned to the article
4645
*
@@ -338,10 +337,11 @@ public function getUsername(): string
338337
/**
339338
* @return Attachment[]
340339
* @since 6.0
340+
* @deprecated 6.3 Use `ArticleContent::getAttachments()` instead.
341341
*/
342342
public function getAttachments(): array
343343
{
344-
return $this->getCollection()->getAttachments($this);
344+
return $this->getArticleContent()->getAttachments();
345345
}
346346

347347
#[\Override]

wcfsetup/install/files/lib/data/article/ArticleAction.class.php

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,6 @@ class ArticleAction extends AbstractDatabaseObjectAction
9292
#[\Override]
9393
public function create()
9494
{
95-
if (!empty($this->parameters['attachmentHandler'])) {
96-
$this->parameters['data']['attachments'] = \count($this->parameters['attachmentHandler']);
97-
}
98-
9995
$article = parent::create();
10096

10197
// save article content
@@ -116,9 +112,17 @@ public function create()
116112
'teaserImageID' => $content['teaserImageID'],
117113
'metaTitle' => $content['metaTitle'] ?? '',
118114
'metaDescription' => $content['metaDescription'] ?? '',
115+
'attachments' => isset($content['attachmentHandler'])
116+
? \count($content['attachmentHandler'])
117+
: 0,
119118
]);
120119
$articleContentEditor = new ArticleContentEditor($articleContent);
121120

121+
// update attachments
122+
$attachmentHandler = $content['attachmentHandler'] ?? null;
123+
/** @var ?AttachmentHandler $attachmentHandler */
124+
$attachmentHandler?->updateObjectID($articleContent->getObjectID());
125+
122126
// save tags
123127
if (!empty($content['tags'])) {
124128
TagEngine::getInstance()->addObjectTags(
@@ -174,20 +178,12 @@ public function create()
174178
);
175179
}
176180

177-
if (!empty($this->parameters['attachmentHandler'])) {
178-
$this->parameters['attachmentHandler']->updateObjectID($article->articleID);
179-
}
180-
181181
return $article;
182182
}
183183

184184
#[\Override]
185185
public function update()
186186
{
187-
if (!empty($this->parameters['attachmentHandler'])) {
188-
$this->parameters['data']['attachments'] = \count($this->parameters['attachmentHandler']);
189-
}
190-
191187
parent::update();
192188

193189
$isRevert = (!empty($this->parameters['isRevert']));
@@ -206,17 +202,21 @@ public function update()
206202
$articleContent = ArticleContent::getArticleContent($article->articleID, ($languageID ?: null));
207203
$articleContentEditor = null;
208204
if ($articleContent !== null) {
209-
// update
210-
$articleContentEditor = new ArticleContentEditor($articleContent);
211-
$articleContentEditor->update([
205+
$updateData = [
212206
'title' => $content['title'],
213207
'teaser' => $content['teaser'],
214208
'content' => $content['content'],
215209
'imageID' => ($isRevert) ? $articleContent->imageID : $content['imageID'],
216210
'teaserImageID' => ($isRevert) ? $articleContent->teaserImageID : $content['teaserImageID'],
217211
'metaTitle' => $content['metaTitle'] ?? '',
218212
'metaDescription' => $content['metaDescription'] ?? '',
219-
]);
213+
];
214+
if (isset($content['attachmentHandler'])) {
215+
$updateData['attachments'] = \count($content['attachmentHandler']);
216+
}
217+
218+
$articleContentEditor = new ArticleContentEditor($articleContent);
219+
$articleContentEditor->update($updateData);
220220

221221
$versionData[] = $articleContent;
222222
if ($articleContent->content != $content['content'] || $articleContent->teaser != $content['teaser'] || $articleContent->title != $content['title']) {
@@ -243,9 +243,18 @@ public function update()
243243
'teaserImageID' => ($isRevert) ? null : $content['teaserImageID'],
244244
'metaTitle' => $content['metaTitle'] ?? '',
245245
'metaDescription' => $content['metaDescription'] ?? '',
246+
'attachments' => isset($content['attachmentHandler'])
247+
? \count($content['attachmentHandler'])
248+
: 0,
246249
]);
247250
$articleContentEditor = new ArticleContentEditor($articleContent);
248251

252+
// update attachments
253+
if (isset($content['attachmentHandler'])) {
254+
/** @var AttachmentHandler $content['attachmentHandler'] */
255+
$content['attachmentHandler']->updateObjectID($articleContent->getObjectID());
256+
}
257+
249258
$versionData[] = $articleContent;
250259
$hasChanges = true;
251260
}
@@ -403,11 +412,15 @@ public function delete()
403412
$this->readObjects();
404413
}
405414

406-
$usersToArticles = $articleIDs = $articleContentIDs = $attachmentArticleIDs = [];
415+
$usersToArticles = $articleIDs = $articleContentIDs = $attachmentArticleContentIDs = [];
407416
foreach ($this->getObjects() as $article) {
408417
$articleIDs[] = $article->articleID;
409418
foreach ($article->getArticleContents() as $articleContent) {
410419
$articleContentIDs[] = $articleContent->articleContentID;
420+
421+
if ($articleContent->attachments) {
422+
$attachmentArticleContentIDs[] = $articleContent->articleContentID;
423+
}
411424
}
412425

413426
if ($article->publicationStatus == Article::PUBLISHED) {
@@ -416,10 +429,6 @@ public function delete()
416429
}
417430
$usersToArticles[$article->userID]--;
418431
}
419-
420-
if ($article->attachments) {
421-
$attachmentArticleIDs[] = $article->articleID;
422-
}
423432
}
424433

425434
// delete articles
@@ -452,8 +461,11 @@ public function delete()
452461
// update wcf1_user.articles
453462
ArticleEditor::updateArticleCounter($usersToArticles);
454463
// delete attachments
455-
if (!empty($attachmentArticleIDs)) {
456-
AttachmentHandler::removeAttachments('com.woltlab.wcf.article', $attachmentArticleIDs);
464+
if ($attachmentArticleContentIDs !== []) {
465+
AttachmentHandler::removeAttachments(
466+
'com.woltlab.wcf.article.content',
467+
$attachmentArticleContentIDs
468+
);
457469
}
458470
}
459471

wcfsetup/install/files/lib/data/article/ArticleCollection.class.php

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
use wcf\data\article\content\ArticleContent;
66
use wcf\data\article\content\ArticleContentList;
77
use wcf\data\DatabaseObjectCollection;
8-
use wcf\data\TCollectionAttachments;
98
use wcf\data\TCollectionLabels;
109
use wcf\data\TCollectionReactions;
1110
use wcf\data\TCollectionUserProfiles;
@@ -30,7 +29,6 @@ class ArticleCollection extends DatabaseObjectCollection
3029
use TCollectionUserProfiles;
3130
use TCollectionLabels;
3231
use TCollectionVisitTimes;
33-
use TCollectionAttachments;
3432

3533
/**
3634
* @var array<int, array<int, ArticleContent>>
@@ -133,10 +131,4 @@ protected function getVisitTrackerObjectType(): string
133131
{
134132
return 'com.woltlab.wcf.article';
135133
}
136-
137-
#[\Override]
138-
protected function getAttachmentObjectType(): string
139-
{
140-
return 'com.woltlab.wcf.article';
141-
}
142134
}

wcfsetup/install/files/lib/data/article/content/ArticleContent.class.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace wcf\data\article\content;
44

55
use wcf\data\article\Article;
6+
use wcf\data\attachment\Attachment;
67
use wcf\data\CollectionDatabaseObject;
78
use wcf\data\ILinkableObject;
89
use wcf\data\language\Language;
@@ -35,6 +36,7 @@
3536
* @property-read string $metaTitle title of the article used in the title tag
3637
* @property-read string $metaDescription meta description of the article
3738
* @property-read int $comments number of comments
39+
* @property-read int $attachments number of attachments
3840
*
3941
* @extends CollectionDatabaseObject<ArticleContentCollection>
4042
*/
@@ -242,4 +244,13 @@ public function getTeaserImage(): ?ViewableMedia
242244

243245
return $image;
244246
}
247+
248+
/**
249+
* @return Attachment[]
250+
* @since 6.3
251+
*/
252+
public function getAttachments(): array
253+
{
254+
return $this->getCollection()->getAttachments($this);
255+
}
245256
}

wcfsetup/install/files/lib/data/article/content/ArticleContentCollection.class.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use wcf\data\DatabaseObjectCollection;
77
use wcf\data\media\ViewableMedia;
88
use wcf\data\media\ViewableMediaList;
9+
use wcf\data\TCollectionAttachments;
910
use wcf\data\TCollectionEmbeddedObjects;
1011
use wcf\system\cache\runtime\ArticleRuntimeCache;
1112

@@ -22,6 +23,7 @@
2223
class ArticleContentCollection extends DatabaseObjectCollection
2324
{
2425
use TCollectionEmbeddedObjects;
26+
use TCollectionAttachments;
2527

2628
/**
2729
* @var array<int, ViewableMedia>
@@ -106,4 +108,10 @@ private function cacheArticles(): void
106108

107109
ArticleRuntimeCache::getInstance()->cacheObjectIDs($articleIDs);
108110
}
111+
112+
#[\Override]
113+
protected function getAttachmentObjectType(): string
114+
{
115+
return 'com.woltlab.wcf.article.content';
116+
}
109117
}

wcfsetup/install/files/lib/page/ArticlePage.class.php

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
use wcf\data\article\category\ArticleCategory;
99
use wcf\data\article\CategoryArticleList;
1010
use wcf\data\article\content\ArticleContent;
11-
use wcf\data\object\type\ObjectTypeCache;
1211
use wcf\data\tag\Tag;
1312
use wcf\http\Helper;
1413
use wcf\system\exception\IllegalLinkException;
@@ -99,7 +98,6 @@ public function readData(): void
9998
$this->loadTags();
10099
$this->loadRelatedArticles();
101100
$this->setLocation();
102-
$this->filterEmbeddedAttachments();
103101
$this->loadNextArticle();
104102
$this->loadPreviousArticle();
105103
$this->setMetaTags();
@@ -295,41 +293,4 @@ public function assignVariables()
295293
),
296294
]);
297295
}
298-
299-
/**
300-
* Filters attachments embedded in the article's description from the normal listing.
301-
*
302-
* @since 6.3
303-
*/
304-
protected function filterEmbeddedAttachments(): void
305-
{
306-
$attachments = $this->article->getAttachments();
307-
if ($attachments === []) {
308-
return;
309-
}
310-
311-
$sql = "SELECT embeddedObjectID
312-
FROM wcf1_message_embedded_object
313-
WHERE messageObjectTypeID = ?
314-
AND messageID IN (
315-
SELECT articleContentID
316-
FROM wcf1_article_content
317-
WHERE articleID = ?
318-
)
319-
AND embeddedObjectTypeID = ?";
320-
$statement = WCF::getDB()->prepare($sql);
321-
$statement->execute([
322-
ObjectTypeCache::getInstance()
323-
->getObjectTypeIDByName('com.woltlab.wcf.message', 'com.woltlab.wcf.article.content'),
324-
$this->article->articleID,
325-
ObjectTypeCache::getInstance()
326-
->getObjectTypeIDByName('com.woltlab.wcf.message.embeddedObject', 'com.woltlab.wcf.attachment'),
327-
]);
328-
$attachmentIDs = $statement->fetchAll(\PDO::FETCH_COLUMN);
329-
foreach ($attachmentIDs as $attachmentID) {
330-
if (isset($attachments[$attachmentID])) {
331-
$attachments[$attachmentID]->markAsEmbedded();
332-
}
333-
}
334-
}
335296
}

0 commit comments

Comments
 (0)