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;
36
37$maintClass = CargoRecreateData::class;
38
39class CargoRecreateData extends Maintenance {
40    /** @var array */
41    private $templatesThatDeclareTables;
42    /** @var array */
43    private $templatesThatAttachToTables;
44
45    public function __construct() {
46        parent::__construct();
47
48        $this->requireExtension( 'Cargo' );
49        $this->addDescription( "Recreate the data for one or more Cargo database tables." );
50        $this->addOption( 'table', 'The Cargo table to recreate', false, true );
51        $this->addOption( 'replacement', 'Put all new data into a replacement table, to be switched in later' );
52    }
53
54    public function execute() {
55        $quiet = $this->getOption( 'quiet' );
56        $this->templatesThatDeclareTables = CargoUtils::getAllPageProps( 'CargoTableName' );
57        $this->templatesThatAttachToTables = CargoUtils::getAllPageProps( 'CargoAttachedTable' );
58
59        $tableName = $this->getOption( 'table' );
60        $createReplacement = $this->hasOption( 'replacement' );
61
62        if ( $tableName == null ) {
63            $tableNames = CargoUtils::getTables();
64            foreach ( $tableNames as $i => $tableName ) {
65                if ( $tableName == '_pageData' || $tableName == '_fileData' ) {
66                    // This is handled in a separate script.
67                    continue;
68                }
69                if ( $i > 0 && !$quiet ) {
70                    print "\n";
71                }
72                $this->recreateAllDataForTable( $tableName, $createReplacement );
73            }
74        } else {
75            $this->recreateAllDataForTable( $tableName, $createReplacement );
76        }
77    }
78
79    private function recreateAllDataForTable( $tableName, $createReplacement ) {
80        global $wgTitle;
81
82        $quiet = $this->getOption( 'quiet' );
83
84        // Quick retrieval and check before we do anything else.
85        $templatePageID = CargoUtils::getTemplateIDForDBTable( $tableName );
86        if ( $templatePageID == null ) {
87            if ( !$quiet ) {
88                print "Table \"$tableName\" is not declared in any template; skipping.\n";
89            }
90            return;
91        }
92
93        if ( !$quiet ) {
94            print "Recreating data for Cargo table $tableName in 5 seconds... hit [Ctrl]-C to escape.\n";
95            if ( $createReplacement ) {
96                print "(Data will be placed in a separate, replacement table.)\n";
97            }
98            // No point waiting if the user doesn't know about it
99            // anyway, right?
100            sleep( 5 );
101        }
102
103        if ( !$quiet ) {
104            print "Deleting and recreating table...\n";
105        }
106
107        try {
108            $user = User::newSystemUser( 'Maintenance script', [ 'steal' => true ] );
109            CargoUtils::recreateDBTablesForTemplate(
110                $templatePageID,
111                $createReplacement,
112                $user,
113                $tableName
114            );
115        } catch ( MWException $e ) {
116            print "Error: " . $e->getMessage() . "\n";
117            return;
118        }
119
120        // These arrays are poorly named. @TODO - fix names
121        if ( array_key_exists( $tableName, $this->templatesThatDeclareTables ) ) {
122            $templatesThatDeclareThisTable = $this->templatesThatDeclareTables[$tableName];
123        } else {
124            // This shouldn't happen, given that we already did
125            // a check.
126            print "Table \"$tableName\" is not declared in any template.\n";
127            return;
128        }
129
130        if ( array_key_exists( $tableName, $this->templatesThatAttachToTables ) ) {
131            $templatesThatAttachToThisTable = $this->templatesThatAttachToTables[$tableName];
132        } else {
133            $templatesThatAttachToThisTable = [];
134        }
135        $templatesForThisTable = array_merge( $templatesThatDeclareThisTable, $templatesThatAttachToThisTable );
136        $wikiPageFactory = MediaWikiServices::getInstance()->getWikiPageFactory();
137
138        foreach ( $templatesForThisTable as $templatePageID ) {
139            $templateTitle = Title::newFromID( $templatePageID );
140            if ( $templateTitle == null ) {
141                // It is possible that the Template to which the table is associated, is now deleted by the user
142                print "Template (Template Page ID = $templatePageID) does not exist, cannot recreate data corresponding to this template\n";
143                continue;
144            }
145            if ( !$quiet ) {
146                print "Handling template that adds to this table: " . $templateTitle->getText() . "\n";
147            }
148
149            $offset = 0;
150            do {
151                $titlesWithThisTemplate = CargoUtils::getTemplateLinksTo( $templateTitle, [
152                    'LIMIT' => 500, 'OFFSET' => $offset ] );
153                if ( !$quiet ) {
154                    print "Saving data for pages " . ( $offset + 1 ) . " to " . ( $offset + count( $titlesWithThisTemplate ) ) . " that call this template...\n";
155                }
156
157                foreach ( $titlesWithThisTemplate as $title ) {
158                    // This may be helpful.
159                    $wgTitle = $title;
160                    // All we need to do here is set some global variables based
161                    // on the parameters of this job, then parse the page -
162                    // the #cargo_store function will take care of the rest.
163                    CargoStore::$settings['origin'] = 'template';
164                    CargoStore::$settings['dbTableName'] = $tableName;
165                    $wikiPage = $wikiPageFactory->newFromID( $title->getArticleID() );
166                    if ( $wikiPage == null ) {
167                        continue;
168                    }
169                    $content = $wikiPage->getContent();
170                    $contentText = ContentHandler::getContentText( $content );
171                    CargoUtils::parsePageForStorage( $title, $contentText );
172                }
173                $offset += 500;
174            } while ( count( $titlesWithThisTemplate ) == 500 );
175        }
176    }
177
178}
179
180require_once RUN_MAINTENANCE_IF_MAIN;