Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 88
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
MigrateZ16K1StringsToZ61s
0.00% covered (danger)
0.00%
0 / 82
0.00% covered (danger)
0.00%
0 / 2
210
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
2
 execute
0.00% covered (danger)
0.00%
0 / 73
0.00% covered (danger)
0.00%
0 / 1
182
1<?php
2
3/**
4 * WikiLambda maintenance script to migrate Z16K1s from strings to Z61 references
5 *
6 * Updates all
7 *
8 * @file
9 * @ingroup Extensions
10 * @copyright 2020– Abstract Wikipedia team; see AUTHORS.txt
11 * @license MIT
12 */
13
14namespace MediaWiki\Extensions\WikiLambda\Maintenance;
15
16use MediaWiki\Context\RequestContext;
17use MediaWiki\Extension\WikiLambda\ZObjects\ZReference;
18use MediaWiki\Extension\WikiLambda\ZObjects\ZString;
19use MediaWiki\Extension\WikiLambda\ZObjectStore;
20use MediaWiki\Logger\LoggerFactory;
21use MediaWiki\Maintenance\Maintenance;
22
23$IP = getenv( 'MW_INSTALL_PATH' );
24if ( $IP === false ) {
25    $IP = __DIR__ . '/../../..';
26}
27require_once "$IP/maintenance/Maintenance.php";
28
29class MigrateZ16K1StringsToZ61s extends Maintenance {
30    // TODO (T287153): Once the data is fully migrated, we should remove this
31    // script and the fetchAllImplementations method from ZObjectStore
32
33    /**
34     * @var ZObjectStore
35     */
36    private $zObjectStore = null;
37
38    /**
39     * @inheritDoc
40     */
41    public function __construct() {
42        parent::__construct();
43        $this->requireExtension( 'WikiLambda' );
44        $this->addDescription( 'Migrates saved ZImplementations to reference a Z61 rather than hard-code a string' );
45
46        $this->addOption(
47            'implement',
48            'Whether to actually make the changes or (default) just dry-run',
49            false,
50            false
51        );
52    }
53
54    /**
55     * @inheritDoc
56     */
57    public function execute() {
58        // Construct the ZObjectStore, because ServiceWiring hasn't run
59        $services = $this->getServiceContainer();
60        $this->zObjectStore = new ZObjectStore(
61            $services->getDBLoadBalancerFactory(),
62            $services->getTitleFactory(),
63            $services->getWikiPageFactory(),
64            $services->getRevisionStore(),
65            $services->getUserGroupManager(),
66            LoggerFactory::getInstance( 'WikiLambda' )
67        );
68
69        $implement = $this->getOption( 'implement' );
70
71        $queryLimit = 10;
72
73        $targets = $this->zObjectStore->fetchAllImplementations();
74
75        $this->output( "Found " . count( $targets ) . " Z14s\n" );
76
77        $offset = 0;
78
79        $updateComment = wfMessage( 'wikilambda-migration-edit-comment' )->inLanguage( 'en' )->text();
80
81        do {
82            $contents = $this->zObjectStore->fetchBatchZObjects( array_slice( $targets, $offset, $queryLimit ) );
83            $offset += $queryLimit;
84
85            foreach ( $contents as $zid => $persistentObject ) {
86                $newValue = null;
87
88                $this->output( "Reviewing $zid" );
89
90                $zCode = $persistentObject->getInnerZObject()->getValueByKey( 'Z14K3' );
91
92                if ( $zCode === null ) {
93                    $this->output( "… not using a ZCode!\n" );
94                    continue;
95                }
96
97                $reference = $zCode->getValueByKey( 'Z16K1' );
98
99                if ( $reference instanceof ZReference ) {
100                    $this->output( "… already a ZReference, success!\n" );
101                    continue;
102                }
103
104                $programmingLanguage = $reference->getValueByKey( 'Z61K1' );
105
106                if ( $programmingLanguage instanceof ZString ) {
107                    $this->output( "… a hard-coded string " );
108                    switch ( $programmingLanguage->getSerialized() ) {
109                        case 'javascript':
110                            $this->output( "for JS" );
111                            $newValue = 'Z600';
112                            break;
113
114                        case 'python':
115                        case 'python-3':
116                            $this->output( "for Py" );
117                            $newValue = 'Z610';
118                            break;
119
120                        case 'lua':
121                            $this->output( "for Lua(!)" );
122                            $newValue = 'Z620';
123                            break;
124
125                        default:
126                            $this->output( "but not understood: " . $programmingLanguage );
127                            continue 2;
128                    }
129                } else {
130                    $this->output(
131                        '… but  \'' . var_export( $programmingLanguage, true )
132                        . "', not a reference or a simple string? Skipping.\n"
133                    );
134                    continue;
135                }
136
137                if ( !$newValue ) {
138                    $this->output( "… nothing to do?\n" );
139                    continue;
140                }
141
142                if ( !$implement ) {
143                    $this->output( ".\n\tWould have updated $zid, changing '$programmingLanguage' to '$newValue'.\n" );
144                    continue;
145
146                }
147
148                $persistentObject->getInnerZObject()->getValueByKey( 'Z14K3' )
149                    ->setValueByKey( 'Z16K1', new ZReference( $newValue ) );
150                $data = json_encode( $persistentObject->getSerialized() );
151
152                $response = $this->zObjectStore->updateZObjectAsSystemUser(
153                    RequestContext::getMain(),
154                    /* String ZID */ $zid,
155                    /* String content */ $data,
156                    /* Edit summary */ $updateComment,
157                    /* Update flags */ EDIT_UPDATE
158                );
159
160                if ( $response->isOK() ) {
161                    $this->output( ", now updated!\n" );
162                } else {
163                    $this->output( ", but there was a problem updating:\n" );
164                    $this->output( "\t" . $response->getErrors() . "\n" );
165                }
166            }
167
168        } while ( count( $targets ) - $offset > 0 );
169    }
170}
171
172$maintClass = MigrateZ16K1StringsToZ61s::class;
173require_once RUN_MAINTENANCE_IF_MAIN;