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