Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
41 / 41 |
|
100.00% |
6 / 6 |
CRAP | |
100.00% |
1 / 1 |
HashtagCommentParserFactory | |
100.00% |
41 / 41 |
|
100.00% |
6 / 6 |
14 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
1 | |||
setContext | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
create | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
createWithTagTarget | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
1 | |||
getDefaultTagTarget | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
4 | |||
getInvalidList | |
100.00% |
15 / 15 |
|
100.00% |
1 / 1 |
6 |
1 | <?php |
2 | namespace MediaWiki\Extension\Hashtags; |
3 | |
4 | use MediaWiki\ChangeTags\ChangeTagsStore; |
5 | use MediaWiki\CommentFormatter\CommentParserFactory; |
6 | use MediaWiki\Config\ServiceOptions; |
7 | use MediaWiki\Context\IContextSource; |
8 | use MediaWiki\Context\RequestContext; |
9 | use MediaWiki\Linker\LinkRenderer; |
10 | use MediaWiki\Linker\LinkTarget; |
11 | use MediaWiki\SpecialPage\SpecialPageFactory; |
12 | use MediaWiki\Title\TitleValue; |
13 | |
14 | class HashtagCommentParserFactory extends CommentParserFactory { |
15 | |
16 | private CommentParserFactory $commentParserFactory; |
17 | private LinkRenderer $linkRenderer; |
18 | private ChangeTagsStore $changeTagsStore; |
19 | private bool $requireActivation; |
20 | private IContextSource $context; |
21 | private SpecialPageFactory $specialPageFactory; |
22 | private array $invalidList; |
23 | private TagCollector $tagCollector; |
24 | |
25 | public const CONSTRUCTOR_OPTIONS = [ |
26 | "HashtagsRequireActiveTag" |
27 | ]; |
28 | |
29 | public function __construct( |
30 | CommentParserFactory $commentParserFactory, |
31 | LinkRenderer $linkRenderer, |
32 | ChangeTagsStore $changeTagsStore, |
33 | SpecialPageFactory $specialPageFactory, |
34 | ServiceOptions $options, |
35 | TagCollector $tagCollector |
36 | ) { |
37 | $options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS ); |
38 | $this->commentParserFactory = $commentParserFactory; |
39 | $this->linkRenderer = $linkRenderer; |
40 | $this->changeTagsStore = $changeTagsStore; |
41 | $this->requireActivation = $options->get( 'HashtagsRequireActiveTag' ); |
42 | $this->specialPageFactory = $specialPageFactory; |
43 | $this->tagCollector = $tagCollector; |
44 | } |
45 | |
46 | public function setContext( IContextSource $context ) { |
47 | $this->context = $context; |
48 | } |
49 | |
50 | /** |
51 | * @inheritDoc |
52 | * Make a HashtagCommentParser guessing the tag target based on current page |
53 | */ |
54 | public function create() { |
55 | $target = $this->getDefaultTagTarget(); |
56 | return $this->createWithTagTarget( $target ); |
57 | } |
58 | |
59 | /** |
60 | * Make a HashtagCommentParser for a specific tag link target |
61 | * @return CommentParser |
62 | */ |
63 | public function createWithTagTarget( LinkTarget $target ) { |
64 | $originalObj = $this->commentParserFactory->create(); |
65 | return new HashtagCommentParser( |
66 | $originalObj, |
67 | $this->linkRenderer, |
68 | $this->changeTagsStore, |
69 | $this->requireActivation, |
70 | $this->getInvalidList(), |
71 | $target, |
72 | $this->tagCollector |
73 | ); |
74 | } |
75 | |
76 | /** |
77 | * Get page to link tags to |
78 | */ |
79 | private function getDefaultTagTarget(): LinkTarget { |
80 | if ( !isset( $this->context ) ) { |
81 | $this->context = RequestContext::getMain(); |
82 | } |
83 | // I'm unsure how specific to go here. We could |
84 | // potentially try and make it go on the same page - |
85 | // e.g. Clicking on a tag on a history page could show |
86 | // just edits to that page with the tag. I think its |
87 | // better to go broad, just do all of RC for most |
88 | // things and Special:Log if we are already on Special:Log. |
89 | $curTitle = $this->context->getTitle(); |
90 | // curTitle might be null during unit tests but otherwise should not be. |
91 | if ( $curTitle && $curTitle->isSpecial( 'Log' ) ) { |
92 | return new TitleValue( NS_SPECIAL, $this->specialPageFactory->getLocalNameFor( 'Log' ) ); |
93 | } |
94 | return new TitleValue( NS_SPECIAL, $this->specialPageFactory->getLocalNameFor( 'Recentchanges' ) ); |
95 | } |
96 | |
97 | /** |
98 | * Get a list of tags not to use from the i18n message |
99 | * |
100 | * @return array [ tagname => true, ... ] |
101 | */ |
102 | private function getInvalidList(): array { |
103 | if ( isset( $this->invalidList ) ) { |
104 | return $this->invalidList; |
105 | } |
106 | if ( !isset( $this->context ) ) { |
107 | $this->context = RequestContext::getMain(); |
108 | } |
109 | $list = []; |
110 | $msg = $this->context->msg( |
111 | 'hashtags-invalid-tags' |
112 | )->inContentLanguage()->plain(); |
113 | $items = explode( "\n", $msg ); |
114 | foreach ( $items as $i ) { |
115 | $item = trim( $i ); |
116 | if ( substr( $item, 0, 1 ) === '#' && strpos( $item, ' ' ) === false ) { |
117 | $list[substr( $item, 1 )] = true; |
118 | } |
119 | } |
120 | $this->invalidList = $list; |
121 | return $this->invalidList; |
122 | } |
123 | } |