MediaWiki master
grep.php
Go to the documentation of this file.
1<?php
2// phpcs:disable MediaWiki.Files.ClassMatchesFilename.NotMatch
10
11require_once __DIR__ . '/Maintenance.php';
12
18class GrepPages extends Maintenance {
20 private $contLang;
21
23 private $wikiPageFactory;
24
25 public function __construct() {
26 parent::__construct();
27 $this->addDescription( 'Search the source text of pages for lines matching ' .
28 'a given regex, and print the lines.' );
29 $this->addOption( 'prefix',
30 'Title prefix. Can be specified more than once. ' .
31 'Use e.g. --prefix=Talk: to search an entire namespace.',
32 false, true, false, true );
33 $this->addOption( 'show-wiki', 'Add the wiki ID to the output' );
34 $this->addOption( 'pages-with-matches',
35 'Suppress normal output; instead print the title of each page ' .
36 'from which output would normally have been printed.',
37 false, false, 'l' );
38 $this->addArg( 'regex', 'The regex to search for' );
39 }
40
41 private function init() {
42 $services = $this->getServiceContainer();
43 $this->contLang = $services->getContentLanguage();
44 $this->wikiPageFactory = $services->getWikiPageFactory();
45 }
46
47 public function execute() {
48 $this->init();
49
50 $showWiki = $this->getOption( 'show-wiki' );
51 $wikiId = WikiMap::getCurrentWikiId();
52 $prefix = $this->getOption( 'prefix' );
53 $regex = $this->getArg( 0 );
54 $titleOnly = $this->hasOption( 'pages-with-matches' );
55
56 if ( ( $regex[0] ?? '' ) === '/' ) {
57 $delimRegex = $regex[0];
58 } else {
59 $delimRegex = '{' . $regex . '}';
60 }
61
62 foreach ( $this->findPages( $prefix ) as $page ) {
63 $content = $page->getContent( RevisionRecord::RAW );
64 $titleText = $page->getTitle()->getPrefixedDBkey();
65 if ( !$content ) {
66 $this->error( "Page has no content: $titleText" );
67 continue;
68 }
69 if ( !$content instanceof TextContent ) {
70 $this->error( "Page has a non-text content model: $titleText" );
71 continue;
72 }
73
74 $text = $content->getText();
75
76 if ( $titleOnly ) {
77 if ( preg_match( $delimRegex, $text ) ) {
78 if ( $showWiki ) {
79 echo "$wikiId\t$titleText\n";
80 } else {
81 echo "$titleText\n";
82 }
83 }
84 } else {
85 foreach ( StringUtils::explode( "\n", $text ) as $lineNum => $line ) {
86 $lineNum++;
87 if ( preg_match( $delimRegex, $line ) ) {
88 if ( $showWiki ) {
89 echo "$wikiId\t$titleText:$lineNum:$line\n";
90 } else {
91 echo "$titleText:$lineNum:$line\n";
92 }
93 }
94 }
95 }
96 }
97 }
98
99 public function findPages( $prefixes = null ) {
100 $dbr = $this->getReplicaDB();
101 $orConds = [];
102 if ( $prefixes !== null ) {
103 foreach ( $prefixes as $prefix ) {
104 $colonPos = strpos( $prefix, ':' );
105 if ( $colonPos !== false ) {
106 $ns = $this->contLang->getNsIndex( substr( $prefix, 0, $colonPos ) );
107 $prefixDBkey = substr( $prefix, $colonPos + 1 );
108 } else {
109 $ns = NS_MAIN;
110 $prefixDBkey = $prefix;
111 }
112 $prefixExpr = $dbr->expr( 'page_namespace', '=', $ns );
113 if ( $prefixDBkey !== '' ) {
114 $prefixExpr = $prefixExpr->and(
115 'page_title',
116 IExpression::LIKE,
117 new LikeValue( $prefixDBkey, $dbr->anyString() )
118 );
119 }
120 $orConds[] = $prefixExpr;
121 }
122 }
123 $res = $dbr->newSelectQueryBuilder()
124 ->queryInfo( WikiPage::getQueryInfo() )
125 ->where( $orConds ? new OrExpressionGroup( ...$orConds ) : [] )
126 ->caller( __METHOD__ )
127 ->fetchResultSet();
128 foreach ( $res as $row ) {
129 $title = Title::newFromRow( $row );
130 yield $this->wikiPageFactory->newFromTitle( $title );
131 }
132 }
133}
134
135$maintClass = GrepPages::class;
136require_once RUN_MAINTENANCE_IF_MAIN;
const NS_MAIN
Definition Defines.php:64
Search pages for a given regex.
Definition grep.php:18
execute()
Do the actual work.
Definition grep.php:47
findPages( $prefixes=null)
Definition grep.php:99
__construct()
Default constructor.
Definition grep.php:25
Base class for language-specific code.
Definition Language.php:63
Abstract maintenance class for quickly writing and churning out maintenance scripts with minimal effo...
error( $err, $die=0)
Throw an error to the user.
addArg( $arg, $description, $required=true, $multi=false)
Add some args that are needed.
hasOption( $name)
Checks to see if a particular option was set.
getServiceContainer()
Returns the main service container.
getArg( $argId=0, $default=null)
Get an argument.
addDescription( $text)
Set the description text.
addOption( $name, $description, $required=false, $withArg=false, $shortName=false, $multiOccurrence=false)
Add a parameter to the script.
getOption( $name, $default=null)
Get an option, or return the default.
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 object implementation for representing flat text.
Content of like value.
Definition LikeValue.php:14
Representing a group of expressions chained via OR.
$maintClass
Definition grep.php:135