Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 81
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
CargoRecreateData
0.00% covered (danger)
0.00%
0 / 76
0.00% covered (danger)
0.00%
0 / 3
552
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 execute
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
56
 recreateAllDataForTable
0.00% covered (danger)
0.00%
0 / 57
0.00% covered (danger)
0.00%
0 / 1
240
1<?php
2
3/**
4 * This script creates, or recreates, one or more Cargo database tables,
5 * based on the relevant data contained in the wiki.
6 *
7 * Usage:
8 *  php cargoRecreateData.php [--table tableName] [--quiet] etc.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 * http://www.gnu.org/copyleft/gpl.html
24 *
25 * @author Yaron Koren
26 * @ingroup Maintenance
27 */
28
29if ( getenv( 'MW_INSTALL_PATH' ) ) {
30    require_once getenv( 'MW_INSTALL_PATH' ) . '/maintenance/Maintenance.php';
31} else {
32    require_once __DIR__ . '/../../../maintenance/Maintenance.php';
33}
34
35use MediaWiki\MediaWikiServices;
36use MediaWiki\Title\Title;
37
38$maintClass = CargoRecreateData::class;
39
40class CargoRecreateData extends Maintenance {
41    /** @var array */
42    private $templatesThatDeclareTables;
43    /** @var array */
44    private $templatesThatAttachToTables;
45
46    public function __construct() {
47        parent::__construct();
48
49        $this->requireExtension( 'Cargo' );
50        $this->addDescription( "Recreate the data for one or more Cargo database tables." );
51        $this->addOption( 'table', 'The Cargo table to recreate', false, true );
52        $this->addOption( 'replacement', 'Put all new data into a replacement table, to be switched in later' );
53    }
54
55    public function execute() {
56        $quiet = $this->getOption( 'quiet' );
57        $this->templatesThatDeclareTables = CargoUtils::getAllPageProps( 'CargoTableName' );
58        $this->templatesThatAttachToTables = CargoUtils::getAllPageProps( 'CargoAttachedTable' );
59
60        $tableName = $this->getOption( 'table' );
61        $createReplacement = $this->hasOption( 'replacement' );
62
63        if ( $tableName == null ) {
64            $tableNames = CargoUtils::getTables();
65            foreach ( $tableNames as $i => $tableName ) {
66                if ( $tableName == '_pageData' || $tableName == '_fileData' ) {
67                    // This is handled in a separate script.
68                    continue;
69                }
70                if ( $i > 0 && !$quiet ) {
71                    print "\n";
72                }
73                $this->recreateAllDataForTable( $tableName, $createReplacement );
74            }
75        } else {
76            $this->recreateAllDataForTable( $tableName, $createReplacement );
77        }
78    }
79
80    private function recreateAllDataForTable( $tableName, $createReplacement ) {
81        global $wgTitle;
82
83        $quiet = $this->getOption( 'quiet' );
84
85        // Quick retrieval and check before we do anything else.
86        $templatePageID = CargoUtils::getTemplateIDForDBTable( $tableName );
87        if ( $templatePageID == null ) {
88            if ( !$quiet ) {
89                print "Table \"$tableName\" is not declared in any template; skipping.\n";
90            }
91            return;
92        }
93
94        if ( !$quiet ) {
95            print "Recreating data for Cargo table $tableName in 5 seconds... hit [Ctrl]-C to escape.\n";
96            if ( $createReplacement ) {
97                print "(Data will be placed in a separate, replacement table.)\n";
98            }
99            // No point waiting if the user doesn't know about it
100            // anyway, right?
101            sleep( 5 );
102        }
103
104        if ( !$quiet ) {
105            print "Deleting and recreating table...\n";
106        }
107
108        try {
109            $user = User::newSystemUser( 'Maintenance script', [ 'steal' => true ] );
110            CargoUtils::recreateDBTablesForTemplate(
111                $templatePageID,
112                $createReplacement,
113                $user,
114                $tableName
115            );
116        } catch ( MWException $e ) {
117            print "Error: " . $e->getMessage() . "\n";
118            return;
119        }
120
121        // These arrays are poorly named. @TODO - fix names
122        if ( array_key_exists( $tableName, $this->templatesThatDeclareTables ) ) {
123            $templatesThatDeclareThisTable = $this->templatesThatDeclareTables[$tableName];
124        } else {
125            // This shouldn't happen, given that we already did
126            // a check.
127            print "Table \"$tableName\" is not declared in any template.\n";
128            return;
129        }
130
131        if ( array_key_exists( $tableName, $this->templatesThatAttachToTables ) ) {
132            $templatesThatAttachToThisTable = $this->templatesThatAttachToTables[$tableName];
133        } else {
134            $templatesThatAttachToThisTable = [];
135        }
136        $templatesForThisTable = array_merge( $templatesThatDeclareThisTable, $templatesThatAttachToThisTable );
137        $wikiPageFactory = MediaWikiServices::getInstance()->getWikiPageFactory();
138
139        foreach ( $templatesForThisTable as $templatePageID ) {
140            $templateTitle = Title::newFromID( $templatePageID );
141            if ( $templateTitle == null ) {
142                // It is possible that the Template to which the table is associated, is now deleted by the user
143                print "Template (Template Page ID = $templatePageID) does not exist, cannot recreate data corresponding to this template\n";
144                continue;
145            }
146            if ( !$quiet ) {
147                print "Handling template that adds to this table: " . $templateTitle->getText() . "\n";
148            }
149
150            $offset = 0;
151            do {
152                $titlesWithThisTemplate = $templateTitle->getTemplateLinksTo( [
153                    'LIMIT' => 500, 'OFFSET' => $offset ] );
154                if ( !$quiet ) {
155                    print "Saving data for pages " . ( $offset + 1 ) . " to " . ( $offset + count( $titlesWithThisTemplate ) ) . " that call this template...\n";
156                }
157
158                foreach ( $titlesWithThisTemplate as $title ) {
159                    // This may be helpful.
160                    $wgTitle = $title;
161                    // All we need to do here is set some global variables based
162                    // on the parameters of this job, then parse the page -
163                    // the #cargo_store function will take care of the rest.
164                    CargoStore::$settings['origin'] = 'template';
165                    CargoStore::$settings['dbTableName'] = $tableName;
166                    $wikiPage = $wikiPageFactory->newFromID( $title->getArticleID() );
167                    if ( $wikiPage == null ) {
168                        continue;
169                    }
170                    $content = $wikiPage->getContent();
171                    $contentText = CargoUtils::getContentText( $content );
172                    CargoUtils::parsePageForStorage( $title, $contentText );
173                }
174                $offset += 500;
175            } while ( count( $titlesWithThisTemplate ) == 500 );
176        }
177    }
178
179}
180
181require_once RUN_MAINTENANCE_IF_MAIN;