MediaWiki 1.43.1
grep.php
Go to the documentation of this file.
1<?php
2// phpcs:disable MediaWiki.Files.ClassMatchesFilename.NotMatch
11
12// @codeCoverageIgnoreStart
13require_once __DIR__ . '/Maintenance.php';
14// @codeCoverageIgnoreEnd
15
21class GrepPages extends Maintenance {
23 private $contLang;
24
26 private $wikiPageFactory;
27
28 public function __construct() {
29 parent::__construct();
30 $this->addDescription( 'Search the source text of pages for lines matching ' .
31 'a given regex, and print the lines.' );
32 $this->addOption( 'prefix',
33 'Title prefix. Can be specified more than once. ' .
34 'Use e.g. --prefix=Talk: to search an entire namespace.',
35 false, true, false, true );
36 $this->addOption( 'show-wiki', 'Add the wiki ID to the output' );
37 $this->addOption( 'pages-with-matches',
38 'Suppress normal output; instead print the title of each page ' .
39 'from which output would normally have been printed.',
40 false, false, 'l' );
41 $this->addArg( 'regex', 'The regex to search for' );
42 }
43
44 private function init() {
45 $services = $this->getServiceContainer();
46 $this->contLang = $services->getContentLanguage();
47 $this->wikiPageFactory = $services->getWikiPageFactory();
48 }
49
50 public function execute() {
51 $this->init();
52
53 $showWiki = $this->getOption( 'show-wiki' );
54 $wikiId = WikiMap::getCurrentWikiId();
55 $prefix = $this->getOption( 'prefix' );
56 $regex = $this->getArg( 0 );
57 $titleOnly = $this->hasOption( 'pages-with-matches' );
58
59 if ( ( $regex[0] ?? '' ) === '/' ) {
60 $delimRegex = $regex;
61 } else {
62 $delimRegex = '{' . $regex . '}';
63 }
64
65 foreach ( $this->findPages( $prefix ) as $page ) {
66 $content = $page->getContent( RevisionRecord::RAW );
67 $titleText = $page->getTitle()->getPrefixedDBkey();
68 if ( !$content ) {
69 $this->error( "Page has no content: $titleText" );
70 continue;
71 }
72 if ( !$content instanceof TextContent ) {
73 $this->error( "Page has a non-text content model: $titleText" );
74 continue;
75 }
76
77 $text = $content->getText();
78
79 if ( $titleOnly ) {
80 if ( preg_match( $delimRegex, $text ) ) {
81 if ( $showWiki ) {
82 echo "$wikiId\t$titleText\n";
83 } else {
84 echo "$titleText\n";
85 }
86 }
87 } else {
88 foreach ( StringUtils::explode( "\n", $text ) as $lineNum => $line ) {
89 $lineNum++;
90 if ( preg_match( $delimRegex, $line ) ) {
91 if ( $showWiki ) {
92 echo "$wikiId\t$titleText:$lineNum:$line\n";
93 } else {
94 echo "$titleText:$lineNum:$line\n";
95 }
96 }
97 }
98 }
99 }
100 }
101
102 public function findPages( $prefixes = null ) {
103 $dbr = $this->getReplicaDB();
104 $orConds = [];
105 if ( $prefixes !== null ) {
106 foreach ( $prefixes as $prefix ) {
107 $colonPos = strpos( $prefix, ':' );
108 if ( $colonPos !== false ) {
109 $ns = $this->contLang->getNsIndex( substr( $prefix, 0, $colonPos ) );
110 $prefixDBkey = substr( $prefix, $colonPos + 1 );
111 } else {
112 $ns = NS_MAIN;
113 $prefixDBkey = $prefix;
114 }
115 $prefixExpr = $dbr->expr( 'page_namespace', '=', $ns );
116 if ( $prefixDBkey !== '' ) {
117 $prefixExpr = $prefixExpr->and(
118 'page_title',
119 IExpression::LIKE,
120 new LikeValue( $prefixDBkey, $dbr->anyString() )
121 );
122 }
123 $orConds[] = $prefixExpr;
124 }
125 }
126 $lastId = 0;
127 do {
128 $res = $dbr->newSelectQueryBuilder()
129 ->queryInfo( WikiPage::getQueryInfo() )
130 ->where( $orConds ? $dbr->orExpr( $orConds ) : [] )
131 ->andWhere( $dbr->expr( 'page_id', '>', $lastId ) )
132 ->limit( 200 )
133 ->caller( __METHOD__ )
134 ->fetchResultSet();
135 foreach ( $res as $row ) {
136 $title = Title::newFromRow( $row );
137 yield $this->wikiPageFactory->newFromTitle( $title );
138 $lastId = $row->page_id;
139 }
140 } while ( $res->numRows() );
141 }
142}
143
144// @codeCoverageIgnoreStart
145$maintClass = GrepPages::class;
146require_once RUN_MAINTENANCE_IF_MAIN;
147// @codeCoverageIgnoreEnd
const NS_MAIN
Definition Defines.php:65
Search pages for a given regex.
Definition grep.php:21
execute()
Definition grep.php:50
findPages( $prefixes=null)
Definition grep.php:102
__construct()
Definition grep.php:28
Content object implementation for representing flat text.
Base class for language-specific code.
Definition Language.php:79
Service for creating WikiPage objects.
Page revision base class.
Represents a title within MediaWiki.
Definition Title.php:78
Tools for dealing with other locally-hosted wikis.
Definition WikiMap.php:31
Content of like value.
Definition LikeValue.php:14
$maintClass
Definition grep.php:145