Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
90.91% covered (success)
90.91%
30 / 33
66.67% covered (warning)
66.67%
2 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
BabelAutoCreate
90.91% covered (success)
90.91%
30 / 33
66.67% covered (warning)
66.67%
2 / 3
9.06
0.00% covered (danger)
0.00%
0 / 1
 create
87.50% covered (warning)
87.50%
21 / 24
0.00% covered (danger)
0.00%
0 / 1
6.07
 user
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getCategoryText
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2/**
3 * Code for automatic creation of categories.
4 *
5 * @file
6 * @author Robert Leverington
7 * @author Robin Pepermans
8 * @author Niklas Laxström
9 * @author Brian Wolff
10 * @author Purodha Blissenbach
11 * @author Sam Reed
12 * @author Siebrand Mazeland
13 * @author Winston Sung
14 * @license GPL-2.0-or-later
15 */
16
17declare( strict_types = 1 );
18
19namespace MediaWiki\Babel;
20
21use ContentHandler;
22use DeferredUpdates;
23use MediaWiki\MediaWikiServices;
24use MediaWiki\Title\Title;
25use User;
26
27/**
28 * Class for automatic creation of Babel category pages.
29 */
30class BabelAutoCreate {
31    public const MSG_USERNAME = 'babel-autocreate-user';
32
33    /**
34     * Create category.
35     *
36     * @param string $category Name of category to create.
37     * @param string $text Text to use when creating the category.
38     */
39    public static function create( string $category, string $text ): void {
40        $category = strip_tags( $category );
41        $title = Title::makeTitleSafe( NS_CATEGORY, $category );
42        # T170654: We need to check whether non-existing category page in one language variant actually
43        #  exists in another language variant when a language supports multiple language variants.
44        MediaWikiServices::getInstance()->getLanguageConverterFactory()->getLanguageConverter()
45            ->findVariantLink( $category, $title, true );
46        DeferredUpdates::addCallableUpdate( function () use ( $title, $text ) {
47            // Extra exists check here in case the category was created while this code was running
48            if ( $title === null || $title->exists() ) {
49                return;
50            }
51
52            $user = self::user();
53            # Do not add a message if the username is invalid or if the account that adds it, is blocked
54            if ( !$user || $user->getBlock() ) {
55                return;
56            }
57
58            if ( !MediaWikiServices::getInstance()->getPermissionManager()
59                ->quickUserCan( 'create', $user, $title )
60            ) {
61                # The Babel AutoCreate account is not allowed to create the page
62                return;
63            }
64
65            $url = wfMessage( 'babel-url' )->inContentLanguage()->plain();
66            $article = MediaWikiServices::getInstance()->getWikiPageFactory()->newFromTitle( $title );
67
68            $content = ContentHandler::makeContent( $text, $title );
69            $editSummary = wfMessage( 'babel-autocreate-reason', $url )->inContentLanguage()->text();
70            $article->doUserEditContent(
71                $content,
72                $user,
73                $editSummary,
74                EDIT_FORCE_BOT
75            );
76        } );
77    }
78
79    /**
80     * Get user object.
81     *
82     * @return User|null User object for autocreate user, null if invalid.
83     */
84    public static function user(): ?User {
85        $userName = wfMessage( self::MSG_USERNAME )->inContentLanguage()->plain();
86        return User::newSystemUser( $userName, [ 'steal' => true ] );
87    }
88
89    /**
90     * Returns the text to use when creating a babel category with the given code and level
91     * @param string $code Code of language that the category is for.
92     * @param string|null $level Level that the category is for.
93     * @return string The text to use to create the category.
94     */
95    public static function getCategoryText( string $code, ?string $level ): string {
96        global $wgLanguageCode;
97        $language = BabelLanguageCodes::getName( $code, $wgLanguageCode );
98        $params = [ $language, $code ];
99        if ( $level === null ) {
100            $text = wfMessage( 'babel-autocreate-text-main', $params )->inContentLanguage()->plain();
101        } else {
102            array_unshift( $params, $level );
103            $text = wfMessage( 'babel-autocreate-text-levels', $params )->inContentLanguage()->plain();
104        }
105        return $text;
106    }
107}