PageRenderTime 52ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/maintenance/findhooks.php

https://github.com/tav/confluence
PHP | 158 lines | 88 code | 14 blank | 56 comment | 17 complexity | cf481017c209231ae41bbe2c4c52b305 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-3.0
  1. <?php
  2. /**
  3. * Simple script that try to find documented hook and hooks actually
  4. * in the code and show what's missing.
  5. *
  6. * This script assumes that:
  7. * - hooks names in hooks.txt are at the beginning of a line and single quoted.
  8. * - hooks names in code are the first parameter of wfRunHooks.
  9. *
  10. * if --online option is passed, the script will compare the hooks in the code
  11. * with the ones at http://www.mediawiki.org/wiki/Manual:Hooks
  12. *
  13. * Any instance of wfRunHooks that doesn't meet these parameters will be noted.
  14. *
  15. * @file
  16. * @ingroup Maintenance
  17. *
  18. * @author Ashar Voultoiz <hashar@altern.org>
  19. * @copyright Copyright © Ashar voultoiz
  20. * @license http://www.gnu.org/copyleft/gpl.html GNU General Public Licence 2.0 or later
  21. */
  22. /** This is a command line script*/
  23. require('commandLine.inc');
  24. # GLOBALS
  25. $doc = $IP . '/docs/hooks.txt';
  26. $pathinc = array(
  27. $IP.'/',
  28. $IP.'/includes/',
  29. $IP.'/includes/api/',
  30. $IP.'/includes/db/',
  31. $IP.'/includes/diff/',
  32. $IP.'/includes/filerepo/',
  33. $IP.'/includes/parser/',
  34. $IP.'/includes/specials/',
  35. $IP.'/languages/',
  36. $IP.'/maintenance/',
  37. $IP.'/skins/',
  38. );
  39. # FUNCTIONS
  40. /**
  41. * @return array of documented hooks
  42. */
  43. function getHooksFromDoc() {
  44. global $doc, $options;
  45. $m = array();
  46. if( isset( $options['online'] ) ){
  47. $content = Http::get( 'http://www.mediawiki.org/w/index.php?title=Manual:Hooks&action=raw' );
  48. preg_match_all( '/\[\[\/([a-zA-Z0-9-_:]+)\|/', $content, $m );
  49. } else {
  50. $content = file_get_contents( $doc );
  51. preg_match_all( "/\n'(.*?)'/", $content, $m );
  52. }
  53. return array_unique( $m[1] );
  54. }
  55. /**
  56. * Get hooks from a PHP file
  57. * @param $file Full filename to the PHP file.
  58. * @return array of hooks found.
  59. */
  60. function getHooksFromFile( $file ) {
  61. $content = file_get_contents( $file );
  62. $m = array();
  63. preg_match_all( '/wfRunHooks\(\s*([\'"])(.*?)\1/', $content, $m);
  64. return $m[2];
  65. }
  66. /**
  67. * Get hooks from the source code.
  68. * @param $path Directory where the include files can be found
  69. * @return array of hooks found.
  70. */
  71. function getHooksFromPath( $path ) {
  72. $hooks = array();
  73. if( $dh = opendir($path) ) {
  74. while(($file = readdir($dh)) !== false) {
  75. if( filetype($path.$file) == 'file' ) {
  76. $hooks = array_merge( $hooks, getHooksFromFile($path.$file) );
  77. }
  78. }
  79. closedir($dh);
  80. }
  81. return $hooks;
  82. }
  83. /**
  84. * Get bad hooks (where the hook name could not be determined) from a PHP file
  85. * @param $file Full filename to the PHP file.
  86. * @return array of bad wfRunHooks() lines
  87. */
  88. function getBadHooksFromFile( $file ) {
  89. $content = file_get_contents( $file );
  90. $m = array();
  91. # We want to skip the "function wfRunHooks()" one. :)
  92. preg_match_all( '/(?<!function )wfRunHooks\(\s*[^\s\'"].*/', $content, $m);
  93. $list = array();
  94. foreach( $m[0] as $match ){
  95. $list[] = $match . "(" . $file . ")";
  96. }
  97. return $list;
  98. }
  99. /**
  100. * Get bad hooks from the source code.
  101. * @param $path Directory where the include files can be found
  102. * @return array of bad wfRunHooks() lines
  103. */
  104. function getBadHooksFromPath( $path ) {
  105. $hooks = array();
  106. if( $dh = opendir($path) ) {
  107. while(($file = readdir($dh)) !== false) {
  108. # We don't want to read this file as it contains bad calls to wfRunHooks()
  109. if( filetype( $path.$file ) == 'file' && !$path.$file == __FILE__ ) {
  110. $hooks = array_merge( $hooks, getBadHooksFromFile($path.$file) );
  111. }
  112. }
  113. closedir($dh);
  114. }
  115. return $hooks;
  116. }
  117. /**
  118. * Nicely output the array
  119. * @param $msg A message to show before the value
  120. * @param $arr An array
  121. * @param $sort Boolean : wheter to sort the array (Default: true)
  122. */
  123. function printArray( $msg, $arr, $sort = true ) {
  124. if($sort) asort($arr);
  125. foreach($arr as $v) echo "$msg: $v\n";
  126. }
  127. # MAIN
  128. $documented = getHooksFromDoc($doc);
  129. $potential = array();
  130. $bad = array();
  131. foreach( $pathinc as $dir ) {
  132. $potential = array_merge( $potential, getHooksFromPath( $dir ) );
  133. $bad = array_merge( $bad, getBadHooksFromPath( $dir ) );
  134. }
  135. $potential = array_unique( $potential );
  136. $bad = array_unique( $bad );
  137. $todo = array_diff( $potential, $documented );
  138. $deprecated = array_diff( $documented, $potential );
  139. // let's show the results:
  140. printArray('undocumented', $todo );
  141. printArray('not found', $deprecated );
  142. printArray('unclear hook calls', $bad );
  143. if ( count( $todo ) == 0 && count( $deprecated ) == 0 && count( $bad ) == 0 )
  144. echo "Looks good!\n";