Skip to content

Commit 73aa8cf

Browse files
authored
Merge pull request #6557 from WoltLab/62-preserve-article-discussions
Migrate discussions when transitioning article to i18n
2 parents 6a9bedd + 86964a5 commit 73aa8cf

File tree

4 files changed

+72
-21
lines changed

4 files changed

+72
-21
lines changed

wcfsetup/install/files/lib/command/article/EnableI18n.class.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,14 @@
44

55
use wcf\data\article\Article;
66
use wcf\data\article\ArticleAction;
7+
use wcf\data\article\content\ArticleContent;
78
use wcf\data\article\content\ArticleContentAction;
9+
use wcf\data\article\content\ArticleContentEditor;
10+
use wcf\data\object\type\ObjectTypeCache;
11+
use wcf\system\article\discussion\IArticleDiscussionProvider;
812
use wcf\system\language\LanguageFactory;
913
use wcf\system\version\VersionTracker;
14+
use wcf\system\WCF;
1015

1116
/**
1217
* Converts a monolingual article to a multilingual.
@@ -36,14 +41,19 @@ public function __invoke(): void
3641
];
3742
}
3843

44+
$discussionProvider = $this->article->getDiscussionProvider();
45+
3946
$action = new ArticleAction([$this->article], 'update', [
4047
'content' => $data,
4148
'data' => [
4249
'isMultilingual' => 1,
4350
],
51+
'migrateDiscussions' => true,
4452
]);
4553
$action->executeAction();
4654

55+
$this->migrateDiscussions($discussionProvider, $this->article, $articleContent);
56+
4757
$action = new ArticleContentAction([$articleContent], 'delete');
4858
$action->executeAction();
4959

@@ -52,4 +62,22 @@ public function __invoke(): void
5262
$this->article->articleID
5363
);
5464
}
65+
66+
/**
67+
* Preserves the comments by associating the existing comments with the
68+
* content matching the site’s default language id.
69+
*/
70+
private function migrateDiscussions(IArticleDiscussionProvider $discussionProvider, Article $article, ArticleContent $oldContent): void
71+
{
72+
$article = new Article($article->articleID);
73+
$newContent = $article->getArticleContents()[LanguageFactory::getInstance()->getDefaultLanguageID()] ?? null;
74+
if ($newContent === null) {
75+
// This shouldn’t be possible but throwing an exception here would
76+
// yield a malformed article that cannot be fixed except through
77+
// manual editing of the database.
78+
return;
79+
}
80+
81+
$discussionProvider->migrateDiscussions($oldContent, $newContent);
82+
}
5583
}

wcfsetup/install/files/lib/system/article/discussion/AbstractArticleDiscussionProvider.class.php

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,17 @@ abstract class AbstractArticleDiscussionProvider implements IArticleDiscussionPr
2626
*/
2727
protected $articleContent;
2828

29-
/**
30-
* AbstractArticleDiscussionProvider constructor.
31-
*
32-
* @param Article $article
33-
*/
3429
public function __construct(Article $article)
3530
{
3631
$this->article = $article;
3732
}
3833

39-
/**
40-
* @inheritDoc
41-
*/
34+
#[\Override]
4235
public function setArticleContent(ArticleContent $articleContent)
4336
{
4437
$this->articleContent = $articleContent;
4538
}
39+
40+
#[\Override]
41+
public function migrateDiscussions(ArticleContent $oldContent, ArticleContent $newContent): void {}
4642
}

wcfsetup/install/files/lib/system/article/discussion/CommentArticleDiscussionProvider.class.php

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
namespace wcf\system\article\discussion;
44

55
use wcf\data\article\Article;
6+
use wcf\data\article\content\ArticleContent;
7+
use wcf\data\article\content\ArticleContentEditor;
8+
use wcf\data\object\type\ObjectTypeCache;
69
use wcf\system\comment\CommentHandler;
710
use wcf\system\WCF;
811

@@ -12,21 +15,16 @@
1215
* @author Alexander Ebert
1316
* @copyright 2001-2019 WoltLab GmbH
1417
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
15-
* @since 5.2
1618
*/
1719
class CommentArticleDiscussionProvider extends AbstractArticleDiscussionProvider
1820
{
19-
/**
20-
* @inheritDoc
21-
*/
21+
#[\Override]
2222
public function getDiscussionCount()
2323
{
2424
return $this->articleContent ? $this->articleContent->comments : $this->article->getArticleContent()->comments;
2525
}
2626

27-
/**
28-
* @inheritDoc
29-
*/
27+
#[\Override]
3028
public function getDiscussionCountPhrase()
3129
{
3230
return WCF::getLanguage()->getDynamicVariable('wcf.article.articleComments', [
@@ -35,17 +33,13 @@ public function getDiscussionCountPhrase()
3533
]);
3634
}
3735

38-
/**
39-
* @inheritDoc
40-
*/
36+
#[\Override]
4137
public function getDiscussionLink()
4238
{
4339
return $this->articleContent->getLink() . '#comments';
4440
}
4541

46-
/**
47-
* @inheritDoc
48-
*/
42+
#[\Override]
4943
public function renderDiscussions()
5044
{
5145
$commentCanAdd = WCF::getSession()->getPermission('user.article.canAddComment');
@@ -66,6 +60,31 @@ public function renderDiscussions()
6660
]);
6761
}
6862

63+
#[\Override]
64+
public function migrateDiscussions(ArticleContent $oldContent, ArticleContent $newContent): void
65+
{
66+
$objectTypeID = ObjectTypeCache::getInstance()->getObjectTypeIDByName(
67+
'com.woltlab.wcf.comment.commentableContent',
68+
'com.woltlab.wcf.articleComment',
69+
);
70+
\assert($objectTypeID !== null);
71+
72+
$sql = "UPDATE wcf1_comment
73+
SET objectID = ?
74+
WHERE objectTypeID = ?
75+
AND objectID = ?";
76+
$statement = WCF::getDB()->prepare($sql);
77+
$statement->execute([
78+
$newContent->articleContentID,
79+
$objectTypeID,
80+
$oldContent->articleContentID,
81+
]);
82+
83+
(new ArticleContentEditor($newContent))->update([
84+
'comments' => $oldContent->comments,
85+
]);
86+
}
87+
6988
/**
7089
* @inheritDoc
7190
*/

wcfsetup/install/files/lib/system/article/discussion/IArticleDiscussionProvider.class.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,12 @@ public function setArticleContent(ArticleContent $articleContent);
5858
* @return bool
5959
*/
6060
public static function isResponsible(Article $article);
61+
62+
/**
63+
* Migrates discussions from one content to another. This is intended to be
64+
* used when converting a monolingual article into a multilingual one.
65+
*
66+
* @since 6.2
67+
*/
68+
public function migrateDiscussions(ArticleContent $oldContent, ArticleContent $newContent): void;
6169
}

0 commit comments

Comments
 (0)