MediaWiki  1.23.14
findHooks.php
Go to the documentation of this file.
1 <?php
37 require_once __DIR__ . '/Maintenance.php';
38 
44 class FindHooks extends Maintenance {
45  /*
46  * Hooks that are ignored
47  */
48  protected static $ignore = array( 'testRunLegacyHooks' );
49 
50  public function __construct() {
51  parent::__construct();
52  $this->mDescription = 'Find hooks that are undocumented, missing, or just plain wrong';
53  $this->addOption( 'online', 'Check against MediaWiki.org hook documentation' );
54  }
55 
56  public function getDbType() {
57  return Maintenance::DB_NONE;
58  }
59 
60  public function execute() {
61  global $IP;
62 
63  $documented = $this->getHooksFromDoc( $IP . '/docs/hooks.txt' );
64  $potential = array();
65  $bad = array();
66  $pathinc = array(
67  $IP . '/',
68  $IP . '/includes/',
69  $IP . '/includes/actions/',
70  $IP . '/includes/api/',
71  $IP . '/includes/cache/',
72  $IP . '/includes/changes/',
73  $IP . '/includes/clientpool/',
74  $IP . '/includes/content/',
75  $IP . '/includes/context/',
76  $IP . '/includes/dao/',
77  $IP . '/includes/db/',
78  $IP . '/includes/debug/',
79  $IP . '/includes/deferred/',
80  $IP . '/includes/diff/',
81  $IP . '/includes/externalstore/',
82  $IP . '/includes/filebackend/',
83  $IP . '/includes/filerepo/',
84  $IP . '/includes/filerepo/file/',
85  $IP . '/includes/gallery/',
86  $IP . '/includes/htmlform/',
87  $IP . '/includes/installer/',
88  $IP . '/includes/interwiki/',
89  $IP . '/includes/jobqueue/',
90  $IP . '/includes/json/',
91  $IP . '/includes/logging/',
92  $IP . '/includes/media/',
93  $IP . '/includes/parser/',
94  $IP . '/includes/rcfeed/',
95  $IP . '/includes/resourceloader/',
96  $IP . '/includes/revisiondelete/',
97  $IP . '/includes/search/',
98  $IP . '/includes/site/',
99  $IP . '/includes/specialpage/',
100  $IP . '/includes/specials/',
101  $IP . '/includes/upload/',
102  $IP . '/languages/',
103  $IP . '/maintenance/',
104  $IP . '/maintenance/language/',
105  $IP . '/tests/',
106  $IP . '/tests/parser/',
107  $IP . '/tests/phpunit/suites/',
108  $IP . '/skins/',
109  );
110 
111  foreach ( $pathinc as $dir ) {
112  $potential = array_merge( $potential, $this->getHooksFromPath( $dir ) );
113  $bad = array_merge( $bad, $this->getBadHooksFromPath( $dir ) );
114  }
115 
116  $potential = array_unique( $potential );
117  $bad = array_unique( $bad );
118  $todo = array_diff( $potential, $documented );
119  $deprecated = array_diff( $documented, $potential );
120 
121  // let's show the results:
122  $this->printArray( 'Undocumented', $todo );
123  $this->printArray( 'Documented and not found', $deprecated );
124  $this->printArray( 'Unclear hook calls', $bad );
125 
126  if ( count( $todo ) == 0 && count( $deprecated ) == 0 && count( $bad ) == 0 ) {
127  $this->output( "Looks good!\n" );
128  }
129  }
130 
135  private function getHooksFromDoc( $doc ) {
136  if ( $this->hasOption( 'online' ) ) {
137  return $this->getHooksFromOnlineDoc();
138  } else {
139  return $this->getHooksFromLocalDoc( $doc );
140  }
141  }
142 
148  private function getHooksFromLocalDoc( $doc ) {
149  $m = array();
150  $content = file_get_contents( $doc );
151  preg_match_all( "/\n'(.*?)':/", $content, $m );
152  return array_unique( $m[1] );
153  }
154 
159  private function getHooksFromOnlineDoc() {
160  // All hooks
161  $allhookdata = Http::get( 'http://www.mediawiki.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:MediaWiki_hooks&cmlimit=500&format=php' );
162  $allhookdata = unserialize( $allhookdata );
163  $allhooks = array();
164  foreach ( $allhookdata['query']['categorymembers'] as $page ) {
165  $found = preg_match( '/Manual\:Hooks\/([a-zA-Z0-9- :]+)/', $page['title'], $matches );
166  if ( $found ) {
167  $hook = str_replace( ' ', '_', $matches[1] );
168  $allhooks[] = $hook;
169  }
170  }
171  // Removed hooks
172  $oldhookdata = Http::get( 'http://www.mediawiki.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:Removed_hooks&cmlimit=500&format=php' );
173  $oldhookdata = unserialize( $oldhookdata );
174  $removed = array();
175  foreach ( $oldhookdata['query']['categorymembers'] as $page ) {
176  $found = preg_match( '/Manual\:Hooks\/([a-zA-Z0-9- :]+)/', $page['title'], $matches );
177  if ( $found ) {
178  $hook = str_replace( ' ', '_', $matches[1] );
179  $removed[] = $hook;
180  }
181  }
182  return array_diff( $allhooks, $removed );
183  }
184 
190  private function getHooksFromFile( $file ) {
191  $content = file_get_contents( $file );
192  $m = array();
193  preg_match_all( '/(?:wfRunHooks|Hooks\:\:run|ContentHandler\:\:runLegacyHooks)\(\s*([\'"])(.*?)\1/', $content, $m );
194  return $m[2];
195  }
196 
202  private function getHooksFromPath( $path ) {
203  $hooks = array();
204  $dh = opendir( $path );
205  if ( $dh ) {
206  while ( ( $file = readdir( $dh ) ) !== false ) {
207  if ( filetype( $path . $file ) == 'file' ) {
208  $hooks = array_merge( $hooks, $this->getHooksFromFile( $path . $file ) );
209  }
210  }
211  closedir( $dh );
212  }
213  return $hooks;
214  }
215 
221  private function getBadHooksFromFile( $file ) {
222  $content = file_get_contents( $file );
223  $m = array();
224  # We want to skip the "function wfRunHooks()" one. :)
225  preg_match_all( '/(?<!function )wfRunHooks\(\s*[^\s\'"].*/', $content, $m );
226  $list = array();
227  foreach ( $m[0] as $match ) {
228  $list[] = $match . "(" . $file . ")";
229  }
230  return $list;
231  }
232 
238  private function getBadHooksFromPath( $path ) {
239  $hooks = array();
240  $dh = opendir( $path );
241  if ( $dh ) {
242  while ( ( $file = readdir( $dh ) ) !== false ) {
243  # We don't want to read this file as it contains bad calls to wfRunHooks()
244  if ( filetype( $path . $file ) == 'file' && !$path . $file == __FILE__ ) {
245  $hooks = array_merge( $hooks, $this->getBadHooksFromFile( $path . $file ) );
246  }
247  }
248  closedir( $dh );
249  }
250  return $hooks;
251  }
252 
259  private function printArray( $msg, $arr, $sort = true ) {
260  if ( $sort ) {
261  asort( $arr );
262  }
263 
264  foreach ( $arr as $v ) {
265  if ( !in_array( $v, self::$ignore ) ) {
266  $this->output( "$msg: $v\n" );
267  }
268  }
269  }
270 }
271 
272 $maintClass = 'FindHooks';
273 require_once RUN_MAINTENANCE_IF_MAIN;
php
skin txt MediaWiki includes four core it has been set as the default in MediaWiki since the replacing Monobook it had been been the default skin since before being replaced by Vector largely rewritten in while keeping its appearance Several legacy skins were removed in the as the burden of supporting them became too heavy to bear Those in etc for skin dependent CSS etc for skin dependent JavaScript These can also be customised on a per user by etc This feature has led to a wide variety of user styles becoming that gallery is a good place to ending in php
Definition: skin.txt:62
Maintenance\addOption
addOption( $name, $description, $required=false, $withArg=false, $shortName=false)
Add a parameter to the script.
Definition: Maintenance.php:169
FindHooks\getHooksFromDoc
getHooksFromDoc( $doc)
Get the hook documentation, either locally or from MediaWiki.org.
Definition: findHooks.php:135
RUN_MAINTENANCE_IF_MAIN
require_once RUN_MAINTENANCE_IF_MAIN
Definition: maintenance.txt:50
FindHooks
Maintenance script that compares documented and actually present mismatches.
Definition: findHooks.php:44
Maintenance
Abstract maintenance class for quickly writing and churning out maintenance scripts with minimal effo...
Definition: maintenance.txt:39
FindHooks\getHooksFromOnlineDoc
getHooksFromOnlineDoc()
Get hooks from www.mediawiki.org using the API.
Definition: findHooks.php:159
FindHooks\__construct
__construct()
Default constructor.
Definition: findHooks.php:50
FindHooks\getHooksFromLocalDoc
getHooksFromLocalDoc( $doc)
Get hooks from a local file (for example docs/hooks.txt)
Definition: findHooks.php:148
FindHooks\$ignore
static $ignore
Definition: findHooks.php:48
array
the array() calling protocol came about after MediaWiki 1.4rc1.
List of Api Query prop modules.
FindHooks\getBadHooksFromPath
getBadHooksFromPath( $path)
Get bad hooks from the source code.
Definition: findHooks.php:238
global
when a variable name is used in a it is silently declared as a new masking the global
Definition: design.txt:93
$sort
$sort
Definition: profileinfo.php:301
Http\get
static get( $url, $timeout='default', $options=array())
Simple wrapper for Http::request( 'GET' )
Definition: HttpFunctions.php:99
$ignore
while(false !==( $line=fgets( $in))) if(! $columns) $ignore
Definition: Utf8Test.php:68
$matches
if(!defined( 'MEDIAWIKI')) if(!isset( $wgVersion)) $matches
Definition: NoLocalSettings.php:33
FindHooks\printArray
printArray( $msg, $arr, $sort=true)
Nicely output the array.
Definition: findHooks.php:259
Maintenance\DB_NONE
const DB_NONE
Constants for DB access type.
Definition: Maintenance.php:57
$file
if(PHP_SAPI !='cli') $file
Definition: UtfNormalTest2.php:30
FindHooks\getHooksFromPath
getHooksFromPath( $path)
Get hooks from the source code.
Definition: findHooks.php:202
$dir
if(count( $args)==0) $dir
Definition: importImages.php:49
$path
$path
Definition: NoLocalSettings.php:35
as
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
FindHooks\getHooksFromFile
getHooksFromFile( $file)
Get hooks from a PHP file.
Definition: findHooks.php:190
$maintClass
$maintClass
Definition: findHooks.php:272
Maintenance\output
output( $out, $channel=null)
Throw some output to the user.
Definition: Maintenance.php:314
Maintenance\hasOption
hasOption( $name)
Checks to see if a particular param exists.
Definition: Maintenance.php:181
FindHooks\getDbType
getDbType()
Does the script need different DB access? By default, we give Maintenance scripts normal rights to th...
Definition: findHooks.php:56
$IP
$IP
Definition: WebStart.php:92
FindHooks\execute
execute()
Do the actual work.
Definition: findHooks.php:60
FindHooks\getBadHooksFromFile
getBadHooksFromFile( $file)
Get bad hooks (where the hook name could not be determined) from a PHP file.
Definition: findHooks.php:221