Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
92.50% covered (success)
92.50%
74 / 80
50.00% covered (danger)
50.00%
2 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
QueryBuildDocument
92.50% covered (success)
92.50%
74 / 80
50.00% covered (danger)
50.00%
2 / 4
16.11
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 execute
96.67% covered (success)
96.67%
58 / 60
0.00% covered (danger)
0.00%
0 / 1
13
 getAllowedParams
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
1
 getExamplesMessages
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace CirrusSearch\Api;
4
5use ApiBase;
6use CirrusSearch\BuildDocument\BuildDocument;
7use CirrusSearch\BuildDocument\DocumentSizeLimiter;
8use CirrusSearch\CirrusSearch;
9use CirrusSearch\Profile\SearchProfileService;
10use CirrusSearch\Search\CirrusIndexField;
11use CirrusSearch\SearchConfig;
12use MediaWiki\MediaWikiServices;
13use Wikimedia\ParamValidator\ParamValidator;
14
15/**
16 * Generate CirrusSearch document for page.
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License along
29 * with this program; if not, write to the Free Software Foundation, Inc.,
30 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
31 * http://www.gnu.org/copyleft/gpl.html
32 */
33class QueryBuildDocument extends \ApiQueryBase {
34    use ApiTrait;
35
36    public function __construct( \ApiQuery $query, $moduleName ) {
37        parent::__construct( $query, $moduleName, 'cb' );
38    }
39
40    public function execute() {
41        $result = $this->getResult();
42        $services = MediaWikiServices::getInstance();
43        $engine = $services->getSearchEngineFactory()->create();
44
45        $builders = $this->getParameter( 'builders' );
46        $profile = $this->getParameter( 'limiterprofile' );
47        $flags = 0;
48        if ( !in_array( 'content', $builders ) ) {
49            $flags |= BuildDocument::SKIP_PARSE;
50        }
51        if ( !in_array( 'links', $builders ) ) {
52            $flags |= BuildDocument::SKIP_LINKS;
53        }
54
55        if ( $engine instanceof CirrusSearch ) {
56            $pages = [];
57            $wikiPageFactory = $services->getWikiPageFactory();
58            $revisionStore = $services->getRevisionStore();
59            $revisionBased = false;
60            if ( $this->getPageSet()->getRevisionIDs() ) {
61                $revisionBased = true;
62                foreach ( $this->getPageSet()->getRevisionIDs() as $revId => $pageId ) {
63                    $pages[$revId] = $revisionStore->getRevisionById( $revId );
64                }
65            } else {
66                foreach ( $this->getPageSet()->getGoodPages() as $pageId => $title ) {
67                    $pages[$pageId] = $wikiPageFactory->newFromTitle( $title );
68                }
69            }
70
71            $searchConfig = $engine->getConfig();
72            $builder = new BuildDocument(
73                $this->getCirrusConnection(),
74                $this->getDB(),
75                $services->getRevisionStore(),
76                $services->getBacklinkCacheFactory(),
77                new DocumentSizeLimiter( $searchConfig->getProfileService()
78                    ->loadProfile( SearchProfileService::DOCUMENT_SIZE_LIMITER, SearchProfileService::CONTEXT_DEFAULT, $profile ) ),
79                $services->getTitleFormatter(),
80                $services->getWikiPageFactory()
81            );
82            $baseMetadata = [];
83            $clusterGroup = $searchConfig->getClusterAssignment()->getCrossClusterName();
84            if ( $clusterGroup !== null ) {
85                $baseMetadata['cluster_group'] = $clusterGroup;
86            }
87            $docs = $builder->initialize( $pages, $flags );
88            foreach ( $docs as $pageId => $doc ) {
89                $revisionId = $doc->get( 'version' );
90                $revision = $revisionBased ? $pages[$revisionId] : null;
91                if ( $builder->finalize( $doc, false, $revision ) ) {
92                    $result->addValue(
93                        [ 'query', 'pages', $pageId ],
94                        'cirrusbuilddoc', $doc->getData()
95                    );
96                    $hints = CirrusIndexField::getHint( $doc, CirrusIndexField::NOOP_HINT );
97                    $metadata = [];
98                    if ( $hints !== null ) {
99                        $metadata = $baseMetadata + [ 'noop_hints' => $hints ];
100                    }
101                    $limiterStats = CirrusIndexField::getHint( $doc, DocumentSizeLimiter::HINT_DOC_SIZE_LIMITER_STATS );
102                    if ( $limiterStats !== null ) {
103                        $metadata += [ 'size_limiter_stats' => $limiterStats ];
104                    }
105                    $indexName = $this->getCirrusConnection()->getIndexName( $searchConfig->get( SearchConfig::INDEX_BASE_NAME ),
106                        $this->getCirrusConnection()->getIndexSuffixForNamespace( $doc->get( 'namespace' ) ) );
107                    $metadata += [
108                        'index_name' => $indexName
109                    ];
110
111                    $result->addValue( [ 'query', 'pages', $pageId ],
112                        'cirrusbuilddoc_metadata', $metadata );
113                }
114            }
115        } else {
116            throw new \RuntimeException( 'Could not create cirrus engine' );
117        }
118    }
119
120    public function getAllowedParams() {
121        return [
122            'builders' => [
123                ParamValidator::PARAM_DEFAULT => [ 'content', 'links' ],
124                ParamValidator::PARAM_ISMULTI => true,
125                ParamValidator::PARAM_ALLOW_DUPLICATES => false,
126                ParamValidator::PARAM_TYPE => [
127                    'content',
128                    'links',
129                ],
130                ApiBase::PARAM_HELP_MSG => 'apihelp-query+cirrusbuilddoc-param-builders',
131            ],
132            'limiterprofile' => [
133                ParamValidator::PARAM_TYPE => 'string'
134            ],
135        ];
136    }
137
138    /**
139     * @see ApiBase::getExamplesMessages
140     * @return array
141     */
142    protected function getExamplesMessages() {
143        return [
144            'action=query&prop=cirrusbuilddoc&titles=Main_Page' =>
145                'apihelp-query+cirrusbuilddoc-example'
146        ];
147    }
148
149}