Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 46
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
TranslatableBundleDeleter
0.00% covered (danger)
0.00%
0 / 46
0.00% covered (danger)
0.00%
0 / 4
156
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 getPagesForDeletion
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
6
 deleteAsynchronously
0.00% covered (danger)
0.00%
0 / 29
0.00% covered (danger)
0.00%
0 / 1
56
 getValidBundleFromTitle
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2declare( strict_types = 1 );
3
4namespace MediaWiki\Extension\Translate\PageTranslation;
5
6use BagOStuff;
7use JobQueueGroup;
8use MediaWiki\Extension\Translate\MessageGroupProcessing\DeleteTranslatableBundleJob;
9use MediaWiki\Extension\Translate\MessageGroupProcessing\SubpageListBuilder;
10use MediaWiki\Extension\Translate\MessageGroupProcessing\TranslatableBundle;
11use MediaWiki\Extension\Translate\MessageGroupProcessing\TranslatableBundleFactory;
12use MediaWiki\Extension\Translate\Utilities\Utilities;
13use MediaWiki\Title\Title;
14use MediaWiki\User\UserIdentity;
15
16/**
17 * Contains the core logic to delete translatable bundles or translation pages
18 * @author Abijeet Patro
19 * @license GPL-2.0-or-later
20 * @since 2023.10
21 */
22class TranslatableBundleDeleter {
23    private BagOStuff $mainCache;
24    private JobQueueGroup $jobQueueGroup;
25    private SubpageListBuilder $subpageBuilder;
26    private TranslatableBundleFactory $bundleFactory;
27
28    public function __construct(
29        BagOStuff $mainCache,
30        JobQueueGroup $jobQueueGroup,
31        SubpageListBuilder $subpageBuilder,
32        TranslatableBundleFactory $bundleFactory
33    ) {
34        $this->mainCache = $mainCache;
35        $this->jobQueueGroup = $jobQueueGroup;
36        $this->subpageBuilder = $subpageBuilder;
37        $this->bundleFactory = $bundleFactory;
38    }
39
40    /**
41     * Returns list of pages to be deleted based on whether the page being deleted is a translation page, translatable
42     * page or a translatable bundle.
43     * @param Title $title
44     * @param string|null $languageCode
45     * @param bool $isTranslationPage
46     * @return array<string,Title[]>
47     */
48    public function getPagesForDeletion( Title $title, ?string $languageCode, bool $isTranslationPage ): array {
49        if ( $isTranslationPage ) {
50            $resultSet = $this->subpageBuilder->getEmptyResultSet();
51
52            [ $titleKey, ] = Utilities::figureMessage( $title->getPrefixedDBkey() );
53            $translatablePage = TranslatablePage::newFromTitle( Title::newFromText( $titleKey ) );
54
55            $resultSet['translationPages'] = [ $title ];
56            $resultSet['translationUnitPages'] = $translatablePage->getTranslationUnitPages( $languageCode );
57            return $resultSet;
58        } else {
59            $bundle = $this->bundleFactory->getValidBundle( $title );
60            return $this->subpageBuilder->getSubpagesPerType( $bundle, false );
61        }
62    }
63
64    /** Creates the necessary jobs required to delete translation, translatable pages or message bundles. */
65    public function deleteAsynchronously(
66        Title $title,
67        bool $isTranslation,
68        UserIdentity $user,
69        array $subpageList,
70        bool $deleteSubpages,
71        string $reason
72    ): void {
73        $jobs = [];
74        $base = $title->getPrefixedText();
75        $bundle = $this->getValidBundleFromTitle( $title, $isTranslation );
76        $bundleType = get_class( $bundle );
77
78        foreach ( $subpageList[ 'translationPages' ] as $old ) {
79            $jobs[$old->getPrefixedText()] = DeleteTranslatableBundleJob::newJob(
80                $old, $base, $bundleType, $isTranslation, $user, $reason
81            );
82        }
83
84        foreach ( $subpageList[ 'translationUnitPages' ] as $old ) {
85            $jobs[$old->getPrefixedText()] = DeleteTranslatableBundleJob::newJob(
86                $old, $base, $bundleType, $isTranslation, $user, $reason
87            );
88        }
89
90        if ( $deleteSubpages ) {
91            foreach ( $subpageList[ 'normalSubpages' ] as $old ) {
92                $jobs[$old->getPrefixedText()] = DeleteTranslatableBundleJob::newJob(
93                    $old, $base, $bundleType, $isTranslation, $user, $reason
94                );
95            }
96        }
97
98        if ( !$isTranslation ) {
99            $jobs[$title->getPrefixedText()] = DeleteTranslatableBundleJob::newJob(
100                $title, $base, $bundleType, false, $user, $reason
101            );
102        }
103
104        $this->jobQueueGroup->push( $jobs );
105
106        $this->mainCache->set(
107            $this->mainCache->makeKey( 'pt-base', $title->getPrefixedText() ),
108            array_keys( $jobs ),
109            6 * $this->mainCache::TTL_HOUR
110        );
111
112        if ( !$isTranslation ) {
113            $this->bundleFactory->getStore( $bundle )->delete( $title );
114        }
115    }
116
117    private function getValidBundleFromTitle( Title $bundleTitle, bool $isTranslation ): TranslatableBundle {
118        if ( $isTranslation ) {
119            [ $key, ] = Utilities::figureMessage( $bundleTitle->getPrefixedDBkey() );
120            $bundleTitle = Title::newFromText( $key );
121        }
122
123        return $this->bundleFactory->getValidBundle( $bundleTitle );
124    }
125}