Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 119
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
SpecialCargoRecreateData
0.00% covered (danger)
0.00%
0 / 119
0.00% covered (danger)
0.00%
0 / 3
462
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 execute
0.00% covered (danger)
0.00%
0 / 100
0.00% covered (danger)
0.00%
0 / 1
342
 getNumPagesThatCallTemplate
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3use MediaWiki\Linker\LinkTarget;
4use MediaWiki\Linker\LinkTargetLookup;
5use MediaWiki\MediaWikiServices;
6
7/**
8 * Displays an interface to let users recreate data via the Cargo
9 * extension.
10 *
11 * @author Yaron Koren
12 * @ingroup Cargo
13 */
14
15class SpecialCargoRecreateData extends UnlistedSpecialPage {
16    public $mTemplateTitle;
17    public $mTableName;
18    public $mIsDeclared;
19
20    public function __construct( $templateTitle = null, $tableName = null, $isDeclared = false ) {
21        parent::__construct( 'RecreateCargoData', 'recreatecargodata' );
22        $this->mTemplateTitle = $templateTitle;
23        $this->mTableName = $tableName;
24        $this->mIsDeclared = $isDeclared;
25    }
26
27    public function execute( $query = null ) {
28        global $cgScriptPath;
29
30        $this->checkPermissions();
31
32        $out = $this->getOutput();
33        $out->enableOOUI();
34        $this->setHeaders();
35
36        if ( $this->mTableName == null ) {
37            $this->mTableName = $query;
38        }
39        $tableExists = CargoUtils::tableFullyExists( $this->mTableName );
40        if ( !$tableExists ) {
41            $out->setPageTitle( $this->msg( 'cargo-createdatatable' )->parse() );
42        }
43
44        // Disable page if "replacement table" exists.
45        $possibleReplacementTable = $this->mTableName . '__NEXT';
46        if ( CargoUtils::tableFullyExists( $this->mTableName ) && CargoUtils::tableFullyExists( $possibleReplacementTable ) ) {
47            $text = $this->msg( 'cargo-recreatedata-replacementexists', $this->mTableName, $possibleReplacementTable )->parse();
48            $ctURL = SpecialPage::getTitleFor( 'CargoTables' )->getFullURL();
49            $viewURL = $ctURL . '/' . $this->mTableName;
50            $viewURL .= strpos( $viewURL, '?' ) ? '&' : '?';
51            $viewURL .= "_replacement";
52            $viewReplacementText = $this->msg( 'cargo-cargotables-viewreplacementlink' )->parse();
53
54            $text .= ' (' . Xml::element( 'a', [ 'href' => $viewURL ], $viewReplacementText ) . ')';
55            $out->addHTML( $text );
56            return true;
57        }
58
59        $specialTableNames = CargoUtils::specialTableNames();
60        if ( !$this->mTemplateTitle && !in_array( $this->mTableName, $specialTableNames ) ) {
61            // TODO - show an error message.
62            return true;
63        }
64
65        $out->addModules( 'ext.cargo.recreatedata' );
66
67        $templateData = [];
68        $dbr = CargoUtils::getMainDBForRead();
69        if ( $this->mTemplateTitle === null ) {
70            if ( $this->mTableName == '_pageData' ) {
71                $conds = null;
72            } elseif ( $this->mTableName == '_fileData' ) {
73                $conds = 'page_namespace = ' . NS_FILE;
74            } elseif ( $this->mTableName == '_bpmnData' ) {
75                $conds = 'page_namespace = ' . FD_NS_BPMN;
76            } else { // if ( $this->mTableName == '_ganttData' ) {
77                $conds = 'page_namespace = ' . FD_NS_GANTT;
78            }
79            $numTotalPages = $dbr->selectField( 'page', 'COUNT(*)', $conds );
80        } else {
81            $numTotalPages = null;
82            $templateData[] = [
83                'name' => $this->mTemplateTitle->getText(),
84                'numPages' => $this->getNumPagesThatCallTemplate( $dbr, $this->mTemplateTitle )
85            ];
86        }
87
88        if ( $this->mIsDeclared ) {
89            // Get all attached templates.
90            $res = $dbr->select( 'page_props',
91                [
92                    'pp_page'
93                ],
94                [
95                    'pp_value' => $this->mTableName,
96                    'pp_propname' => 'CargoAttachedTable'
97                ]
98            );
99            foreach ( $res as $row ) {
100                $templateID = $row->pp_page;
101                $attachedTemplateTitle = Title::newFromID( $templateID );
102                $numPages = $this->getNumPagesThatCallTemplate( $dbr, $attachedTemplateTitle );
103                $attachedTemplateName = $attachedTemplateTitle->getText();
104                $templateData[] = [
105                    'name' => $attachedTemplateName,
106                    'numPages' => $numPages
107                ];
108            }
109        }
110
111        $ct = SpecialPage::getTitleFor( 'CargoTables' );
112        $viewTableURL = $ct->getLocalURL() . '/' . $this->mTableName;
113
114        // Store all the necesssary data on the page.
115        $text = Html::element( 'div', [
116                'hidden' => 'true',
117                'id' => 'recreateDataData',
118                // 'cargoscriptpath' is not data-
119                // specific, but this seemed like the
120                // easiest way to pass it over without
121                // interfering with any other pages.
122                'cargoscriptpath' => $cgScriptPath,
123                'tablename' => $this->mTableName,
124                'isspecialtable' => ( $this->mTemplateTitle == null ),
125                'isdeclared' => $this->mIsDeclared,
126                'totalpages' => $numTotalPages,
127                'viewtableurl' => $viewTableURL
128            ], json_encode( $templateData ) );
129
130        // Simple form.
131        $text .= '<div id="recreateDataCanvas">' . "\n";
132        if ( $tableExists ) {
133            $checkBox = new OOUI\FieldLayout(
134                new OOUI\CheckboxInputWidget( [
135                    'name' => 'createReplacement',
136                    'selected' => true,
137                    'value' => 1,
138                ] ),
139                [
140                    'label' => $this->msg( 'cargo-recreatedata-createreplacement' )->parse(),
141                    'align' => 'inline',
142                    'infusable' => true,
143                ]
144            );
145            $text .= Html::rawElement( 'p', null, $checkBox );
146        }
147
148        if ( $this->mTemplateTitle == null ) {
149            $msg = $tableExists ? 'cargo-recreatedata-recreatetable' : 'cargo-recreatedata-createtable';
150            $text .= Html::element( 'p', null, $this->msg( $msg, $this->mTableName )->parse() );
151        } else {
152            $msg = $tableExists ? 'cargo-recreatedata-desc' : 'cargo-recreatedata-createdata';
153            $text .= Html::element( 'p', null, $this->msg( $msg )->parse() );
154        }
155
156        $text .= new OOUI\ButtonInputWidget( [
157            'id' => 'cargoSubmit',
158            'label' => $this->msg( 'ok' )->parse(),
159            'flags' => [ 'primary', 'progressive' ]
160         ] );
161        $text .= "\n</div>";
162
163        $out->addHTML( $text );
164
165        return true;
166    }
167
168    public function getNumPagesThatCallTemplate( $dbr, LinkTarget $templateTitle ) {
169        $conds = [ "tl_from=page_id" ];
170        if ( method_exists( LinkTargetLookup::class, 'getLinkTargetId' ) ) {
171            // MW 1.38+
172            $linkTargetLookup = MediaWikiServices::getInstance()->getLinkTargetLookup();
173            $conds['tl_target_id'] = $linkTargetLookup->getLinkTargetId( $templateTitle );
174        } else {
175            $conds['tl_namespace'] = $templateTitle->getNamespace();
176            $conds['tl_title'] = $templateTitle->getDBkey();
177        }
178
179        $res = $dbr->select(
180            [ 'page', 'templatelinks' ],
181            'COUNT(*) AS total',
182            $conds,
183            __METHOD__,
184            []
185        );
186        $row = $res->fetchRow();
187        return intval( $row['total'] );
188    }
189
190}