Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 95
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
CargoPageData
0.00% covered (danger)
0.00%
0 / 95
0.00% covered (danger)
0.00%
0 / 2
1640
0.00% covered (danger)
0.00%
0 / 1
 getTableSchema
0.00% covered (danger)
0.00%
0 / 31
0.00% covered (danger)
0.00%
0 / 1
182
 storeValuesForPage
0.00% covered (danger)
0.00%
0 / 64
0.00% covered (danger)
0.00%
0 / 1
756
1<?php
2
3use MediaWiki\MediaWikiServices;
4
5/**
6 * Static functions for dealing with the "_pageData" table.
7 *
8 * @author Yaron Koren
9 */
10class CargoPageData {
11
12    /**
13     * Set the schema based on what has been entered in LocalSettings.php.
14     * Strings are used to set the field names; it would have been
15     * better to use constants (like CARGO_CREATION_DATE or
16     * CargoPageData::CREATION_DATE instead of 'creationDate') but
17     * unfortunately the extension.json system doesn't support any kind
18     * of constants.
19     *
20     * @return CargoTableSchema
21     */
22    public static function getTableSchema() {
23        global $wgCargoPageDataColumns;
24
25        $fieldTypes = [];
26
27        // @TODO - change this code to match the approach taken in
28        // CargoFileData.php. This will be more important if/when
29        // some additional parameter is added, like 'hidden'.
30        if ( in_array( 'creationDate', $wgCargoPageDataColumns ) ) {
31            $fieldTypes['_creationDate'] = [ 'Datetime', false ];
32        }
33        if ( in_array( 'modificationDate', $wgCargoPageDataColumns ) ) {
34            $fieldTypes['_modificationDate'] = [ 'Datetime', false ];
35        }
36        if ( in_array( 'creator', $wgCargoPageDataColumns ) ) {
37            $fieldTypes['_creator'] = [ 'String', false ];
38        }
39        if ( in_array( 'fullText', $wgCargoPageDataColumns ) ) {
40            $fieldTypes['_fullText'] = [ 'Searchtext', false ];
41        }
42        if ( in_array( 'categories', $wgCargoPageDataColumns ) ) {
43            $fieldTypes['_categories'] = [ 'String', true ];
44        }
45        if ( in_array( 'numRevisions', $wgCargoPageDataColumns ) ) {
46            $fieldTypes['_numRevisions'] = [ 'Integer', false ];
47        }
48        if ( in_array( 'isRedirect', $wgCargoPageDataColumns ) ) {
49            $fieldTypes['_isRedirect'] = [ 'Boolean', false ];
50        }
51        if ( in_array( 'pageNameOrRedirect', $wgCargoPageDataColumns ) ) {
52            $fieldTypes['_pageNameOrRedirect'] = [ 'String', false ];
53        }
54        if ( in_array( 'pageIDOrRedirect', $wgCargoPageDataColumns ) ) {
55            $fieldTypes['_pageIDOrRedirect'] = [ 'Integer', false ];
56        }
57        if ( in_array( 'lastEditor', $wgCargoPageDataColumns ) ) {
58            $fieldTypes['_lastEditor'] = [ 'String', false ];
59        }
60
61        $tableSchema = new CargoTableSchema();
62        foreach ( $fieldTypes as $field => $fieldVals ) {
63            [ $type, $isList ] = $fieldVals;
64            $fieldDesc = new CargoFieldDescription();
65            $fieldDesc->mType = $type;
66            if ( $isList ) {
67                $fieldDesc->mIsList = true;
68                $fieldDesc->setDelimiter( '|' );
69            }
70            $tableSchema->mFieldDescriptions[$field] = $fieldDesc;
71        }
72
73        return $tableSchema;
74    }
75
76    /**
77     * The $setToBlank argument is a bit of a hack - used right now only
78     * for "blank if unapproved" with the Approved Revs extension, because
79     * that setting doesn't seem to take effect soon enough to get parsed
80     * as a blank page.
81     *
82     * @param Title $title
83     * @param bool $createReplacement
84     * @param bool $storeCategories
85     * @param bool $setToBlank
86     */
87    public static function storeValuesForPage(
88        Title $title, $createReplacement, $storeCategories = true, $setToBlank = false
89    ) {
90        global $wgCargoPageDataColumns;
91
92        $pageDataTable = $createReplacement ? '_pageData__NEXT' : '_pageData';
93
94        // If this table does not exist, getTableSchemas() will
95        // throw an error.
96        try {
97            $tableSchemas = CargoUtils::getTableSchemas( [ $pageDataTable ] );
98        } catch ( MWException $e ) {
99            return;
100        }
101
102        $wikiPage = CargoUtils::makeWikiPage( $title );
103        $pageDataValues = [];
104
105        if ( in_array( 'creationDate', $wgCargoPageDataColumns ) ) {
106            $firstRevision = MediaWikiServices::getInstance()->getRevisionLookup()->getFirstRevision( $title );
107            if ( $firstRevision == null ) {
108                // This can sometimes happen.
109                $pageDataValues['_creationDate'] = null;
110            } else {
111                $pageDataValues['_creationDate'] = $firstRevision->getTimestamp();
112            }
113        }
114        if ( in_array( 'modificationDate', $wgCargoPageDataColumns ) ) {
115            $pageDataValues['_modificationDate'] = $wikiPage->getTimestamp();
116        }
117        if ( in_array( 'creator', $wgCargoPageDataColumns ) ) {
118            $pageDataValues['_creator'] = $wikiPage->getCreator();
119        }
120        if ( in_array( 'fullText', $wgCargoPageDataColumns ) ) {
121            if ( $setToBlank ) {
122                $pageDataValues['_fullText'] = '';
123            } else {
124                $pageDataValues['_fullText'] = ContentHandler::getContentText( $wikiPage->getContent() );
125            }
126        }
127        if ( $storeCategories && in_array( 'categories', $wgCargoPageDataColumns ) ) {
128            $pageCategories = [];
129            if ( !$setToBlank ) {
130                $dbr = CargoUtils::getMainDBForRead();
131                $res = $dbr->select(
132                    'categorylinks',
133                    'cl_to',
134                    [ 'cl_from' => $title->getArticleID() ],
135                    __METHOD__
136                );
137                foreach ( $res as $row ) {
138                    $pageCategories[] = str_replace( '_', ' ', $row->cl_to );
139                }
140            }
141
142            $pageCategoriesString = implode( '|', $pageCategories );
143            $pageDataValues['_categories'] = $pageCategoriesString;
144        }
145        if ( in_array( 'numRevisions', $wgCargoPageDataColumns ) ) {
146            $dbr = CargoUtils::getMainDBForRead();
147            $pageDataValues['_numRevisions'] = $dbr->selectRowCount(
148                'revision',
149                '*',
150                [ 'rev_page' => $title->getArticleID() ],
151                __METHOD__
152            );
153        }
154        if ( in_array( 'isRedirect', $wgCargoPageDataColumns ) ) {
155            $pageDataValues['_isRedirect'] = ( $title->isRedirect() ? 1 : 0 );
156        }
157        // Check whether the page is a redirect only once,
158        // and evaluate pageNameOrRedirect and pageIDOrRedirect at the same time
159        if ( in_array( 'pageNameOrRedirect', $wgCargoPageDataColumns ) || in_array( 'pageIDOrRedirect', $wgCargoPageDataColumns ) ) {
160            // case when redirect
161            if ( $title->isRedirect() ) {
162                $redirTitle = $wikiPage->getRedirectTarget();
163                if ( $redirTitle !== null ) {
164                    if ( in_array( 'pageNameOrRedirect', $wgCargoPageDataColumns ) ) {
165                        $pageDataValues['_pageNameOrRedirect'] = $redirTitle->getPrefixedText();
166                    }
167                    if ( in_array( 'pageIDOrRedirect', $wgCargoPageDataColumns ) ) {
168                        $pageDataValues['_pageIDOrRedirect'] = $redirTitle->getArticleID();
169                    }
170                }
171            // case when not a redirect
172            } else {
173                if ( in_array( 'pageNameOrRedirect', $wgCargoPageDataColumns ) ) {
174                    $pageDataValues['_pageNameOrRedirect'] = $title->getPrefixedText();
175                }
176                if ( in_array( 'pageIDOrRedirect', $wgCargoPageDataColumns ) ) {
177                    $pageDataValues['_pageIDOrRedirect'] = $title->getArticleID();
178                }
179            }
180        }
181        if ( in_array( 'lastEditor', $wgCargoPageDataColumns ) ) {
182            $latestRevision = MediaWikiServices::getInstance()->getRevisionLookup()->getRevisionByTitle( $title );
183            if ( $latestRevision == null ) {
184                $pageDataValues['_lastEditor'] = null;
185            } else {
186                $pageDataValues['_lastEditor'] = $latestRevision->getUser()->getName();
187            }
188        }
189
190        $pageDataSchema = $tableSchemas[$pageDataTable];
191        // If this is being called as a result of a page save, we
192        // don't handle the '_categories' field, because categories
193        // often don't get set until after the page has been saved,
194        // due to jobs. Instead there are separate hooks to handle it.
195        if ( !$storeCategories ) {
196            $pageDataSchema->removeField( '_categories' );
197        }
198
199        CargoStore::storeAllData( $title, $pageDataTable, $pageDataValues, $pageDataSchema );
200    }
201
202}