Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
TranslationUnitValidator
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 4
90
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getParsoidClient
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 validateTranslationUnitsForTitleUser
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
30
 validateContent
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2/**
3 * @copyright See AUTHORS.txt
4 * @license GPL-2.0-or-later
5 */
6
7declare( strict_types = 1 );
8
9namespace ContentTranslation\Validator;
10
11use ContentTranslation\AbuseFilterChecker;
12use ContentTranslation\Entity\TranslationUnit;
13use ContentTranslation\ParsoidClient;
14use ContentTranslation\ParsoidClientFactory;
15use Exception;
16use MediaWiki\Title\Title;
17use MediaWiki\User\User;
18
19class TranslationUnitValidator {
20    /** @var AbuseFilterChecker */
21    private $abuseFilterChecker;
22
23    /** @var ParsoidClientFactory */
24    protected $parsoidClientFactory;
25
26    public function __construct( AbuseFilterChecker $abuseFilterChecker, ParsoidClientFactory $parsoidClientFactory ) {
27        $this->abuseFilterChecker = $abuseFilterChecker;
28        $this->parsoidClientFactory = $parsoidClientFactory;
29    }
30
31    protected function getParsoidClient(): ParsoidClient {
32        return $this->parsoidClientFactory->createParsoidClient();
33    }
34
35    /**
36     * @param TranslationUnit[] $translationUnits
37     * @param string $targetTitle
38     * @param User $user
39     * @return array
40     */
41    public function validateTranslationUnitsForTitleUser(
42        array $translationUnits,
43        string $targetTitle,
44        User $user
45    ): array {
46        $validationResults = [];
47
48        $title = Title::newFromText( $targetTitle );
49        if ( !$title ) {
50            return $validationResults;
51        }
52
53        $titleResults = $this->abuseFilterChecker->checkTitleForUser( $title, $user );
54        foreach ( $translationUnits as $translationUnit ) {
55            if ( !$translationUnit->getValidate() ) {
56                continue;
57            }
58            $sectionId = $translationUnit->getSectionId();
59            if ( $sectionId === 'mwcx-source-title' ) {
60                $validationResults[ $sectionId ] = $titleResults;
61            } else {
62                $sectionHTML = $translationUnit->getContent();
63                $validationResults[ $sectionId ] = $this->validateContent( $sectionHTML, $title, $user );
64            }
65        }
66
67        return $validationResults;
68    }
69
70    /**
71     * Validate the section content using AbuseFilterChecker
72     * @param string $sectionHTML
73     * @param Title $title Target title
74     * @param User $user
75     * @return array List of any rule violations
76     */
77    protected function validateContent( string $sectionHTML, Title $title, User $user ): array {
78        $results = [];
79        // We need to catch any exceptions here - For example, if restbase is down
80        // it should not affect the saving of translations.
81        try {
82            // The section content is HTML. AbuseFilter need wikitext.
83            $text = $this->getParsoidClient()->convertHtmlToWikitext( $title, $sectionHTML )['body'];
84            $results = $this->abuseFilterChecker->checkSectionForTitleAndUser( $user, $title, $text );
85        } catch ( Exception $e ) {
86            // Validation failed. But proceed.
87        }
88        return $results;
89    }
90
91}