Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
46.67% covered (danger)
46.67%
14 / 30
22.22% covered (danger)
22.22%
2 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
MultiGadgetRepo
46.67% covered (danger)
46.67%
14 / 30
22.22% covered (danger)
22.22%
2 / 9
73.77
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getGadget
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
3.14
 getGadgetIds
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 handlePageUpdate
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
6
 getRepoForGadget
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 getGadgetDefinitionTitle
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 titleWithoutPrefix
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 validationWarnings
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 isDefinedTwice
75.00% covered (warning)
75.00%
6 / 8
0.00% covered (danger)
0.00%
0 / 1
4.25
1<?php
2/**
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
17 *
18 * @file
19 */
20
21namespace MediaWiki\Extension\Gadgets;
22
23use InvalidArgumentException;
24use MediaWiki\Linker\LinkTarget;
25use MediaWiki\Title\Title;
26
27/**
28 * Combine two gadget repos during migrations
29 *
30 * @copyright 2017 Kunal Mehta <legoktm@member.fsf.org>
31 * @copyright 2023 Siddharth VP
32 */
33class MultiGadgetRepo extends GadgetRepo {
34
35    /**
36     * @var GadgetRepo[]
37     */
38    private array $repos;
39
40    /**
41     * @param GadgetRepo[] $repos
42     */
43    public function __construct( array $repos ) {
44        $this->repos = $repos;
45    }
46
47    /**
48     * @inheritDoc
49     */
50    public function getGadget( string $id ): Gadget {
51        foreach ( $this->repos as $repo ) {
52            try {
53                return $repo->getGadget( $id );
54            } catch ( InvalidArgumentException $e ) {
55                // Try next repo
56            }
57        }
58
59        throw new InvalidArgumentException( "No gadget registered for '$id'" );
60    }
61
62    /**
63     * @inheritDoc
64     */
65    public function getGadgetIds(): array {
66        $ids = [];
67        foreach ( $this->repos as $repo ) {
68            $ids = array_merge( $ids, $repo->getGadgetIds() );
69        }
70        return array_values( array_unique( $ids ) );
71    }
72
73    /**
74     * @inheritDoc
75     */
76    public function handlePageUpdate( LinkTarget $target ): void {
77        foreach ( $this->repos as $repo ) {
78            $repo->handlePageUpdate( $target );
79        }
80    }
81
82    private function getRepoForGadget( string $id ): GadgetRepo {
83        foreach ( $this->repos as $repo ) {
84            try {
85                $repo->getGadget( $id );
86                // return repo if it didn't throw
87                return $repo;
88            } catch ( InvalidArgumentException $e ) {
89            }
90        }
91        throw new InvalidArgumentException( "No repo found for gadget $id" );
92    }
93
94    public function getGadgetDefinitionTitle( string $id ): ?Title {
95        return $this->getRepoForGadget( $id )->getGadgetDefinitionTitle( $id );
96    }
97
98    public function titleWithoutPrefix( string $titleText, string $gadgetId ): string {
99        return $this->getRepoForGadget( $gadgetId )->titleWithoutPrefix( $titleText, $gadgetId );
100    }
101
102    public function validationWarnings( Gadget $gadget ): array {
103        $duplicateWarnings = $this->isDefinedTwice( $gadget->getName() ) ? [
104            wfMessage( "gadgets-validate-duplicate", $gadget->getName() )
105        ] : [];
106        return array_merge( $duplicateWarnings, parent::validationWarnings( $gadget ) );
107    }
108
109    /**
110     * Checks if a gadget is defined with the same name in two different repos.
111     * @param string $id Gadget name
112     * @return bool
113     */
114    private function isDefinedTwice( string $id ) {
115        $found = false;
116        foreach ( $this->repos as $repo ) {
117            try {
118                $repo->getGadget( $id );
119                if ( $found ) {
120                    // found it a second time
121                    return true;
122                } else {
123                    $found = true;
124                }
125            } catch ( InvalidArgumentException $e ) {
126            }
127        }
128        return false;
129    }
130
131}