Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 56 |
|
0.00% |
0 / 7 |
CRAP | |
0.00% |
0 / 1 |
WikiRevisionFactory | |
0.00% |
0 / 56 |
|
0.00% |
0 / 7 |
132 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
newWikiRevision | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
6 | |||
setInterWikiPrefix | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
6 | |||
newFromFileRevision | |
0.00% |
0 / 13 |
|
0.00% |
0 / 1 |
6 | |||
newFromTextRevision | |
0.00% |
0 / 19 |
|
0.00% |
0 / 1 |
2 | |||
createCentralAuthUser | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
prefixCommentLinks | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
6 |
1 | <?php |
2 | |
3 | namespace FileImporter\Services; |
4 | |
5 | use FileImporter\Data\FileRevision; |
6 | use FileImporter\Data\TextRevision; |
7 | use MediaWiki\Content\IContentHandlerFactory; |
8 | use MediaWiki\Revision\SlotRecord; |
9 | use MediaWiki\Title\Title; |
10 | use MediaWiki\User\ExternalUserNames; |
11 | use WikiRevision; |
12 | |
13 | /** |
14 | * @license GPL-2.0-or-later |
15 | * @author Addshore |
16 | */ |
17 | class WikiRevisionFactory { |
18 | |
19 | private IContentHandlerFactory $contentHandlerFactory; |
20 | /** @var string */ |
21 | private $interwikiPrefix; |
22 | private ExternalUserNames $externalUserNames; |
23 | |
24 | // TODO: should be changed back to lowercase when T221235 is fixed. |
25 | public const DEFAULT_USERNAME_PREFIX = 'Imported'; |
26 | |
27 | public function __construct( IContentHandlerFactory $contentHandlerFactory ) { |
28 | $this->contentHandlerFactory = $contentHandlerFactory; |
29 | $this->externalUserNames = new ExternalUserNames( self::DEFAULT_USERNAME_PREFIX, true ); |
30 | } |
31 | |
32 | private function newWikiRevision( |
33 | string $title, |
34 | string $timestamp, |
35 | ?string $sha1 |
36 | ): WikiRevision { |
37 | $titleParts = explode( ':', $title ); |
38 | $filename = end( $titleParts ); |
39 | |
40 | // The 3 fields rev_page, rev_timestamp, and rev_sha1 make a revision unique, see |
41 | // ImportableOldRevisionImporter::import() |
42 | $revision = new WikiRevision(); |
43 | $revision->setTitle( Title::makeTitleSafe( NS_FILE, $filename ) ); |
44 | $revision->setTimestamp( $timestamp ); |
45 | // File revisions older than 2012 might not have a hash yet. Import as is. |
46 | if ( $sha1 ) { |
47 | $revision->setSha1Base36( $sha1 ); |
48 | } |
49 | |
50 | return $revision; |
51 | } |
52 | |
53 | public function setInterWikiPrefix( string $prefix ): void { |
54 | $this->interwikiPrefix = $prefix; |
55 | $this->externalUserNames = new ExternalUserNames( |
56 | $prefix ?: self::DEFAULT_USERNAME_PREFIX, |
57 | true |
58 | ); |
59 | } |
60 | |
61 | public function newFromFileRevision( FileRevision $fileRevision, string $src ): WikiRevision { |
62 | $revision = $this->newWikiRevision( |
63 | $fileRevision->getField( 'name' ), |
64 | $fileRevision->getField( 'timestamp' ), |
65 | $fileRevision->getField( 'sha1' ) |
66 | ); |
67 | $revision->setFileSrc( $src, true ); |
68 | $revision->setComment( $fileRevision->getField( 'description' ) ); |
69 | |
70 | $importedUser = $this->createCentralAuthUser( $fileRevision->getField( 'user' ) ); |
71 | $revision->setUsername( $importedUser ); |
72 | |
73 | // Mark old file revisions as such |
74 | $archiveName = $fileRevision->getField( 'archivename' ); |
75 | if ( $archiveName ) { |
76 | $revision->setArchiveName( $archiveName ); |
77 | } |
78 | |
79 | return $revision; |
80 | } |
81 | |
82 | /** |
83 | * @return WikiRevision |
84 | */ |
85 | public function newFromTextRevision( TextRevision $textRevision ) { |
86 | $content = $this->contentHandlerFactory |
87 | ->getContentHandler( $textRevision->getContentModel() ) |
88 | ->unserializeContent( |
89 | $textRevision->getContent(), |
90 | $textRevision->getContentFormat() |
91 | ); |
92 | |
93 | $revision = $this->newWikiRevision( |
94 | $textRevision->getField( 'title' ), |
95 | $textRevision->getField( 'timestamp' ), |
96 | $textRevision->getField( 'sha1' ) |
97 | ); |
98 | $revision->setUsername( $this->createCentralAuthUser( $textRevision->getField( 'user' ) ) ); |
99 | $revision->setComment( $this->prefixCommentLinks( $textRevision->getField( 'comment' ) ) ); |
100 | $revision->setMinor( $textRevision->getField( 'minor' ) ); |
101 | $revision->setContent( SlotRecord::MAIN, $content ); |
102 | $revision->setTags( |
103 | array_merge( $textRevision->getField( 'tags' ), [ 'fileimporter-imported' ] ) |
104 | ); |
105 | |
106 | return $revision; |
107 | } |
108 | |
109 | /** |
110 | * @return string Either the unchanged username if it's a known local or valid CentralAuth/SUL |
111 | * user, otherwise the name with the DEFAULT_USERNAME_PREFIX prefix prepended. |
112 | */ |
113 | private function createCentralAuthUser( string $username ): string { |
114 | // This uses the prefix only as fallback |
115 | return $this->externalUserNames->applyPrefix( $username ); |
116 | } |
117 | |
118 | /** |
119 | * TODO: We can almost certainly replace this with WikiLinkCleaners. |
120 | */ |
121 | private function prefixCommentLinks( string $summaryText ): string { |
122 | if ( !$this->interwikiPrefix ) { |
123 | return $summaryText; |
124 | } |
125 | |
126 | /** Mostly taken from @see \MediaWiki\CommentFormatter\CommentParser::doWikiLinks */ |
127 | return preg_replace( |
128 | '/ |
129 | \[\[ |
130 | \s*+ # ignore leading whitespace, the *+ quantifier disallows backtracking |
131 | :? |
132 | (?= |
133 | [^\[\]|]+ |
134 | (?:\| |
135 | # The "possessive" *+ quantifier disallows backtracking |
136 | (?:]?[^\]])*+ |
137 | )? |
138 | \]\] |
139 | ) |
140 | /x', |
141 | '[[' . $this->interwikiPrefix . ':', |
142 | $summaryText |
143 | ); |
144 | } |
145 | |
146 | } |