Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 21
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 / 21
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 / 1
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
21    public function __construct(
22        private readonly AbuseFilterChecker $abuseFilterChecker,
23        private readonly ParsoidClientFactory $parsoidClientFactory
24    ) {
25    }
26
27    protected function getParsoidClient(): ParsoidClient {
28        return $this->parsoidClientFactory->createParsoidClient();
29    }
30
31    /**
32     * @param TranslationUnit[] $translationUnits
33     * @param string $targetTitle
34     * @param User $user
35     * @return array
36     */
37    public function validateTranslationUnitsForTitleUser(
38        array $translationUnits,
39        string $targetTitle,
40        User $user
41    ): array {
42        $validationResults = [];
43
44        $title = Title::newFromText( $targetTitle );
45        if ( !$title ) {
46            return $validationResults;
47        }
48
49        $titleResults = $this->abuseFilterChecker->checkTitleForUser( $title, $user );
50        foreach ( $translationUnits as $translationUnit ) {
51            if ( !$translationUnit->getValidate() ) {
52                continue;
53            }
54            $sectionId = $translationUnit->getSectionId();
55            if ( $sectionId === 'mwcx-source-title' ) {
56                $validationResults[ $sectionId ] = $titleResults;
57            } else {
58                $sectionHTML = $translationUnit->getContent();
59                $validationResults[ $sectionId ] = $this->validateContent( $sectionHTML, $title, $user );
60            }
61        }
62
63        return $validationResults;
64    }
65
66    /**
67     * Validate the section content using AbuseFilterChecker
68     * @param string $sectionHTML
69     * @param Title $title Target title
70     * @param User $user
71     * @return array List of any rule violations
72     */
73    protected function validateContent( string $sectionHTML, Title $title, User $user ): array {
74        $results = [];
75        // We need to catch any exceptions here - For example, if Parsoid is down
76        // it should not affect the saving of translations.
77        try {
78            // The section content is HTML. AbuseFilter need wikitext.
79            $text = $this->getParsoidClient()->convertHtmlToWikitext( $title, $sectionHTML )['body'];
80            $results = $this->abuseFilterChecker->checkSectionForTitleAndUser( $user, $title, $text );
81        } catch ( Exception ) {
82            // Validation failed. But proceed.
83        }
84        return $results;
85    }
86
87}