Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
79.17% covered (warning)
79.17%
57 / 72
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
TranslationRepo
79.17% covered (warning)
79.17%
57 / 72
50.00% covered (danger)
50.00%
1 / 2
18.31
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 setTranslation
78.26% covered (warning)
78.26%
54 / 69
0.00% covered (danger)
0.00%
0 / 1
17.31
1<?php
2
3namespace MediaWiki\Extension\SecurePoll;
4
5use MediaWiki\CommentStore\CommentStoreComment;
6use MediaWiki\Config\Config;
7use MediaWiki\Extension\SecurePoll\Entities\Election;
8use MediaWiki\Page\WikiPageFactory;
9use MediaWiki\Revision\SlotRecord;
10use MediaWiki\User\User;
11use MediaWiki\WikiMap\WikiMap;
12use MWExceptionHandler;
13use Wikimedia\Rdbms\DBError;
14use Wikimedia\Rdbms\ILoadBalancer;
15use Wikimedia\Rdbms\LBFactory;
16
17class TranslationRepo {
18
19    /** @var LBFactory */
20    private $lbFactory;
21
22    /**
23     * @var WikiPageFactory
24     */
25    private $wikiPageFactory = null;
26
27    /**
28     * @var bool
29     */
30    private $useNamespace = false;
31
32    /**
33     *
34     * @param LBFactory $lbFactory
35     * @param WikiPageFactory $wikiPageFactory
36     * @param Config $config
37     */
38    public function __construct( LBFactory $lbFactory, WikiPageFactory $wikiPageFactory, Config $config ) {
39        $this->lbFactory = $lbFactory;
40        $this->wikiPageFactory = $wikiPageFactory;
41        $this->useNamespace = $config->get( 'SecurePollUseNamespace' );
42    }
43
44    /**
45     *
46     * @param Election $election
47     * @param array $data
48     * @param string $language
49     * @param User $user
50     * @param string $comment
51     * @return void
52     */
53    public function setTranslation( $election, $data, $language, $user, $comment ) {
54        $entities = array_merge( [ $election ], $election->getDescendants() );
55
56        $replaceBatch = [];
57        $jumpReplaceBatch = [];
58        foreach ( $entities as $entity ) {
59            foreach ( $entity->getMessageNames() as $messageName ) {
60                $controlName = 'trans_' . $entity->getId() . '_' . $messageName;
61                if ( isset( $data[ $controlName ] ) ) {
62                    $value = $data[ $controlName ];
63                    if ( $value !== '' ) {
64                        $replace = [
65                            'msg_entity' => $entity->getId(),
66                            'msg_lang' => $language,
67                            'msg_key' => $messageName,
68                            'msg_text' => $value
69                        ];
70                        $replaceBatch[] = $replace;
71
72                        // Jump wikis don't have subentities
73                        if ( $entity === $election ) {
74                            $jumpReplaceBatch[] = $replace;
75                        }
76                    }
77                }
78            }
79        }
80
81        if ( $replaceBatch ) {
82            $wikis = $election->getProperty( 'wikis' );
83            if ( $wikis ) {
84                $wikis = explode( "\n", $wikis );
85                $wikis = array_map( 'trim', $wikis );
86            } else {
87                $wikis = [];
88            }
89
90            // First, the main wiki
91            $dbw = $this->lbFactory->getMainLB()->getConnection( ILoadBalancer::DB_PRIMARY );
92
93            $dbw->newReplaceQueryBuilder()
94                ->replaceInto( 'securepoll_msgs' )
95                ->uniqueIndexFields( [ 'msg_entity', 'msg_lang', 'msg_key' ] )
96                ->rows( $replaceBatch )
97                ->caller( __METHOD__ )
98                ->execute();
99
100            if ( $this->useNamespace ) {
101                // Create a new context to bypass caching
102                $context = new Context;
103                $contextElection = $context->getElection( $election->getId() );
104
105                [ $title, $content ] = SecurePollContentHandler::makeContentFromElection(
106                    $contextElection,
107                    "msg/$language"
108                );
109
110                $page = $this->wikiPageFactory->newFromTitle( $title );
111                $updater = $page->newPageUpdater( $user );
112                $updater->setContent( SlotRecord::MAIN, $content );
113                $updater->saveRevision(
114                    CommentStoreComment::newUnsavedComment( trim( $comment ) )
115                );
116            }
117
118            // Then each jump-wiki
119            foreach ( $wikis as $dbname ) {
120                if ( $dbname === WikiMap::getCurrentWikiId() ) {
121                    continue;
122                }
123
124                $lb = $this->lbFactory->getMainLB( $dbname );
125                $dbw = $lb->getConnection( ILoadBalancer::DB_PRIMARY, [], $dbname );
126                try {
127                    $id = $dbw->selectField(
128                        'securepoll_elections',
129                        'el_entity',
130                        [
131                            'el_title' => $election->title
132                        ],
133                        __METHOD__
134                    );
135                    if ( $id && $jumpReplaceBatch ) {
136                        foreach ( $jumpReplaceBatch as &$row ) {
137                            $row['msg_entity'] = $id;
138                        }
139                        unset( $row );
140
141                        $dbw->newReplaceQueryBuilder()
142                            ->replaceInto( 'securepoll_msgs' )
143                            ->uniqueIndexFields( [ 'msg_entity', 'msg_lang', 'msg_key' ] )
144                            ->rows( $jumpReplaceBatch )
145                            ->caller( __METHOD__ )
146                            ->execute();
147                    }
148                } catch ( DBError $ex ) {
149                    // Log the exception, but don't abort the updating of the rest of the jump-wikis
150                    MWExceptionHandler::logException( $ex );
151                }
152            }
153        }
154    }
155
156}