SG Optimizer - Version 3.2.3

Version Description

Download this release

Release Info

Developer Hristo Sg
Plugin Icon 128x128 SG Optimizer
Version 3.2.3
Comparing to
See all releases

Code changes from version 2.3.2 to 3.2.3

Files changed (159) hide show
  1. class-sg-cachepress-admin.php +93 -17
  2. class-sg-cachepress-environment.php +72 -0
  3. class-sg-cachepress-memcache.php +25 -4
  4. class-sg-cachepress-options.php +4 -2
  5. class-sg-cachepress-phpversion-checker.php +103 -0
  6. class-sg-cachepress-ssl.php +434 -0
  7. class-sg-cachepress-supercacher.php +8 -10
  8. class-sg-cachepress.php +15 -6
  9. css/admin.css +59 -40
  10. css/cache.png +0 -0
  11. css/coming-soon.jpg +0 -0
  12. css/loader.gif +0 -0
  13. css/logo-white.svg +0 -0
  14. css/onoff.jpg +0 -0
  15. css/php.png +0 -0
  16. css/ssl.png +0 -0
  17. js/admin.js +94 -28
  18. js/admin_global.js +27 -2
  19. languages/sg-cachepress-bg_BG.mo +0 -0
  20. languages/sg-cachepress-bg_BG.po +0 -0
  21. languages/sg-cachepress-en_US.mo +0 -0
  22. languages/sg-cachepress-en_US.po +189 -0
  23. languages/sg-cachepress-es_ES.mo +0 -0
  24. languages/sg-cachepress-es_ES.po +0 -0
  25. languages/sg-cachepress.pot +173 -0
  26. memcache.tpl +8 -6
  27. memcached.tpl +22 -15
  28. php-compatibility-checker/readme.txt +188 -0
  29. php-compatibility-checker/sg-wpengine-phpcompat.php +460 -0
  30. php-compatibility-checker/src/css/style.css +90 -0
  31. php-compatibility-checker/src/images/check.png +0 -0
  32. php-compatibility-checker/src/images/question.png +0 -0
  33. php-compatibility-checker/src/images/x.png +0 -0
  34. php-compatibility-checker/src/js/download.min.js +2 -0
  35. php-compatibility-checker/src/js/handlebars.js +4607 -0
  36. php-compatibility-checker/src/js/run.js +364 -0
  37. php-compatibility-checker/src/ruleset-wordpress.xml +16 -0
  38. php-compatibility-checker/src/sg-wpephpcompat.php +636 -0
  39. php-compatibility-checker/src/wpcli.php +78 -0
  40. php-compatibility-checker/vendor/autoload.php +7 -0
  41. php-compatibility-checker/vendor/composer/ClassLoader.php +413 -0
  42. php-compatibility-checker/vendor/composer/LICENSE +21 -0
  43. php-compatibility-checker/vendor/composer/autoload_classmap.php +258 -0
  44. php-compatibility-checker/vendor/composer/autoload_namespaces.php +10 -0
  45. php-compatibility-checker/vendor/composer/autoload_psr4.php +10 -0
  46. php-compatibility-checker/vendor/composer/autoload_real.php +45 -0
  47. php-compatibility-checker/vendor/composer/installed.json +185 -0
  48. php-compatibility-checker/vendor/simplyadmire/composer-plugins/Configuration/Settings.yaml +5 -0
  49. php-compatibility-checker/vendor/simplyadmire/composer-plugins/LICENSE +56 -0
  50. php-compatibility-checker/vendor/simplyadmire/composer-plugins/README.md +62 -0
  51. php-compatibility-checker/vendor/simplyadmire/composer-plugins/SimplyAdmire/ComposerPlugins/Installers/PhpCodesnifferStandardInstaller.php +49 -0
  52. php-compatibility-checker/vendor/simplyadmire/composer-plugins/SimplyAdmire/ComposerPlugins/PhpCodesnifferStandardInstallerPlugin.php +20 -0
  53. php-compatibility-checker/vendor/simplyadmire/composer-plugins/composer.json +33 -0
  54. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CONTRIBUTING.md +13 -0
  55. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer.conf.dist +9 -0
  56. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer.php +2557 -0
  57. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/CLI.php +1390 -0
  58. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/Generator.php +184 -0
  59. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/HTML.php +292 -0
  60. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/Markdown.php +179 -0
  61. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/Text.php +265 -0
  62. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Exception.php +31 -0
  63. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/File.php +3715 -0
  64. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Fixer.php +734 -0
  65. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Report.php +83 -0
  66. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reporting.php +425 -0
  67. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Cbf.php +151 -0
  68. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Checkstyle.php +128 -0
  69. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Csv.php +111 -0
  70. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Diff.php +149 -0
  71. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Emacs.php +110 -0
  72. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Full.php +237 -0
  73. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Gitblame.php +131 -0
  74. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Hgblame.php +132 -0
  75. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Info.php +162 -0
  76. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Json.php +128 -0
  77. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Junit.php +149 -0
  78. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Notifysend.php +262 -0
  79. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Source.php +334 -0
  80. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Summary.php +189 -0
  81. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Svnblame.php +98 -0
  82. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/VersionControl.php +342 -0
  83. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Xml.php +132 -0
  84. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Sniff.php +94 -0
  85. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/AbstractPatternSniff.php +962 -0
  86. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/AbstractScopeSniff.php +199 -0
  87. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/AbstractVariableSniff.php +244 -0
  88. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Classes/DuplicateClassNameStandard.xml +27 -0
  89. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/CodeAnalysis/EmptyStatementStandard.xml +23 -0
  90. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/CodeAnalysis/ForLoopShouldBeWhileLoopStandard.xml +23 -0
  91. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/CodeAnalysis/ForLoopWithTestFunctionCallStandard.xml +24 -0
  92. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/CodeAnalysis/JumbledIncrementerStandard.xml +25 -0
  93. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/CodeAnalysis/UnconditionalIfStatementStandard.xml +39 -0
  94. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/CodeAnalysis/UnnecessaryFinalModifierStandard.xml +29 -0
  95. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/CodeAnalysis/UnusedFunctionParameterStandard.xml +25 -0
  96. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/CodeAnalysis/UselessOverridingMethodStandard.xml +32 -0
  97. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Commenting/FixmeStandard.xml +25 -0
  98. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Commenting/TodoStandard.xml +25 -0
  99. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/ControlStructures/InlineControlStructureStandard.xml +22 -0
  100. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Debug/CSSLintStandard.xml +19 -0
  101. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Debug/ClosureLinterStandard.xml +19 -0
  102. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Debug/JSHintStandard.xml +19 -0
  103. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Files/ByteOrderMarkStandard.xml +7 -0
  104. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Files/EndFileNewlineStandard.xml +7 -0
  105. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Files/EndFileNoNewlineStandard.xml +7 -0
  106. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Files/InlineHTMLStandard.xml +24 -0
  107. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Files/LineEndingsStandard.xml +7 -0
  108. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Files/LineLengthStandard.xml +7 -0
  109. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Files/LowercasedFilenameStandard.xml +7 -0
  110. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Files/OneClassPerFileStandard.xml +29 -0
  111. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Files/OneInterfacePerFileStandard.xml +29 -0
  112. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Formatting/DisallowMultipleStatementsStandard.xml +20 -0
  113. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Formatting/MultipleStatementAlignmentStandard.xml +56 -0
  114. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Formatting/NoSpaceAfterCastStandard.xml +19 -0
  115. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Formatting/SpaceAfterCastStandard.xml +19 -0
  116. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Functions/CallTimePassByReferenceStandard.xml +31 -0
  117. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Functions/FunctionCallArgumentSpacingStandard.xml +39 -0
  118. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Functions/OpeningFunctionBraceBsdAllmanStandard.xml +24 -0
  119. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Functions/OpeningFunctionBraceKernighanRitchieStandard.xml +24 -0
  120. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Metrics/CyclomaticComplexityStandard.xml +7 -0
  121. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Metrics/NestingLevelStandard.xml +7 -0
  122. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/NamingConventions/CamelCapsFunctionNameStandard.xml +23 -0
  123. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/NamingConventions/ConstructorNameStandard.xml +29 -0
  124. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/NamingConventions/UpperCaseConstantNameStandard.xml +29 -0
  125. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/PHP/CharacterBeforePHPOpeningTagStandard.xml +22 -0
  126. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/PHP/ClosingPHPTagStandard.xml +22 -0
  127. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/PHP/DeprecatedFunctionsStandard.xml +19 -0
  128. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/PHP/DisallowShortOpenTagStandard.xml +7 -0
  129. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/PHP/ForbiddenFunctionsStandard.xml +19 -0
  130. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/PHP/LowerCaseConstantStandard.xml +23 -0
  131. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/PHP/LowerCaseKeywordStandard.xml +19 -0
  132. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/PHP/NoSilencedErrorsStandard.xml +23 -0
  133. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/PHP/SAPIUsageStandard.xml +23 -0
  134. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/PHP/UpperCaseConstantStandard.xml +23 -0
  135. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Strings/UnnecessaryStringConcatStandard.xml +19 -0
  136. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/VersionControl/SubversionPropertiesStandard.xml +7 -0
  137. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/WhiteSpace/DisallowSpaceIndentStandard.xml +7 -0
  138. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/WhiteSpace/DisallowTabIndentStandard.xml +7 -0
  139. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/WhiteSpace/ScopeIndentStandard.xml +23 -0
  140. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Arrays/DisallowLongArraySyntaxSniff.php +79 -0
  141. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Arrays/DisallowShortArraySyntaxSniff.php +72 -0
  142. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Classes/DuplicateClassNameSniff.php +127 -0
  143. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/EmptyStatementSniff.php +106 -0
  144. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/ForLoopShouldBeWhileLoopSniff.php +102 -0
  145. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/ForLoopWithTestFunctionCallSniff.php +111 -0
  146. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/JumbledIncrementerSniff.php +146 -0
  147. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/UnconditionalIfStatementSniff.php +104 -0
  148. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/UnnecessaryFinalModifierSniff.php +96 -0
  149. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/UnusedFunctionParameterSniff.php +184 -0
  150. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/UselessOverridingMethodSniff.php +178 -0
  151. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Commenting/DocCommentSniff.php +350 -0
  152. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Commenting/FixmeSniff.php +91 -0
  153. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Commenting/TodoSniff.php +89 -0
  154. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/ControlStructures/InlineControlStructureSniff.php +255 -0
  155. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Debug/CSSLintSniff.php +107 -0
  156. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Debug/ClosureLinterSniff.php +127 -0
  157. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Debug/JSHintSniff.php +96 -0
  158. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/ByteOrderMarkSniff.php +94 -0
  159. php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/EndFileNewlineSniff.php +16 -0
class-sg-cachepress-admin.php CHANGED
@@ -12,7 +12,8 @@
12
 
13
  /** SG CachePress purge cache admin class */
14
 
15
- class SG_CachePress_Admin {
 
16
 
17
  /**
18
  * Slug of the plugin screen.
@@ -52,6 +53,14 @@ class SG_CachePress_Admin {
52
  // Add the admin page and menu item.
53
  add_action( 'admin_menu', array( $this, 'add_plugin_admin_menu' ));
54
 
 
 
 
 
 
 
 
 
55
  // Admin Init
56
  add_action( 'admin_init', array( $this, 'load_admin_global_js' ));
57
 
@@ -71,11 +80,17 @@ class SG_CachePress_Admin {
71
  add_action( 'wp_ajax_sg-cachepress-parameter-update', array( $this, 'update_parameter' ) );
72
  add_action( 'wp_ajax_sg-cachepress-cache-test', array( $this, 'cache_test_callback' ) );
73
  add_action( 'wp_ajax_sg-cachepress-cache-test-message-hide', array( $this, 'cache_test_message_hide' ) );
74
-
75
 
76
  // Add the admin bar purge button handler
77
  add_action( 'admin_post_sg-cachepress-purge', array( 'SG_CachePress_Supercacher', 'purge_cache_admin_bar' ) );
78
- }
 
 
 
 
 
 
79
 
80
  /**
81
  * Displays the notice on the top of admin panel if it has caching issues
@@ -89,7 +104,7 @@ class SG_CachePress_Admin {
89
  {
90
  $html = '<div id="ajax-notification" class="updated sg-cachepress-notification">';
91
  $html .= '<p>';
92
- $html .= __( '<strong>SG CachePress:</strong> Your site '.get_site_url().' is <strong>not cached</strong>! Make sure the Dynamic Cache is enabled in the SuperCacher tool in cPanel. <a href="javascript:;" id="dismiss-sg-cahepress-notification">Click here to hide this notice</a>.', 'ajax-notification' );
93
  $html .= '</p>';
94
  $html .= '<span id="ajax-notification-nonce" class="hidden">' . wp_create_nonce( 'ajax-notification-nonce' ) . '</span>';
95
  $html .= '</div>';
@@ -115,7 +130,7 @@ class SG_CachePress_Admin {
115
  */
116
  function cache_test_callback()
117
  {
118
- $urlToCheck = get_site_url()."/".$_POST['url'];
119
  $result = SG_CachePress_Supercacher::return_cache_result($urlToCheck);
120
 
121
  if($result == 1 && empty($_POST['url']))
@@ -196,12 +211,12 @@ class SG_CachePress_Admin {
196
  $paramTranslator = array(
197
  'dynamic-cache' => 'enable_cache',
198
  'memcached' => 'enable_memcached',
199
- 'autoflush-cache' => 'autoflush_cache',
200
  );
201
 
202
  $paramName = $paramTranslator[$_POST['parameterName']];
203
  $currentValue = (int)$this->options_handler->get_option($paramName);
204
- $toggledValue = (int)!$currentValue;
205
 
206
  //if cache is turned on or off it's a good idea to flush it on right away
207
  if ($paramName == 'enable_cache') {
@@ -256,8 +271,10 @@ class SG_CachePress_Admin {
256
  return;
257
 
258
  $screen = get_current_screen();
259
- if ( $screen->id == $this->page_hook )
260
- wp_enqueue_style( SG_CachePress::PLUGIN_SLUG . '-admin', plugins_url( 'css/admin.css', __FILE__ ), array(), SG_CachePress::VERSION );
 
 
261
  }
262
 
263
  /**
@@ -268,11 +285,14 @@ class SG_CachePress_Admin {
268
  * @return null Return early if no settings page is registered.
269
  */
270
  public function enqueue_admin_scripts() {
 
271
  if ( ! isset( $this->page_hook ) )
272
  return;
273
-
274
  $screen = get_current_screen();
275
- if ( $screen->id == $this->page_hook ) {
 
 
 
276
  wp_enqueue_script( SG_CachePress::PLUGIN_SLUG . '-admin', plugins_url( 'js/admin.js', __FILE__ ), array( 'jquery' ), SG_CachePress::VERSION, true );
277
  $strings = array(
278
  'purge' => __( 'Purge the Cache', 'sg-cachepress' ),
@@ -286,12 +306,16 @@ class SG_CachePress_Admin {
286
  'notcached' => __( 'DYNAMIC', 'sg-cachepress' ),
287
  'noheaders' => __( 'CAN\'T GET HEADERS', 'sg-cachepress' ),
288
  'testurl' => __( 'Test URL', 'sg-cachepress' ),
289
- 'showstat' => __( 'Test URL', 'sg-cachepress' )
 
 
 
 
290
  );
291
  wp_localize_script( SG_CachePress::PLUGIN_SLUG . '-admin', 'sgCachePressL10n', $strings );
292
  }
293
- }
294
-
295
  /**
296
  * Register the top level page into the WordPress admin menu.
297
  *
@@ -299,14 +323,57 @@ class SG_CachePress_Admin {
299
  */
300
  public function add_plugin_admin_menu() {
301
  $this->page_hook = add_menu_page(
302
- __( 'SuperCacher', 'sg-cachepress' ), // Page title
303
- __( 'SuperCacher', 'sg-cachepress' ), // Menu item title
304
  'manage_options',
305
  SG_CachePress::PLUGIN_SLUG, // Page slug
306
  array( $this, 'display_plugin_admin_page' ),
307
  plugins_url('sg-cachepress/css/logo-white.svg')
308
  );
309
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
310
 
311
  /**
312
  * Render the settings page for this plugin.
@@ -316,4 +383,13 @@ class SG_CachePress_Admin {
316
  public function display_plugin_admin_page() {
317
  include 'views/sg-cache.php';
318
  }
319
- }
 
 
 
 
 
 
 
 
 
12
 
13
  /** SG CachePress purge cache admin class */
14
 
15
+ class SG_CachePress_Admin {
16
+ public static $enable_php_version_checker = true;
17
 
18
  /**
19
  * Slug of the plugin screen.
53
  // Add the admin page and menu item.
54
  add_action( 'admin_menu', array( $this, 'add_plugin_admin_menu' ));
55
 
56
+ // Add the submenu pages and menu items
57
+ add_action( 'admin_menu', array( $this, 'add_plugin_caching_menu' ));
58
+ add_action( 'admin_menu', array( $this, 'add_plugin_ssl_menu' ));
59
+ if (self::$enable_php_version_checker) {
60
+ add_action( 'admin_menu', array( $this, 'add_plugin_php_menu' ));
61
+ }
62
+
63
+
64
  // Admin Init
65
  add_action( 'admin_init', array( $this, 'load_admin_global_js' ));
66
 
80
  add_action( 'wp_ajax_sg-cachepress-parameter-update', array( $this, 'update_parameter' ) );
81
  add_action( 'wp_ajax_sg-cachepress-cache-test', array( $this, 'cache_test_callback' ) );
82
  add_action( 'wp_ajax_sg-cachepress-cache-test-message-hide', array( $this, 'cache_test_message_hide' ) );
83
+ add_action( 'wp_ajax_sg-cachepress-ssl-toggle', array( 'SG_CachePress_SSL', 'toggle' ) );
84
 
85
  // Add the admin bar purge button handler
86
  add_action( 'admin_post_sg-cachepress-purge', array( 'SG_CachePress_Supercacher', 'purge_cache_admin_bar' ) );
87
+
88
+ if (!is_admin() && get_option('sg_cachepress_ssl_enabled') === '1') {
89
+ SG_CachePress_SSL::fix_mixed_content();
90
+ }
91
+
92
+
93
+ }
94
 
95
  /**
96
  * Displays the notice on the top of admin panel if it has caching issues
104
  {
105
  $html = '<div id="ajax-notification" class="updated sg-cachepress-notification">';
106
  $html .= '<p>';
107
+ $html .= __( '<strong>SG Optimizer:</strong> Your site '.get_home_url().' is <strong>not cached</strong>! Make sure the Dynamic Cache is enabled in the SuperCacher tool in cPanel. <a href="javascript:;" id="dismiss-sg-cahepress-notification">Click here to hide this notice</a>.', 'ajax-notification' );
108
  $html .= '</p>';
109
  $html .= '<span id="ajax-notification-nonce" class="hidden">' . wp_create_nonce( 'ajax-notification-nonce' ) . '</span>';
110
  $html .= '</div>';
130
  */
131
  function cache_test_callback()
132
  {
133
+ $urlToCheck = get_home_url()."/".$_POST['url'];
134
  $result = SG_CachePress_Supercacher::return_cache_result($urlToCheck);
135
 
136
  if($result == 1 && empty($_POST['url']))
211
  $paramTranslator = array(
212
  'dynamic-cache' => 'enable_cache',
213
  'memcached' => 'enable_memcached',
214
+ 'autoflush-cache' => 'autoflush_cache'
215
  );
216
 
217
  $paramName = $paramTranslator[$_POST['parameterName']];
218
  $currentValue = (int)$this->options_handler->get_option($paramName);
219
+ $toggledValue = (int)!$currentValue;
220
 
221
  //if cache is turned on or off it's a good idea to flush it on right away
222
  if ($paramName == 'enable_cache') {
271
  return;
272
 
273
  $screen = get_current_screen();
274
+ if ( in_array($screen->id, array('sg-optimizer_page_ssl','sg-optimizer_page_caching','toplevel_page_sg-cachepress','sg-optimizer_page_php-check') ) )
275
+ {
276
+ wp_enqueue_style( 'SGOptimizer', plugins_url( 'css/admin.css', __FILE__ ), array(), SG_CachePress::VERSION );
277
+ }
278
  }
279
 
280
  /**
285
  * @return null Return early if no settings page is registered.
286
  */
287
  public function enqueue_admin_scripts() {
288
+
289
  if ( ! isset( $this->page_hook ) )
290
  return;
 
291
  $screen = get_current_screen();
292
+
293
+ if ( in_array($screen->id, array('sg-optimizer_page_ssl','sg-optimizer_page_caching','toplevel_page_sg-cachepress','sg-optimizer_page_php-check') ) )
294
+
295
+ {
296
  wp_enqueue_script( SG_CachePress::PLUGIN_SLUG . '-admin', plugins_url( 'js/admin.js', __FILE__ ), array( 'jquery' ), SG_CachePress::VERSION, true );
297
  $strings = array(
298
  'purge' => __( 'Purge the Cache', 'sg-cachepress' ),
306
  'notcached' => __( 'DYNAMIC', 'sg-cachepress' ),
307
  'noheaders' => __( 'CAN\'T GET HEADERS', 'sg-cachepress' ),
308
  'testurl' => __( 'Test URL', 'sg-cachepress' ),
309
+ 'showstat' => __( 'Test URL', 'sg-cachepress' ),
310
+ 'phpversion_check' => __( 'Check PHP Version', 'sg-cachepress' ),
311
+ 'phpversion_checking' => __( 'Checking, please wait...', 'sg-cachepress' ),
312
+ 'phpversion_change' => __( 'Change PHP Version', 'sg-cachepress' ),
313
+ 'ssl_toggle_failed' => __( 'SSL toggle failed', 'sg-cachepress' ),
314
  );
315
  wp_localize_script( SG_CachePress::PLUGIN_SLUG . '-admin', 'sgCachePressL10n', $strings );
316
  }
317
+ }
318
+
319
  /**
320
  * Register the top level page into the WordPress admin menu.
321
  *
323
  */
324
  public function add_plugin_admin_menu() {
325
  $this->page_hook = add_menu_page(
326
+ __( 'SG Optimizer', 'sg-cachepress' ), // Page title
327
+ __( 'SG Optimizer', 'sg-cachepress' ), // Menu item title
328
  'manage_options',
329
  SG_CachePress::PLUGIN_SLUG, // Page slug
330
  array( $this, 'display_plugin_admin_page' ),
331
  plugins_url('sg-cachepress/css/logo-white.svg')
332
  );
333
  }
334
+
335
+ /**
336
+ * Register the sub-pages in the WordPress Admin Menu
337
+ *
338
+ * @since 3.0.0
339
+ */
340
+
341
+ public function add_plugin_ssl_menu() {
342
+ $this->page_hook = add_submenu_page(
343
+ SG_CachePress::PLUGIN_SLUG,
344
+ __( 'HTTPS Config', 'sg-cachepress' ), // Page title
345
+ __( 'HTTPS Config', 'sg-cachepress' ), // Menu item title
346
+ 'manage_options',
347
+ 'ssl', // Page slug
348
+ array( $this, 'display_plugin_ssl_page' ),
349
+ plugins_url('sg-cachepress/css/logo-white.svg')
350
+ );
351
+ }
352
+
353
+ public function add_plugin_caching_menu() {
354
+ $this->page_hook = add_submenu_page(
355
+ SG_CachePress::PLUGIN_SLUG,
356
+ __( 'SuperCacher Config', 'sg-cachepress' ), // Page title
357
+ __( 'SuperCacher Config', 'sg-cachepress' ), // Menu item title
358
+ 'manage_options',
359
+ 'caching', // Page slug
360
+ array( $this, 'display_plugin_caching_page' ),
361
+ plugins_url('sg-cachepress/css/logo-white.svg')
362
+ );
363
+ }
364
+
365
+ public function add_plugin_php_menu() {
366
+ $this->page_hook = add_submenu_page(
367
+ SG_CachePress::PLUGIN_SLUG,
368
+ __( 'PHP Config', 'sg-cachepress' ), // Page title
369
+ __( 'PHP Config', 'sg-cachepress' ), // Menu item title
370
+ 'manage_options',
371
+ 'php-check', // Page slug
372
+ array( $this, 'display_plugin_php_page' ),
373
+ plugins_url('sg-cachepress/css/logo-white.svg')
374
+ );
375
+ }
376
+
377
 
378
  /**
379
  * Render the settings page for this plugin.
383
  public function display_plugin_admin_page() {
384
  include 'views/sg-cache.php';
385
  }
386
+ public function display_plugin_ssl_page() {
387
+ include 'views/ssl.php';
388
+ }
389
+ public function display_plugin_caching_page() {
390
+ include 'views/caching.php';
391
+ }
392
+ public function display_plugin_php_page() {
393
+ include 'views/php-check.php';
394
+ }
395
+ }
class-sg-cachepress-environment.php CHANGED
@@ -31,6 +31,20 @@ class SG_CachePress_Environment {
31
  * @type array
32
  */
33
  protected $data = array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
 
35
  /**
36
  * Assign dependencies.
@@ -145,4 +159,62 @@ class SG_CachePress_Environment {
145
  public function action_data_is( $value ) {
146
  return $this->post_data_is( $value, 'action' );
147
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
  }
31
  * @type array
32
  */
33
  protected $data = array();
34
+
35
+ /**
36
+ * This is the path to the log file withing the plugin directory
37
+ *
38
+ * @var string
39
+ */
40
+ private $log_file = 'debug.log';
41
+
42
+ /**
43
+ * Max allowed filesize for the log file in MB
44
+ *
45
+ * @var integer
46
+ */
47
+ private $log_max_filesize_mb = 200;
48
 
49
  /**
50
  * Assign dependencies.
159
  public function action_data_is( $value ) {
160
  return $this->post_data_is( $value, 'action' );
161
  }
162
+
163
+
164
+ /**
165
+ * This function is used to store log data into debug.log file into the plugin directory.
166
+ *
167
+ * @since 2.3.9
168
+ *
169
+ * @param string $message Message for logging
170
+ *
171
+ * @return bool Trus if writing is successful
172
+ */
173
+ public function log( $message ) {
174
+
175
+ if ($this->log_file_check()) {
176
+ $logMessage = date('Y-m-d H:i:s') . " | {$message}\n";
177
+ $file = $this->log_file_path();
178
+ return @file_put_contents($file, $logMessage, FILE_APPEND);
179
+ }
180
+
181
+ }
182
+
183
+ /**
184
+ * Returns the full path of the log file
185
+ *
186
+ * @since 2.3.9
187
+ *
188
+ * @return string
189
+ */
190
+ private function log_file_path() {
191
+ return plugin_dir_path(__FILE__) . $this->log_file;
192
+ }
193
+
194
+ /**
195
+ * This function keeps the log file with maximum size 200MB,
196
+ * and if it is over that size it will backup the file,
197
+ * also deleting the last backup.
198
+ *
199
+ * @since 2.3.9
200
+ */
201
+ private function log_file_check() {
202
+
203
+ $file = $this->log_file_path();
204
+ if (@file_exists($file) && @is_readable($file) && @is_writable($file)) {
205
+
206
+ if (@filesize($file) > $this->log_max_filesize_mb*1000000){
207
+ // The file has exceeded the maximum allowed filesize
208
+ $new_name = $file . '.1';
209
+ @rename($file, $new_name);
210
+ }
211
+
212
+ }
213
+
214
+ if (@file_exists($file) && !@is_writable($file)) {
215
+ return false;
216
+ }
217
+
218
+ return true;
219
+ }
220
  }
class-sg-cachepress-memcache.php CHANGED
@@ -63,16 +63,37 @@ class SG_CachePress_Memcache {
63
  * @return null Return early and avoid any further interaction if accessing the script via CLI.
64
  */
65
  public function run() {
 
66
  if ( $this->options_handler->is_enabled( 'enable_memcached' ) && !$this->check_if_dropin_exists()){
67
- if (!$this->check_and_create_memcached_dropin()){
68
- $this->options_handler->disable_option('enable_memcached');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  }
70
  }
71
-
 
72
  if ( !$this->options_handler->is_enabled( 'enable_memcached' ) && $this->check_if_dropin_exists())
73
  {
74
- if (!$this->remove_memcached_dropin()){
 
 
75
  $this->options_handler->enable_option('enable_memcached');
 
 
 
76
  }
77
  }
78
  }
63
  * @return null Return early and avoid any further interaction if accessing the script via CLI.
64
  */
65
  public function run() {
66
+ // If memcache is enabled and object cache is missing
67
  if ( $this->options_handler->is_enabled( 'enable_memcached' ) && !$this->check_if_dropin_exists()){
68
+ $this->environment->log('Memcached option in wp-admin is enabled, but object-cache.php file does not exist or Memcached connection can\'t be established. Trying to establish new connection and create object-cache.php file.');
69
+ // If cannot create memcache - FAIL
70
+ if (!$this->check_and_create_memcached_dropin()) {
71
+ $this->environment->log('Creating of new object-cache.php failed or Memcached connection can\'t be established.');
72
+ // Start fail timer of 5 minutes cooldown until memcache will be disabled as option in wp-admin
73
+ if ($this->options_handler->get_option('last_fail') == 0) {
74
+ $this->environment->log('Set timer to disable Memcached option in wp-admin after 5 minutes');
75
+ $this->options_handler->update_option('last_fail', time());
76
+ } elseif ($this->options_handler->get_option('last_fail') < time() - 60*5) {
77
+ $this->environment->log('Disabling Memcached option in wp-admin panel');
78
+ $this->options_handler->disable_option('enable_memcached');
79
+ $this->options_handler->disable_option('last_fail');
80
+ }
81
+ } else {
82
+ $this->environment->log('Memcached connection has been established successfully and object-cache.php file has been created. The Memcached is now working and the timer has been reset.');
83
+ $this->options_handler->disable_option('last_fail');
84
  }
85
  }
86
+
87
+ // If there is object cache file but memcache is not enabled
88
  if ( !$this->options_handler->is_enabled( 'enable_memcached' ) && $this->check_if_dropin_exists())
89
  {
90
+ $this->environment->log('object-cache.php file exist, but memcache is disabled! Trying to delete object-cache.php file.');
91
+ if (!$this->remove_memcached_dropin()) {
92
+ // Enable Memcache
93
  $this->options_handler->enable_option('enable_memcached');
94
+ $this->environment->log('object-cache.php can not be removed, so memcache is enabled.');
95
+ } else {
96
+ $this->environment->log('object-cache.php is removed.');
97
  }
98
  }
99
  }
class-sg-cachepress-options.php CHANGED
@@ -139,7 +139,8 @@ class SG_CachePress_Options {
139
  'show_notice' => get_option( 'SGCP_ShowNotice', 0 ),
140
  'is_nginx' => get_option( 'SGCP_IsNginx', 0),
141
  'checked_nginx' => get_option( 'SGCP_CheckedNginx', 0),
142
- 'first_run' => get_option( 'SGCP_FristRun', 0)
 
143
  );
144
  }
145
 
@@ -155,7 +156,8 @@ class SG_CachePress_Options {
155
  delete_option( 'SGCP_ShowNotice' );
156
  delete_option( 'SGCP_IsNginx' );
157
  delete_option( 'SGCP_CheckedNginx' );
158
- delete_option( 'SGCP_FirstRun' );
 
159
  }
160
 
161
  /**
139
  'show_notice' => get_option( 'SGCP_ShowNotice', 0 ),
140
  'is_nginx' => get_option( 'SGCP_IsNginx', 0),
141
  'checked_nginx' => get_option( 'SGCP_CheckedNginx', 0),
142
+ 'first_run' => get_option( 'SGCP_FristRun', 0),
143
+ 'last_fail' => get_option( 'SGCP_LastFail', 0)
144
  );
145
  }
146
 
156
  delete_option( 'SGCP_ShowNotice' );
157
  delete_option( 'SGCP_IsNginx' );
158
  delete_option( 'SGCP_CheckedNginx' );
159
+ delete_option( 'SGCP_FristRun' );
160
+ delete_option( 'SGCP_LastFail' );
161
  }
162
 
163
  /**
class-sg-cachepress-phpversion-checker.php ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * SG CachePress
4
+ *
5
+ * @package SG_CachePress
6
+ * @author SiteGround
7
+ * @author PACETO
8
+ * @link http://www.siteground.com/
9
+ * @copyright 2017 SiteGround
10
+ */
11
+ class SG_CachePress_PHPVersionChecker
12
+ {
13
+
14
+ /**
15
+ * Holds the options object
16
+ *
17
+ * @since 2.3.11
18
+ *
19
+ * @type SG_CachePress_Options
20
+ */
21
+ protected $options_handler;
22
+
23
+ /**
24
+ * Assign dependencies.
25
+ *
26
+ * @since 2.3.11
27
+ *
28
+ * @param SG_CachePress_Options $options_handler
29
+ */
30
+ public function __construct($options_handler)
31
+ {
32
+ $this->options_handler = $options_handler;
33
+ }
34
+
35
+ /**
36
+ * Initialize the administration functions.
37
+ *
38
+ * @since 2.3.11
39
+ */
40
+ public function run()
41
+ {
42
+ // Register the SG_WPEngine_PHPCompat instance
43
+ $phpcompat = SG_WPEngine_PHPCompat::instance();
44
+ add_action('admin_notices', array($this, 'global_notice_phpversion_not_updated'));
45
+ add_action('wp_ajax_sg-cachepress-message-hide', array($this, 'message_hide'));
46
+ }
47
+
48
+ public function activate()
49
+ {
50
+ if (SG_CachePress_Admin::$enable_php_version_checker && !SG_WPEngine_PHPCompat::isUpToDate()) {
51
+ // @Todo to enable this message also onPluginUpdate
52
+ $this->options_handler->enable_option('show_notice_notification-1');
53
+ }
54
+ }
55
+
56
+ /**
57
+ * This function hides the notice from displaying when it is manually closed
58
+ *
59
+ * @since 2.2.7
60
+ * @return void
61
+ */
62
+ function message_hide()
63
+ {
64
+ $id = $_POST['notice_id'];
65
+ $this->options_handler->disable_option('show_notice_' . $id);
66
+
67
+ echo $id;
68
+ wp_die();
69
+ }
70
+
71
+ /**
72
+ * Template for global messages
73
+ *
74
+ * @since 2.2.7
75
+ * @return void
76
+ */
77
+ public function global_notice_template($msg, $id)
78
+ {
79
+ if ($this->options_handler->is_enabled('show_notice_' . $id)) {
80
+ $html = '<div id="ajax-' . $id . '" class="updated sg-cachepress-notification-by-id">';
81
+ $html .= '<p>';
82
+ $html .= __('<strong>SG Optimizer:</strong>'
83
+ . $msg . ' Click <a href="./admin.php?page=php-check" target="_self">here</a> for more details. '
84
+ . '<a href="javascript:;" id="' . $id . '" class="dismiss-sg-cahepress-notification-by-id">Click here to hide this notice</a>.', 'ajax-notification');
85
+ $html .= '</p>';
86
+ $html .= '<span id="ajax-notification-nonce" class="hidden">' . wp_create_nonce('ajax-notification-nonce') . '</span>';
87
+ $html .= '</div>';
88
+ echo $html;
89
+ }
90
+ }
91
+
92
+ /**
93
+ * This notice is printed on plugin activation or update
94
+ *
95
+ * @since 2.2.7
96
+ * @return void
97
+ */
98
+ public function global_notice_phpversion_not_updated()
99
+ {
100
+ $this->global_notice_template(__(' You website doesn\'t run on the recommended by SiteGround PHP version. ',
101
+ 'ajax-notification'), 'notification-1');
102
+ }
103
+ }
class-sg-cachepress-ssl.php ADDED
@@ -0,0 +1,434 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * SG CachePress
5
+ *
6
+ * @package SG_CachePress
7
+ * @author SiteGround
8
+ * @author PACETO
9
+ * @link http://www.siteground.com/
10
+ * @copyright 2014 SiteGround
11
+ * @since 3.0.0
12
+ */
13
+
14
+ /** SG CachePress main plugin class */
15
+ class SG_CachePress_SSL
16
+ {
17
+
18
+ public static $http_urls = array();
19
+ public static $is_certificate_enabled = null;
20
+ public static $is_fully_enabled = null;
21
+
22
+ /**
23
+ * Holds the options object.
24
+ *
25
+ * @type SG_CachePress_Options
26
+ */
27
+
28
+ public function __construct()
29
+ {
30
+ }
31
+
32
+ public static function is_certificate_enabled() {
33
+ if (self::$is_certificate_enabled !== null) {
34
+ return self::$is_certificate_enabled;
35
+ }
36
+
37
+ $siteurl = get_option('siteurl').'?sgCacheCheck=022870ae06716782ce17e4f6e7f69cc2';
38
+ $siteurlHTTPS = SG_CachePress_SSL::switchProtocol('http', 'https', $siteurl);
39
+
40
+ ini_set('user_agent','SG-Optimizer 3.0.2;');
41
+ $stream = stream_context_create (array("ssl" => array("capture_peer_cert" => true)));
42
+ $read = @fopen($siteurlHTTPS, "rb", false, $stream);
43
+ $cont = @stream_context_get_params($read);
44
+ $var = ($cont["options"]["ssl"]["peer_certificate"]);
45
+ $result = (!is_null($var)) ? true : false;
46
+
47
+ self::$is_certificate_enabled = $result;
48
+ return $result;
49
+ }
50
+
51
+
52
+ /**
53
+ *
54
+ * Enable SSL in .htaccess
55
+ *
56
+ * @since 3.0.0
57
+ *
58
+ * @return
59
+ *
60
+ * dies with:
61
+ * 1 - enabled
62
+ * 0 - disabled
63
+ * or error message
64
+ *
65
+ */
66
+ public static function toggle()
67
+ {
68
+ sg_cachepress_purge_cache();
69
+
70
+ if (self::is_fully_enabled()) {
71
+ self::disable();
72
+ die('0');
73
+ }
74
+
75
+ if (self::is_partially_enabled()) {
76
+ self::enable();
77
+ die('1');
78
+ }
79
+
80
+ if (!self::is_fully_enabled()) {
81
+ self::enable();
82
+ die('1');
83
+ }
84
+
85
+
86
+
87
+ // if (self::is_enabled_from_wordpress_options() && !self::is_enabled_from_htaccess()) {
88
+ // //self::enable_from_htaccess();
89
+ // die('1');
90
+ // }
91
+
92
+ }
93
+
94
+ /**
95
+ *
96
+ */
97
+ private static function disable()
98
+ {
99
+
100
+ if (self::disable_from_wordpress_options() && self::disable_from_htaccess()) {
101
+ update_option('sg_cachepress_ssl_enabled', 0);
102
+ return true;
103
+ } else {
104
+ return false;
105
+ }
106
+
107
+ }
108
+
109
+ /**
110
+ * @return boolean
111
+ */
112
+ private static function enable()
113
+ {
114
+
115
+ if (!self::is_enabled_from_htaccess()) {
116
+ self::enable_from_htaccess();
117
+ }
118
+
119
+ if (!self::is_enabled_from_wordpress_options()) {
120
+ self::enable_from_wordpress_options();
121
+ }
122
+
123
+ update_option('sg_cachepress_ssl_enabled', 1);
124
+
125
+ return true;
126
+ }
127
+
128
+ /**
129
+ *
130
+ * @return type
131
+ */
132
+ public static function is_partially_enabled()
133
+ {
134
+ if (!self::is_certificate_enabled()) {
135
+ return false;
136
+ }
137
+
138
+ return
139
+ !self::is_fully_enabled() &&
140
+ (self::is_enabled_from_htaccess() || self::is_enabled_from_one_of_the_wordpress_options());
141
+ }
142
+
143
+ /**
144
+ *
145
+ * @return type
146
+ */
147
+ //
148
+
149
+ public static function is_fully_enabled()
150
+ {
151
+ if (self::$is_fully_enabled !== null) {
152
+ return self::$is_fully_enabled;
153
+ }
154
+
155
+ $res = false;
156
+ if (!self::is_certificate_enabled()) {
157
+ $res = false;
158
+ }
159
+ $res = self::is_enabled_from_htaccess() && self::is_enabled_from_wordpress_options();
160
+ self::$is_fully_enabled = $res;
161
+ return $res;
162
+ }
163
+
164
+ /**
165
+ *
166
+ * @return boolean
167
+ */
168
+ public static function is_enabled_from_htaccess()
169
+ {
170
+ $filename = self::get_htaccess_filename();
171
+
172
+ if ($filename === false) {
173
+ return false;
174
+ }
175
+
176
+ $htaccessContent = file_get_contents($filename);
177
+
178
+ if (preg_match('/HTTPS forced by SG-Optimizer/s', $htaccessContent, $m)) {
179
+ return true;
180
+ }
181
+
182
+ return false;
183
+ }
184
+
185
+ /**
186
+ * @since 3.0.0
187
+ *
188
+ */
189
+ public static function disable_from_htaccess()
190
+ {
191
+ $filename = self::get_htaccess_filename(false);
192
+ if ($filename === false) {
193
+ return false;
194
+ }
195
+
196
+ $htaccessContent = file_get_contents($filename);
197
+
198
+ $htaccessNewContent = preg_replace("/\#\s+HTTPS\s+forced\s+by\s+SG-Optimizer(.+?)\#\s+END\s+HTTPS/ims", '', $htaccessContent);
199
+
200
+ if (substr($htaccessNewContent, 0, 1) === PHP_EOL) {
201
+ $htaccessNewContent = substr($htaccessNewContent, 1);
202
+ }
203
+
204
+ $fp = fopen($filename, "w+");
205
+ if (flock($fp, LOCK_EX)) { // do an exclusive lock
206
+ fwrite($fp, $htaccessNewContent);
207
+ flock($fp, LOCK_UN); // release the lock
208
+ return true;
209
+ } else {
210
+ return false;
211
+ }
212
+ }
213
+
214
+ /**
215
+ * @since 3.0.0
216
+ * @return boolean
217
+ */
218
+ public static function enable_from_htaccess()
219
+ {
220
+ $filename = self::get_htaccess_filename();
221
+
222
+ if ($filename === false) {
223
+ return false;
224
+ }
225
+
226
+ $htaccessContent = file_get_contents($filename);
227
+
228
+ $forceSSL = '# HTTPS forced by SG-Optimizer' . PHP_EOL;
229
+ $forceSSL .= '<IfModule mod_rewrite.c>' . PHP_EOL;
230
+ $forceSSL .= 'RewriteEngine On' . PHP_EOL;
231
+ $forceSSL .= 'RewriteCond %{HTTPS} off' . PHP_EOL;
232
+ $forceSSL .= 'RewriteRule ^(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]' . PHP_EOL;
233
+ $forceSSL .= '</IfModule>' . PHP_EOL;
234
+ $forceSSL .= '# END HTTPS';
235
+
236
+ if (substr($htaccessContent, 0, 1) !== PHP_EOL) {
237
+ $htaccessNewContent = $forceSSL . PHP_EOL . $htaccessContent;
238
+ } else {
239
+ $htaccessNewContent = $forceSSL . $htaccessContent;
240
+ }
241
+
242
+ $fp = fopen($filename, "w+");
243
+
244
+ if (flock($fp, LOCK_EX)) { // do an exclusive lock
245
+ fwrite($fp, $htaccessNewContent);
246
+ flock($fp, LOCK_UN); // release the lock
247
+ return true;
248
+ } else {
249
+ return false;
250
+ }
251
+ }
252
+
253
+ /**
254
+ * @since 3.0.0
255
+ * @param string protocol $from ('http', 'https')
256
+ * @param string protocol $to ('http', 'https')
257
+ * @param string $url
258
+ * @return type
259
+ */
260
+ public static function switchProtocol($from, $to, $url)
261
+ {
262
+ if (preg_match("/^$from\:/s", $url)) {
263
+ return preg_replace("/^$from:/i", "$to:", $url);
264
+ } else {
265
+ return $url;
266
+ }
267
+ }
268
+
269
+ /**
270
+ * @since 3.0.0
271
+ * @return boolean
272
+ */
273
+ public static function disable_from_wordpress_options()
274
+ {
275
+ $siteurl = get_option('siteurl');
276
+ $home = get_option('home');
277
+
278
+ return
279
+ update_option('siteurl', self::switchProtocol('https', 'http', $siteurl)) &&
280
+ update_option('home', self::switchProtocol('https', 'http', $home));
281
+ }
282
+
283
+ /**
284
+ *
285
+ * @since 3.0.0
286
+ * @return boolean
287
+ *
288
+ */
289
+ public static function enable_from_wordpress_options()
290
+ {
291
+ $siteurl = get_option('siteurl');
292
+ $home = get_option('home');
293
+
294
+ update_option('siteurl', self::switchProtocol('http', 'https', $siteurl));
295
+ update_option('home', self::switchProtocol('http', 'https', $home));
296
+
297
+ return true;
298
+ }
299
+
300
+ /**
301
+ * @since 3.0.0
302
+ * @return boolean
303
+ *
304
+ */
305
+ public static function is_enabled_from_one_of_the_wordpress_options()
306
+ {
307
+ if (preg_match('/^https\:/s', get_option('siteurl')) || preg_match('/^https\:/s', get_option('home'))) {
308
+ return true;
309
+ }
310
+
311
+ return false;
312
+ }
313
+
314
+ /**
315
+ * @since 3.0.0
316
+ * @return boolean
317
+ *
318
+ */
319
+ public static function is_enabled_from_wordpress_options()
320
+ {
321
+ if (preg_match('/^https\:/s', get_option('siteurl')) && preg_match('/^https\:/s', get_option('home'))) {
322
+ return true;
323
+ }
324
+
325
+ return false;
326
+ }
327
+
328
+ /**
329
+ * @since 3.0.0
330
+ * @param type $create
331
+ * @return string | false
332
+ */
333
+ public static function get_htaccess_filename($create = true)
334
+ {
335
+ $basedir = dirname(dirname(dirname(__DIR__)));
336
+ $filename = $basedir . '/.htaccess';
337
+
338
+ if (!is_file($filename) && $create) {
339
+ touch($filename);
340
+ }
341
+
342
+ if (!is_writable($filename)) {
343
+ return false;
344
+ }
345
+
346
+ return $filename;
347
+ }
348
+
349
+ /**
350
+ * add action hooks at the start and at the end of the WP process.
351
+ * @since 3.0.0
352
+ * @access public
353
+ */
354
+ public static function fix_mixed_content()
355
+ {
356
+ self::build_url_list();
357
+
358
+ if (is_admin()) {
359
+ add_action("admin_init", array("SG_CachePress_SSL", "start_buffer"));
360
+ } else {
361
+ add_action("init", array("SG_CachePress_SSL", "start_buffer"));
362
+ }
363
+ add_action("shutdown", array("SG_CachePress_SSL", "end_buffer"));
364
+ }
365
+
366
+ /**
367
+ * Apply the mixed content fixer.
368
+ * @since 3.0.0
369
+ * @access public
370
+ */
371
+ public static function filter_buffer($buffer)
372
+ {
373
+ global $rsssl_front_end;
374
+ $buffer = self::replace_insecure_links($buffer);
375
+ return $buffer;
376
+ }
377
+
378
+ public static function start_buffer()
379
+ {
380
+ ob_start(array("SG_CachePress_SSL", "filter_buffer"));
381
+ }
382
+
383
+ public static function end_buffer()
384
+ {
385
+ if (ob_get_length())
386
+ ob_end_flush();
387
+ }
388
+
389
+ /**
390
+ * Creates an array of insecure links that should be https and an array of secure links to replace with
391
+ * @since 3.0.0
392
+ * @access public
393
+ */
394
+ public static function build_url_list()
395
+ {
396
+ $home_no_www = str_replace("://www.", "://", get_option('home'));
397
+ $home_yes_www = str_replace("://", "://www.", $home_no_www);
398
+
399
+ self::$http_urls = array(
400
+ str_replace("https://", "http://", $home_yes_www),
401
+ str_replace("https://", "http://", $home_no_www),
402
+ "src='http://",
403
+ 'src="http://',
404
+ );
405
+ }
406
+
407
+ /**
408
+ * Just before the page is sent to the visitor's browser, all homeurl links are replaced with https.
409
+ * @since 3.0.0
410
+ * @access public
411
+ */
412
+ public static function replace_insecure_links($str)
413
+ {
414
+ $search_array = apply_filters('rlrsssl_replace_url_args', self::$http_urls);
415
+ $ssl_array = str_replace("http://", "https://", $search_array);
416
+ //now replace these links
417
+ $str = str_replace($search_array, $ssl_array, $str);
418
+
419
+ //replace all http links except hyperlinks
420
+ //all tags with src attr are already fixed by str_replace
421
+ $pattern = array(
422
+ '/url\([\'"]?\K(http:\/\/)(?=[^)]+)/i',
423
+ '/<link .*?href=[\'"]\K(http:\/\/)(?=[^\'"]+)/i',
424
+ '/<meta property="og:image" .*?content=[\'"]\K(http:\/\/)(?=[^\'"]+)/i',
425
+ '/<form [^>]*?action=[\'"]\K(http:\/\/)(?=[^\'"]+)/i',
426
+ /* Don't use these, these links are taken care of by the src replace */
427
+ //'/<(?:img|iframe) .*?src=[\'"]\K(http:\/\/)(?=[^\'"]+)/i',
428
+ //'/<script [^>]*?src=[\'"]\K(http:\/\/)(?=[^\'"]+)/i',
429
+ );
430
+ $str = preg_replace($pattern, 'https://', $str);
431
+ $str = str_replace("<body ", '<body data-rsssl=1 ', $str);
432
+ return apply_filters("rsssl_fixer_output", $str);
433
+ }
434
+ }
class-sg-cachepress-supercacher.php CHANGED
@@ -109,14 +109,14 @@ class SG_CachePress_Supercacher {
109
 
110
  $cache_server_socket = fsockopen( $hostname, 80, $errno, $errstr, 2 );
111
  if( ! $cache_server_socket ) {
112
- $sg_cachepress_supercacher->SGCP_Notify( 'Connection to cache server failed!' );
113
  return;
114
  }
115
-
 
116
  $request = "$purge_method {$purge_request} HTTP/1.0\r\n";
117
- $request .= "Host: {$_SERVER['SERVER_NAME']}\r\n";
118
  $request .= "Connection: Close\r\n\r\n";
119
-
120
  fwrite( $cache_server_socket, $request );
121
  $response = fgets( $cache_server_socket );
122
 
@@ -167,8 +167,7 @@ class SG_CachePress_Supercacher {
167
  }
168
 
169
  self::purge_cache(true);
170
- wp_redirect( wp_get_referer() );
171
- die();
172
  }
173
  }
174
  /**
@@ -458,7 +457,7 @@ class SG_CachePress_Supercacher {
458
  */
459
  public static function return_check_is_nginx()
460
  {
461
- $url = get_site_url();
462
  $headers = self::request_data( $url );
463
 
464
  if( isset($headers['server']) && !empty($headers['server']) )
@@ -479,10 +478,9 @@ class SG_CachePress_Supercacher {
479
  {
480
  $headers = self::request_data( $url );
481
  //Status 0: Cache is not working, 1: Cache is working, 2: Unable to connect
482
- if( !$headers || !is_array($headers) )
483
  $status = 2;
484
- else
485
- {
486
  if( isset($headers['x-proxy-cache']) && mb_strtoupper( $headers['x-proxy-cache'] ) == 'HIT' )
487
  $status = 1;
488
  else if( isset($headers['x-cache']) && mb_strtoupper( $headers['x-cache'] ) == 'SGCACHE-HIT' )
109
 
110
  $cache_server_socket = fsockopen( $hostname, 80, $errno, $errstr, 2 );
111
  if( ! $cache_server_socket ) {
 
112
  return;
113
  }
114
+
115
+ $realhost= parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST );
116
  $request = "$purge_method {$purge_request} HTTP/1.0\r\n";
117
+ $request .= "Host: {$realhost}\r\n";
118
  $request .= "Connection: Close\r\n\r\n";
119
+
120
  fwrite( $cache_server_socket, $request );
121
  $response = fgets( $cache_server_socket );
122
 
167
  }
168
 
169
  self::purge_cache(true);
170
+ wp_redirect( $_SERVER["HTTP_REFERER"] );
 
171
  }
172
  }
173
  /**
457
  */
458
  public static function return_check_is_nginx()
459
  {
460
+ $url = get_home_url();
461
  $headers = self::request_data( $url );
462
 
463
  if( isset($headers['server']) && !empty($headers['server']) )
478
  {
479
  $headers = self::request_data( $url );
480
  //Status 0: Cache is not working, 1: Cache is working, 2: Unable to connect
481
+ if (!$headers || (!is_array($headers) && !($headers instanceof ArrayAccess))) {
482
  $status = 2;
483
+ } else {
 
484
  if( isset($headers['x-proxy-cache']) && mb_strtoupper( $headers['x-proxy-cache'] ) == 'HIT' )
485
  $status = 1;
486
  else if( isset($headers['x-cache']) && mb_strtoupper( $headers['x-cache'] ) == 'SGCACHE-HIT' )
class-sg-cachepress.php CHANGED
@@ -73,9 +73,15 @@ class SG_CachePress {
73
 
74
  // Allow a check to see if this plugin is running
75
  // curl -s http://domain.com/?sgCacheCheck=022870ae06716782ce17e4f6e7f69cc2
76
- if ( isset( $_GET['sgCacheCheck'] ) && md5( 'wpCheck' ) === $_GET['sgCacheCheck'] )
77
- die( 'OK' );
78
-
 
 
 
 
 
 
79
  $this->options_handler->upgrade();
80
 
81
  $this->set_headers_cookies();
@@ -89,8 +95,11 @@ class SG_CachePress {
89
  * @param boolean $network_wide True if WPMU superadmin uses "Network Activate" action, false if WPMU is
90
  * disabled or plugin is activated on an individual blog.
91
  */
92
- public static function activate( $network_wide ) {
93
-
 
 
 
94
  if ( function_exists( 'is_multisite' ) && is_multisite() ) {
95
  if ( $network_wide ) {
96
  // Get all blog ids
@@ -237,7 +246,7 @@ class SG_CachePress {
237
  public static function check_if_plugin_caches()
238
  {
239
  $sg_cachepress_options = new SG_CachePress_Options();
240
- $urlToCheck = get_site_url();
241
 
242
  if( $sg_cachepress_options->is_enabled('enable_cache') )
243
  {
73
 
74
  // Allow a check to see if this plugin is running
75
  // curl -s http://domain.com/?sgCacheCheck=022870ae06716782ce17e4f6e7f69cc2
76
+ if ( isset( $_GET['sgCacheCheck'] ) && md5( 'wpCheck' ) === $_GET['sgCacheCheck'] ) {
77
+ die( 'OK' );
78
+ }
79
+
80
+ // Check PHP version
81
+ // // curl -s http://domain.com/?sgphpCheck=819483ed1511baac6c92a176da3bcfca
82
+ // if ( isset( $_GET['sgphpCheck'] ) && md5( 'showmeversion' ) === $_GET['sgphpCheck'] ) {
83
+ // die( PHP_VERSION );
84
+ // }
85
  $this->options_handler->upgrade();
86
 
87
  $this->set_headers_cookies();
95
  * @param boolean $network_wide True if WPMU superadmin uses "Network Activate" action, false if WPMU is
96
  * disabled or plugin is activated on an individual blog.
97
  */
98
+ public static function activate( $network_wide ) {
99
+ // call versionChecker's active method
100
+ $versionChecker = new SG_CachePress_PHPVersionChecker(new SG_CachePress_Options);
101
+ $versionChecker->activate();
102
+
103
  if ( function_exists( 'is_multisite' ) && is_multisite() ) {
104
  if ( $network_wide ) {
105
  // Get all blog ids
246
  public static function check_if_plugin_caches()
247
  {
248
  $sg_cachepress_options = new SG_CachePress_Options();
249
+ $urlToCheck = get_home_url();
250
 
251
  if( $sg_cachepress_options->is_enabled('enable_cache') )
252
  {
css/admin.css CHANGED
@@ -5,14 +5,34 @@ p { display: block; }
5
  h3 { margin: 0 0 10px; }
6
  .m0 { margin: 0 !important; }
7
  .clr { clear: both; display: block; height: 0; line-height: 0; font-size: 0; }
8
- .clear:before, .clear:after { content: ""; display: table; }
9
- .clear:after { clear: both;}
10
- .clear { zoom: 1; }
11
- .error, .notcached { color: red; text-align: center;}
12
  .sgwrap p.error { border: none !important;}
13
  .cached { color: green; font-weight:700 }
14
  input[type="name"] {box-shadow: none !important; height: 10px}
15
- #sg-cachepress-purge {background: #3e4b68; color: #FFF; border: none; box-shadow: none;}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  .wp-core-ui .button-primary { background: #3D4A69; color: #fff; border: none; border-color: #3D4A69; box-shadow: none; height: 40px; line-height: 40px; text-align: center; }
17
  .wp-core-ui .button-primary:hover,
18
  .wp-core-ui .button-primary:active,
@@ -28,54 +48,53 @@ input[type="name"] {box-shadow: none !important; height: 10px}
28
  .greybox p { font-style: italic; color: #999;}
29
 
30
  /* BOX 2 */
31
- .box:nth-of-type(2) .greybox > div:nth-of-type(1) { float: left; width: 70%; margin: 0 2% 0 0; }
32
- .box:nth-of-type(2) .greybox > div:nth-of-type(2) { float: left; width: 28%; }
33
- .box:nth-of-type(2) .greybox > div input { width: 100%; height: 40px; padding: 0 10px; margin: 0; }
34
- .box:nth-of-type(2) .three { margin: 10px 0 0; }
35
- .box:nth-of-type(2) .three > .greybox { float: left; width: 32%; min-height: 90px; margin: 0 0 0 2%; text-align: center; }
36
- .box:nth-of-type(2) .three > .greybox:first-of-type { margin: 0; }
37
- .box:nth-of-type(2) .three > .greybox .button-primary { display: block; height: 24px; line-height: 24px; background: #e37755; margin: 10px auto; padding: 0 20px; }
38
- .box:nth-of-type(2) .three > .greybox .button-primary:hover { background: #f28462 !important;; }
39
- .box:nth-of-type(2) > .greybox:last-of-type p { margin: 0 0 10px; }
40
- .box:nth-of-type(2) > .greybox:last-of-type form { text-align: center; }
41
- .box:nth-of-type(2) > .greybox:last-of-type textarea { display: block; width: 100%; height: 100px; }
42
- .box:nth-of-type(2) > .greybox:last-of-type .button-primary { margin: 10px 0 0; padding: 0 20px; }
43
 
44
  /* BOX 3 */
45
- .box:nth-of-type(3) form > div { float: left; width: 48%; }
46
- .box:nth-of-type(3) form > div:first-of-type { margin: 0 4% 0 0; }
47
- .box:nth-of-type(3) form > div > input { width: 100%; }
48
- .box:nth-of-type(3) form input { margin: 0; }
49
- .box:nth-of-type(3) > .greybox > p { float: left; margin: 1em 0 1em 10px; }
50
- .box:nth-of-type(3) > .greybox > a { float: left; }
51
- .box:nth-of-type(3) > .greybox:last-of-type p { text-align: left; }
52
- .box:nth-of-type(3) > .greybox:last-of-type form { margin: 20px 0 0; text-align: center; }
53
- .box:nth-of-type(3) > .greybox:last-of-type .button-primary { margin: 10px 0 0; padding: 0 20px; }
54
  .toggleon, .toggleoff { overflow: hidden; display: block; margin: 10px auto; width: 72px; height: 24px; background: url(onoff.jpg) 0 0 no-repeat; }
55
  .toggleoff { background: url(onoff.jpg) -72px 0 no-repeat; }
56
 
57
  #sg-cachepress-blacklist-textarea { resize: vertical; }
58
 
59
  @media screen and (max-width: 782px), screen and (max-device-width: 782px) {
60
- .wp-core-ui .button { padding: 0; font-size: 13px; }
61
- .box:nth-of-type(2) .three > .greybox { width: 100%; margin: 10px 0 0; }
62
  }
63
 
64
- @media screen and (max-width: 360px), screen and (max-device-width: 360px) {
65
- .sgwrap { margin: 10px 10px 10px 0; }
66
- .sgwrap h2 { font-size: 20px; }
67
- .box { margin: 10px 0 0; padding: 10px; }
68
- .box:nth-of-type(2) .greybox:first-of-type > div { float: none; width: 100%; }
69
- .box:nth-of-type(2) .greybox > div:nth-of-type(1) { margin: 0 0 20px; }
70
- }
71
 
72
  #adminmenu .wp-menu-image img {
73
  padding-left: 9px !important;
74
  }
75
 
76
- input#testurl {
77
- width: 50%;
78
- height: 38px;
79
- margin-right: 20px;
80
- border: 1px solid #dbdbdb;
 
 
 
 
 
 
81
  }
 
5
  h3 { margin: 0 0 10px; }
6
  .m0 { margin: 0 !important; }
7
  .clr { clear: both; display: block; height: 0; line-height: 0; font-size: 0; }
8
+ .sgclr:before, .sgclr:after { content: ""; display: table; }
9
+ .sgclr:after { clear: both;}
10
+ .sgclr { zoom: 1; }
11
+ .error, .notcached { color: red !important; text-align: center;}
12
  .sgwrap p.error { border: none !important;}
13
  .cached { color: green; font-weight:700 }
14
  input[type="name"] {box-shadow: none !important; height: 10px}
15
+
16
+ .greybox img {
17
+ text-align: center;
18
+ display: block;
19
+ margin: 20px auto
20
+ }
21
+
22
+ #sg-cachepress-purge, #caching-link, #ssl-link, #php-link {background: #3e4b68; color: #FFF; border: none; box-shadow: none;}
23
+
24
+ #sg-cachepress-party, #sg-cachepress-logout, #sg-cachepress-ssl-error {
25
+ clear: both;
26
+ }
27
+
28
+ p#sg-cachepress-partial-error strong, p#sg-cachepress-htaccess-error strong, p#sg-cachepress-ssl-error strong {
29
+ color: red !important;
30
+ }
31
+
32
+ .ssl-ul {
33
+ padding-left: 20px;
34
+ list-style: inside;
35
+ }
36
  .wp-core-ui .button-primary { background: #3D4A69; color: #fff; border: none; border-color: #3D4A69; box-shadow: none; height: 40px; line-height: 40px; text-align: center; }
37
  .wp-core-ui .button-primary:hover,
38
  .wp-core-ui .button-primary:active,
48
  .greybox p { font-style: italic; color: #999;}
49
 
50
  /* BOX 2 */
51
+ .box:nth-of-type(1) .greybox > div:nth-of-type(1) { float: left; width: 70%; margin: 0 2% 0 0; }
52
+ .box:nth-of-type(1) .greybox > div:nth-of-type(2) { float: left; width: 28%; }
53
+ .box:nth-of-type(1) .greybox > div input { width: 100%; height: 40px; padding: 0 10px; margin: 0; }
54
+ .box:nth-of-type(1) .three { margin: 10px 0 0; }
55
+ .box:nth-of-type(1) .three > .greybox { float: left; width: 32%; min-height: 90px; margin: 0 0 0 2%; text-align: center; }
56
+ .box:nth-of-type(1) .three > .greybox:first-of-type { margin: 0; }
57
+ .box:nth-of-type(1) .three > .greybox .button-primary { display: block; height: 24px; line-height: 24px; background: #e37755; margin: 10px auto; padding: 0 20px; }
58
+ .box:nth-of-type(1) .three > .greybox .button-primary:hover { background: #f28462 !important;; }
59
+ .box:nth-of-type(1) > .greybox:last-of-type p { margin: 0 0 10px; }
60
+ .box:nth-of-type(1) > .greybox:last-of-type form { text-align: center; }
61
+ .box:nth-of-type(1) > .greybox:last-of-type textarea { display: block; width: 100%; height: 100px; }
62
+ .box:nth-of-type(1) > .greybox:last-of-type .button-primary { margin: 10px 0 0; padding: 0 20px; }
63
 
64
  /* BOX 3 */
65
+ .box:nth-of-type(2) form > div { float: left; width: 48%; }
66
+ .box:nth-of-type(2) form > div:first-of-type { margin: 0 4% 0 0; }
67
+ .box:nth-of-type(2) form > div > input { width: 100%; }
68
+ .box:nth-of-type(2) form input { margin: 0; }
69
+ .box:nth-of-type(2) > .greybox > p { float: left; margin: 1em 0 1em 10px; }
70
+ .box:nth-of-type(2) > .greybox > a { float: left; }
71
+ .box:nth-of-type(2) > .greybox:last-of-type p { text-align: left; }
72
+ .box:nth-of-type(2) > .greybox:last-of-type form { margin: 20px 0 0; text-align: center; }
73
+ .box:nth-of-type(2) > .greybox:last-of-type .button-primary { margin: 10px 0 0; padding: 0 20px; }
74
  .toggleon, .toggleoff { overflow: hidden; display: block; margin: 10px auto; width: 72px; height: 24px; background: url(onoff.jpg) 0 0 no-repeat; }
75
  .toggleoff { background: url(onoff.jpg) -72px 0 no-repeat; }
76
 
77
  #sg-cachepress-blacklist-textarea { resize: vertical; }
78
 
79
  @media screen and (max-width: 782px), screen and (max-device-width: 782px) {
80
+ .box:nth-of-type(1) .three > .greybox { width: 100%; margin: 10px 0 0; }
 
81
  }
82
 
 
 
 
 
 
 
 
83
 
84
  #adminmenu .wp-menu-image img {
85
  padding-left: 9px !important;
86
  }
87
 
88
+ input#testurl {width: 50%; height: 38px; margin-right: 20px; border: 1px solid #dbdbdb;}
89
+
90
+
91
+ input#runButton.button-primary.sgloading {
92
+ padding-left: 35px !important;
93
+ background: #3D4A69 url(loader.gif) 5px center no-repeat !important;
94
+ }
95
+
96
+ h3#phpVersionCheckerTextBelow {
97
+ color: #444;
98
+ font-size: 1.2em;
99
  }
100
+
css/cache.png ADDED
Binary file
css/coming-soon.jpg ADDED
Binary file
css/loader.gif ADDED
Binary file
css/logo-white.svg CHANGED
File without changes
css/onoff.jpg CHANGED
File without changes
css/php.png ADDED
Binary file
css/ssl.png ADDED
Binary file
js/admin.js CHANGED
@@ -6,8 +6,49 @@ jQuery( function ($) {
6
  jQuery('#sg-cachepress-memcached-toggle').on('click.sg-cachepress', function(event){event.preventDefault();sg_cachepress_toggle_option('memcached');});
7
  jQuery('#sg-cachepress-autoflush-cache-toggle').on('click.sg-cachepress', function(event){event.preventDefault();sg_cachepress_toggle_option('autoflush-cache');});
8
  jQuery('#sg-cachepress-blacklist').on('click.sg-cachepress', sg_cachepress_save_blacklist);
 
9
  });
10
  var sg_cachepress_toggle_in_progress = false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  /**
12
  * Update a setting parameter
13
  *
@@ -18,34 +59,35 @@ var sg_cachepress_toggle_in_progress = false;
18
  * @param {jQuery.event} event
19
  */
20
  function sg_cachepress_toggle_option(optionName) {
21
- if (sg_cachepress_toggle_in_progress)
22
- return;
23
-
24
- sg_cachepress_toggle_in_progress = true;
25
- var $ajaxArgs;
26
- $ajaxArgs = {
27
- action: 'sg-cachepress-parameter-update',
28
- parameterName: optionName,
29
- objects: 'all'
30
- };
31
- jQuery.post(ajaxurl, $ajaxArgs).done(function(data){
32
- sg_cachepress_toggle_in_progress = false;
33
- jQuery('#sg-cachepress-'+optionName+'-text').show();
34
- jQuery('#sg-cachepress-'+optionName+'-error').hide();
35
- if (data == 1)
36
- {
37
- jQuery('#sg-cachepress-'+optionName+'-toggle').removeClass('toggleoff').addClass('toggleon', 1000);
38
- return;
39
- }
40
- if (data == 0)
41
- {
42
- jQuery('#sg-cachepress-'+optionName+'-toggle').removeClass('toggleon').addClass('toggleoff', 1000);
43
- return;
44
- }
45
-
46
- jQuery('#sg-cachepress-'+optionName+'-text').hide();
47
- jQuery('#sg-cachepress-'+optionName+'-error').html(data).show();
48
- });
 
49
  }
50
 
51
  /**
@@ -72,6 +114,30 @@ function sg_cachepress_save_blacklist(event) {
72
  jQuery('#sg-cachepress-blacklist').removeAttr('disabled').attr('value', sgCachePressL10n.updated);
73
  });
74
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  /**
76
  * Start the purge procedure from a button click.
77
  *
6
  jQuery('#sg-cachepress-memcached-toggle').on('click.sg-cachepress', function(event){event.preventDefault();sg_cachepress_toggle_option('memcached');});
7
  jQuery('#sg-cachepress-autoflush-cache-toggle').on('click.sg-cachepress', function(event){event.preventDefault();sg_cachepress_toggle_option('autoflush-cache');});
8
  jQuery('#sg-cachepress-blacklist').on('click.sg-cachepress', sg_cachepress_save_blacklist);
9
+ jQuery('#sg-cachepress-phpversion-check').on('click.sg-cachepress', sg_cachepress_phpversion_check);
10
  });
11
  var sg_cachepress_toggle_in_progress = false;
12
+ var sg_cachepress_toggle_ssl_in_progress = false;
13
+
14
+
15
+ /**
16
+ * 0 - disabled
17
+ * 1 - enabled
18
+ * or error message
19
+ */
20
+ jQuery('#sg-cachepress-ssl-toggle').on('click.sg-cachepress', function(event){
21
+ event.preventDefault();
22
+ if (sg_cachepress_toggle_ssl_in_progress) {
23
+ return;
24
+ }
25
+ sg_cachepress_toggle_ssl_in_progress = true;
26
+
27
+ var $ajaxArgs = {
28
+ action: 'sg-cachepress-ssl-toggle',
29
+ objects: 'all'
30
+ };
31
+
32
+ jQuery.post(ajaxurl, $ajaxArgs).done(function(data){
33
+ sg_cachepress_toggle_ssl_in_progress = false;
34
+ jQuery('#sg-cachepress-ssl-text').show();
35
+ jQuery('#sg-cachepress-ssl-error').hide();
36
+
37
+ if (data === '0') {
38
+ //HTTP
39
+ jQuery('#sg-cachepress-ssl-toggle').removeClass('toggleon').addClass('toggleoff', 1000);
40
+ location.href = 'http:' + window.location.href.substring(window.location.protocol.length);
41
+ } else if (data === '1') {
42
+ //HTTPS
43
+ jQuery('#sg-cachepress-ssl-toggle').removeClass('toggleoff').addClass('toggleon', 1000);
44
+ location.href = 'https:' + window.location.href.substring(window.location.protocol.length);
45
+ } else {
46
+ jQuery('#sg-cachepress-ssl-text').hide();
47
+ jQuery('#sg-cachepress-ssl-error').html(sgCachePressL10n.ssl_toggle_failed).show();
48
+ }
49
+ });
50
+ });
51
+
52
  /**
53
  * Update a setting parameter
54
  *
59
  * @param {jQuery.event} event
60
  */
61
  function sg_cachepress_toggle_option(optionName) {
62
+ if (sg_cachepress_toggle_in_progress) {
63
+ return;
64
+ }
65
+
66
+ sg_cachepress_toggle_in_progress = true;
67
+ var $ajaxArgs;
68
+ $ajaxArgs = {
69
+ action: 'sg-cachepress-parameter-update',
70
+ parameterName: optionName,
71
+ objects: 'all'
72
+ };
73
+ jQuery.post(ajaxurl, $ajaxArgs).done(function(data){
74
+ sg_cachepress_toggle_in_progress = false;
75
+ jQuery('#sg-cachepress-'+optionName+'-text').show();
76
+ jQuery('#sg-cachepress-'+optionName+'-error').hide();
77
+ if (data == 1)
78
+ {
79
+ jQuery('#sg-cachepress-'+optionName+'-toggle').removeClass('toggleoff').addClass('toggleon', 1000);
80
+ return;
81
+ }
82
+ if (data == 0)
83
+ {
84
+ jQuery('#sg-cachepress-'+optionName+'-toggle').removeClass('toggleon').addClass('toggleoff', 1000);
85
+ return;
86
+ }
87
+
88
+ jQuery('#sg-cachepress-'+optionName+'-text').hide();
89
+ jQuery('#sg-cachepress-'+optionName+'-error').html(data).show();
90
+ });
91
  }
92
 
93
  /**
114
  jQuery('#sg-cachepress-blacklist').removeAttr('disabled').attr('value', sgCachePressL10n.updated);
115
  });
116
  }
117
+
118
+ /**
119
+ * Find optimal PHP version
120
+ *
121
+ * @since 2.3.11
122
+ *
123
+ * @function
124
+ *
125
+ * @param {jQuery.event} event
126
+ */
127
+ function sg_cachepress_phpversion_check(event) {
128
+ event.preventDefault();
129
+ var $ajaxArgs;
130
+ $ajaxArgs = {
131
+ action: 'sg-cachepress-phpversion-check',
132
+ objects: 'all'
133
+ };
134
+ jQuery(event.target).attr('disabled','disabled').attr('value', sgCachePressL10n.phpversion_checking);
135
+ jQuery.post(ajaxurl, $ajaxArgs).done(function(){
136
+ jQuery('#sg-cachepress-phpversion-check').removeAttr('disabled').attr('value', sgCachePressL10n.phpversion_check);
137
+ });
138
+ }
139
+
140
+
141
  /**
142
  * Start the purge procedure from a button click.
143
  *
js/admin_global.js CHANGED
@@ -1,10 +1,35 @@
1
  jQuery(document).ready(function(){
2
  if(jQuery('#dismiss-sg-cahepress-notification').length)
3
  jQuery('#dismiss-sg-cahepress-notification').click(function(){ sg_cachepress_notice_hide(); });
 
 
 
 
 
 
 
 
 
4
  });
5
 
6
  function sg_cachepress_notice_hide()
7
  {
8
- jQuery('.sg-cachepress-notification').slideUp();
9
- jQuery.post(ajaxurl,{action:'sg-cachepress-cache-test-message-hide'});
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  }
1
  jQuery(document).ready(function(){
2
  if(jQuery('#dismiss-sg-cahepress-notification').length)
3
  jQuery('#dismiss-sg-cahepress-notification').click(function(){ sg_cachepress_notice_hide(); });
4
+
5
+ if(jQuery('.dismiss-sg-cahepress-notification-by-id').length) {
6
+ jQuery('.dismiss-sg-cahepress-notification-by-id').click(
7
+ function(event){
8
+ sg_cachepress_notice_hide_by_id(event.target.id);
9
+ }
10
+ );
11
+ }
12
+
13
  });
14
 
15
  function sg_cachepress_notice_hide()
16
  {
17
+ jQuery('.sg-cachepress-notification').slideUp();
18
+ jQuery.post(ajaxurl,{action:'sg-cachepress-cache-test-message-hide'});
19
+ }
20
+
21
+ /**
22
+ *
23
+ * @param {string} id could be 'notification-1' , 'notification-2', ... etc
24
+ * @returns {undefined}
25
+ */
26
+ function sg_cachepress_notice_hide_by_id(id)
27
+ {
28
+ jQuery('#ajax-' + id).slideUp();
29
+ $ajaxArgs = {
30
+ action: 'sg-cachepress-message-hide',
31
+ notice_id: id
32
+ };
33
+
34
+ jQuery.post(ajaxurl, $ajaxArgs);
35
  }
languages/sg-cachepress-bg_BG.mo CHANGED
File without changes
languages/sg-cachepress-bg_BG.po CHANGED
File without changes
languages/sg-cachepress-en_US.mo ADDED
Binary file
languages/sg-cachepress-en_US.po ADDED
@@ -0,0 +1,189 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: SG CachePress\n"
4
+ "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: Fri Jan 08 2016 11:09:50 GMT+0200 (EET)\n"
6
+ "PO-Revision-Date: Fri Jan 08 2016 11:19:38 GMT+0200 (EET)\n"
7
+ "Last-Translator: Hristo Pandjarov <pandjarov@me.com>\n"
8
+ "Language-Team: \n"
9
+ "Language: English\n"
10
+ "Plural-Forms: nplurals=2; plural=n != 1\n"
11
+ "MIME-Version: 1.0\n"
12
+ "Content-Type: text/plain; charset=UTF-8\n"
13
+ "Content-Transfer-Encoding: 8bit\n"
14
+ "X-Poedit-SourceCharset: UTF-8\n"
15
+ "X-Poedit-Basepath: .\n"
16
+ "X-Poedit-SearchPath-0: ..\n"
17
+ "X-Poedit-KeywordsList: _:1;gettext:1;dgettext:2;ngettext:1,2;dngettext:2,3;"
18
+ "__:1;_e:1;_c:1;_n:1,2;_n_noop:1,2;_nc:1,2;__ngettext:1,2;__ngettext_noop:1,2;"
19
+ "_x:1,2c;_ex:1,2c;_nx:1,2,4c;_nx_noop:1,2,3c;_n_js:1,2;_nx_js:1,2,3c;"
20
+ "esc_attr__:1;esc_html__:1;esc_attr_e:1;esc_html_e:1;esc_attr_x:1,2c;"
21
+ "esc_html_x:1,2c;comments_number_link:2,3;t:1;st:1;trans:1;transChoice:1,2\n"
22
+ "X-Generator: Loco - https://localise.biz/\n"
23
+ "X-Loco-Target-Locale: en_US"
24
+
25
+ #. Name of the plugin
26
+ msgid "SG CachePress"
27
+ msgstr "SG CachePress"
28
+
29
+ #. Description of the plugin
30
+ msgid ""
31
+ "Through the settings of this plugin you can manage how your Wordpress "
32
+ "interracts with NGINX and Memcached."
33
+ msgstr ""
34
+ "Through the settings of this plugin you can manage how your Wordpress "
35
+ "interracts with NGINX and Memcached."
36
+
37
+ #. Author of the plugin
38
+ msgid "SiteGround"
39
+ msgstr "SiteGround"
40
+
41
+ #: ../class-sg-cachepress-admin.php:181
42
+ msgid "Purge SG Cache"
43
+ msgstr "Purge SG Cache"
44
+
45
+ #: ../class-sg-cachepress-admin.php:278 ../views/sg-cache.php:28
46
+ msgid "Purge the Cache"
47
+ msgstr "Purge the Cache"
48
+
49
+ #: ../class-sg-cachepress-admin.php:279
50
+ msgid "Purging, please wait..."
51
+ msgstr "Purging, please wait..."
52
+
53
+ #: ../class-sg-cachepress-admin.php:280
54
+ msgid "Updating, please wait..."
55
+ msgstr "Updating, please wait..."
56
+
57
+ #: ../class-sg-cachepress-admin.php:281 ../views/sg-cache.php:41
58
+ msgid "Update the Exclude List"
59
+ msgstr "Update the Exclude List"
60
+
61
+ #: ../class-sg-cachepress-admin.php:282
62
+ msgid "Successfully Purged"
63
+ msgstr "Successfully Purged"
64
+
65
+ #: ../class-sg-cachepress-admin.php:284
66
+ msgid "Testing..."
67
+ msgstr "Testing..."
68
+
69
+ #: ../class-sg-cachepress-admin.php:285
70
+ msgid "CACHED"
71
+ msgstr "CACHED"
72
+
73
+ #: ../class-sg-cachepress-admin.php:286
74
+ msgid "DYNAMIC"
75
+ msgstr "NOT CACHED"
76
+
77
+ #: ../class-sg-cachepress-admin.php:287
78
+ msgid "CAN'T GET HEADERS"
79
+ msgstr "CAN'T GET HEADERS"
80
+
81
+ #: ../class-sg-cachepress-admin.php:288 ../class-sg-cachepress-admin.php:289 ..
82
+ #: views/sg-cache.php:66
83
+ msgid "Test URL"
84
+ msgstr "Test URL"
85
+
86
+ #. Page title
87
+ #: ../class-sg-cachepress-admin.php:302 ../class-sg-cachepress-admin.php:303
88
+ msgid "SuperCacher"
89
+ msgstr "SuperCacher"
90
+
91
+ #: ../views/sg-cache.php:3
92
+ msgid "SuperCacher for WordPress by SiteGround"
93
+ msgstr "SuperCacher for WordPress by SiteGround"
94
+
95
+ #: ../views/sg-cache.php:4
96
+ msgid ""
97
+ "The SuperCacher is a system that allows you to use the SiteGround dynamic "
98
+ "cache and Memcached to optimize the performance of your WordPress. In order "
99
+ "to take advantage of the system you should have the SuperCacher enabled at "
100
+ "your web host plus the required cache options turned on below. For more "
101
+ "information on the different caching options refer to the <a href=\"http:"
102
+ "//www.siteground.com/tutorials/supercacher/\" target=\"_blank\">SuperCacher "
103
+ "Tutorial</a>!"
104
+ msgstr ""
105
+ "The SuperCacher is a system that allows you to use the SiteGround dynamic "
106
+ "cache and Memcached to optimize the performance of your WordPress. In order "
107
+ "to take advantage of the system you should have the SuperCacher enabled at "
108
+ "your web host plus the required cache options turned on below. For more "
109
+ "information on the different caching options refer to the <a href=\"http:"
110
+ "//www.siteground.com/tutorials/supercacher/\" target=\"_blank\">SuperCacher "
111
+ "Tutorial</a>!"
112
+
113
+ #: ../views/sg-cache.php:8
114
+ msgid "Dynamic Cache Settings"
115
+ msgstr "Dynamic Cache Settings"
116
+
117
+ #: ../views/sg-cache.php:12
118
+ msgid "Dynamic Cache"
119
+ msgstr "Dynamic Cache"
120
+
121
+ #: ../views/sg-cache.php:14
122
+ msgid "Enable the Dynamic caching system"
123
+ msgstr "Enable the Dynamic caching system"
124
+
125
+ #: ../views/sg-cache.php:19
126
+ msgid "AutoFlush Cache"
127
+ msgstr "AutoFlush Cache"
128
+
129
+ #: ../views/sg-cache.php:21
130
+ msgid "Automatically flush the Dynamic cache when you edit your content."
131
+ msgstr "Automatically flush the Dynamic cache when you edit your content."
132
+
133
+ #: ../views/sg-cache.php:26
134
+ msgid "Purge Cache"
135
+ msgstr "Purge Cache"
136
+
137
+ #: ../views/sg-cache.php:30
138
+ msgid "Purge all the data cached by the Dynamic cache."
139
+ msgstr "Purge all the data cached by the Dynamic cache."
140
+
141
+ #: ../views/sg-cache.php:35
142
+ msgid "Exclude URLs From Dynamic Caching"
143
+ msgstr "Exclude URLs From Dynamic Caching"
144
+
145
+ #: ../views/sg-cache.php:36
146
+ msgid ""
147
+ "Provide a list of your website URLs you would like to exclude from the cache."
148
+ " For example if you would like to exclude: <strong>http://domain."
149
+ "com/path/to/url</strong><br>\n"
150
+ " You can simply input the \"path\" string part of the URL. Then each URL "
151
+ "that consists of it will be excluded. Divide each URL by a new line."
152
+ msgstr ""
153
+ "Provide a list of your website URLs you would like to exclude from the cache."
154
+ " For example if you would like to exclude: <strong>http://domain."
155
+ "com/path/to/url</strong><br>\n"
156
+ " You can simply input the \"path\" string part of the URL. Then each URL "
157
+ "that consists of it will be excluded. Divide each URL by a new line."
158
+
159
+ #: ../views/sg-cache.php:46
160
+ msgid "Memcached Settings"
161
+ msgstr "Memcached Settings"
162
+
163
+ #: ../views/sg-cache.php:51
164
+ msgid "Enable Memcached"
165
+ msgstr "Enable Memcached"
166
+
167
+ #: ../views/sg-cache.php:55
168
+ msgid ""
169
+ "Store in the server's memory frequently executed queries to the database for "
170
+ "a faster access on a later use."
171
+ msgstr ""
172
+ "Store in the server's memory frequently executed queries to the database for "
173
+ "a faster access on a later use."
174
+
175
+ #: ../views/sg-cache.php:61
176
+ msgid "Dynamic Cache Status"
177
+ msgstr "Dynamic Cache Status"
178
+
179
+ #: ../views/sg-cache.php:69
180
+ msgid "Status:"
181
+ msgstr "Status:"
182
+
183
+ #: ../views/sg-cache.php:72
184
+ msgid ""
185
+ "Check if this URL is dynamic or cached. Leave empty for your index or "
186
+ "<strong>/example/</strong> for another page."
187
+ msgstr ""
188
+ "Check if this URL is dynamic or cached. Leave empty for your index or "
189
+ "<strong>/example/</strong> for another page."
languages/sg-cachepress-es_ES.mo CHANGED
File without changes
languages/sg-cachepress-es_ES.po CHANGED
File without changes
languages/sg-cachepress.pot ADDED
@@ -0,0 +1,173 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Loco Gettext template
2
+ #, fuzzy
3
+ msgid ""
4
+ msgstr ""
5
+ "Project-Id-Version: SG CachePress\n"
6
+ "Report-Msgid-Bugs-To: \n"
7
+ "POT-Creation-Date: Fri Jan 08 2016 11:09:50 GMT+0200 (EET)\n"
8
+ "POT-Revision-Date: Fri Jan 08 2016 11:09:58 GMT+0200 (EET)\n"
9
+ "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
10
+ "Last-Translator: \n"
11
+ "Language-Team: \n"
12
+ "Language: \n"
13
+ "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION\n"
14
+ "MIME-Version: 1.0\n"
15
+ "Content-Type: text/plain; charset=UTF-8\n"
16
+ "Content-Transfer-Encoding: 8bit\n"
17
+ "X-Poedit-SourceCharset: UTF-8\n"
18
+ "X-Poedit-Basepath: .\n"
19
+ "X-Poedit-SearchPath-0: ..\n"
20
+ "X-Poedit-KeywordsList: _:1;gettext:1;dgettext:2;ngettext:1,2;dngettext:2,3;"
21
+ "__:1;_e:1;_c:1;_n:1,2;_n_noop:1,2;_nc:1,2;__ngettext:1,2;__ngettext_noop:1,2;"
22
+ "_x:1,2c;_ex:1,2c;_nx:1,2,4c;_nx_noop:1,2,3c;_n_js:1,2;_nx_js:1,2,3c;"
23
+ "esc_attr__:1;esc_html__:1;esc_attr_e:1;esc_html_e:1;esc_attr_x:1,2c;"
24
+ "esc_html_x:1,2c;comments_number_link:2,3;t:1;st:1;trans:1;transChoice:1,2\n"
25
+ "X-Generator: Loco - https://localise.biz/"
26
+
27
+ #. Name of the plugin
28
+ msgid "SG CachePress"
29
+ msgstr ""
30
+
31
+ #. Description of the plugin
32
+ msgid ""
33
+ "Through the settings of this plugin you can manage how your Wordpress "
34
+ "interracts with NGINX and Memcached."
35
+ msgstr ""
36
+
37
+ #. Author of the plugin
38
+ msgid "SiteGround"
39
+ msgstr ""
40
+
41
+ #: ../class-sg-cachepress-admin.php:181
42
+ msgid "Purge SG Cache"
43
+ msgstr ""
44
+
45
+ #: ../class-sg-cachepress-admin.php:278 ../views/sg-cache.php:28
46
+ msgid "Purge the Cache"
47
+ msgstr ""
48
+
49
+ #: ../class-sg-cachepress-admin.php:279
50
+ msgid "Purging, please wait..."
51
+ msgstr ""
52
+
53
+ #: ../class-sg-cachepress-admin.php:280
54
+ msgid "Updating, please wait..."
55
+ msgstr ""
56
+
57
+ #: ../class-sg-cachepress-admin.php:281 ../views/sg-cache.php:41
58
+ msgid "Update the Exclude List"
59
+ msgstr ""
60
+
61
+ #: ../class-sg-cachepress-admin.php:282
62
+ msgid "Successfully Purged"
63
+ msgstr ""
64
+
65
+ #: ../class-sg-cachepress-admin.php:284
66
+ msgid "Testing..."
67
+ msgstr ""
68
+
69
+ #: ../class-sg-cachepress-admin.php:285
70
+ msgid "CACHED"
71
+ msgstr ""
72
+
73
+ #: ../class-sg-cachepress-admin.php:286
74
+ msgid "DYNAMIC"
75
+ msgstr ""
76
+
77
+ #: ../class-sg-cachepress-admin.php:287
78
+ msgid "CAN'T GET HEADERS"
79
+ msgstr ""
80
+
81
+ #: ../class-sg-cachepress-admin.php:288 ../class-sg-cachepress-admin.php:289 ..
82
+ #: /views/sg-cache.php:66
83
+ msgid "Test URL"
84
+ msgstr ""
85
+
86
+ #. Page title
87
+ #: ../class-sg-cachepress-admin.php:302 ../class-sg-cachepress-admin.php:303
88
+ msgid "SuperCacher"
89
+ msgstr ""
90
+
91
+ #: ../views/sg-cache.php:3
92
+ msgid "SuperCacher for WordPress by SiteGround"
93
+ msgstr ""
94
+
95
+ #: ../views/sg-cache.php:4
96
+ msgid ""
97
+ "The SuperCacher is a system that allows you to use the SiteGround dynamic "
98
+ "cache and Memcached to optimize the performance of your WordPress. In order "
99
+ "to take advantage of the system you should have the SuperCacher enabled at "
100
+ "your web host plus the required cache options turned on below. For more "
101
+ "information on the different caching options refer to the <a href=\"http:"
102
+ "//www.siteground.com/tutorials/supercacher/\" target=\"_blank\">SuperCacher "
103
+ "Tutorial</a>!"
104
+ msgstr ""
105
+
106
+ #: ../views/sg-cache.php:8
107
+ msgid "Dynamic Cache Settings"
108
+ msgstr ""
109
+
110
+ #: ../views/sg-cache.php:12
111
+ msgid "Dynamic Cache"
112
+ msgstr ""
113
+
114
+ #: ../views/sg-cache.php:14
115
+ msgid "Enable the Dynamic caching system"
116
+ msgstr ""
117
+
118
+ #: ../views/sg-cache.php:19
119
+ msgid "AutoFlush Cache"
120
+ msgstr ""
121
+
122
+ #: ../views/sg-cache.php:21
123
+ msgid "Automatically flush the Dynamic cache when you edit your content."
124
+ msgstr ""
125
+
126
+ #: ../views/sg-cache.php:26
127
+ msgid "Purge Cache"
128
+ msgstr ""
129
+
130
+ #: ../views/sg-cache.php:30
131
+ msgid "Purge all the data cached by the Dynamic cache."
132
+ msgstr ""
133
+
134
+ #: ../views/sg-cache.php:35
135
+ msgid "Exclude URLs From Dynamic Caching"
136
+ msgstr ""
137
+
138
+ #: ../views/sg-cache.php:36
139
+ msgid ""
140
+ "Provide a list of your website URLs you would like to exclude from the cache."
141
+ " For example if you would like to exclude: <strong>http://domain."
142
+ "com/path/to/url</strong><br>\n"
143
+ " You can simply input the \"path\" string part of the URL. Then each URL "
144
+ "that consists of it will be excluded. Divide each URL by a new line."
145
+ msgstr ""
146
+
147
+ #: ../views/sg-cache.php:46
148
+ msgid "Memcached Settings"
149
+ msgstr ""
150
+
151
+ #: ../views/sg-cache.php:51
152
+ msgid "Enable Memcached"
153
+ msgstr ""
154
+
155
+ #: ../views/sg-cache.php:55
156
+ msgid ""
157
+ "Store in the server's memory frequently executed queries to the database for "
158
+ "a faster access on a later use."
159
+ msgstr ""
160
+
161
+ #: ../views/sg-cache.php:61
162
+ msgid "Dynamic Cache Status"
163
+ msgstr ""
164
+
165
+ #: ../views/sg-cache.php:69
166
+ msgid "Status:"
167
+ msgstr ""
168
+
169
+ #: ../views/sg-cache.php:72
170
+ msgid ""
171
+ "Check if this URL is dynamic or cached. Leave empty for your index or "
172
+ "<strong>/example/</strong> for another page."
173
+ msgstr ""
memcache.tpl CHANGED
@@ -16,9 +16,6 @@ Install this file to wp-content/object-cache.php
16
  if ( class_exists( 'Memcache' ) )
17
  {
18
 
19
- if ( !defined( 'WP_CACHE_KEY_SALT' ) )
20
- define( 'WP_CACHE_KEY_SALT', substr(md5(dirname(__FILE__)),7));
21
-
22
  function wp_cache_add($key, $data, $group = '', $expire = 0) {
23
  global $wp_object_cache;
24
 
@@ -101,7 +98,12 @@ class WP_Object_Cache {
101
 
102
  var $cache = array();
103
  var $mc = array();
104
- var $stats = array();
 
 
 
 
 
105
  var $group_ops = array();
106
 
107
  var $cache_enabled = true;
@@ -272,7 +274,7 @@ class WP_Object_Cache {
272
  else
273
  $prefix = $this->blog_prefix;
274
 
275
- return preg_replace('/\s+/', '', WP_CACHE_KEY_SALT . "$prefix$group:$key");
276
  }
277
 
278
  function replace($id, $data, $group = 'default', $expire = 0) {
@@ -365,7 +367,7 @@ class WP_Object_Cache {
365
  }
366
  }
367
 
368
- function WP_Object_Cache() {
369
 
370
  $memcached_servers = array(
371
  'default' => array(
16
  if ( class_exists( 'Memcache' ) )
17
  {
18
 
 
 
 
19
  function wp_cache_add($key, $data, $group = '', $expire = 0) {
20
  global $wp_object_cache;
21
 
98
 
99
  var $cache = array();
100
  var $mc = array();
101
+ var $stats = array(
102
+ 'add' => 0,
103
+ 'delete' => 0,
104
+ 'get' => 0,
105
+ 'get_multi' => 0,
106
+ );
107
  var $group_ops = array();
108
 
109
  var $cache_enabled = true;
274
  else
275
  $prefix = $this->blog_prefix;
276
 
277
+ return preg_replace('/\s+/', '', substr(md5(dirname(__FILE__)),7) . "$prefix$group:$key");
278
  }
279
 
280
  function replace($id, $data, $group = 'default', $expire = 0) {
367
  }
368
  }
369
 
370
+ function __construct() {
371
 
372
  $memcached_servers = array(
373
  'default' => array(
memcached.tpl CHANGED
@@ -2,7 +2,7 @@
2
  /*
3
  Plugin Name: Memcached Redux
4
  Description: The real Memcached (not Memcache) backend for the WP Object Cache.
5
- Version: 0.1.3
6
  Plugin URI: http://wordpress.org/extend/plugins/memcached/
7
  Author: Scott Taylor - uses code from Ryan Boren, Denis de Bernardy, Matt Martz, Mike Schroder
8
 
@@ -12,10 +12,6 @@ Install this file to wp-content/object-cache.php
12
  if ( class_exists( 'Memcached' ) )
13
  {
14
 
15
- if ( !defined( 'WP_CACHE_KEY_SALT' ) ) {
16
- define( 'WP_CACHE_KEY_SALT', '' );
17
- }
18
-
19
  function wp_cache_add( $key, $data, $group = '', $expire = 0 ) {
20
  global $wp_object_cache;
21
 
@@ -52,10 +48,10 @@ function wp_cache_flush() {
52
  return $wp_object_cache->flush();
53
  }
54
 
55
- function wp_cache_get( $key, $group = '' ) {
56
  global $wp_object_cache;
57
 
58
- return $wp_object_cache->get( $key, $group );
59
  }
60
 
61
  /**
@@ -126,7 +122,12 @@ class WP_Object_Cache {
126
 
127
  var $cache = array();
128
  var $mc = array();
129
- var $stats = array();
 
 
 
 
 
130
  var $group_ops = array();
131
 
132
  var $cache_enabled = true;
@@ -224,11 +225,13 @@ class WP_Object_Cache {
224
  return $ret;
225
  }
226
 
227
- function get( $id, $group = 'default' ) {
228
  $key = $this->key( $id, $group );
229
  $mc =& $this->get_mc( $group );
230
-
231
- if ( isset( $this->cache[$key] ) ) {
 
 
232
  if ( is_object( $this->cache[$key] ) )
233
  $value = clone $this->cache[$key];
234
  else
@@ -237,8 +240,12 @@ class WP_Object_Cache {
237
  $this->cache[$key] = $value = false;
238
  } else {
239
  $value = $mc->get( $key );
240
- if ( empty( $value ) || ( is_integer( $value ) && -1 == $value ) )
241
- $value = false;
 
 
 
 
242
  $this->cache[$key] = $value;
243
  }
244
 
@@ -301,7 +308,7 @@ class WP_Object_Cache {
301
  else
302
  $prefix = $this->blog_prefix;
303
 
304
- return preg_replace( '/\s+/', '', WP_CACHE_KEY_SALT . "$prefix$group:$key" );
305
  }
306
 
307
  function replace( $id, $data, $group = 'default', $expire = 0 ) {
@@ -416,7 +423,7 @@ class WP_Object_Cache {
416
  return $this->mc['default'];
417
  }
418
 
419
- function WP_Object_Cache() {
420
 
421
  $memcached_servers = array(
422
  'default' => array(
2
  /*
3
  Plugin Name: Memcached Redux
4
  Description: The real Memcached (not Memcache) backend for the WP Object Cache.
5
+ Version: 0.1.4
6
  Plugin URI: http://wordpress.org/extend/plugins/memcached/
7
  Author: Scott Taylor - uses code from Ryan Boren, Denis de Bernardy, Matt Martz, Mike Schroder
8
 
12
  if ( class_exists( 'Memcached' ) )
13
  {
14
 
 
 
 
 
15
  function wp_cache_add( $key, $data, $group = '', $expire = 0 ) {
16
  global $wp_object_cache;
17
 
48
  return $wp_object_cache->flush();
49
  }
50
 
51
+ function wp_cache_get( $key, $group = '', $force = false, &$found = null ) {
52
  global $wp_object_cache;
53
 
54
+ return $wp_object_cache->get( $key, $group, $force, $found );
55
  }
56
 
57
  /**
122
 
123
  var $cache = array();
124
  var $mc = array();
125
+ var $stats = array(
126
+ 'add' => 0,
127
+ 'delete' => 0,
128
+ 'get' => 0,
129
+ 'get_multi' => 0,
130
+ );
131
  var $group_ops = array();
132
 
133
  var $cache_enabled = true;
225
  return $ret;
226
  }
227
 
228
+ function get( $id, $group = 'default', $force = false, &$found = null ) {
229
  $key = $this->key( $id, $group );
230
  $mc =& $this->get_mc( $group );
231
+ $found = false;
232
+
233
+ if ( isset( $this->cache[$key] ) && ( !$force || in_array( $group, $this->no_mc_groups ) ) ) {
234
+ $found = true;
235
  if ( is_object( $this->cache[$key] ) )
236
  $value = clone $this->cache[$key];
237
  else
240
  $this->cache[$key] = $value = false;
241
  } else {
242
  $value = $mc->get( $key );
243
+ if ( empty( $value ) || ( is_integer( $value ) && -1 == $value ) ){
244
+ $value = false;
245
+ $found = $mc->getResultCode() !== Memcached::RES_NOTFOUND;
246
+ } else {
247
+ $found = true;
248
+ }
249
  $this->cache[$key] = $value;
250
  }
251
 
308
  else
309
  $prefix = $this->blog_prefix;
310
 
311
+ return preg_replace( '/\s+/', '', substr(md5(dirname(__FILE__)),7) . "$prefix$group:$key" );
312
  }
313
 
314
  function replace( $id, $data, $group = 'default', $expire = 0 ) {
423
  return $this->mc['default'];
424
  }
425
 
426
+ function __construct() {
427
 
428
  $memcached_servers = array(
429
  'default' => array(
php-compatibility-checker/readme.txt ADDED
@@ -0,0 +1,188 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === PHP Compatibility Checker ===
2
+ Contributors: wpengine, octalmage, stevenkword, Taylor4484, pross
3
+ Tags: php 7, php 5.5, php, version, compatibility, checker, wp engine, wpe, wpengine
4
+ Requires at least: 3.5
5
+ Tested up to: 4.6
6
+ Stable tag: 1.3.2
7
+ License: GPLv2 or later
8
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
+
10
+ Make sure your plugins and themes are compatible with newer PHP versions.
11
+
12
+ == Description ==
13
+
14
+ The WP Engine PHP Compatibility Checker can be used by any WordPress website on any web host to check PHP version compatibility.
15
+
16
+ This plugin will lint theme and plugin code inside your WordPress file system and give you back a report of compatibility issues for you to fix. Compatibility issues are categorized into errors and warnings and will list the file and line number of the offending code, as well as the info about why that line of code is incompatible with the chosen version of PHP. The plugin will also suggest updates to themes and plugins, as a new version may offer compatible code.
17
+
18
+ **This plugin does not execute your theme and plugin code, as such this plugin cannot detect runtime compatibility issues.**
19
+
20
+ **Please note that linting code is not perfect. This plugin cannot detect unused code-paths that might be used for backwards compatibility, and thus might show false positives. We maintain a [whitelist of plugins](https://github.com/wpengine/phpcompat/wiki/Results) that can cause false positives. We are continuously working to ensure the checker provides the most accurate results possible.**
21
+
22
+ **This plugin relies on WP-Cron to scan files in the background. The scan will get stuck if the site's WP-Cron isn't running correctly. Please see the [FAQ](https://wordpress.org/plugins/php-compatibility-checker/faq/) for more information.**
23
+
24
+ = Update to PHP 7 =
25
+ * Use this plugin to check your site for compatibility for PHP 7!
26
+ * As of [November 2016](https://wordpress.org/about/stats/), 52.9% of WordPress websites run a PHP version less PHP 5.5.
27
+ * These versions of PHP have been deprecated and unsupported for over 9 months.
28
+ * Only 3.4% of WordPress websites run PHP 7, the current main version of PHP.
29
+
30
+
31
+ = Disclaimer =
32
+ *While this plugin is written to detect as many problems as accurately as possible, 100% reliable detection is very difficult to ensure. It is best practice to run comprehensive tests before you migrate to a new PHP version.*
33
+
34
+ The plugin was created by WP Engine to help the WordPress community increase adoption of modern PHP versions. We [welcome contributors](https://github.com/wpengine/phpcompat) to this plugin, and are excited to see how developers and other WordPress hosts use this plugin.
35
+
36
+ To disclose security issues for this plugin please email WordPress@wpengine.com
37
+
38
+ == Installation ==
39
+
40
+ *Note: If you have WordPress 2.7 or above you can simply go to 'Plugins' > 'Add New' in the WordPress admin and search for "PHP Compatibility Checker" and install it from there.*
41
+
42
+ To manually install:
43
+ 1. Upload `phpcompat` to the `/wpengine-wp-content/plugins/` directory
44
+ 2. Activate the plugin through the 'Plugins' menu in WordPress
45
+
46
+ You will find the plugin options in the WP Admin `Tools => PHP Compatibility` menu. Once you click `run` it will take a few minutes to conduct the test. Feel free to navigate away from the page and check back later.
47
+
48
+ There are WP-CLI commands available see the [Other Notes](https://wordpress.org/plugins/php-compatibility-checker/other_notes/) tab for details.
49
+
50
+ == Other Notes ==
51
+
52
+ PHP Compatibility Checker includes WP-CLI command support:
53
+
54
+ `wp phpcompat <version> [--scan=<scan>]`
55
+
56
+ `
57
+ <version>
58
+ PHP version to test.
59
+
60
+ [--scan=<scan>]
61
+ Whether to scan only active plugins and themes or all of them.
62
+ default: active
63
+ options:
64
+ - active
65
+ - all
66
+ `
67
+ Example: `wp phpcompat 7.0 --scan=active`
68
+
69
+
70
+ == Frequently Asked Questions ==
71
+
72
+ 1. Will this work outside of the WP Engine hosting account?
73
+
74
+ Yes, this plugin can be used any ANY WordPress website on ANY host.
75
+
76
+ 2. Are there WP-CLI commands available?
77
+
78
+ Yes, this plugin does extend WP-CLI and provide commands. See the [Other Notes](https://wordpress.org/plugins/php-compatibility-checker/other_notes/) tab for details.
79
+
80
+ 3. A plugin I created is listed as not compatible, what should I do?
81
+
82
+ We maintain a [whitelist of plugins](https://github.com/wpengine/phpcompat/wiki/Results) that cause false positives. If your plugin shows up as incompatible but you think that is wrong, please open a [GitHub issue](https://github.com/wpengine/phpcompat/issues/new) on the project, or email wordpress@wpengine.com with info about your plugin and why you know it is compatible (you have automated tests, the failure is on backwards compatibility code paths, etc).
83
+
84
+ 4. Can I use this to test non-WordPress PHP Projects?
85
+
86
+ Yes! While you cannot use this WordPress plugin to test your non-WordPress projects, you can use the [Open Source PHPCompatibility Library](https://github.com/wimg/PHPCompatibility) that this plugin is built on.
87
+
88
+ 5. Why was my plugin/theme skipped?
89
+
90
+ Some servers have timeouts to prevent long running queries, this is commonly 60 seconds. This can prevent the checker from being able to process large themes or plugins. You should check with your host to see if this timeout can be temporarily removed. The best way around this timeout issue is to run this plugin on a [local copy](https://make.wordpress.org/core/handbook/tutorials/installing-a-local-server/) of your site, or you can use the WP-CLI command.
91
+
92
+ You can use the filter `wpephpcompat_scan_timeout` to customize the scan timeout. See [this](https://gist.github.com/octalmage/07f26e0d1f25cea9a8ca92ebc67a3a14) for an example.
93
+
94
+ Setting the timeout to 0 disables the cron/timeout.
95
+
96
+ 6. The scan is stuck, what can I do?
97
+
98
+ The PHP Compatibility Checker relies on WP-Cron to process plugins/themes in batches, this is necessary to avoid server timeouts. The scan will get stuck if your site's WP-Cron isn't functioning. You can look into this using [WP Crontrol](https://wordpress.org/plugins/wp-crontrol/). The cron is called `wpephpcompat_start_test_cron`. This could also be an issue if your site is using basic authentication.
99
+
100
+ You can also use the [WP-CLI command](https://wordpress.org/plugins/php-compatibility-checker/other_notes/) or disable the timeout to avoid using WP-Cron.
101
+
102
+ 7. I found a bug, or have a suggestion, can I contribute back?
103
+
104
+ Yes! WP Engine has a public GitHub repo where you can contribute back to this plugin. Please open an issue on the [Plugin GitHub](https://github.com/wpengine/phpcompat). We actively develop this plugin, and are always happy to receive pull requests.
105
+
106
+ The plugin was created by WP Engine to help the WordPress community increase adoption of modern PHP versions. We welcome contributors to this plugin, and are excited to see how developers and other WordPress hosts use this plugin.
107
+
108
+ To disclose security issues for this plugin please email WordPress@wpengine.com
109
+
110
+ == Screenshots ==
111
+
112
+ 1. Main screen: compatibility checker options
113
+ 2. Compatibility results screen
114
+
115
+ == Changelog ==
116
+
117
+ = 1.3.2 =
118
+ - Added a "Clean up" button and uninstall.php.
119
+ - Added phpcompat_phpversions filter.
120
+
121
+ = 1.3.1 =
122
+ - Whitelisted a number of plugins.
123
+
124
+ = 1.3.0 =
125
+ - Updated the PHPCompatibility library to latest version. Should fix many false positives.
126
+ - Changed language and added help text to Admin UI.
127
+
128
+ = 1.2.4 =
129
+ - Fixed Composer issue.
130
+
131
+ = 1.2.3 =
132
+ - Updated the PHPCompatibility library to latest version.
133
+ - Whitelisted TablePress.
134
+
135
+ = 1.2.2 =
136
+ - Whitelisted UpdraftPlus and Max Mega Menu.
137
+
138
+ = 1.2.1 =
139
+ - Updated the PHPCompatibility library to latest version
140
+
141
+ = 1.2.0 =
142
+ - Updated the PHPCompatibility library to latest version
143
+ - Added support for PHP 5.6
144
+
145
+ = 1.1.2 =
146
+ - Fixed issue with WordPress notices breaking the plugin header.
147
+ - Changed the way we send and parse JSON.
148
+ - You can now restart an in progress scan.
149
+ - Updated download.js to v4.2 for better Safari compatibility.
150
+
151
+ = 1.1.1 =
152
+ - Fixed bug with active job display.
153
+ - Updated progress bar calculation.
154
+
155
+ = 1.1.0 =
156
+ - Test results now persist page reloads.
157
+ - Failed tests will show an overview of the results.
158
+ - The scan timeout is now configurable using a filter. See the FAQ for more details.
159
+
160
+ = 1.0.3 =
161
+ - Fixed a bug in the WP-CLI command
162
+ - Added a handful of PHP 7 compatible plugins to the whitelist
163
+
164
+ = 1.0.2 =
165
+ - Added additional role protections
166
+ - Changed the UI colors to better understand output at a glance
167
+ - Exclude checking node_modules and tmp directories
168
+ - Added support for child theme's parent theme
169
+
170
+ = 1.0.1 =
171
+ - Updated compatibility library with a few bugfixes
172
+ - Added skip logic to prevent checker from hanging
173
+
174
+ = 1.0.0 =
175
+ - Major update to add PHP 7 checking support
176
+ - Improved the UX of the progress bar
177
+ - Fixed bug with the way the plugin menu was registered
178
+
179
+ = 0.1.0 =
180
+ - Initial version
181
+ - PHP 5.5, 5.4, and 5.3 Support
182
+ - Basic WP-CLI Commands
183
+
184
+ == Upgrade Notice ==
185
+
186
+ = 1.3.2 =
187
+ - Added a "Clean up" button and uninstall.php.
188
+ - Added phpcompat_phpversions filter.
php-compatibility-checker/sg-wpengine-phpcompat.php ADDED
@@ -0,0 +1,460 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Exit if this file is directly accessed
3
+ if ( ! defined( 'ABSPATH' ) ) { exit; }
4
+
5
+ require_once( __DIR__ . '/vendor/autoload.php' );
6
+
7
+ // Add the phpcompat WP-CLI command.
8
+ if ( defined( 'WP_CLI' ) && WP_CLI ) {
9
+ require_once( __DIR__ . '/src/wpcli.php' );
10
+ }
11
+
12
+ /**
13
+ * This handles hooking into WordPress.
14
+ */
15
+ class SG_WPEngine_PHPCompat {
16
+
17
+ /* Define and register singleton */
18
+ private static $instance = false;
19
+
20
+ /* Hook for the settings page */
21
+ private $page;
22
+
23
+ /**
24
+ * Returns an instance of this class.
25
+ *
26
+ * @return self An instance of this class.
27
+ */
28
+ public static function instance() {
29
+ if ( ! self::$instance ) {
30
+ self::$instance = new self;
31
+ self::$instance->init();
32
+ }
33
+ return self::$instance;
34
+ }
35
+
36
+ /**
37
+ * Initialize hooks and setup environment variables.
38
+ *
39
+ * @since 2.3.11
40
+ */
41
+ public static function init() {
42
+ // Load our JavaScript.
43
+ add_action( 'admin_enqueue_scripts', array( self::instance(), 'admin_enqueue' ) );
44
+
45
+ // The action to run the compatibility test.
46
+ add_action( 'wp_ajax_sg_wpephpcompat_start_test', array( self::instance(), 'start_test' ) );
47
+ add_action( 'wp_ajax_sg_wpephpcompat_check_status', array( self::instance(), 'check_status' ) );
48
+ add_action( 'sg_wpephpcompat_start_test_cron', array( self::instance(), 'start_test' ) );
49
+ add_action( 'wp_ajax_sg_wpephpcompat_clean_up', array( self::instance(), 'clean_up' ) );
50
+ add_action( 'wp_ajax_sg_wpephpcompat_change_version', array( self::instance(), 'change_current_php_version' ) );
51
+
52
+ // Create custom post type.
53
+ add_action( 'init', array( self::instance(), 'create_job_queue' ) );
54
+ }
55
+
56
+ /**
57
+ * Start the test!
58
+ *
59
+ * @since 2.3.11
60
+ * @action wp_ajax_sg_wpephpcompat_start_test
61
+ * @action sg_wpephpcompat_start_test_cron
62
+ * @return null
63
+ */
64
+ function start_test() {
65
+ if ( current_user_can( 'manage_options' ) || ( defined( 'DOING_CRON' ) && DOING_CRON ) ) {
66
+ global $wpdb;
67
+
68
+ $wpephpc = new \SG_WPEPHPCompat( dirname(__DIR__) );
69
+
70
+ if ( isset( $_POST['startScan'] ) ) {
71
+ $test_version = sanitize_text_field( $_POST['test_version'] );
72
+ $only_active = sanitize_text_field( $_POST['only_active'] );
73
+
74
+ $wpephpc->test_version = $test_version;
75
+ $wpephpc->only_active = $only_active;
76
+ $wpephpc->clean_after_scan();
77
+ }
78
+
79
+ $wpephpc->start_test();
80
+ wp_die();
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Check the progress or result of the tests.
86
+ *
87
+ * @todo Use heartbeat API.
88
+ * @since 2.3.11
89
+ * @action wp_ajax_wpephpcompat_check_status
90
+ * @return null
91
+ */
92
+ function check_status() {
93
+ if ( current_user_can( 'manage_options' ) || ( defined( 'DOING_CRON' ) && DOING_CRON ) ) {
94
+ $scan_status = get_option( 'sg_wpephpcompat.status' );
95
+ $count_jobs = wp_count_posts( 'sg_optimizer_jobs' );
96
+ $total_jobs = get_option( 'sg_wpephpcompat.numdirs' );
97
+ $test_version = get_option( 'sg_wpephpcompat.test_version' );
98
+ $only_active = get_option( 'sg_wpephpcompat.only_active' );
99
+
100
+ $active_job = false;
101
+ $jobs = get_posts( array(
102
+ 'posts_per_page' => -1,
103
+ 'post_type' => 'sg_optimizer_jobs',
104
+ 'orderby' => 'title',
105
+ 'order' => 'ASC',
106
+ ) );
107
+
108
+ if ( 0 < count( $jobs ) ) {
109
+ $active_job = $jobs[0]->post_title;
110
+ }
111
+
112
+ $to_encode = array(
113
+ 'status' => $scan_status,
114
+ 'count' => $count_jobs->publish,
115
+ 'total' => $total_jobs,
116
+ 'activeJob' => $active_job,
117
+ 'version' => $test_version,
118
+ 'onlyActive' => $only_active,
119
+ );
120
+
121
+ // If the scan is still running.
122
+ if ( $scan_status ) {
123
+ $to_encode['results'] = '0';
124
+ $to_encode['progress'] = ( ( $total_jobs - $count_jobs->publish ) / $total_jobs) * 100;
125
+ } else {
126
+ // Else return the results and clean up!
127
+ $scan_results = get_option( 'sg_wpephpcompat.scan_results' );
128
+ // Not using esc_html since the results are shown in a textarea.
129
+ $to_encode['results'] = $scan_results;
130
+
131
+ $wpephpc = new \SG_WPEPHPCompat( dirname(__DIR__) );
132
+ $wpephpc->clean_after_scan();
133
+ }
134
+ wp_send_json( $to_encode );
135
+ }
136
+ }
137
+
138
+ /**
139
+ * Remove all database options from the database.
140
+ *
141
+ * @since 2.3.11
142
+ * @action wp_ajax_wpephpcompat_clean_up
143
+ */
144
+ function clean_up() {
145
+ if ( current_user_can( 'manage_options' ) || ( defined( 'DOING_CRON' ) && DOING_CRON ) ) {
146
+ $wpephpc = new \SG_WPEPHPCompat( dirname(__DIR__) );
147
+ $wpephpc->clean_after_scan();
148
+ delete_option( 'sg_wpephpcompat.scan_results' );
149
+ wp_send_json( 'success' );
150
+ }
151
+ }
152
+
153
+ /**
154
+ * Create custom post type to store the directories we need to process.
155
+ *
156
+ * @since 2.3.11
157
+ * @return null
158
+ */
159
+ function create_job_queue() {
160
+ register_post_type( 'sg_optimizer_jobs',
161
+ array(
162
+ 'labels' => array(
163
+ 'name' => __( 'Jobs' ),
164
+ 'singular_name' => __( 'Job' ),
165
+ ),
166
+ 'public' => false,
167
+ 'has_archive' => false,
168
+ )
169
+ );
170
+ }
171
+
172
+ /**
173
+ * Enqueue our JavaScript and CSS.
174
+ *
175
+ * @since 2.3.11
176
+ * @action admin_enqueue_scripts
177
+ * @return null
178
+ */
179
+ function admin_enqueue( $hook ) {
180
+ if ( $hook !== 'sg-optimizer_page_php-check' ) {
181
+ return;
182
+ }
183
+
184
+ // Styles
185
+ wp_enqueue_style( 'sg_wpephpcompat-style', plugins_url( '/src/css/style.css', __FILE__ ) );
186
+
187
+ // Scripts
188
+ wp_enqueue_script( 'sg_wpephpcompat-handlebars', plugins_url( '/src/js/handlebars.js', __FILE__ ), array( 'jquery' ) );
189
+ wp_enqueue_script( 'sg_wpephpcompat-download', plugins_url( '/src/js/download.min.js', __FILE__ ) );
190
+ wp_enqueue_script( 'sg_wpephpcompat', plugins_url( '/src/js/run.js', __FILE__ ), array( 'jquery', 'sg_wpephpcompat-handlebars', 'sg_wpephpcompat-download' ) );
191
+
192
+ // Progress Bar
193
+ wp_enqueue_script( 'jquery-ui-progressbar' );
194
+ wp_enqueue_style( 'jquery-style', '//ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/themes/smoothness/jquery-ui.css' );
195
+
196
+ /**
197
+ * i18n strings
198
+ *
199
+ * These translated strings can be access in jquery with window.sg_wpephpcompat object.
200
+ */
201
+
202
+ $recommended = self::get_recommended_php_versions();
203
+ $strings = array(
204
+ 'name' => __( 'Name', 'sg-cachepress' ),
205
+ 'compatible' => __( 'compatible', 'sg-cachepress' ),
206
+ 'not_compatible' => __( 'The following plugins/themes are not compatible with PHP ', 'sg-cachepress' ),
207
+ 'see_details_below' => __( '', 'sg-cachepress' ),
208
+ 'click_upgrade_version' => __( 'Click upgrade button to ugprade your PHP version.', 'sg-cachepress' ),
209
+ //'are_not' => __( 'plugins/themes are possibly not compatible', 'sg-cachepress' ),
210
+ //'is_not' => __( 'Your WordPress site is possibly not PHP', 'sg-cachepress' ),
211
+ //'out_of' => __( 'out of', 'sg-cachepress' ),
212
+ 'run' => __( 'Check PHP ' . $recommended [0] . ' Compatibility', 'sg-cachepress' ),
213
+ 'loading' => __( 'Updating PHP Version', 'sg-cachepress' ),
214
+ 'rerun' => __( 'Check PHP ' . $recommended [0] . ' Compatibility Again', 'sg-cachepress' ),
215
+ 'your_wp' => __( 'Your WordPress site is', 'sg-cachepress' ),
216
+ 'check_your_php_version' => __( 'Checks the PHP version your WordPress site is running and whether you\'re on the fastest possible PHP version.', 'sg-cachepress' ),
217
+ 'upgrade_to' => __( 'Upgrade to', 'sg-cachepress' ),
218
+ 'you_running_running_on' => __( 'Site is compatible and running on', 'sg-cachepress' ),
219
+ 'recommended_or_higher' => __( 'which is our recommended PHP version or higher.', 'sg-cachepress' ),
220
+ 'if_you_fixed_retry' => __( 'If you have fixed the reported errors, you may <a style="cursor: pointer;" onclick="runAction();">try to check the PHP 7.0 compatibility</a> of your Wordpress site again. ', 'sg-cachepress' ),
221
+ 'recommend_to_switch' => __( 'If you can\'t update to PHP 7.0 right away, we recommend that you <a style="cursor: pointer;" onclick="upgradeTo(\'5.6\');">switch to PHP 5.6</a> which is the safest and fastest version of the 5 branch.')
222
+ );
223
+
224
+
225
+ wp_localize_script( 'sg_wpephpcompat', 'sg_wpephpcompat', $strings );
226
+ }
227
+
228
+ /**
229
+ *
230
+ * Change current php version in .htaccess
231
+ *
232
+ * @since 2.3.11
233
+ *
234
+ * @return string
235
+ * 0 - failed
236
+ * 1 - success
237
+ * 2 - no changes
238
+ */
239
+ public static function change_current_php_version() {
240
+ $availableVersions = self::get_available_php_versions();
241
+
242
+ if ( !in_array($_POST['version'], $availableVersions) ) {
243
+ die(0);
244
+ } else {
245
+ $newVersionOrig = $_POST['version'];
246
+ }
247
+
248
+ $currentVersion = self::get_current_php_version();
249
+ $basedir = dirname(dirname(dirname(dirname(__DIR__))));
250
+ $filename = $basedir. '/.htaccess';
251
+
252
+ if (!is_writable($filename)) {
253
+ die(0);
254
+ }
255
+
256
+ $htaccessContent = file_get_contents($filename);
257
+ $newVersion = str_replace('.', '', $newVersionOrig);
258
+
259
+ $addHandlerOption = 'AddHandler application/x-httpd-php' . $newVersion . ' .php .php5 .php4 .php3';
260
+
261
+ $htaccessNewContent = preg_replace(
262
+ '/(AddHandler\s+application\/x-httpd-php)(\w+)(\s+\.php\s+\.php5\s+\.php4\s+\.php3)/s',
263
+ '${1}'. $newVersion .'${3}',
264
+ $htaccessContent,
265
+ -1,
266
+ $count
267
+ );
268
+
269
+ // add it manually
270
+ if (!$count) {
271
+ $htaccessNewContent .= PHP_EOL . $addHandlerOption;
272
+ }
273
+
274
+ // no changes
275
+ if ($htaccessContent === $htaccessNewContent) {
276
+ die('2');
277
+ }
278
+
279
+ $fp = fopen($filename, "w+");
280
+
281
+ if (flock($fp, LOCK_EX)) { // do an exclusive lock
282
+ fwrite($fp, $htaccessNewContent);
283
+ flock($fp, LOCK_UN); // release the lock
284
+ } else {
285
+ die(0);
286
+ }
287
+
288
+ update_option('sg_wpephpcompat.current_php_version', $newVersionOrig);
289
+ update_option('sg_wpephpcompat.prev_php_version', $currentVersion);
290
+
291
+ // Log
292
+ $user = @get_current_user();
293
+ $r = @posix_getpwnam($user);
294
+
295
+ $report = time() .
296
+ ' from_' . $currentVersion .
297
+ ' to_' . $newVersionOrig .
298
+ ' ' . $basedir .
299
+ ' ' . get_site_url();
300
+
301
+ @file_put_contents($r['dir'] . '/.wp_version_change', $report . PHP_EOL , FILE_APPEND);
302
+
303
+ if (self::isUpToDate($newVersionOrig)) {
304
+ $options_handler = new \SG_CachePress_Options();
305
+ $options_handler->disable_option('show_notice_notification-1');
306
+ }
307
+
308
+ die('1');
309
+ }
310
+
311
+ /**
312
+ *
313
+ * Returns an associative array of all available PHP versions we support.
314
+ *
315
+ * @since 2.3.11
316
+ */
317
+ public static function get_available_php_versions() {
318
+ return apply_filters('phpcompat_phpversions', array(
319
+ 'PHP 7.1' => '7.1',
320
+ 'PHP 7.0' => '7.0',
321
+ 'PHP 5.6' => '5.6',
322
+ 'PHP 5.5' => '5.5',
323
+ 'PHP 5.4' => '5.4',
324
+ 'PHP 5.3' => '5.3',
325
+ ));
326
+ }
327
+
328
+ /**
329
+ * get previous PHP version
330
+ * @since 2.3.11
331
+ */
332
+ public static function get_prev_php_version() {
333
+ return get_option('sg_wpephpcompat.prev_php_version');
334
+ }
335
+
336
+ /**
337
+ *
338
+ * @param type $url
339
+ * @return type
340
+ */
341
+ public static function curl_get_content($url) {
342
+ $options = array(
343
+ CURLOPT_RETURNTRANSFER => true, // return web page
344
+ CURLOPT_HEADER => false, // don't return headers
345
+ CURLOPT_FOLLOWLOCATION => true, // follow redirects
346
+ CURLOPT_MAXREDIRS => 10, // stop after 10 redirects
347
+ CURLOPT_ENCODING => "", // handle compressed
348
+ CURLOPT_USERAGENT => "test", // name of client
349
+ CURLOPT_AUTOREFERER => true, // set referrer on redirect
350
+ CURLOPT_CONNECTTIMEOUT => 120, // time-out on connect
351
+ CURLOPT_TIMEOUT => 120, // time-out on response
352
+ CURLOPT_SSL_VERIFYPEER => false,
353
+ CURLOPT_SSL_VERIFYHOST => false,
354
+ );
355
+
356
+ $ch = curl_init($url);
357
+ curl_setopt_array($ch, $options);
358
+ $content = curl_exec($ch);
359
+
360
+ // if (false === $content) {
361
+ // var_dump(curl_error($ch));
362
+ // throw new Exception(curl_error($ch), curl_errno($ch));
363
+ // }
364
+
365
+ curl_close($ch);
366
+
367
+ return $content;
368
+ }
369
+
370
+ public static function create_tmp_phpversion_script() {
371
+ $basedir = dirname(dirname(dirname(dirname(__DIR__))));
372
+ $filename = $basedir. '/sgtestphpver.php';
373
+
374
+ $myfile = fopen($filename, "w") or die("Unable to open file!");
375
+ $txt = "<?php die( PHP_VERSION );?>";
376
+ fwrite($myfile, $txt);
377
+ fclose($myfile);
378
+ }
379
+
380
+ public static function delete_tmp_phpversion_script() {
381
+ $basedir = dirname(dirname(dirname(dirname(__DIR__))));
382
+ $filename = $basedir. '/sgtestphpver.php';
383
+ unlink($filename);
384
+ }
385
+
386
+
387
+ /**
388
+ *
389
+ * Returns the current PHP version Wordpress is running on.
390
+ * example (5.6, 7.0 ... etc)
391
+ *
392
+ * @since 2.3.11
393
+ */
394
+ public static function get_current_php_version() {
395
+ if (php_sapi_name() == "cli") {
396
+ self::create_tmp_phpversion_script();
397
+ // md5( 'showmeversion ')
398
+ $url = get_option('siteurl') . '/sgtestphpver.php';
399
+ $phpversion = self::curl_get_content($url);
400
+
401
+ // when wunning via cli if unable to get current version
402
+ if (!preg_match("/^\d+\.\d+/", $phpversion)) {
403
+ $recommended = self::get_recommended_php_versions();
404
+ $phpversion = $recommended[0];
405
+ }
406
+
407
+ self::delete_tmp_phpversion_script();
408
+ $version = explode('.', $phpversion);
409
+
410
+ return $version[0] .'.'. $version[1];
411
+ } else {
412
+ $phpversion = PHP_VERSION;
413
+ }
414
+
415
+ if (!defined('PHP_VERSION_ID')) {
416
+ $version = explode('.', $phpversion);
417
+ define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2]));
418
+ }
419
+
420
+ if (PHP_VERSION_ID < 50207) {
421
+ define('PHP_MAJOR_VERSION', $version[0]);
422
+ define('PHP_MINOR_VERSION', $version[1]);
423
+ define('PHP_RELEASE_VERSION', $version[2]);
424
+ }
425
+
426
+ return PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION;
427
+ }
428
+
429
+ /**
430
+ *
431
+ * Returns an associative array of recommended php versions by priority
432
+ *
433
+ * @since 2.3.11
434
+ */
435
+ public static function get_recommended_php_versions() {
436
+ return array(
437
+ '7.0', '5.6'
438
+ );
439
+ }
440
+ /**
441
+ * @since 2.3.11
442
+ * @param type $newVersionOrig
443
+ * @return bool
444
+ */
445
+ public static function isUpToDate($newVersionOrig=false) {
446
+ if ($newVersionOrig !== false) {
447
+ $currentVersion = $newVersionOrig;
448
+ } else {
449
+ $currentVersion = self::get_current_php_version();
450
+ }
451
+
452
+ $recommendedPHPVersions = self::get_recommended_php_versions();
453
+ $recommendedPHPVersion = $recommendedPHPVersions[0];
454
+ $recommendedPHPVersion = intval(str_replace('.', '', $recommendedPHPVersion ));
455
+ $currentVersion = intval(str_replace('.', '', $currentVersion ));
456
+
457
+ return ($currentVersion >= $recommendedPHPVersion);
458
+ }
459
+
460
+ }
php-compatibility-checker/src/css/style.css ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .wpe-results-card
2
+ {
3
+ width: 100%;
4
+ margin-bottom: 10px;
5
+ position: relative;
6
+ display: inline-block;
7
+ }
8
+
9
+ .wpe-results-card .inner-left
10
+ {
11
+ display: inline-block;
12
+ letter-spacing: normal;
13
+ text-rendering: auto;
14
+ vertical-align: top;
15
+ float: left;
16
+ }
17
+
18
+ .wpe-results-card .inner-right
19
+ {
20
+ display: inline-block;
21
+ font-family: sans-serif;
22
+ letter-spacing: normal;
23
+ text-rendering: auto;
24
+ vertical-align: top;
25
+ float: left;
26
+ word-spacing: 0px;
27
+ width: 100%;
28
+ }
29
+
30
+ .wpe-results-card img
31
+ {
32
+ width: 25px;
33
+ }
34
+
35
+ .wpe-results-card textarea
36
+ {
37
+ white-space: nowrap;
38
+ width: 100%;
39
+ height: 200px;
40
+ }
41
+
42
+ .wpe-results-card .view-details
43
+ {
44
+ font-size: 14px;
45
+ color: #ff0000;
46
+ cursor: pointer;
47
+ float: right;
48
+ }
49
+
50
+
51
+ #developerMode textarea
52
+ {
53
+ width: 100%; height: 500px; background: #FFF; color: #000;
54
+ }
55
+
56
+ #progressbar .ui-progressbar-value
57
+ {
58
+ background: #0085ba;
59
+ }
60
+
61
+ #wpe-progress-count, #wpe-progress-active
62
+ {
63
+ display: inline;
64
+ }
65
+
66
+ /* Tooltip container */
67
+ .wpe-tooltip {
68
+ position: relative;
69
+ display: inline-block;
70
+ }
71
+
72
+ /* Tooltip text */
73
+ .wpe-tooltip .wpe-tooltiptext {
74
+ visibility: hidden;
75
+ width: 340px;
76
+ background-color: black;
77
+ color: #fff;
78
+ text-align: center;
79
+ padding: 5px 0;
80
+ border-radius: 6px;
81
+ position: absolute;
82
+ z-index: 1;
83
+ top: -25px;
84
+ left: 105%;
85
+ }
86
+
87
+ /* Show the tooltip text when you mouse over the tooltip container */
88
+ .wpe-tooltip:hover .wpe-tooltiptext {
89
+ visibility: visible;
90
+ }
php-compatibility-checker/src/images/check.png ADDED
Binary file
php-compatibility-checker/src/images/question.png ADDED
Binary file
php-compatibility-checker/src/images/x.png ADDED
Binary file
php-compatibility-checker/src/js/download.min.js ADDED
@@ -0,0 +1,2 @@
 
 
1
+ //download.js v4.2, by dandavis; 2008-2016. [CCBY2] see http://danml.com/download.html for tests/usage
2
+ (function(r,k){"function"==typeof define&&define.amd?define([],k):"object"==typeof exports?module.exports=k():r.download=k()})(this,function(){return function k(a,b,g){function q(p){var a=p.split(/[:;,]/);p=a[1];var a=("base64"==a[2]?atob:decodeURIComponent)(a.pop()),d=a.length,b=0,c=new Uint8Array(d);for(b;b<d;++b)c[b]=a.charCodeAt(b);return new f([c],{type:p})}function l(a,b){if("download"in d)return d.href=a,d.setAttribute("download",m),d.className="download-js-link",d.innerHTML="downloading...",d.style.display="none",document.body.appendChild(d),setTimeout(function(){d.click(),document.body.removeChild(d),!0===b&&setTimeout(function(){e.URL.revokeObjectURL(d.href)},250)},66),!0;if(/(Version)\/(\d+)\.(\d+)(?:\.(\d+))?.*Safari\//.test(navigator.userAgent))return a=a.replace(/^data:([\w\/\-\+]+)/,"application/octet-stream"),!window.open(a)&&confirm("Displaying New Document\n\nUse Save As... to download, then click back to return to this page.")&&(location.href=a),!0;var c=document.createElement("iframe");document.body.appendChild(c),b||(a="data:"+a.replace(/^data:([\w\/\-\+]+)/,"application/octet-stream")),c.src=a,setTimeout(function(){document.body.removeChild(c)},333)}var e=window,c=g||"application/octet-stream",h=!b&&!g&&a,d=document.createElement("a");g=function(a){return String(a)};var f=e.Blob||e.MozBlob||e.WebKitBlob||g,m=b||"download",f=f.call?f.bind(e):Blob;"true"===String(this)&&(a=[a,c],c=a[0],a=a[1]);if(h&&2048>h.length&&(m=h.split("/").pop().split("?")[0],d.href=h,-1!==d.href.indexOf(h))){var n=new XMLHttpRequest;return n.open("GET",h,!0),n.responseType="blob",n.onload=function(a){k(a.target.response,m,"application/octet-stream")},setTimeout(function(){n.send()},0),n}if(/^data\:[\w+\-]+\/[\w+\-]+[,;]/.test(a)){if(!(2096103.424<a.length&&f!==g))return navigator.msSaveBlob?navigator.msSaveBlob(q(a),m):l(a);a=q(a),c=a.type||"application/octet-stream"}b=a instanceof f?a:new f([a],{type:c});if(navigator.msSaveBlob)return navigator.msSaveBlob(b,m);if(e.URL)l(e.URL.createObjectURL(b),!0);else{if("string"==typeof b||b.constructor===g)try{return l("data:"+c+";base64,"+e.btoa(b))}catch(p){return l("data:"+c+","+encodeURIComponent(b))}c=new FileReader,c.onload=function(a){l(this.result)},c.readAsDataURL(b)}return!0}});
php-compatibility-checker/src/js/handlebars.js ADDED
@@ -0,0 +1,4607 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+
3
+ handlebars v4.0.3
4
+
5
+ Copyright (C) 2011-2015 by Yehuda Katz
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in
15
+ all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ THE SOFTWARE.
24
+
25
+ @license
26
+ */
27
+ (function webpackUniversalModuleDefinition(root, factory) {
28
+ if(typeof exports === 'object' && typeof module === 'object')
29
+ module.exports = factory();
30
+ else if(typeof define === 'function' && define.amd)
31
+ define([], factory);
32
+ else if(typeof exports === 'object')
33
+ exports["Handlebars"] = factory();
34
+ else
35
+ root["Handlebars"] = factory();
36
+ })(this, function() {
37
+ return /******/ (function(modules) { // webpackBootstrap
38
+ /******/ // The module cache
39
+ /******/ var installedModules = {};
40
+
41
+ /******/ // The require function
42
+ /******/ function __webpack_require__(moduleId) {
43
+
44
+ /******/ // Check if module is in cache
45
+ /******/ if(installedModules[moduleId])
46
+ /******/ return installedModules[moduleId].exports;
47
+
48
+ /******/ // Create a new module (and put it into the cache)
49
+ /******/ var module = installedModules[moduleId] = {
50
+ /******/ exports: {},
51
+ /******/ id: moduleId,
52
+ /******/ loaded: false
53
+ /******/ };
54
+
55
+ /******/ // Execute the module function
56
+ /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
57
+
58
+ /******/ // Flag the module as loaded
59
+ /******/ module.loaded = true;
60
+
61
+ /******/ // Return the exports of the module
62
+ /******/ return module.exports;
63
+ /******/ }
64
+
65
+
66
+ /******/ // expose the modules object (__webpack_modules__)
67
+ /******/ __webpack_require__.m = modules;
68
+
69
+ /******/ // expose the module cache
70
+ /******/ __webpack_require__.c = installedModules;
71
+
72
+ /******/ // __webpack_public_path__
73
+ /******/ __webpack_require__.p = "";
74
+
75
+ /******/ // Load entry module and return exports
76
+ /******/ return __webpack_require__(0);
77
+ /******/ })
78
+ /************************************************************************/
79
+ /******/ ([
80
+ /* 0 */
81
+ /***/ function(module, exports, __webpack_require__) {
82
+
83
+ 'use strict';
84
+
85
+ var _interopRequireDefault = __webpack_require__(1)['default'];
86
+
87
+ exports.__esModule = true;
88
+
89
+ var _handlebarsRuntime = __webpack_require__(2);
90
+
91
+ var _handlebarsRuntime2 = _interopRequireDefault(_handlebarsRuntime);
92
+
93
+ // Compiler imports
94
+
95
+ var _handlebarsCompilerAst = __webpack_require__(21);
96
+
97
+ var _handlebarsCompilerAst2 = _interopRequireDefault(_handlebarsCompilerAst);
98
+
99
+ var _handlebarsCompilerBase = __webpack_require__(22);
100
+
101
+ var _handlebarsCompilerCompiler = __webpack_require__(27);
102
+
103
+ var _handlebarsCompilerJavascriptCompiler = __webpack_require__(28);
104
+
105
+ var _handlebarsCompilerJavascriptCompiler2 = _interopRequireDefault(_handlebarsCompilerJavascriptCompiler);
106
+
107
+ var _handlebarsCompilerVisitor = __webpack_require__(25);
108
+
109
+ var _handlebarsCompilerVisitor2 = _interopRequireDefault(_handlebarsCompilerVisitor);
110
+
111
+ var _handlebarsNoConflict = __webpack_require__(20);
112
+
113
+ var _handlebarsNoConflict2 = _interopRequireDefault(_handlebarsNoConflict);
114
+
115
+ var _create = _handlebarsRuntime2['default'].create;
116
+ function create() {
117
+ var hb = _create();
118
+
119
+ hb.compile = function (input, options) {
120
+ return _handlebarsCompilerCompiler.compile(input, options, hb);
121
+ };
122
+ hb.precompile = function (input, options) {
123
+ return _handlebarsCompilerCompiler.precompile(input, options, hb);
124
+ };
125
+
126
+ hb.AST = _handlebarsCompilerAst2['default'];
127
+ hb.Compiler = _handlebarsCompilerCompiler.Compiler;
128
+ hb.JavaScriptCompiler = _handlebarsCompilerJavascriptCompiler2['default'];
129
+ hb.Parser = _handlebarsCompilerBase.parser;
130
+ hb.parse = _handlebarsCompilerBase.parse;
131
+
132
+ return hb;
133
+ }
134
+
135
+ var inst = create();
136
+ inst.create = create;
137
+
138
+ _handlebarsNoConflict2['default'](inst);
139
+
140
+ inst.Visitor = _handlebarsCompilerVisitor2['default'];
141
+
142
+ inst['default'] = inst;
143
+
144
+ exports['default'] = inst;
145
+ module.exports = exports['default'];
146
+
147
+ /***/ },
148
+ /* 1 */
149
+ /***/ function(module, exports) {
150
+
151
+ "use strict";
152
+
153
+ exports["default"] = function (obj) {
154
+ return obj && obj.__esModule ? obj : {
155
+ "default": obj
156
+ };
157
+ };
158
+
159
+ exports.__esModule = true;
160
+
161
+ /***/ },
162
+ /* 2 */
163
+ /***/ function(module, exports, __webpack_require__) {
164
+
165
+ 'use strict';
166
+
167
+ var _interopRequireWildcard = __webpack_require__(3)['default'];
168
+
169
+ var _interopRequireDefault = __webpack_require__(1)['default'];
170
+
171
+ exports.__esModule = true;
172
+
173
+ var _handlebarsBase = __webpack_require__(4);
174
+
175
+ var base = _interopRequireWildcard(_handlebarsBase);
176
+
177
+ // Each of these augment the Handlebars object. No need to setup here.
178
+ // (This is done to easily share code between commonjs and browse envs)
179
+
180
+ var _handlebarsSafeString = __webpack_require__(18);
181
+
182
+ var _handlebarsSafeString2 = _interopRequireDefault(_handlebarsSafeString);
183
+
184
+ var _handlebarsException = __webpack_require__(6);
185
+
186
+ var _handlebarsException2 = _interopRequireDefault(_handlebarsException);
187
+
188
+ var _handlebarsUtils = __webpack_require__(5);
189
+
190
+ var Utils = _interopRequireWildcard(_handlebarsUtils);
191
+
192
+ var _handlebarsRuntime = __webpack_require__(19);
193
+
194
+ var runtime = _interopRequireWildcard(_handlebarsRuntime);
195
+
196
+ var _handlebarsNoConflict = __webpack_require__(20);
197
+
198
+ var _handlebarsNoConflict2 = _interopRequireDefault(_handlebarsNoConflict);
199
+
200
+ // For compatibility and usage outside of module systems, make the Handlebars object a namespace
201
+ function create() {
202
+ var hb = new base.HandlebarsEnvironment();
203
+
204
+ Utils.extend(hb, base);
205
+ hb.SafeString = _handlebarsSafeString2['default'];
206
+ hb.Exception = _handlebarsException2['default'];
207
+ hb.Utils = Utils;
208
+ hb.escapeExpression = Utils.escapeExpression;
209
+
210
+ hb.VM = runtime;
211
+ hb.template = function (spec) {
212
+ return runtime.template(spec, hb);
213
+ };
214
+
215
+ return hb;
216
+ }
217
+
218
+ var inst = create();
219
+ inst.create = create;
220
+
221
+ _handlebarsNoConflict2['default'](inst);
222
+
223
+ inst['default'] = inst;
224
+
225
+ exports['default'] = inst;
226
+ module.exports = exports['default'];
227
+
228
+ /***/ },
229
+ /* 3 */
230
+ /***/ function(module, exports) {
231
+
232
+ "use strict";
233
+
234
+ exports["default"] = function (obj) {
235
+ if (obj && obj.__esModule) {
236
+ return obj;
237
+ } else {
238
+ var newObj = {};
239
+
240
+ if (obj != null) {
241
+ for (var key in obj) {
242
+ if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key];
243
+ }
244
+ }
245
+
246
+ newObj["default"] = obj;
247
+ return newObj;
248
+ }
249
+ };
250
+
251
+ exports.__esModule = true;
252
+
253
+ /***/ },
254
+ /* 4 */
255
+ /***/ function(module, exports, __webpack_require__) {
256
+
257
+ 'use strict';
258
+
259
+ var _interopRequireDefault = __webpack_require__(1)['default'];
260
+
261
+ exports.__esModule = true;
262
+ exports.HandlebarsEnvironment = HandlebarsEnvironment;
263
+
264
+ var _utils = __webpack_require__(5);
265
+
266
+ var _exception = __webpack_require__(6);
267
+
268
+ var _exception2 = _interopRequireDefault(_exception);
269
+
270
+ var _helpers = __webpack_require__(7);
271
+
272
+ var _decorators = __webpack_require__(15);
273
+
274
+ var _logger = __webpack_require__(17);
275
+
276
+ var _logger2 = _interopRequireDefault(_logger);
277
+
278
+ var VERSION = '4.0.3';
279
+ exports.VERSION = VERSION;
280
+ var COMPILER_REVISION = 7;
281
+
282
+ exports.COMPILER_REVISION = COMPILER_REVISION;
283
+ var REVISION_CHANGES = {
284
+ 1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
285
+ 2: '== 1.0.0-rc.3',
286
+ 3: '== 1.0.0-rc.4',
287
+ 4: '== 1.x.x',
288
+ 5: '== 2.0.0-alpha.x',
289
+ 6: '>= 2.0.0-beta.1',
290
+ 7: '>= 4.0.0'
291
+ };
292
+
293
+ exports.REVISION_CHANGES = REVISION_CHANGES;
294
+ var objectType = '[object Object]';
295
+
296
+ function HandlebarsEnvironment(helpers, partials, decorators) {
297
+ this.helpers = helpers || {};
298
+ this.partials = partials || {};
299
+ this.decorators = decorators || {};
300
+
301
+ _helpers.registerDefaultHelpers(this);
302
+ _decorators.registerDefaultDecorators(this);
303
+ }
304
+
305
+ HandlebarsEnvironment.prototype = {
306
+ constructor: HandlebarsEnvironment,
307
+
308
+ logger: _logger2['default'],
309
+ log: _logger2['default'].log,
310
+
311
+ registerHelper: function registerHelper(name, fn) {
312
+ if (_utils.toString.call(name) === objectType) {
313
+ if (fn) {
314
+ throw new _exception2['default']('Arg not supported with multiple helpers');
315
+ }
316
+ _utils.extend(this.helpers, name);
317
+ } else {
318
+ this.helpers[name] = fn;
319
+ }
320
+ },
321
+ unregisterHelper: function unregisterHelper(name) {
322
+ delete this.helpers[name];
323
+ },
324
+
325
+ registerPartial: function registerPartial(name, partial) {
326
+ if (_utils.toString.call(name) === objectType) {
327
+ _utils.extend(this.partials, name);
328
+ } else {
329
+ if (typeof partial === 'undefined') {
330
+ throw new _exception2['default']('Attempting to register a partial as undefined');
331
+ }
332
+ this.partials[name] = partial;
333
+ }
334
+ },
335
+ unregisterPartial: function unregisterPartial(name) {
336
+ delete this.partials[name];
337
+ },
338
+
339
+ registerDecorator: function registerDecorator(name, fn) {
340
+ if (_utils.toString.call(name) === objectType) {
341
+ if (fn) {
342
+ throw new _exception2['default']('Arg not supported with multiple decorators');
343
+ }
344
+ _utils.extend(this.decorators, name);
345
+ } else {
346
+ this.decorators[name] = fn;
347
+ }
348
+ },
349
+ unregisterDecorator: function unregisterDecorator(name) {
350
+ delete this.decorators[name];
351
+ }
352
+ };
353
+
354
+ var log = _logger2['default'].log;
355
+
356
+ exports.log = log;
357
+ exports.createFrame = _utils.createFrame;
358
+ exports.logger = _logger2['default'];
359
+
360
+ /***/ },
361
+ /* 5 */
362
+ /***/ function(module, exports) {
363
+
364
+ 'use strict';
365
+
366
+ exports.__esModule = true;
367
+ exports.extend = extend;
368
+ exports.indexOf = indexOf;
369
+ exports.escapeExpression = escapeExpression;
370
+ exports.isEmpty = isEmpty;
371
+ exports.createFrame = createFrame;
372
+ exports.blockParams = blockParams;
373
+ exports.appendContextPath = appendContextPath;
374
+ var escape = {
375
+ '&': '&amp;',
376
+ '<': '&lt;',
377
+ '>': '&gt;',
378
+ '"': '&quot;',
379
+ "'": '&#x27;',
380
+ '`': '&#x60;',
381
+ '=': '&#x3D;'
382
+ };
383
+
384
+ var badChars = /[&<>"'`=]/g,
385
+ possible = /[&<>"'`=]/;
386
+
387
+ function escapeChar(chr) {
388
+ return escape[chr];
389
+ }
390
+
391
+ function extend(obj /* , ...source */) {
392
+ for (var i = 1; i < arguments.length; i++) {
393
+ for (var key in arguments[i]) {
394
+ if (Object.prototype.hasOwnProperty.call(arguments[i], key)) {
395
+ obj[key] = arguments[i][key];
396
+ }
397
+ }
398
+ }
399
+
400
+ return obj;
401
+ }
402
+
403
+ var toString = Object.prototype.toString;
404
+
405
+ exports.toString = toString;
406
+ // Sourced from lodash
407
+ // https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
408
+ /* eslint-disable func-style */
409
+ var isFunction = function isFunction(value) {
410
+ return typeof value === 'function';
411
+ };
412
+ // fallback for older versions of Chrome and Safari
413
+ /* istanbul ignore next */
414
+ if (isFunction(/x/)) {
415
+ exports.isFunction = isFunction = function (value) {
416
+ return typeof value === 'function' && toString.call(value) === '[object Function]';
417
+ };
418
+ }
419
+ exports.isFunction = isFunction;
420
+
421
+ /* eslint-enable func-style */
422
+
423
+ /* istanbul ignore next */
424
+ var isArray = Array.isArray || function (value) {
425
+ return value && typeof value === 'object' ? toString.call(value) === '[object Array]' : false;
426
+ };
427
+
428
+ exports.isArray = isArray;
429
+ // Older IE versions do not directly support indexOf so we must implement our own, sadly.
430
+
431
+ function indexOf(array, value) {
432
+ for (var i = 0, len = array.length; i < len; i++) {
433
+ if (array[i] === value) {
434
+ return i;
435
+ }
436
+ }
437
+ return -1;
438
+ }
439
+
440
+ function escapeExpression(string) {
441
+ if (typeof string !== 'string') {
442
+ // don't escape SafeStrings, since they're already safe
443
+ if (string && string.toHTML) {
444
+ return string.toHTML();
445
+ } else if (string == null) {
446
+ return '';
447
+ } else if (!string) {
448
+ return string + '';
449
+ }
450
+
451
+ // Force a string conversion as this will be done by the append regardless and
452
+ // the regex test will do this transparently behind the scenes, causing issues if
453
+ // an object's to string has escaped characters in it.
454
+ string = '' + string;
455
+ }
456
+
457
+ if (!possible.test(string)) {
458
+ return string;
459
+ }
460
+ return string.replace(badChars, escapeChar);
461
+ }
462
+
463
+ function isEmpty(value) {
464
+ if (!value && value !== 0) {
465
+ return true;
466
+ } else if (isArray(value) && value.length === 0) {
467
+ return true;
468
+ } else {
469
+ return false;
470
+ }
471
+ }
472
+
473
+ function createFrame(object) {
474
+ var frame = extend({}, object);
475
+ frame._parent = object;
476
+ return frame;
477
+ }
478
+
479
+ function blockParams(params, ids) {
480
+ params.path = ids;
481
+ return params;
482
+ }
483
+
484
+ function appendContextPath(contextPath, id) {
485
+ return (contextPath ? contextPath + '.' : '') + id;
486
+ }
487
+
488
+ /***/ },
489
+ /* 6 */
490
+ /***/ function(module, exports) {
491
+
492
+ 'use strict';
493
+
494
+ exports.__esModule = true;
495
+
496
+ var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
497
+
498
+ function Exception(message, node) {
499
+ var loc = node && node.loc,
500
+ line = undefined,
501
+ column = undefined;
502
+ if (loc) {
503
+ line = loc.start.line;
504
+ column = loc.start.column;
505
+
506
+ message += ' - ' + line + ':' + column;
507
+ }
508
+
509
+ var tmp = Error.prototype.constructor.call(this, message);
510
+
511
+ // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
512
+ for (var idx = 0; idx < errorProps.length; idx++) {
513
+ this[errorProps[idx]] = tmp[errorProps[idx]];
514
+ }
515
+
516
+ /* istanbul ignore else */
517
+ if (Error.captureStackTrace) {
518
+ Error.captureStackTrace(this, Exception);
519
+ }
520
+
521
+ if (loc) {
522
+ this.lineNumber = line;
523
+ this.column = column;
524
+ }
525
+ }
526
+
527
+ Exception.prototype = new Error();
528
+
529
+ exports['default'] = Exception;
530
+ module.exports = exports['default'];
531
+
532
+ /***/ },
533
+ /* 7 */
534
+ /***/ function(module, exports, __webpack_require__) {
535
+
536
+ 'use strict';
537
+
538
+ var _interopRequireDefault = __webpack_require__(1)['default'];
539
+
540
+ exports.__esModule = true;
541
+ exports.registerDefaultHelpers = registerDefaultHelpers;
542
+
543
+ var _helpersBlockHelperMissing = __webpack_require__(8);
544
+
545
+ var _helpersBlockHelperMissing2 = _interopRequireDefault(_helpersBlockHelperMissing);
546
+
547
+ var _helpersEach = __webpack_require__(9);
548
+
549
+ var _helpersEach2 = _interopRequireDefault(_helpersEach);
550
+
551
+ var _helpersHelperMissing = __webpack_require__(10);
552
+
553
+ var _helpersHelperMissing2 = _interopRequireDefault(_helpersHelperMissing);
554
+
555
+ var _helpersIf = __webpack_require__(11);
556
+
557
+ var _helpersIf2 = _interopRequireDefault(_helpersIf);
558
+
559
+ var _helpersLog = __webpack_require__(12);
560
+
561
+ var _helpersLog2 = _interopRequireDefault(_helpersLog);
562
+
563
+ var _helpersLookup = __webpack_require__(13);
564
+
565
+ var _helpersLookup2 = _interopRequireDefault(_helpersLookup);
566
+
567
+ var _helpersWith = __webpack_require__(14);
568
+
569
+ var _helpersWith2 = _interopRequireDefault(_helpersWith);
570
+
571
+ function registerDefaultHelpers(instance) {
572
+ _helpersBlockHelperMissing2['default'](instance);
573
+ _helpersEach2['default'](instance);
574
+ _helpersHelperMissing2['default'](instance);
575
+ _helpersIf2['default'](instance);
576
+ _helpersLog2['default'](instance);
577
+ _helpersLookup2['default'](instance);
578
+ _helpersWith2['default'](instance);
579
+ }
580
+
581
+ /***/ },
582
+ /* 8 */
583
+ /***/ function(module, exports, __webpack_require__) {
584
+
585
+ 'use strict';
586
+
587
+ exports.__esModule = true;
588
+
589
+ var _utils = __webpack_require__(5);
590
+
591
+ exports['default'] = function (instance) {
592
+ instance.registerHelper('blockHelperMissing', function (context, options) {
593
+ var inverse = options.inverse,
594
+ fn = options.fn;
595
+
596
+ if (context === true) {
597
+ return fn(this);
598
+ } else if (context === false || context == null) {
599
+ return inverse(this);
600
+ } else if (_utils.isArray(context)) {
601
+ if (context.length > 0) {
602
+ if (options.ids) {
603
+ options.ids = [options.name];
604
+ }
605
+
606
+ return instance.helpers.each(context, options);
607
+ } else {
608
+ return inverse(this);
609
+ }
610
+ } else {
611
+ if (options.data && options.ids) {
612
+ var data = _utils.createFrame(options.data);
613
+ data.contextPath = _utils.appendContextPath(options.data.contextPath, options.name);
614
+ options = { data: data };
615
+ }
616
+
617
+ return fn(context, options);
618
+ }
619
+ });
620
+ };
621
+
622
+ module.exports = exports['default'];
623
+
624
+ /***/ },
625
+ /* 9 */
626
+ /***/ function(module, exports, __webpack_require__) {
627
+
628
+ 'use strict';
629
+
630
+ var _interopRequireDefault = __webpack_require__(1)['default'];
631
+
632
+ exports.__esModule = true;
633
+
634
+ var _utils = __webpack_require__(5);
635
+
636
+ var _exception = __webpack_require__(6);
637
+
638
+ var _exception2 = _interopRequireDefault(_exception);
639
+
640
+ exports['default'] = function (instance) {
641
+ instance.registerHelper('each', function (context, options) {
642
+ if (!options) {
643
+ throw new _exception2['default']('Must pass iterator to #each');
644
+ }
645
+
646
+ var fn = options.fn,
647
+ inverse = options.inverse,
648
+ i = 0,
649
+ ret = '',
650
+ data = undefined,
651
+ contextPath = undefined;
652
+
653
+ if (options.data && options.ids) {
654
+ contextPath = _utils.appendContextPath(options.data.contextPath, options.ids[0]) + '.';
655
+ }
656
+
657
+ if (_utils.isFunction(context)) {
658
+ context = context.call(this);
659
+ }
660
+
661
+ if (options.data) {
662
+ data = _utils.createFrame(options.data);
663
+ }
664
+
665
+ function execIteration(field, index, last) {
666
+ if (data) {
667
+ data.key = field;
668
+ data.index = index;
669
+ data.first = index === 0;
670
+ data.last = !!last;
671
+
672
+ if (contextPath) {
673
+ data.contextPath = contextPath + field;
674
+ }
675
+ }
676
+
677
+ ret = ret + fn(context[field], {
678
+ data: data,
679
+ blockParams: _utils.blockParams([context[field], field], [contextPath + field, null])
680
+ });
681
+ }
682
+
683
+ if (context && typeof context === 'object') {
684
+ if (_utils.isArray(context)) {
685
+ for (var j = context.length; i < j; i++) {
686
+ if (i in context) {
687
+ execIteration(i, i, i === context.length - 1);
688
+ }
689
+ }
690
+ } else {
691
+ var priorKey = undefined;
692
+
693
+ for (var key in context) {
694
+ if (context.hasOwnProperty(key)) {
695
+ // We're running the iterations one step out of sync so we can detect
696
+ // the last iteration without have to scan the object twice and create
697
+ // an itermediate keys array.
698
+ if (priorKey !== undefined) {
699
+ execIteration(priorKey, i - 1);
700
+ }
701
+ priorKey = key;
702
+ i++;
703
+ }
704
+ }
705
+ if (priorKey !== undefined) {
706
+ execIteration(priorKey, i - 1, true);
707
+ }
708
+ }
709
+ }
710
+
711
+ if (i === 0) {
712
+ ret = inverse(this);
713
+ }
714
+
715
+ return ret;
716
+ });
717
+ };
718
+
719
+ module.exports = exports['default'];
720
+
721
+ /***/ },
722
+ /* 10 */
723
+ /***/ function(module, exports, __webpack_require__) {
724
+
725
+ 'use strict';
726
+
727
+ var _interopRequireDefault = __webpack_require__(1)['default'];
728
+
729
+ exports.__esModule = true;
730
+
731
+ var _exception = __webpack_require__(6);
732
+
733
+ var _exception2 = _interopRequireDefault(_exception);
734
+
735
+ exports['default'] = function (instance) {
736
+ instance.registerHelper('helperMissing', function () /* [args, ]options */{
737
+ if (arguments.length === 1) {
738
+ // A missing field in a {{foo}} construct.
739
+ return undefined;
740
+ } else {
741
+ // Someone is actually trying to call something, blow up.
742
+ throw new _exception2['default']('Missing helper: "' + arguments[arguments.length - 1].name + '"');
743
+ }
744
+ });
745
+ };
746
+
747
+ module.exports = exports['default'];
748
+
749
+ /***/ },
750
+ /* 11 */
751
+ /***/ function(module, exports, __webpack_require__) {
752
+
753
+ 'use strict';
754
+
755
+ exports.__esModule = true;
756
+
757
+ var _utils = __webpack_require__(5);
758
+
759
+ exports['default'] = function (instance) {
760
+ instance.registerHelper('if', function (conditional, options) {
761
+ if (_utils.isFunction(conditional)) {
762
+ conditional = conditional.call(this);
763
+ }
764
+
765
+ // Default behavior is to render the positive path if the value is truthy and not empty.
766
+ // The `includeZero` option may be set to treat the condtional as purely not empty based on the
767
+ // behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
768
+ if (!options.hash.includeZero && !conditional || _utils.isEmpty(conditional)) {
769
+ return options.inverse(this);
770
+ } else {
771
+ return options.fn(this);
772
+ }
773
+ });
774
+
775
+ instance.registerHelper('unless', function (conditional, options) {
776
+ return instance.helpers['if'].call(this, conditional, { fn: options.inverse, inverse: options.fn, hash: options.hash });
777
+ });
778
+ };
779
+
780
+ module.exports = exports['default'];
781
+
782
+ /***/ },
783
+ /* 12 */
784
+ /***/ function(module, exports) {
785
+
786
+ 'use strict';
787
+
788
+ exports.__esModule = true;
789
+
790
+ exports['default'] = function (instance) {
791
+ instance.registerHelper('log', function () /* message, options */{
792
+ var args = [undefined],
793
+ options = arguments[arguments.length - 1];
794
+ for (var i = 0; i < arguments.length - 1; i++) {
795
+ args.push(arguments[i]);
796
+ }
797
+
798
+ var level = 1;
799
+ if (options.hash.level != null) {
800
+ level = options.hash.level;
801
+ } else if (options.data && options.data.level != null) {
802
+ level = options.data.level;
803
+ }
804
+ args[0] = level;
805
+
806
+ instance.log.apply(instance, args);
807
+ });
808
+ };
809
+
810
+ module.exports = exports['default'];
811
+
812
+ /***/ },
813
+ /* 13 */
814
+ /***/ function(module, exports) {
815
+
816
+ 'use strict';
817
+
818
+ exports.__esModule = true;
819
+
820
+ exports['default'] = function (instance) {
821
+ instance.registerHelper('lookup', function (obj, field) {
822
+ return obj && obj[field];
823
+ });
824
+ };
825
+
826
+ module.exports = exports['default'];
827
+
828
+ /***/ },
829
+ /* 14 */
830
+ /***/ function(module, exports, __webpack_require__) {
831
+
832
+ 'use strict';
833
+
834
+ exports.__esModule = true;
835
+
836
+ var _utils = __webpack_require__(5);
837
+
838
+ exports['default'] = function (instance) {
839
+ instance.registerHelper('with', function (context, options) {
840
+ if (_utils.isFunction(context)) {
841
+ context = context.call(this);
842
+ }
843
+
844
+ var fn = options.fn;
845
+
846
+ if (!_utils.isEmpty(context)) {
847
+ var data = options.data;
848
+ if (options.data && options.ids) {
849
+ data = _utils.createFrame(options.data);
850
+ data.contextPath = _utils.appendContextPath(options.data.contextPath, options.ids[0]);
851
+ }
852
+
853
+ return fn(context, {
854
+ data: data,
855
+ blockParams: _utils.blockParams([context], [data && data.contextPath])
856
+ });
857
+ } else {
858
+ return options.inverse(this);
859
+ }
860
+ });
861
+ };
862
+
863
+ module.exports = exports['default'];
864
+
865
+ /***/ },
866
+ /* 15 */
867
+ /***/ function(module, exports, __webpack_require__) {
868
+
869
+ 'use strict';
870
+
871
+ var _interopRequireDefault = __webpack_require__(1)['default'];
872
+
873
+ exports.__esModule = true;
874
+ exports.registerDefaultDecorators = registerDefaultDecorators;
875
+
876
+ var _decoratorsInline = __webpack_require__(16);
877
+
878
+ var _decoratorsInline2 = _interopRequireDefault(_decoratorsInline);
879
+
880
+ function registerDefaultDecorators(instance) {
881
+ _decoratorsInline2['default'](instance);
882
+ }
883
+
884
+ /***/ },
885
+ /* 16 */
886
+ /***/ function(module, exports, __webpack_require__) {
887
+
888
+ 'use strict';
889
+
890
+ exports.__esModule = true;
891
+
892
+ var _utils = __webpack_require__(5);
893
+
894
+ exports['default'] = function (instance) {
895
+ instance.registerDecorator('inline', function (fn, props, container, options) {
896
+ var ret = fn;
897
+ if (!props.partials) {
898
+ props.partials = {};
899
+ ret = function (context, options) {
900
+ // Create a new partials stack frame prior to exec.
901
+ var original = container.partials;
902
+ container.partials = _utils.extend({}, original, props.partials);
903
+ var ret = fn(context, options);
904
+ container.partials = original;
905
+ return ret;
906
+ };
907
+ }
908
+
909
+ props.partials[options.args[0]] = options.fn;
910
+
911
+ return ret;
912
+ });
913
+ };
914
+
915
+ module.exports = exports['default'];
916
+
917
+ /***/ },
918
+ /* 17 */
919
+ /***/ function(module, exports, __webpack_require__) {
920
+
921
+ 'use strict';
922
+
923
+ exports.__esModule = true;
924
+
925
+ var _utils = __webpack_require__(5);
926
+
927
+ var logger = {
928
+ methodMap: ['debug', 'info', 'warn', 'error'],
929
+ level: 'info',
930
+
931
+ // Maps a given level value to the `methodMap` indexes above.
932
+ lookupLevel: function lookupLevel(level) {
933
+ if (typeof level === 'string') {
934
+ var levelMap = _utils.indexOf(logger.methodMap, level.toLowerCase());
935
+ if (levelMap >= 0) {
936
+ level = levelMap;
937
+ } else {
938
+ level = parseInt(level, 10);
939
+ }
940
+ }
941
+
942
+ return level;
943
+ },
944
+
945
+ // Can be overridden in the host environment
946
+ log: function log(level) {
947
+ level = logger.lookupLevel(level);
948
+
949
+ if (typeof console !== 'undefined' && logger.lookupLevel(logger.level) <= level) {
950
+ var method = logger.methodMap[level];
951
+ if (!console[method]) {
952
+ // eslint-disable-line no-console
953
+ method = 'log';
954
+ }
955
+
956
+ for (var _len = arguments.length, message = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
957
+ message[_key - 1] = arguments[_key];
958
+ }
959
+
960
+ console[method].apply(console, message); // eslint-disable-line no-console
961
+ }
962
+ }
963
+ };
964
+
965
+ exports['default'] = logger;
966
+ module.exports = exports['default'];
967
+
968
+ /***/ },
969
+ /* 18 */
970
+ /***/ function(module, exports) {
971
+
972
+ // Build out our basic SafeString type
973
+ 'use strict';
974
+
975
+ exports.__esModule = true;
976
+ function SafeString(string) {
977
+ this.string = string;
978
+ }
979
+
980
+ SafeString.prototype.toString = SafeString.prototype.toHTML = function () {
981
+ return '' + this.string;
982
+ };
983
+
984
+ exports['default'] = SafeString;
985
+ module.exports = exports['default'];
986
+
987
+ /***/ },
988
+ /* 19 */
989
+ /***/ function(module, exports, __webpack_require__) {
990
+
991
+ 'use strict';
992
+
993
+ var _interopRequireWildcard = __webpack_require__(3)['default'];
994
+
995
+ var _interopRequireDefault = __webpack_require__(1)['default'];
996
+
997
+ exports.__esModule = true;
998
+ exports.checkRevision = checkRevision;
999
+ exports.template = template;
1000
+ exports.wrapProgram = wrapProgram;
1001
+ exports.resolvePartial = resolvePartial;
1002
+ exports.invokePartial = invokePartial;
1003
+ exports.noop = noop;
1004
+
1005
+ var _utils = __webpack_require__(5);
1006
+
1007
+ var Utils = _interopRequireWildcard(_utils);
1008
+
1009
+ var _exception = __webpack_require__(6);
1010
+
1011
+ var _exception2 = _interopRequireDefault(_exception);
1012
+
1013
+ var _base = __webpack_require__(4);
1014
+
1015
+ function checkRevision(compilerInfo) {
1016
+ var compilerRevision = compilerInfo && compilerInfo[0] || 1,
1017
+ currentRevision = _base.COMPILER_REVISION;
1018
+
1019
+ if (compilerRevision !== currentRevision) {
1020
+ if (compilerRevision < currentRevision) {
1021
+ var runtimeVersions = _base.REVISION_CHANGES[currentRevision],
1022
+ compilerVersions = _base.REVISION_CHANGES[compilerRevision];
1023
+ throw new _exception2['default']('Template was precompiled with an older version of Handlebars than the current runtime. ' + 'Please update your precompiler to a newer version (' + runtimeVersions + ') or downgrade your runtime to an older version (' + compilerVersions + ').');
1024
+ } else {
1025
+ // Use the embedded version info since the runtime doesn't know about this revision yet
1026
+ throw new _exception2['default']('Template was precompiled with a newer version of Handlebars than the current runtime. ' + 'Please update your runtime to a newer version (' + compilerInfo[1] + ').');
1027
+ }
1028
+ }
1029
+ }
1030
+
1031
+ function template(templateSpec, env) {
1032
+ /* istanbul ignore next */
1033
+ if (!env) {
1034
+ throw new _exception2['default']('No environment passed to template');
1035
+ }
1036
+ if (!templateSpec || !templateSpec.main) {
1037
+ throw new _exception2['default']('Unknown template object: ' + typeof templateSpec);
1038
+ }
1039
+
1040
+ templateSpec.main.decorator = templateSpec.main_d;
1041
+
1042
+ // Note: Using env.VM references rather than local var references throughout this section to allow
1043
+ // for external users to override these as psuedo-supported APIs.
1044
+ env.VM.checkRevision(templateSpec.compiler);
1045
+
1046
+ function invokePartialWrapper(partial, context, options) {
1047
+ if (options.hash) {
1048
+ context = Utils.extend({}, context, options.hash);
1049
+ if (options.ids) {
1050
+ options.ids[0] = true;
1051
+ }
1052
+ }
1053
+
1054
+ partial = env.VM.resolvePartial.call(this, partial, context, options);
1055
+ var result = env.VM.invokePartial.call(this, partial, context, options);
1056
+
1057
+ if (result == null && env.compile) {
1058
+ options.partials[options.name] = env.compile(partial, templateSpec.compilerOptions, env);
1059
+ result = options.partials[options.name](context, options);
1060
+ }
1061
+ if (result != null) {
1062
+ if (options.indent) {
1063
+ var lines = result.split('\n');
1064
+ for (var i = 0, l = lines.length; i < l; i++) {
1065
+ if (!lines[i] && i + 1 === l) {
1066
+ break;
1067
+ }
1068
+
1069
+ lines[i] = options.indent + lines[i];
1070
+ }
1071
+ result = lines.join('\n');
1072
+ }
1073
+ return result;
1074
+ } else {
1075
+ throw new _exception2['default']('The partial ' + options.name + ' could not be compiled when running in runtime-only mode');
1076
+ }
1077
+ }
1078
+
1079
+ // Just add water
1080
+ var container = {
1081
+ strict: function strict(obj, name) {
1082
+ if (!(name in obj)) {
1083
+ throw new _exception2['default']('"' + name + '" not defined in ' + obj);
1084
+ }
1085
+ return obj[name];
1086
+ },
1087
+ lookup: function lookup(depths, name) {
1088
+ var len = depths.length;
1089
+ for (var i = 0; i < len; i++) {
1090
+ if (depths[i] && depths[i][name] != null) {
1091
+ return depths[i][name];
1092
+ }
1093
+ }
1094
+ },
1095
+ lambda: function lambda(current, context) {
1096
+ return typeof current === 'function' ? current.call(context) : current;
1097
+ },
1098
+
1099
+ escapeExpression: Utils.escapeExpression,
1100
+ invokePartial: invokePartialWrapper,
1101
+
1102
+ fn: function fn(i) {
1103
+ var ret = templateSpec[i];
1104
+ ret.decorator = templateSpec[i + '_d'];
1105
+ return ret;
1106
+ },
1107
+
1108
+ programs: [],
1109
+ program: function program(i, data, declaredBlockParams, blockParams, depths) {
1110
+ var programWrapper = this.programs[i],
1111
+ fn = this.fn(i);
1112
+ if (data || depths || blockParams || declaredBlockParams) {
1113
+ programWrapper = wrapProgram(this, i, fn, data, declaredBlockParams, blockParams, depths);
1114
+ } else if (!programWrapper) {
1115
+ programWrapper = this.programs[i] = wrapProgram(this, i, fn);
1116
+ }
1117
+ return programWrapper;
1118
+ },
1119
+
1120
+ data: function data(value, depth) {
1121
+ while (value && depth--) {
1122
+ value = value._parent;
1123
+ }
1124
+ return value;
1125
+ },
1126
+ merge: function merge(param, common) {
1127
+ var obj = param || common;
1128
+
1129
+ if (param && common && param !== common) {
1130
+ obj = Utils.extend({}, common, param);
1131
+ }
1132
+
1133
+ return obj;
1134
+ },
1135
+
1136
+ noop: env.VM.noop,
1137
+ compilerInfo: templateSpec.compiler
1138
+ };
1139
+
1140
+ function ret(context) {
1141
+ var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
1142
+
1143
+ var data = options.data;
1144
+
1145
+ ret._setup(options);
1146
+ if (!options.partial && templateSpec.useData) {
1147
+ data = initData(context, data);
1148
+ }
1149
+ var depths = undefined,
1150
+ blockParams = templateSpec.useBlockParams ? [] : undefined;
1151
+ if (templateSpec.useDepths) {
1152
+ if (options.depths) {
1153
+ depths = context !== options.depths[0] ? [context].concat(options.depths) : options.depths;
1154
+ } else {
1155
+ depths = [context];
1156
+ }
1157
+ }
1158
+
1159
+ function main(context /*, options*/) {
1160
+ return '' + templateSpec.main(container, context, container.helpers, container.partials, data, blockParams, depths);
1161
+ }
1162
+ main = executeDecorators(templateSpec.main, main, container, options.depths || [], data, blockParams);
1163
+ return main(context, options);
1164
+ }
1165
+ ret.isTop = true;
1166
+
1167
+ ret._setup = function (options) {
1168
+ if (!options.partial) {
1169
+ container.helpers = container.merge(options.helpers, env.helpers);
1170
+
1171
+ if (templateSpec.usePartial) {
1172
+ container.partials = container.merge(options.partials, env.partials);
1173
+ }
1174
+ if (templateSpec.usePartial || templateSpec.useDecorators) {
1175
+ container.decorators = container.merge(options.decorators, env.decorators);
1176
+ }
1177
+ } else {
1178
+ container.helpers = options.helpers;
1179
+ container.partials = options.partials;
1180
+ container.decorators = options.decorators;
1181
+ }
1182
+ };
1183
+
1184
+ ret._child = function (i, data, blockParams, depths) {
1185
+ if (templateSpec.useBlockParams && !blockParams) {
1186
+ throw new _exception2['default']('must pass block params');
1187
+ }
1188
+ if (templateSpec.useDepths && !depths) {
1189
+ throw new _exception2['default']('must pass parent depths');
1190
+ }
1191
+
1192
+ return wrapProgram(container, i, templateSpec[i], data, 0, blockParams, depths);
1193
+ };
1194
+ return ret;
1195
+ }
1196
+
1197
+ function wrapProgram(container, i, fn, data, declaredBlockParams, blockParams, depths) {
1198
+ function prog(context) {
1199
+ var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
1200
+
1201
+ var currentDepths = depths;
1202
+ if (depths && context !== depths[0]) {
1203
+ currentDepths = [context].concat(depths);
1204
+ }
1205
+
1206
+ return fn(container, context, container.helpers, container.partials, options.data || data, blockParams && [options.blockParams].concat(blockParams), currentDepths);
1207
+ }
1208
+
1209
+ prog = executeDecorators(fn, prog, container, depths, data, blockParams);
1210
+
1211
+ prog.program = i;
1212
+ prog.depth = depths ? depths.length : 0;
1213
+ prog.blockParams = declaredBlockParams || 0;
1214
+ return prog;
1215
+ }
1216
+
1217
+ function resolvePartial(partial, context, options) {
1218
+ if (!partial) {
1219
+ if (options.name === '@partial-block') {
1220
+ partial = options.data['partial-block'];
1221
+ } else {
1222
+ partial = options.partials[options.name];
1223
+ }
1224
+ } else if (!partial.call && !options.name) {
1225
+ // This is a dynamic partial that returned a string
1226
+ options.name = partial;
1227
+ partial = options.partials[partial];
1228
+ }
1229
+ return partial;
1230
+ }
1231
+
1232
+ function invokePartial(partial, context, options) {
1233
+ options.partial = true;
1234
+ if (options.ids) {
1235
+ options.data.contextPath = options.ids[0] || options.data.contextPath;
1236
+ }
1237
+
1238
+ var partialBlock = undefined;
1239
+ if (options.fn && options.fn !== noop) {
1240
+ options.data = _base.createFrame(options.data);
1241
+ partialBlock = options.data['partial-block'] = options.fn;
1242
+
1243
+ if (partialBlock.partials) {
1244
+ options.partials = Utils.extend({}, options.partials, partialBlock.partials);
1245
+ }
1246
+ }
1247
+
1248
+ if (partial === undefined && partialBlock) {
1249
+ partial = partialBlock;
1250
+ }
1251
+
1252
+ if (partial === undefined) {
1253
+ throw new _exception2['default']('The partial ' + options.name + ' could not be found');
1254
+ } else if (partial instanceof Function) {
1255
+ return partial(context, options);
1256
+ }
1257
+ }
1258
+
1259
+ function noop() {
1260
+ return '';
1261
+ }
1262
+
1263
+ function initData(context, data) {
1264
+ if (!data || !('root' in data)) {
1265
+ data = data ? _base.createFrame(data) : {};
1266
+ data.root = context;
1267
+ }
1268
+ return data;
1269
+ }
1270
+
1271
+ function executeDecorators(fn, prog, container, depths, data, blockParams) {
1272
+ if (fn.decorator) {
1273
+ var props = {};
1274
+ prog = fn.decorator(prog, props, container, depths && depths[0], data, blockParams, depths);
1275
+ Utils.extend(prog, props);
1276
+ }
1277
+ return prog;
1278
+ }
1279
+
1280
+ /***/ },
1281
+ /* 20 */
1282
+ /***/ function(module, exports) {
1283
+
1284
+ /* WEBPACK VAR INJECTION */(function(global) {/* global window */
1285
+ 'use strict';
1286
+
1287
+ exports.__esModule = true;
1288
+
1289
+ exports['default'] = function (Handlebars) {
1290
+ /* istanbul ignore next */
1291
+ var root = typeof global !== 'undefined' ? global : window,
1292
+ $Handlebars = root.Handlebars;
1293
+ /* istanbul ignore next */
1294
+ Handlebars.noConflict = function () {
1295
+ if (root.Handlebars === Handlebars) {
1296
+ root.Handlebars = $Handlebars;
1297
+ }
1298
+ };
1299
+ };
1300
+
1301
+ module.exports = exports['default'];
1302
+ /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
1303
+
1304
+ /***/ },
1305
+ /* 21 */
1306
+ /***/ function(module, exports) {
1307
+
1308
+ 'use strict';
1309
+
1310
+ exports.__esModule = true;
1311
+ var AST = {
1312
+ // Public API used to evaluate derived attributes regarding AST nodes
1313
+ helpers: {
1314
+ // a mustache is definitely a helper if:
1315
+ // * it is an eligible helper, and
1316
+ // * it has at least one parameter or hash segment
1317
+ helperExpression: function helperExpression(node) {
1318
+ return node.type === 'SubExpression' || (node.type === 'MustacheStatement' || node.type === 'BlockStatement') && !!(node.params && node.params.length || node.hash);
1319
+ },
1320
+
1321
+ scopedId: function scopedId(path) {
1322
+ return (/^\.|this\b/.test(path.original)
1323
+ );
1324
+ },
1325
+
1326
+ // an ID is simple if it only has one part, and that part is not
1327
+ // `..` or `this`.
1328
+ simpleId: function simpleId(path) {
1329
+ return path.parts.length === 1 && !AST.helpers.scopedId(path) && !path.depth;
1330
+ }
1331
+ }
1332
+ };
1333
+
1334
+ // Must be exported as an object rather than the root of the module as the jison lexer
1335
+ // must modify the object to operate properly.
1336
+ exports['default'] = AST;
1337
+ module.exports = exports['default'];
1338
+
1339
+ /***/ },
1340
+ /* 22 */
1341
+ /***/ function(module, exports, __webpack_require__) {
1342
+
1343
+ 'use strict';
1344
+
1345
+ var _interopRequireDefault = __webpack_require__(1)['default'];
1346
+
1347
+ var _interopRequireWildcard = __webpack_require__(3)['default'];
1348
+
1349
+ exports.__esModule = true;
1350
+ exports.parse = parse;
1351
+
1352
+ var _parser = __webpack_require__(23);
1353
+
1354
+ var _parser2 = _interopRequireDefault(_parser);
1355
+
1356
+ var _whitespaceControl = __webpack_require__(24);
1357
+
1358
+ var _whitespaceControl2 = _interopRequireDefault(_whitespaceControl);
1359
+
1360
+ var _helpers = __webpack_require__(26);
1361
+
1362
+ var Helpers = _interopRequireWildcard(_helpers);
1363
+
1364
+ var _utils = __webpack_require__(5);
1365
+
1366
+ exports.parser = _parser2['default'];
1367
+
1368
+ var yy = {};
1369
+ _utils.extend(yy, Helpers);
1370
+
1371
+ function parse(input, options) {
1372
+ // Just return if an already-compiled AST was passed in.
1373
+ if (input.type === 'Program') {
1374
+ return input;
1375
+ }
1376
+
1377
+ _parser2['default'].yy = yy;
1378
+
1379
+ // Altering the shared object here, but this is ok as parser is a sync operation
1380
+ yy.locInfo = function (locInfo) {
1381
+ return new yy.SourceLocation(options && options.srcName, locInfo);
1382
+ };
1383
+
1384
+ var strip = new _whitespaceControl2['default'](options);
1385
+ return strip.accept(_parser2['default'].parse(input));
1386
+ }
1387
+
1388
+ /***/ },
1389
+ /* 23 */
1390
+ /***/ function(module, exports) {
1391
+
1392
+ /* istanbul ignore next */
1393
+ /* Jison generated parser */
1394
+ "use strict";
1395
+
1396
+ var handlebars = (function () {
1397
+ var parser = { trace: function trace() {},
1398
+ yy: {},
1399
+ symbols_: { "error": 2, "root": 3, "program": 4, "EOF": 5, "program_repetition0": 6, "statement": 7, "mustache": 8, "block": 9, "rawBlock": 10, "partial": 11, "partialBlock": 12, "content": 13, "COMMENT": 14, "CONTENT": 15, "openRawBlock": 16, "rawBlock_repetition_plus0": 17, "END_RAW_BLOCK": 18, "OPEN_RAW_BLOCK": 19, "helperName": 20, "openRawBlock_repetition0": 21, "openRawBlock_option0": 22, "CLOSE_RAW_BLOCK": 23, "openBlock": 24, "block_option0": 25, "closeBlock": 26, "openInverse": 27, "block_option1": 28, "OPEN_BLOCK": 29, "openBlock_repetition0": 30, "openBlock_option0": 31, "openBlock_option1": 32, "CLOSE": 33, "OPEN_INVERSE": 34, "openInverse_repetition0": 35, "openInverse_option0": 36, "openInverse_option1": 37, "openInverseChain": 38, "OPEN_INVERSE_CHAIN": 39, "openInverseChain_repetition0": 40, "openInverseChain_option0": 41, "openInverseChain_option1": 42, "inverseAndProgram": 43, "INVERSE": 44, "inverseChain": 45, "inverseChain_option0": 46, "OPEN_ENDBLOCK": 47, "OPEN": 48, "mustache_repetition0": 49, "mustache_option0": 50, "OPEN_UNESCAPED": 51, "mustache_repetition1": 52, "mustache_option1": 53, "CLOSE_UNESCAPED": 54, "OPEN_PARTIAL": 55, "partialName": 56, "partial_repetition0": 57, "partial_option0": 58, "openPartialBlock": 59, "OPEN_PARTIAL_BLOCK": 60, "openPartialBlock_repetition0": 61, "openPartialBlock_option0": 62, "param": 63, "sexpr": 64, "OPEN_SEXPR": 65, "sexpr_repetition0": 66, "sexpr_option0": 67, "CLOSE_SEXPR": 68, "hash": 69, "hash_repetition_plus0": 70, "hashSegment": 71, "ID": 72, "EQUALS": 73, "blockParams": 74, "OPEN_BLOCK_PARAMS": 75, "blockParams_repetition_plus0": 76, "CLOSE_BLOCK_PARAMS": 77, "path": 78, "dataName": 79, "STRING": 80, "NUMBER": 81, "BOOLEAN": 82, "UNDEFINED": 83, "NULL": 84, "DATA": 85, "pathSegments": 86, "SEP": 87, "$accept": 0, "$end": 1 },
1400
+ terminals_: { 2: "error", 5: "EOF", 14: "COMMENT", 15: "CONTENT", 18: "END_RAW_BLOCK", 19: "OPEN_RAW_BLOCK", 23: "CLOSE_RAW_BLOCK", 29: "OPEN_BLOCK", 33: "CLOSE", 34: "OPEN_INVERSE", 39: "OPEN_INVERSE_CHAIN", 44: "INVERSE", 47: "OPEN_ENDBLOCK", 48: "OPEN", 51: "OPEN_UNESCAPED", 54: "CLOSE_UNESCAPED", 55: "OPEN_PARTIAL", 60: "OPEN_PARTIAL_BLOCK", 65: "OPEN_SEXPR", 68: "CLOSE_SEXPR", 72: "ID", 73: "EQUALS", 75: "OPEN_BLOCK_PARAMS", 77: "CLOSE_BLOCK_PARAMS", 80: "STRING", 81: "NUMBER", 82: "BOOLEAN", 83: "UNDEFINED", 84: "NULL", 85: "DATA", 87: "SEP" },
1401
+ productions_: [0, [3, 2], [4, 1], [7, 1], [7, 1], [7, 1], [7, 1], [7, 1], [7, 1], [7, 1], [13, 1], [10, 3], [16, 5], [9, 4], [9, 4], [24, 6], [27, 6], [38, 6], [43, 2], [45, 3], [45, 1], [26, 3], [8, 5], [8, 5], [11, 5], [12, 3], [59, 5], [63, 1], [63, 1], [64, 5], [69, 1], [71, 3], [74, 3], [20, 1], [20, 1], [20, 1], [20, 1], [20, 1], [20, 1], [20, 1], [56, 1], [56, 1], [79, 2], [78, 1], [86, 3], [86, 1], [6, 0], [6, 2], [17, 1], [17, 2], [21, 0], [21, 2], [22, 0], [22, 1], [25, 0], [25, 1], [28, 0], [28, 1], [30, 0], [30, 2], [31, 0], [31, 1], [32, 0], [32, 1], [35, 0], [35, 2], [36, 0], [36, 1], [37, 0], [37, 1], [40, 0], [40, 2], [41, 0], [41, 1], [42, 0], [42, 1], [46, 0], [46, 1], [49, 0], [49, 2], [50, 0], [50, 1], [52, 0], [52, 2], [53, 0], [53, 1], [57, 0], [57, 2], [58, 0], [58, 1], [61, 0], [61, 2], [62, 0], [62, 1], [66, 0], [66, 2], [67, 0], [67, 1], [70, 1], [70, 2], [76, 1], [76, 2]],
1402
+ performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$
1403
+ /**/) {
1404
+
1405
+ var $0 = $$.length - 1;
1406
+ switch (yystate) {
1407
+ case 1:
1408
+ return $$[$0 - 1];
1409
+ break;
1410
+ case 2:
1411
+ this.$ = yy.prepareProgram($$[$0]);
1412
+ break;
1413
+ case 3:
1414
+ this.$ = $$[$0];
1415
+ break;
1416
+ case 4:
1417
+ this.$ = $$[$0];
1418
+ break;
1419
+ case 5:
1420
+ this.$ = $$[$0];
1421
+ break;
1422
+ case 6:
1423
+ this.$ = $$[$0];
1424
+ break;
1425
+ case 7:
1426
+ this.$ = $$[$0];
1427
+ break;
1428
+ case 8:
1429
+ this.$ = $$[$0];
1430
+ break;
1431
+ case 9:
1432
+ this.$ = {
1433
+ type: 'CommentStatement',
1434
+ value: yy.stripComment($$[$0]),
1435
+ strip: yy.stripFlags($$[$0], $$[$0]),
1436
+ loc: yy.locInfo(this._$)
1437
+ };
1438
+
1439
+ break;
1440
+ case 10:
1441
+ this.$ = {
1442
+ type: 'ContentStatement',
1443
+ original: $$[$0],
1444
+ value: $$[$0],
1445
+ loc: yy.locInfo(this._$)
1446
+ };
1447
+
1448
+ break;
1449
+ case 11:
1450
+ this.$ = yy.prepareRawBlock($$[$0 - 2], $$[$0 - 1], $$[$0], this._$);
1451
+ break;
1452
+ case 12:
1453
+ this.$ = { path: $$[$0 - 3], params: $$[$0 - 2], hash: $$[$0 - 1] };
1454
+ break;
1455
+ case 13:
1456
+ this.$ = yy.prepareBlock($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0], false, this._$);
1457
+ break;
1458
+ case 14:
1459
+ this.$ = yy.prepareBlock($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0], true, this._$);
1460
+ break;
1461
+ case 15:
1462
+ this.$ = { open: $$[$0 - 5], path: $$[$0 - 4], params: $$[$0 - 3], hash: $$[$0 - 2], blockParams: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 5], $$[$0]) };
1463
+ break;
1464
+ case 16:
1465
+ this.$ = { path: $$[$0 - 4], params: $$[$0 - 3], hash: $$[$0 - 2], blockParams: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 5], $$[$0]) };
1466
+ break;
1467
+ case 17:
1468
+ this.$ = { path: $$[$0 - 4], params: $$[$0 - 3], hash: $$[$0 - 2], blockParams: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 5], $$[$0]) };
1469
+ break;
1470
+ case 18:
1471
+ this.$ = { strip: yy.stripFlags($$[$0 - 1], $$[$0 - 1]), program: $$[$0] };
1472
+ break;
1473
+ case 19:
1474
+ var inverse = yy.prepareBlock($$[$0 - 2], $$[$0 - 1], $$[$0], $$[$0], false, this._$),
1475
+ program = yy.prepareProgram([inverse], $$[$0 - 1].loc);
1476
+ program.chained = true;
1477
+
1478
+ this.$ = { strip: $$[$0 - 2].strip, program: program, chain: true };
1479
+
1480
+ break;
1481
+ case 20:
1482
+ this.$ = $$[$0];
1483
+ break;
1484
+ case 21:
1485
+ this.$ = { path: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 2], $$[$0]) };
1486
+ break;
1487
+ case 22:
1488
+ this.$ = yy.prepareMustache($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0 - 4], yy.stripFlags($$[$0 - 4], $$[$0]), this._$);
1489
+ break;
1490
+ case 23:
1491
+ this.$ = yy.prepareMustache($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0 - 4], yy.stripFlags($$[$0 - 4], $$[$0]), this._$);
1492
+ break;
1493
+ case 24:
1494
+ this.$ = {
1495
+ type: 'PartialStatement',
1496
+ name: $$[$0 - 3],
1497
+ params: $$[$0 - 2],
1498
+ hash: $$[$0 - 1],
1499
+ indent: '',
1500
+ strip: yy.stripFlags($$[$0 - 4], $$[$0]),
1501
+ loc: yy.locInfo(this._$)
1502
+ };
1503
+
1504
+ break;
1505
+ case 25:
1506
+ this.$ = yy.preparePartialBlock($$[$0 - 2], $$[$0 - 1], $$[$0], this._$);
1507
+ break;
1508
+ case 26:
1509
+ this.$ = { path: $$[$0 - 3], params: $$[$0 - 2], hash: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 4], $$[$0]) };
1510
+ break;
1511
+ case 27:
1512
+ this.$ = $$[$0];
1513
+ break;
1514
+ case 28:
1515
+ this.$ = $$[$0];
1516
+ break;
1517
+ case 29:
1518
+ this.$ = {
1519
+ type: 'SubExpression',
1520
+ path: $$[$0 - 3],
1521
+ params: $$[$0 - 2],
1522
+ hash: $$[$0 - 1],
1523
+ loc: yy.locInfo(this._$)
1524
+ };
1525
+
1526
+ break;
1527
+ case 30:
1528
+ this.$ = { type: 'Hash', pairs: $$[$0], loc: yy.locInfo(this._$) };
1529
+ break;
1530
+ case 31:
1531
+ this.$ = { type: 'HashPair', key: yy.id($$[$0 - 2]), value: $$[$0], loc: yy.locInfo(this._$) };
1532
+ break;
1533
+ case 32:
1534
+ this.$ = yy.id($$[$0 - 1]);
1535
+ break;
1536
+ case 33:
1537
+ this.$ = $$[$0];
1538
+ break;
1539
+ case 34:
1540
+ this.$ = $$[$0];
1541
+ break;
1542
+ case 35:
1543
+ this.$ = { type: 'StringLiteral', value: $$[$0], original: $$[$0], loc: yy.locInfo(this._$) };
1544
+ break;
1545
+ case 36:
1546
+ this.$ = { type: 'NumberLiteral', value: Number($$[$0]), original: Number($$[$0]), loc: yy.locInfo(this._$) };
1547
+ break;
1548
+ case 37:
1549
+ this.$ = { type: 'BooleanLiteral', value: $$[$0] === 'true', original: $$[$0] === 'true', loc: yy.locInfo(this._$) };
1550
+ break;
1551
+ case 38:
1552
+ this.$ = { type: 'UndefinedLiteral', original: undefined, value: undefined, loc: yy.locInfo(this._$) };
1553
+ break;
1554
+ case 39:
1555
+ this.$ = { type: 'NullLiteral', original: null, value: null, loc: yy.locInfo(this._$) };
1556
+ break;
1557
+ case 40:
1558
+ this.$ = $$[$0];
1559
+ break;
1560
+ case 41:
1561
+ this.$ = $$[$0];
1562
+ break;
1563
+ case 42:
1564
+ this.$ = yy.preparePath(true, $$[$0], this._$);
1565
+ break;
1566
+ case 43:
1567
+ this.$ = yy.preparePath(false, $$[$0], this._$);
1568
+ break;
1569
+ case 44:
1570
+ $$[$0 - 2].push({ part: yy.id($$[$0]), original: $$[$0], separator: $$[$0 - 1] });this.$ = $$[$0 - 2];
1571
+ break;
1572
+ case 45:
1573
+ this.$ = [{ part: yy.id($$[$0]), original: $$[$0] }];
1574
+ break;
1575
+ case 46:
1576
+ this.$ = [];
1577
+ break;
1578
+ case 47:
1579
+ $$[$0 - 1].push($$[$0]);
1580
+ break;
1581
+ case 48:
1582
+ this.$ = [$$[$0]];
1583
+ break;
1584
+ case 49:
1585
+ $$[$0 - 1].push($$[$0]);
1586
+ break;
1587
+ case 50:
1588
+ this.$ = [];
1589
+ break;
1590
+ case 51:
1591
+ $$[$0 - 1].push($$[$0]);
1592
+ break;
1593
+ case 58:
1594
+ this.$ = [];
1595
+ break;
1596
+ case 59:
1597
+ $$[$0 - 1].push($$[$0]);
1598
+ break;
1599
+ case 64:
1600
+ this.$ = [];
1601
+ break;
1602
+ case 65:
1603
+ $$[$0 - 1].push($$[$0]);
1604
+ break;
1605
+ case 70:
1606
+ this.$ = [];
1607
+ break;
1608
+ case 71:
1609
+ $$[$0 - 1].push($$[$0]);
1610
+ break;
1611
+ case 78:
1612
+ this.$ = [];
1613
+ break;
1614
+ case 79:
1615
+ $$[$0 - 1].push($$[$0]);
1616
+ break;
1617
+ case 82:
1618
+ this.$ = [];
1619
+ break;
1620
+ case 83:
1621
+ $$[$0 - 1].push($$[$0]);
1622
+ break;
1623
+ case 86:
1624
+ this.$ = [];
1625
+ break;
1626
+ case 87:
1627
+ $$[$0 - 1].push($$[$0]);
1628
+ break;
1629
+ case 90:
1630
+ this.$ = [];
1631
+ break;
1632
+ case 91:
1633
+ $$[$0 - 1].push($$[$0]);
1634
+ break;
1635
+ case 94:
1636
+ this.$ = [];
1637
+ break;
1638
+ case 95:
1639
+ $$[$0 - 1].push($$[$0]);
1640
+ break;
1641
+ case 98:
1642
+ this.$ = [$$[$0]];
1643
+ break;
1644
+ case 99:
1645
+ $$[$0 - 1].push($$[$0]);
1646
+ break;
1647
+ case 100:
1648
+ this.$ = [$$[$0]];
1649
+ break;
1650
+ case 101:
1651
+ $$[$0 - 1].push($$[$0]);
1652
+ break;
1653
+ }
1654
+ },
1655
+ table: [{ 3: 1, 4: 2, 5: [2, 46], 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 1: [3] }, { 5: [1, 4] }, { 5: [2, 2], 7: 5, 8: 6, 9: 7, 10: 8, 11: 9, 12: 10, 13: 11, 14: [1, 12], 15: [1, 20], 16: 17, 19: [1, 23], 24: 15, 27: 16, 29: [1, 21], 34: [1, 22], 39: [2, 2], 44: [2, 2], 47: [2, 2], 48: [1, 13], 51: [1, 14], 55: [1, 18], 59: 19, 60: [1, 24] }, { 1: [2, 1] }, { 5: [2, 47], 14: [2, 47], 15: [2, 47], 19: [2, 47], 29: [2, 47], 34: [2, 47], 39: [2, 47], 44: [2, 47], 47: [2, 47], 48: [2, 47], 51: [2, 47], 55: [2, 47], 60: [2, 47] }, { 5: [2, 3], 14: [2, 3], 15: [2, 3], 19: [2, 3], 29: [2, 3], 34: [2, 3], 39: [2, 3], 44: [2, 3], 47: [2, 3], 48: [2, 3], 51: [2, 3], 55: [2, 3], 60: [2, 3] }, { 5: [2, 4], 14: [2, 4], 15: [2, 4], 19: [2, 4], 29: [2, 4], 34: [2, 4], 39: [2, 4], 44: [2, 4], 47: [2, 4], 48: [2, 4], 51: [2, 4], 55: [2, 4], 60: [2, 4] }, { 5: [2, 5], 14: [2, 5], 15: [2, 5], 19: [2, 5], 29: [2, 5], 34: [2, 5], 39: [2, 5], 44: [2, 5], 47: [2, 5], 48: [2, 5], 51: [2, 5], 55: [2, 5], 60: [2, 5] }, { 5: [2, 6], 14: [2, 6], 15: [2, 6], 19: [2, 6], 29: [2, 6], 34: [2, 6], 39: [2, 6], 44: [2, 6], 47: [2, 6], 48: [2, 6], 51: [2, 6], 55: [2, 6], 60: [2, 6] }, { 5: [2, 7], 14: [2, 7], 15: [2, 7], 19: [2, 7], 29: [2, 7], 34: [2, 7], 39: [2, 7], 44: [2, 7], 47: [2, 7], 48: [2, 7], 51: [2, 7], 55: [2, 7], 60: [2, 7] }, { 5: [2, 8], 14: [2, 8], 15: [2, 8], 19: [2, 8], 29: [2, 8], 34: [2, 8], 39: [2, 8], 44: [2, 8], 47: [2, 8], 48: [2, 8], 51: [2, 8], 55: [2, 8], 60: [2, 8] }, { 5: [2, 9], 14: [2, 9], 15: [2, 9], 19: [2, 9], 29: [2, 9], 34: [2, 9], 39: [2, 9], 44: [2, 9], 47: [2, 9], 48: [2, 9], 51: [2, 9], 55: [2, 9], 60: [2, 9] }, { 20: 25, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 36, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 4: 37, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 39: [2, 46], 44: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 4: 38, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 44: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 13: 40, 15: [1, 20], 17: 39 }, { 20: 42, 56: 41, 64: 43, 65: [1, 44], 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 4: 45, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 5: [2, 10], 14: [2, 10], 15: [2, 10], 18: [2, 10], 19: [2, 10], 29: [2, 10], 34: [2, 10], 39: [2, 10], 44: [2, 10], 47: [2, 10], 48: [2, 10], 51: [2, 10], 55: [2, 10], 60: [2, 10] }, { 20: 46, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 47, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 48, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 42, 56: 49, 64: 43, 65: [1, 44], 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 33: [2, 78], 49: 50, 65: [2, 78], 72: [2, 78], 80: [2, 78], 81: [2, 78], 82: [2, 78], 83: [2, 78], 84: [2, 78], 85: [2, 78] }, { 23: [2, 33], 33: [2, 33], 54: [2, 33], 65: [2, 33], 68: [2, 33], 72: [2, 33], 75: [2, 33], 80: [2, 33], 81: [2, 33], 82: [2, 33], 83: [2, 33], 84: [2, 33], 85: [2, 33] }, { 23: [2, 34], 33: [2, 34], 54: [2, 34], 65: [2, 34], 68: [2, 34], 72: [2, 34], 75: [2, 34], 80: [2, 34], 81: [2, 34], 82: [2, 34], 83: [2, 34], 84: [2, 34], 85: [2, 34] }, { 23: [2, 35], 33: [2, 35], 54: [2, 35], 65: [2, 35], 68: [2, 35], 72: [2, 35], 75: [2, 35], 80: [2, 35], 81: [2, 35], 82: [2, 35], 83: [2, 35], 84: [2, 35], 85: [2, 35] }, { 23: [2, 36], 33: [2, 36], 54: [2, 36], 65: [2, 36], 68: [2, 36], 72: [2, 36], 75: [2, 36], 80: [2, 36], 81: [2, 36], 82: [2, 36], 83: [2, 36], 84: [2, 36], 85: [2, 36] }, { 23: [2, 37], 33: [2, 37], 54: [2, 37], 65: [2, 37], 68: [2, 37], 72: [2, 37], 75: [2, 37], 80: [2, 37], 81: [2, 37], 82: [2, 37], 83: [2, 37], 84: [2, 37], 85: [2, 37] }, { 23: [2, 38], 33: [2, 38], 54: [2, 38], 65: [2, 38], 68: [2, 38], 72: [2, 38], 75: [2, 38], 80: [2, 38], 81: [2, 38], 82: [2, 38], 83: [2, 38], 84: [2, 38], 85: [2, 38] }, { 23: [2, 39], 33: [2, 39], 54: [2, 39], 65: [2, 39], 68: [2, 39], 72: [2, 39], 75: [2, 39], 80: [2, 39], 81: [2, 39], 82: [2, 39], 83: [2, 39], 84: [2, 39], 85: [2, 39] }, { 23: [2, 43], 33: [2, 43], 54: [2, 43], 65: [2, 43], 68: [2, 43], 72: [2, 43], 75: [2, 43], 80: [2, 43], 81: [2, 43], 82: [2, 43], 83: [2, 43], 84: [2, 43], 85: [2, 43], 87: [1, 51] }, { 72: [1, 35], 86: 52 }, { 23: [2, 45], 33: [2, 45], 54: [2, 45], 65: [2, 45], 68: [2, 45], 72: [2, 45], 75: [2, 45], 80: [2, 45], 81: [2, 45], 82: [2, 45], 83: [2, 45], 84: [2, 45], 85: [2, 45], 87: [2, 45] }, { 52: 53, 54: [2, 82], 65: [2, 82], 72: [2, 82], 80: [2, 82], 81: [2, 82], 82: [2, 82], 83: [2, 82], 84: [2, 82], 85: [2, 82] }, { 25: 54, 38: 56, 39: [1, 58], 43: 57, 44: [1, 59], 45: 55, 47: [2, 54] }, { 28: 60, 43: 61, 44: [1, 59], 47: [2, 56] }, { 13: 63, 15: [1, 20], 18: [1, 62] }, { 15: [2, 48], 18: [2, 48] }, { 33: [2, 86], 57: 64, 65: [2, 86], 72: [2, 86], 80: [2, 86], 81: [2, 86], 82: [2, 86], 83: [2, 86], 84: [2, 86], 85: [2, 86] }, { 33: [2, 40], 65: [2, 40], 72: [2, 40], 80: [2, 40], 81: [2, 40], 82: [2, 40], 83: [2, 40], 84: [2, 40], 85: [2, 40] }, { 33: [2, 41], 65: [2, 41], 72: [2, 41], 80: [2, 41], 81: [2, 41], 82: [2, 41], 83: [2, 41], 84: [2, 41], 85: [2, 41] }, { 20: 65, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 26: 66, 47: [1, 67] }, { 30: 68, 33: [2, 58], 65: [2, 58], 72: [2, 58], 75: [2, 58], 80: [2, 58], 81: [2, 58], 82: [2, 58], 83: [2, 58], 84: [2, 58], 85: [2, 58] }, { 33: [2, 64], 35: 69, 65: [2, 64], 72: [2, 64], 75: [2, 64], 80: [2, 64], 81: [2, 64], 82: [2, 64], 83: [2, 64], 84: [2, 64], 85: [2, 64] }, { 21: 70, 23: [2, 50], 65: [2, 50], 72: [2, 50], 80: [2, 50], 81: [2, 50], 82: [2, 50], 83: [2, 50], 84: [2, 50], 85: [2, 50] }, { 33: [2, 90], 61: 71, 65: [2, 90], 72: [2, 90], 80: [2, 90], 81: [2, 90], 82: [2, 90], 83: [2, 90], 84: [2, 90], 85: [2, 90] }, { 20: 75, 33: [2, 80], 50: 72, 63: 73, 64: 76, 65: [1, 44], 69: 74, 70: 77, 71: 78, 72: [1, 79], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 72: [1, 80] }, { 23: [2, 42], 33: [2, 42], 54: [2, 42], 65: [2, 42], 68: [2, 42], 72: [2, 42], 75: [2, 42], 80: [2, 42], 81: [2, 42], 82: [2, 42], 83: [2, 42], 84: [2, 42], 85: [2, 42], 87: [1, 51] }, { 20: 75, 53: 81, 54: [2, 84], 63: 82, 64: 76, 65: [1, 44], 69: 83, 70: 77, 71: 78, 72: [1, 79], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 26: 84, 47: [1, 67] }, { 47: [2, 55] }, { 4: 85, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 39: [2, 46], 44: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 47: [2, 20] }, { 20: 86, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 4: 87, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 26: 88, 47: [1, 67] }, { 47: [2, 57] }, { 5: [2, 11], 14: [2, 11], 15: [2, 11], 19: [2, 11], 29: [2, 11], 34: [2, 11], 39: [2, 11], 44: [2, 11], 47: [2, 11], 48: [2, 11], 51: [2, 11], 55: [2, 11], 60: [2, 11] }, { 15: [2, 49], 18: [2, 49] }, { 20: 75, 33: [2, 88], 58: 89, 63: 90, 64: 76, 65: [1, 44], 69: 91, 70: 77, 71: 78, 72: [1, 79], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 65: [2, 94], 66: 92, 68: [2, 94], 72: [2, 94], 80: [2, 94], 81: [2, 94], 82: [2, 94], 83: [2, 94], 84: [2, 94], 85: [2, 94] }, { 5: [2, 25], 14: [2, 25], 15: [2, 25], 19: [2, 25], 29: [2, 25], 34: [2, 25], 39: [2, 25], 44: [2, 25], 47: [2, 25], 48: [2, 25], 51: [2, 25], 55: [2, 25], 60: [2, 25] }, { 20: 93, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 75, 31: 94, 33: [2, 60], 63: 95, 64: 76, 65: [1, 44], 69: 96, 70: 77, 71: 78, 72: [1, 79], 75: [2, 60], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 75, 33: [2, 66], 36: 97, 63: 98, 64: 76, 65: [1, 44], 69: 99, 70: 77, 71: 78, 72: [1, 79], 75: [2, 66], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 75, 22: 100, 23: [2, 52], 63: 101, 64: 76, 65: [1, 44], 69: 102, 70: 77, 71: 78, 72: [1, 79], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 75, 33: [2, 92], 62: 103, 63: 104, 64: 76, 65: [1, 44], 69: 105, 70: 77, 71: 78, 72: [1, 79], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 33: [1, 106] }, { 33: [2, 79], 65: [2, 79], 72: [2, 79], 80: [2, 79], 81: [2, 79], 82: [2, 79], 83: [2, 79], 84: [2, 79], 85: [2, 79] }, { 33: [2, 81] }, { 23: [2, 27], 33: [2, 27], 54: [2, 27], 65: [2, 27], 68: [2, 27], 72: [2, 27], 75: [2, 27], 80: [2, 27], 81: [2, 27], 82: [2, 27], 83: [2, 27], 84: [2, 27], 85: [2, 27] }, { 23: [2, 28], 33: [2, 28], 54: [2, 28], 65: [2, 28], 68: [2, 28], 72: [2, 28], 75: [2, 28], 80: [2, 28], 81: [2, 28], 82: [2, 28], 83: [2, 28], 84: [2, 28], 85: [2, 28] }, { 23: [2, 30], 33: [2, 30], 54: [2, 30], 68: [2, 30], 71: 107, 72: [1, 108], 75: [2, 30] }, { 23: [2, 98], 33: [2, 98], 54: [2, 98], 68: [2, 98], 72: [2, 98], 75: [2, 98] }, { 23: [2, 45], 33: [2, 45], 54: [2, 45], 65: [2, 45], 68: [2, 45], 72: [2, 45], 73: [1, 109], 75: [2, 45], 80: [2, 45], 81: [2, 45], 82: [2, 45], 83: [2, 45], 84: [2, 45], 85: [2, 45], 87: [2, 45] }, { 23: [2, 44], 33: [2, 44], 54: [2, 44], 65: [2, 44], 68: [2, 44], 72: [2, 44], 75: [2, 44], 80: [2, 44], 81: [2, 44], 82: [2, 44], 83: [2, 44], 84: [2, 44], 85: [2, 44], 87: [2, 44] }, { 54: [1, 110] }, { 54: [2, 83], 65: [2, 83], 72: [2, 83], 80: [2, 83], 81: [2, 83], 82: [2, 83], 83: [2, 83], 84: [2, 83], 85: [2, 83] }, { 54: [2, 85] }, { 5: [2, 13], 14: [2, 13], 15: [2, 13], 19: [2, 13], 29: [2, 13], 34: [2, 13], 39: [2, 13], 44: [2, 13], 47: [2, 13], 48: [2, 13], 51: [2, 13], 55: [2, 13], 60: [2, 13] }, { 38: 56, 39: [1, 58], 43: 57, 44: [1, 59], 45: 112, 46: 111, 47: [2, 76] }, { 33: [2, 70], 40: 113, 65: [2, 70], 72: [2, 70], 75: [2, 70], 80: [2, 70], 81: [2, 70], 82: [2, 70], 83: [2, 70], 84: [2, 70], 85: [2, 70] }, { 47: [2, 18] }, { 5: [2, 14], 14: [2, 14], 15: [2, 14], 19: [2, 14], 29: [2, 14], 34: [2, 14], 39: [2, 14], 44: [2, 14], 47: [2, 14], 48: [2, 14], 51: [2, 14], 55: [2, 14], 60: [2, 14] }, { 33: [1, 114] }, { 33: [2, 87], 65: [2, 87], 72: [2, 87], 80: [2, 87], 81: [2, 87], 82: [2, 87], 83: [2, 87], 84: [2, 87], 85: [2, 87] }, { 33: [2, 89] }, { 20: 75, 63: 116, 64: 76, 65: [1, 44], 67: 115, 68: [2, 96], 69: 117, 70: 77, 71: 78, 72: [1, 79], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 33: [1, 118] }, { 32: 119, 33: [2, 62], 74: 120, 75: [1, 121] }, { 33: [2, 59], 65: [2, 59], 72: [2, 59], 75: [2, 59], 80: [2, 59], 81: [2, 59], 82: [2, 59], 83: [2, 59], 84: [2, 59], 85: [2, 59] }, { 33: [2, 61], 75: [2, 61] }, { 33: [2, 68], 37: 122, 74: 123, 75: [1, 121] }, { 33: [2, 65], 65: [2, 65], 72: [2, 65], 75: [2, 65], 80: [2, 65], 81: [2, 65], 82: [2, 65], 83: [2, 65], 84: [2, 65], 85: [2, 65] }, { 33: [2, 67], 75: [2, 67] }, { 23: [1, 124] }, { 23: [2, 51], 65: [2, 51], 72: [2, 51], 80: [2, 51], 81: [2, 51], 82: [2, 51], 83: [2, 51], 84: [2, 51], 85: [2, 51] }, { 23: [2, 53] }, { 33: [1, 125] }, { 33: [2, 91], 65: [2, 91], 72: [2, 91], 80: [2, 91], 81: [2, 91], 82: [2, 91], 83: [2, 91], 84: [2, 91], 85: [2, 91] }, { 33: [2, 93] }, { 5: [2, 22], 14: [2, 22], 15: [2, 22], 19: [2, 22], 29: [2, 22], 34: [2, 22], 39: [2, 22], 44: [2, 22], 47: [2, 22], 48: [2, 22], 51: [2, 22], 55: [2, 22], 60: [2, 22] }, { 23: [2, 99], 33: [2, 99], 54: [2, 99], 68: [2, 99], 72: [2, 99], 75: [2, 99] }, { 73: [1, 109] }, { 20: 75, 63: 126, 64: 76, 65: [1, 44], 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 5: [2, 23], 14: [2, 23], 15: [2, 23], 19: [2, 23], 29: [2, 23], 34: [2, 23], 39: [2, 23], 44: [2, 23], 47: [2, 23], 48: [2, 23], 51: [2, 23], 55: [2, 23], 60: [2, 23] }, { 47: [2, 19] }, { 47: [2, 77] }, { 20: 75, 33: [2, 72], 41: 127, 63: 128, 64: 76, 65: [1, 44], 69: 129, 70: 77, 71: 78, 72: [1, 79], 75: [2, 72], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 5: [2, 24], 14: [2, 24], 15: [2, 24], 19: [2, 24], 29: [2, 24], 34: [2, 24], 39: [2, 24], 44: [2, 24], 47: [2, 24], 48: [2, 24], 51: [2, 24], 55: [2, 24], 60: [2, 24] }, { 68: [1, 130] }, { 65: [2, 95], 68: [2, 95], 72: [2, 95], 80: [2, 95], 81: [2, 95], 82: [2, 95], 83: [2, 95], 84: [2, 95], 85: [2, 95] }, { 68: [2, 97] }, { 5: [2, 21], 14: [2, 21], 15: [2, 21], 19: [2, 21], 29: [2, 21], 34: [2, 21], 39: [2, 21], 44: [2, 21], 47: [2, 21], 48: [2, 21], 51: [2, 21], 55: [2, 21], 60: [2, 21] }, { 33: [1, 131] }, { 33: [2, 63] }, { 72: [1, 133], 76: 132 }, { 33: [1, 134] }, { 33: [2, 69] }, { 15: [2, 12] }, { 14: [2, 26], 15: [2, 26], 19: [2, 26], 29: [2, 26], 34: [2, 26], 47: [2, 26], 48: [2, 26], 51: [2, 26], 55: [2, 26], 60: [2, 26] }, { 23: [2, 31], 33: [2, 31], 54: [2, 31], 68: [2, 31], 72: [2, 31], 75: [2, 31] }, { 33: [2, 74], 42: 135, 74: 136, 75: [1, 121] }, { 33: [2, 71], 65: [2, 71], 72: [2, 71], 75: [2, 71], 80: [2, 71], 81: [2, 71], 82: [2, 71], 83: [2, 71], 84: [2, 71], 85: [2, 71] }, { 33: [2, 73], 75: [2, 73] }, { 23: [2, 29], 33: [2, 29], 54: [2, 29], 65: [2, 29], 68: [2, 29], 72: [2, 29], 75: [2, 29], 80: [2, 29], 81: [2, 29], 82: [2, 29], 83: [2, 29], 84: [2, 29], 85: [2, 29] }, { 14: [2, 15], 15: [2, 15], 19: [2, 15], 29: [2, 15], 34: [2, 15], 39: [2, 15], 44: [2, 15], 47: [2, 15], 48: [2, 15], 51: [2, 15], 55: [2, 15], 60: [2, 15] }, { 72: [1, 138], 77: [1, 137] }, { 72: [2, 100], 77: [2, 100] }, { 14: [2, 16], 15: [2, 16], 19: [2, 16], 29: [2, 16], 34: [2, 16], 44: [2, 16], 47: [2, 16], 48: [2, 16], 51: [2, 16], 55: [2, 16], 60: [2, 16] }, { 33: [1, 139] }, { 33: [2, 75] }, { 33: [2, 32] }, { 72: [2, 101], 77: [2, 101] }, { 14: [2, 17], 15: [2, 17], 19: [2, 17], 29: [2, 17], 34: [2, 17], 39: [2, 17], 44: [2, 17], 47: [2, 17], 48: [2, 17], 51: [2, 17], 55: [2, 17], 60: [2, 17] }],
1656
+ defaultActions: { 4: [2, 1], 55: [2, 55], 57: [2, 20], 61: [2, 57], 74: [2, 81], 83: [2, 85], 87: [2, 18], 91: [2, 89], 102: [2, 53], 105: [2, 93], 111: [2, 19], 112: [2, 77], 117: [2, 97], 120: [2, 63], 123: [2, 69], 124: [2, 12], 136: [2, 75], 137: [2, 32] },
1657
+ parseError: function parseError(str, hash) {
1658
+ throw new Error(str);
1659
+ },
1660
+ parse: function parse(input) {
1661
+ var self = this,
1662
+ stack = [0],
1663
+ vstack = [null],
1664
+ lstack = [],
1665
+ table = this.table,
1666
+ yytext = "",
1667
+ yylineno = 0,
1668
+ yyleng = 0,
1669
+ recovering = 0,
1670
+ TERROR = 2,
1671
+ EOF = 1;
1672
+ this.lexer.setInput(input);
1673
+ this.lexer.yy = this.yy;
1674
+ this.yy.lexer = this.lexer;
1675
+ this.yy.parser = this;
1676
+ if (typeof this.lexer.yylloc == "undefined") this.lexer.yylloc = {};
1677
+ var yyloc = this.lexer.yylloc;
1678
+ lstack.push(yyloc);
1679
+ var ranges = this.lexer.options && this.lexer.options.ranges;
1680
+ if (typeof this.yy.parseError === "function") this.parseError = this.yy.parseError;
1681
+ function popStack(n) {
1682
+ stack.length = stack.length - 2 * n;
1683
+ vstack.length = vstack.length - n;
1684
+ lstack.length = lstack.length - n;
1685
+ }
1686
+ function lex() {
1687
+ var token;
1688
+ token = self.lexer.lex() || 1;
1689
+ if (typeof token !== "number") {
1690
+ token = self.symbols_[token] || token;
1691
+ }
1692
+ return token;
1693
+ }
1694
+ var symbol,
1695
+ preErrorSymbol,
1696
+ state,
1697
+ action,
1698
+ a,
1699
+ r,
1700
+ yyval = {},
1701
+ p,
1702
+ len,
1703
+ newState,
1704
+ expected;
1705
+ while (true) {
1706
+ state = stack[stack.length - 1];
1707
+ if (this.defaultActions[state]) {
1708
+ action = this.defaultActions[state];
1709
+ } else {
1710
+ if (symbol === null || typeof symbol == "undefined") {
1711
+ symbol = lex();
1712
+ }
1713
+ action = table[state] && table[state][symbol];
1714
+ }
1715
+ if (typeof action === "undefined" || !action.length || !action[0]) {
1716
+ var errStr = "";
1717
+ if (!recovering) {
1718
+ expected = [];
1719
+ for (p in table[state]) if (this.terminals_[p] && p > 2) {
1720
+ expected.push("'" + this.terminals_[p] + "'");
1721
+ }
1722
+ if (this.lexer.showPosition) {
1723
+ errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'";
1724
+ } else {
1725
+ errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1 ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'");
1726
+ }
1727
+ this.parseError(errStr, { text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected });
1728
+ }
1729
+ }
1730
+ if (action[0] instanceof Array && action.length > 1) {
1731
+ throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
1732
+ }
1733
+ switch (action[0]) {
1734
+ case 1:
1735
+ stack.push(symbol);
1736
+ vstack.push(this.lexer.yytext);
1737
+ lstack.push(this.lexer.yylloc);
1738
+ stack.push(action[1]);
1739
+ symbol = null;
1740
+ if (!preErrorSymbol) {
1741
+ yyleng = this.lexer.yyleng;
1742
+ yytext = this.lexer.yytext;
1743
+ yylineno = this.lexer.yylineno;
1744
+ yyloc = this.lexer.yylloc;
1745
+ if (recovering > 0) recovering--;
1746
+ } else {
1747
+ symbol = preErrorSymbol;
1748
+ preErrorSymbol = null;
1749
+ }
1750
+ break;
1751
+ case 2:
1752
+ len = this.productions_[action[1]][1];
1753
+ yyval.$ = vstack[vstack.length - len];
1754
+ yyval._$ = { first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column };
1755
+ if (ranges) {
1756
+ yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]];
1757
+ }
1758
+ r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
1759
+ if (typeof r !== "undefined") {
1760
+ return r;
1761
+ }
1762
+ if (len) {
1763
+ stack = stack.slice(0, -1 * len * 2);
1764
+ vstack = vstack.slice(0, -1 * len);
1765
+ lstack = lstack.slice(0, -1 * len);
1766
+ }
1767
+ stack.push(this.productions_[action[1]][0]);
1768
+ vstack.push(yyval.$);
1769
+ lstack.push(yyval._$);
1770
+ newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
1771
+ stack.push(newState);
1772
+ break;
1773
+ case 3:
1774
+ return true;
1775
+ }
1776
+ }
1777
+ return true;
1778
+ }
1779
+ };
1780
+ /* Jison generated lexer */
1781
+ var lexer = (function () {
1782
+ var lexer = { EOF: 1,
1783
+ parseError: function parseError(str, hash) {
1784
+ if (this.yy.parser) {
1785
+ this.yy.parser.parseError(str, hash);
1786
+ } else {
1787
+ throw new Error(str);
1788
+ }
1789
+ },
1790
+ setInput: function setInput(input) {
1791
+ this._input = input;
1792
+ this._more = this._less = this.done = false;
1793
+ this.yylineno = this.yyleng = 0;
1794
+ this.yytext = this.matched = this.match = '';
1795
+ this.conditionStack = ['INITIAL'];
1796
+ this.yylloc = { first_line: 1, first_column: 0, last_line: 1, last_column: 0 };
1797
+ if (this.options.ranges) this.yylloc.range = [0, 0];
1798
+ this.offset = 0;
1799
+ return this;
1800
+ },
1801
+ input: function input() {
1802
+ var ch = this._input[0];
1803
+ this.yytext += ch;
1804
+ this.yyleng++;
1805
+ this.offset++;
1806
+ this.match += ch;
1807
+ this.matched += ch;
1808
+ var lines = ch.match(/(?:\r\n?|\n).*/g);
1809
+ if (lines) {
1810
+ this.yylineno++;
1811
+ this.yylloc.last_line++;
1812
+ } else {
1813
+ this.yylloc.last_column++;
1814
+ }
1815
+ if (this.options.ranges) this.yylloc.range[1]++;
1816
+
1817
+ this._input = this._input.slice(1);
1818
+ return ch;
1819
+ },
1820
+ unput: function unput(ch) {
1821
+ var len = ch.length;
1822
+ var lines = ch.split(/(?:\r\n?|\n)/g);
1823
+
1824
+ this._input = ch + this._input;
1825
+ this.yytext = this.yytext.substr(0, this.yytext.length - len - 1);
1826
+ //this.yyleng -= len;
1827
+ this.offset -= len;
1828
+ var oldLines = this.match.split(/(?:\r\n?|\n)/g);
1829
+ this.match = this.match.substr(0, this.match.length - 1);
1830
+ this.matched = this.matched.substr(0, this.matched.length - 1);
1831
+
1832
+ if (lines.length - 1) this.yylineno -= lines.length - 1;
1833
+ var r = this.yylloc.range;
1834
+
1835
+ this.yylloc = { first_line: this.yylloc.first_line,
1836
+ last_line: this.yylineno + 1,
1837
+ first_column: this.yylloc.first_column,
1838
+ last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len
1839
+ };
1840
+
1841
+ if (this.options.ranges) {
1842
+ this.yylloc.range = [r[0], r[0] + this.yyleng - len];
1843
+ }
1844
+ return this;
1845
+ },
1846
+ more: function more() {
1847
+ this._more = true;
1848
+ return this;
1849
+ },
1850
+ less: function less(n) {
1851
+ this.unput(this.match.slice(n));
1852
+ },
1853
+ pastInput: function pastInput() {
1854
+ var past = this.matched.substr(0, this.matched.length - this.match.length);
1855
+ return (past.length > 20 ? '...' : '') + past.substr(-20).replace(/\n/g, "");
1856
+ },
1857
+ upcomingInput: function upcomingInput() {
1858
+ var next = this.match;
1859
+ if (next.length < 20) {
1860
+ next += this._input.substr(0, 20 - next.length);
1861
+ }
1862
+ return (next.substr(0, 20) + (next.length > 20 ? '...' : '')).replace(/\n/g, "");
1863
+ },
1864
+ showPosition: function showPosition() {
1865
+ var pre = this.pastInput();
1866
+ var c = new Array(pre.length + 1).join("-");
1867
+ return pre + this.upcomingInput() + "\n" + c + "^";
1868
+ },
1869
+ next: function next() {
1870
+ if (this.done) {
1871
+ return this.EOF;
1872
+ }
1873
+ if (!this._input) this.done = true;
1874
+
1875
+ var token, match, tempMatch, index, col, lines;
1876
+ if (!this._more) {
1877
+ this.yytext = '';
1878
+ this.match = '';
1879
+ }
1880
+ var rules = this._currentRules();
1881
+ for (var i = 0; i < rules.length; i++) {
1882
+ tempMatch = this._input.match(this.rules[rules[i]]);
1883
+ if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
1884
+ match = tempMatch;
1885
+ index = i;
1886
+ if (!this.options.flex) break;
1887
+ }
1888
+ }
1889
+ if (match) {
1890
+ lines = match[0].match(/(?:\r\n?|\n).*/g);
1891
+ if (lines) this.yylineno += lines.length;
1892
+ this.yylloc = { first_line: this.yylloc.last_line,
1893
+ last_line: this.yylineno + 1,
1894
+ first_column: this.yylloc.last_column,
1895
+ last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length };
1896
+ this.yytext += match[0];
1897
+ this.match += match[0];
1898
+ this.matches = match;
1899
+ this.yyleng = this.yytext.length;
1900
+ if (this.options.ranges) {
1901
+ this.yylloc.range = [this.offset, this.offset += this.yyleng];
1902
+ }
1903
+ this._more = false;
1904
+ this._input = this._input.slice(match[0].length);
1905
+ this.matched += match[0];
1906
+ token = this.performAction.call(this, this.yy, this, rules[index], this.conditionStack[this.conditionStack.length - 1]);
1907
+ if (this.done && this._input) this.done = false;
1908
+ if (token) return token;else return;
1909
+ }
1910
+ if (this._input === "") {
1911
+ return this.EOF;
1912
+ } else {
1913
+ return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), { text: "", token: null, line: this.yylineno });
1914
+ }
1915
+ },
1916
+ lex: function lex() {
1917
+ var r = this.next();
1918
+ if (typeof r !== 'undefined') {
1919
+ return r;
1920
+ } else {
1921
+ return this.lex();
1922
+ }
1923
+ },
1924
+ begin: function begin(condition) {
1925
+ this.conditionStack.push(condition);
1926
+ },
1927
+ popState: function popState() {
1928
+ return this.conditionStack.pop();
1929
+ },
1930
+ _currentRules: function _currentRules() {
1931
+ return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;
1932
+ },
1933
+ topState: function topState() {
1934
+ return this.conditionStack[this.conditionStack.length - 2];
1935
+ },
1936
+ pushState: function begin(condition) {
1937
+ this.begin(condition);
1938
+ } };
1939
+ lexer.options = {};
1940
+ lexer.performAction = function anonymous(yy, yy_, $avoiding_name_collisions, YY_START
1941
+ /**/) {
1942
+
1943
+ function strip(start, end) {
1944
+ return yy_.yytext = yy_.yytext.substr(start, yy_.yyleng - end);
1945
+ }
1946
+
1947
+ var YYSTATE = YY_START;
1948
+ switch ($avoiding_name_collisions) {
1949
+ case 0:
1950
+ if (yy_.yytext.slice(-2) === "\\\\") {
1951
+ strip(0, 1);
1952
+ this.begin("mu");
1953
+ } else if (yy_.yytext.slice(-1) === "\\") {
1954
+ strip(0, 1);
1955
+ this.begin("emu");
1956
+ } else {
1957
+ this.begin("mu");
1958
+ }
1959
+ if (yy_.yytext) return 15;
1960
+
1961
+ break;
1962
+ case 1:
1963
+ return 15;
1964
+ break;
1965
+ case 2:
1966
+ this.popState();
1967
+ return 15;
1968
+
1969
+ break;
1970
+ case 3:
1971
+ this.begin('raw');return 15;
1972
+ break;
1973
+ case 4:
1974
+ this.popState();
1975
+ // Should be using `this.topState()` below, but it currently
1976
+ // returns the second top instead of the first top. Opened an
1977
+ // issue about it at https://github.com/zaach/jison/issues/291
1978
+ if (this.conditionStack[this.conditionStack.length - 1] === 'raw') {
1979
+ return 15;
1980
+ } else {
1981
+ yy_.yytext = yy_.yytext.substr(5, yy_.yyleng - 9);
1982
+ return 'END_RAW_BLOCK';
1983
+ }
1984
+
1985
+ break;
1986
+ case 5:
1987
+ return 15;
1988
+ break;
1989
+ case 6:
1990
+ this.popState();
1991
+ return 14;
1992
+
1993
+ break;
1994
+ case 7:
1995
+ return 65;
1996
+ break;
1997
+ case 8:
1998
+ return 68;
1999
+ break;
2000
+ case 9:
2001
+ return 19;
2002
+ break;
2003
+ case 10:
2004
+ this.popState();
2005
+ this.begin('raw');
2006
+ return 23;
2007
+
2008
+ break;
2009
+ case 11:
2010
+ return 55;
2011
+ break;
2012
+ case 12:
2013
+ return 60;
2014
+ break;
2015
+ case 13:
2016
+ return 29;
2017
+ break;
2018
+ case 14:
2019
+ return 47;
2020
+ break;
2021
+ case 15:
2022
+ this.popState();return 44;
2023
+ break;
2024
+ case 16:
2025
+ this.popState();return 44;
2026
+ break;
2027
+ case 17:
2028
+ return 34;
2029
+ break;
2030
+ case 18:
2031
+ return 39;
2032
+ break;
2033
+ case 19:
2034
+ return 51;
2035
+ break;
2036
+ case 20:
2037
+ return 48;
2038
+ break;
2039
+ case 21:
2040
+ this.unput(yy_.yytext);
2041
+ this.popState();
2042
+ this.begin('com');
2043
+
2044
+ break;
2045
+ case 22:
2046
+ this.popState();
2047
+ return 14;
2048
+
2049
+ break;
2050
+ case 23:
2051
+ return 48;
2052
+ break;
2053
+ case 24:
2054
+ return 73;
2055
+ break;
2056
+ case 25:
2057
+ return 72;
2058
+ break;
2059
+ case 26:
2060
+ return 72;
2061
+ break;
2062
+ case 27:
2063
+ return 87;
2064
+ break;
2065
+ case 28:
2066
+ // ignore whitespace
2067
+ break;
2068
+ case 29:
2069
+ this.popState();return 54;
2070
+ break;
2071
+ case 30:
2072
+ this.popState();return 33;
2073
+ break;
2074
+ case 31:
2075
+ yy_.yytext = strip(1, 2).replace(/\\"/g, '"');return 80;
2076
+ break;
2077
+ case 32:
2078
+ yy_.yytext = strip(1, 2).replace(/\\'/g, "'");return 80;
2079
+ break;
2080
+ case 33:
2081
+ return 85;
2082
+ break;
2083
+ case 34:
2084
+ return 82;
2085
+ break;
2086
+ case 35:
2087
+ return 82;
2088
+ break;
2089
+ case 36:
2090
+ return 83;
2091
+ break;
2092
+ case 37:
2093
+ return 84;
2094
+ break;
2095
+ case 38:
2096
+ return 81;
2097
+ break;
2098
+ case 39:
2099
+ return 75;
2100
+ break;
2101
+ case 40:
2102
+ return 77;
2103
+ break;
2104
+ case 41:
2105
+ return 72;
2106
+ break;
2107
+ case 42:
2108
+ yy_.yytext = yy_.yytext.replace(/\\([\\\]])/g, '$1');return 72;
2109
+ break;
2110
+ case 43:
2111
+ return 'INVALID';
2112
+ break;
2113
+ case 44:
2114
+ return 5;
2115
+ break;
2116
+ }
2117
+ };
2118
+ lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/, /^(?:[^\x00]+)/, /^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/, /^(?:\{\{\{\{(?=[^/]))/, /^(?:\{\{\{\{\/[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.])\}\}\}\})/, /^(?:[^\x00]*?(?=(\{\{\{\{)))/, /^(?:[\s\S]*?--(~)?\}\})/, /^(?:\()/, /^(?:\))/, /^(?:\{\{\{\{)/, /^(?:\}\}\}\})/, /^(?:\{\{(~)?>)/, /^(?:\{\{(~)?#>)/, /^(?:\{\{(~)?#\*?)/, /^(?:\{\{(~)?\/)/, /^(?:\{\{(~)?\^\s*(~)?\}\})/, /^(?:\{\{(~)?\s*else\s*(~)?\}\})/, /^(?:\{\{(~)?\^)/, /^(?:\{\{(~)?\s*else\b)/, /^(?:\{\{(~)?\{)/, /^(?:\{\{(~)?&)/, /^(?:\{\{(~)?!--)/, /^(?:\{\{(~)?![\s\S]*?\}\})/, /^(?:\{\{(~)?\*?)/, /^(?:=)/, /^(?:\.\.)/, /^(?:\.(?=([=~}\s\/.)|])))/, /^(?:[\/.])/, /^(?:\s+)/, /^(?:\}(~)?\}\})/, /^(?:(~)?\}\})/, /^(?:"(\\["]|[^"])*")/, /^(?:'(\\[']|[^'])*')/, /^(?:@)/, /^(?:true(?=([~}\s)])))/, /^(?:false(?=([~}\s)])))/, /^(?:undefined(?=([~}\s)])))/, /^(?:null(?=([~}\s)])))/, /^(?:-?[0-9]+(?:\.[0-9]+)?(?=([~}\s)])))/, /^(?:as\s+\|)/, /^(?:\|)/, /^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)|]))))/, /^(?:\[(\\\]|[^\]])*\])/, /^(?:.)/, /^(?:$)/];
2119
+ lexer.conditions = { "mu": { "rules": [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44], "inclusive": false }, "emu": { "rules": [2], "inclusive": false }, "com": { "rules": [6], "inclusive": false }, "raw": { "rules": [3, 4, 5], "inclusive": false }, "INITIAL": { "rules": [0, 1, 44], "inclusive": true } };
2120
+ return lexer;
2121
+ })();
2122
+ parser.lexer = lexer;
2123
+ function Parser() {
2124
+ this.yy = {};
2125
+ }Parser.prototype = parser;parser.Parser = Parser;
2126
+ return new Parser();
2127
+ })();exports.__esModule = true;
2128
+ exports['default'] = handlebars;
2129
+
2130
+ /***/ },
2131
+ /* 24 */
2132
+ /***/ function(module, exports, __webpack_require__) {
2133
+
2134
+ 'use strict';
2135
+
2136
+ var _interopRequireDefault = __webpack_require__(1)['default'];
2137
+
2138
+ exports.__esModule = true;
2139
+
2140
+ var _visitor = __webpack_require__(25);
2141
+
2142
+ var _visitor2 = _interopRequireDefault(_visitor);
2143
+
2144
+ function WhitespaceControl() {
2145
+ var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
2146
+
2147
+ this.options = options;
2148
+ }
2149
+ WhitespaceControl.prototype = new _visitor2['default']();
2150
+
2151
+ WhitespaceControl.prototype.Program = function (program) {
2152
+ var doStandalone = !this.options.ignoreStandalone;
2153
+
2154
+ var isRoot = !this.isRootSeen;
2155
+ this.isRootSeen = true;
2156
+
2157
+ var body = program.body;
2158
+ for (var i = 0, l = body.length; i < l; i++) {
2159
+ var current = body[i],
2160
+ strip = this.accept(current);
2161
+
2162
+ if (!strip) {
2163
+ continue;
2164
+ }
2165
+
2166
+ var _isPrevWhitespace = isPrevWhitespace(body, i, isRoot),
2167
+ _isNextWhitespace = isNextWhitespace(body, i, isRoot),
2168
+ openStandalone = strip.openStandalone && _isPrevWhitespace,
2169
+ closeStandalone = strip.closeStandalone && _isNextWhitespace,
2170
+ inlineStandalone = strip.inlineStandalone && _isPrevWhitespace && _isNextWhitespace;
2171
+
2172
+ if (strip.close) {
2173
+ omitRight(body, i, true);
2174
+ }
2175
+ if (strip.open) {
2176
+ omitLeft(body, i, true);
2177
+ }
2178
+
2179
+ if (doStandalone && inlineStandalone) {
2180
+ omitRight(body, i);
2181
+
2182
+ if (omitLeft(body, i)) {
2183
+ // If we are on a standalone node, save the indent info for partials
2184
+ if (current.type === 'PartialStatement') {
2185
+ // Pull out the whitespace from the final line
2186
+ current.indent = /([ \t]+$)/.exec(body[i - 1].original)[1];
2187
+ }
2188
+ }
2189
+ }
2190
+ if (doStandalone && openStandalone) {
2191
+ omitRight((current.program || current.inverse).body);
2192
+
2193
+ // Strip out the previous content node if it's whitespace only
2194
+ omitLeft(body, i);
2195
+ }
2196
+ if (doStandalone && closeStandalone) {
2197
+ // Always strip the next node
2198
+ omitRight(body, i);
2199
+
2200
+ omitLeft((current.inverse || current.program).body);
2201
+ }
2202
+ }
2203
+
2204
+ return program;
2205
+ };
2206
+
2207
+ WhitespaceControl.prototype.BlockStatement = WhitespaceControl.prototype.DecoratorBlock = WhitespaceControl.prototype.PartialBlockStatement = function (block) {
2208
+ this.accept(block.program);
2209
+ this.accept(block.inverse);
2210
+
2211
+ // Find the inverse program that is involed with whitespace stripping.
2212
+ var program = block.program || block.inverse,
2213
+ inverse = block.program && block.inverse,
2214
+ firstInverse = inverse,
2215
+ lastInverse = inverse;
2216
+
2217
+ if (inverse && inverse.chained) {
2218
+ firstInverse = inverse.body[0].program;
2219
+
2220
+ // Walk the inverse chain to find the last inverse that is actually in the chain.
2221
+ while (lastInverse.chained) {
2222
+ lastInverse = lastInverse.body[lastInverse.body.length - 1].program;
2223
+ }
2224
+ }
2225
+
2226
+ var strip = {
2227
+ open: block.openStrip.open,
2228
+ close: block.closeStrip.close,
2229
+
2230
+ // Determine the standalone candiacy. Basically flag our content as being possibly standalone
2231
+ // so our parent can determine if we actually are standalone
2232
+ openStandalone: isNextWhitespace(program.body),
2233
+ closeStandalone: isPrevWhitespace((firstInverse || program).body)
2234
+ };
2235
+
2236
+ if (block.openStrip.close) {
2237
+ omitRight(program.body, null, true);
2238
+ }
2239
+
2240
+ if (inverse) {
2241
+ var inverseStrip = block.inverseStrip;
2242
+
2243
+ if (inverseStrip.open) {
2244
+ omitLeft(program.body, null, true);
2245
+ }
2246
+
2247
+ if (inverseStrip.close) {
2248
+ omitRight(firstInverse.body, null, true);
2249
+ }
2250
+ if (block.closeStrip.open) {
2251
+ omitLeft(lastInverse.body, null, true);
2252
+ }
2253
+
2254
+ // Find standalone else statments
2255
+ if (!this.options.ignoreStandalone && isPrevWhitespace(program.body) && isNextWhitespace(firstInverse.body)) {
2256
+ omitLeft(program.body);
2257
+ omitRight(firstInverse.body);
2258
+ }
2259
+ } else if (block.closeStrip.open) {
2260
+ omitLeft(program.body, null, true);
2261
+ }
2262
+
2263
+ return strip;
2264
+ };
2265
+
2266
+ WhitespaceControl.prototype.Decorator = WhitespaceControl.prototype.MustacheStatement = function (mustache) {
2267
+ return mustache.strip;
2268
+ };
2269
+
2270
+ WhitespaceControl.prototype.PartialStatement = WhitespaceControl.prototype.CommentStatement = function (node) {
2271
+ /* istanbul ignore next */
2272
+ var strip = node.strip || {};
2273
+ return {
2274
+ inlineStandalone: true,
2275
+ open: strip.open,
2276
+ close: strip.close
2277
+ };
2278
+ };
2279
+
2280
+ function isPrevWhitespace(body, i, isRoot) {
2281
+ if (i === undefined) {
2282
+ i = body.length;
2283
+ }
2284
+
2285
+ // Nodes that end with newlines are considered whitespace (but are special
2286
+ // cased for strip operations)
2287
+ var prev = body[i - 1],
2288
+ sibling = body[i - 2];
2289
+ if (!prev) {
2290
+ return isRoot;
2291
+ }
2292
+
2293
+ if (prev.type === 'ContentStatement') {
2294
+ return (sibling || !isRoot ? /\r?\n\s*?$/ : /(^|\r?\n)\s*?$/).test(prev.original);
2295
+ }
2296
+ }
2297
+ function isNextWhitespace(body, i, isRoot) {
2298
+ if (i === undefined) {
2299
+ i = -1;
2300
+ }
2301
+
2302
+ var next = body[i + 1],
2303
+ sibling = body[i + 2];
2304
+ if (!next) {
2305
+ return isRoot;
2306
+ }
2307
+
2308
+ if (next.type === 'ContentStatement') {
2309
+ return (sibling || !isRoot ? /^\s*?\r?\n/ : /^\s*?(\r?\n|$)/).test(next.original);
2310
+ }
2311
+ }
2312
+
2313
+ // Marks the node to the right of the position as omitted.
2314
+ // I.e. {{foo}}' ' will mark the ' ' node as omitted.
2315
+ //
2316
+ // If i is undefined, then the first child will be marked as such.
2317
+ //
2318
+ // If mulitple is truthy then all whitespace will be stripped out until non-whitespace
2319
+ // content is met.
2320
+ function omitRight(body, i, multiple) {
2321
+ var current = body[i == null ? 0 : i + 1];
2322
+ if (!current || current.type !== 'ContentStatement' || !multiple && current.rightStripped) {
2323
+ return;
2324
+ }
2325
+
2326
+ var original = current.value;
2327
+ current.value = current.value.replace(multiple ? /^\s+/ : /^[ \t]*\r?\n?/, '');
2328
+ current.rightStripped = current.value !== original;
2329
+ }
2330
+
2331
+ // Marks the node to the left of the position as omitted.
2332
+ // I.e. ' '{{foo}} will mark the ' ' node as omitted.
2333
+ //
2334
+ // If i is undefined then the last child will be marked as such.
2335
+ //
2336
+ // If mulitple is truthy then all whitespace will be stripped out until non-whitespace
2337
+ // content is met.
2338
+ function omitLeft(body, i, multiple) {
2339
+ var current = body[i == null ? body.length - 1 : i - 1];
2340
+ if (!current || current.type !== 'ContentStatement' || !multiple && current.leftStripped) {
2341
+ return;
2342
+ }
2343
+
2344
+ // We omit the last node if it's whitespace only and not preceeded by a non-content node.
2345
+ var original = current.value;
2346
+ current.value = current.value.replace(multiple ? /\s+$/ : /[ \t]+$/, '');
2347
+ current.leftStripped = current.value !== original;
2348
+ return current.leftStripped;
2349
+ }
2350
+
2351
+ exports['default'] = WhitespaceControl;
2352
+ module.exports = exports['default'];
2353
+
2354
+ /***/ },
2355
+ /* 25 */
2356
+ /***/ function(module, exports, __webpack_require__) {
2357
+
2358
+ 'use strict';
2359
+
2360
+ var _interopRequireDefault = __webpack_require__(1)['default'];
2361
+
2362
+ exports.__esModule = true;
2363
+
2364
+ var _exception = __webpack_require__(6);
2365
+
2366
+ var _exception2 = _interopRequireDefault(_exception);
2367
+
2368
+ function Visitor() {
2369
+ this.parents = [];
2370
+ }
2371
+
2372
+ Visitor.prototype = {
2373
+ constructor: Visitor,
2374
+ mutating: false,
2375
+
2376
+ // Visits a given value. If mutating, will replace the value if necessary.
2377
+ acceptKey: function acceptKey(node, name) {
2378
+ var value = this.accept(node[name]);
2379
+ if (this.mutating) {
2380
+ // Hacky sanity check: This may have a few false positives for type for the helper
2381
+ // methods but will generally do the right thing without a lot of overhead.
2382
+ if (value && !Visitor.prototype[value.type]) {
2383
+ throw new _exception2['default']('Unexpected node type "' + value.type + '" found when accepting ' + name + ' on ' + node.type);
2384
+ }
2385
+ node[name] = value;
2386
+ }
2387
+ },
2388
+
2389
+ // Performs an accept operation with added sanity check to ensure
2390
+ // required keys are not removed.
2391
+ acceptRequired: function acceptRequired(node, name) {
2392
+ this.acceptKey(node, name);
2393
+
2394
+ if (!node[name]) {
2395
+ throw new _exception2['default'](node.type + ' requires ' + name);
2396
+ }
2397
+ },
2398
+
2399
+ // Traverses a given array. If mutating, empty respnses will be removed
2400
+ // for child elements.
2401
+ acceptArray: function acceptArray(array) {
2402
+ for (var i = 0, l = array.length; i < l; i++) {
2403
+ this.acceptKey(array, i);
2404
+
2405
+ if (!array[i]) {
2406
+ array.splice(i, 1);
2407
+ i--;
2408
+ l--;
2409
+ }
2410
+ }
2411
+ },
2412
+
2413
+ accept: function accept(object) {
2414
+ if (!object) {
2415
+ return;
2416
+ }
2417
+
2418
+ /* istanbul ignore next: Sanity code */
2419
+ if (!this[object.type]) {
2420
+ throw new _exception2['default']('Unknown type: ' + object.type, object);
2421
+ }
2422
+
2423
+ if (this.current) {
2424
+ this.parents.unshift(this.current);
2425
+ }
2426
+ this.current = object;
2427
+
2428
+ var ret = this[object.type](object);
2429
+
2430
+ this.current = this.parents.shift();
2431
+
2432
+ if (!this.mutating || ret) {
2433
+ return ret;
2434
+ } else if (ret !== false) {
2435
+ return object;
2436
+ }
2437
+ },
2438
+
2439
+ Program: function Program(program) {
2440
+ this.acceptArray(program.body);
2441
+ },
2442
+
2443
+ MustacheStatement: visitSubExpression,
2444
+ Decorator: visitSubExpression,
2445
+
2446
+ BlockStatement: visitBlock,
2447
+ DecoratorBlock: visitBlock,
2448
+
2449
+ PartialStatement: visitPartial,
2450
+ PartialBlockStatement: function PartialBlockStatement(partial) {
2451
+ visitPartial.call(this, partial);
2452
+
2453
+ this.acceptKey(partial, 'program');
2454
+ },
2455
+
2456
+ ContentStatement: function ContentStatement() /* content */{},
2457
+ CommentStatement: function CommentStatement() /* comment */{},
2458
+
2459
+ SubExpression: visitSubExpression,
2460
+
2461
+ PathExpression: function PathExpression() /* path */{},
2462
+
2463
+ StringLiteral: function StringLiteral() /* string */{},
2464
+ NumberLiteral: function NumberLiteral() /* number */{},
2465
+ BooleanLiteral: function BooleanLiteral() /* bool */{},
2466
+ UndefinedLiteral: function UndefinedLiteral() /* literal */{},
2467
+ NullLiteral: function NullLiteral() /* literal */{},
2468
+
2469
+ Hash: function Hash(hash) {
2470
+ this.acceptArray(hash.pairs);
2471
+ },
2472
+ HashPair: function HashPair(pair) {
2473
+ this.acceptRequired(pair, 'value');
2474
+ }
2475
+ };
2476
+
2477
+ function visitSubExpression(mustache) {
2478
+ this.acceptRequired(mustache, 'path');
2479
+ this.acceptArray(mustache.params);
2480
+ this.acceptKey(mustache, 'hash');
2481
+ }
2482
+ function visitBlock(block) {
2483
+ visitSubExpression.call(this, block);
2484
+
2485
+ this.acceptKey(block, 'program');
2486
+ this.acceptKey(block, 'inverse');
2487
+ }
2488
+ function visitPartial(partial) {
2489
+ this.acceptRequired(partial, 'name');
2490
+ this.acceptArray(partial.params);
2491
+ this.acceptKey(partial, 'hash');
2492
+ }
2493
+
2494
+ exports['default'] = Visitor;
2495
+ module.exports = exports['default'];
2496
+
2497
+ /***/ },
2498
+ /* 26 */
2499
+ /***/ function(module, exports, __webpack_require__) {
2500
+
2501
+ 'use strict';
2502
+
2503
+ var _interopRequireDefault = __webpack_require__(1)['default'];
2504
+
2505
+ exports.__esModule = true;
2506
+ exports.SourceLocation = SourceLocation;
2507
+ exports.id = id;
2508
+ exports.stripFlags = stripFlags;
2509
+ exports.stripComment = stripComment;
2510
+ exports.preparePath = preparePath;
2511
+ exports.prepareMustache = prepareMustache;
2512
+ exports.prepareRawBlock = prepareRawBlock;
2513
+ exports.prepareBlock = prepareBlock;
2514
+ exports.prepareProgram = prepareProgram;
2515
+ exports.preparePartialBlock = preparePartialBlock;
2516
+
2517
+ var _exception = __webpack_require__(6);
2518
+
2519
+ var _exception2 = _interopRequireDefault(_exception);
2520
+
2521
+ function validateClose(open, close) {
2522
+ close = close.path ? close.path.original : close;
2523
+
2524
+ if (open.path.original !== close) {
2525
+ var errorNode = { loc: open.path.loc };
2526
+
2527
+ throw new _exception2['default'](open.path.original + " doesn't match " + close, errorNode);
2528
+ }
2529
+ }
2530
+
2531
+ function SourceLocation(source, locInfo) {
2532
+ this.source = source;
2533
+ this.start = {
2534
+ line: locInfo.first_line,
2535
+ column: locInfo.first_column
2536
+ };
2537
+ this.end = {
2538
+ line: locInfo.last_line,
2539
+ column: locInfo.last_column
2540
+ };
2541
+ }
2542
+
2543
+ function id(token) {
2544
+ if (/^\[.*\]$/.test(token)) {
2545
+ return token.substr(1, token.length - 2);
2546
+ } else {
2547
+ return token;
2548
+ }
2549
+ }
2550
+
2551
+ function stripFlags(open, close) {
2552
+ return {
2553
+ open: open.charAt(2) === '~',
2554
+ close: close.charAt(close.length - 3) === '~'
2555
+ };
2556
+ }
2557
+
2558
+ function stripComment(comment) {
2559
+ return comment.replace(/^\{\{~?\!-?-?/, '').replace(/-?-?~?\}\}$/, '');
2560
+ }
2561
+
2562
+ function preparePath(data, parts, loc) {
2563
+ loc = this.locInfo(loc);
2564
+
2565
+ var original = data ? '@' : '',
2566
+ dig = [],
2567
+ depth = 0,
2568
+ depthString = '';
2569
+
2570
+ for (var i = 0, l = parts.length; i < l; i++) {
2571
+ var part = parts[i].part,
2572
+
2573
+ // If we have [] syntax then we do not treat path references as operators,
2574
+ // i.e. foo.[this] resolves to approximately context.foo['this']
2575
+ isLiteral = parts[i].original !== part;
2576
+ original += (parts[i].separator || '') + part;
2577
+
2578
+ if (!isLiteral && (part === '..' || part === '.' || part === 'this')) {
2579
+ if (dig.length > 0) {
2580
+ throw new _exception2['default']('Invalid path: ' + original, { loc: loc });
2581
+ } else if (part === '..') {
2582
+ depth++;
2583
+ depthString += '../';
2584
+ }
2585
+ } else {
2586
+ dig.push(part);
2587
+ }
2588
+ }
2589
+
2590
+ return {
2591
+ type: 'PathExpression',
2592
+ data: data,
2593
+ depth: depth,
2594
+ parts: dig,
2595
+ original: original,
2596
+ loc: loc
2597
+ };
2598
+ }
2599
+
2600
+ function prepareMustache(path, params, hash, open, strip, locInfo) {
2601
+ // Must use charAt to support IE pre-10
2602
+ var escapeFlag = open.charAt(3) || open.charAt(2),
2603
+ escaped = escapeFlag !== '{' && escapeFlag !== '&';
2604
+
2605
+ var decorator = /\*/.test(open);
2606
+ return {
2607
+ type: decorator ? 'Decorator' : 'MustacheStatement',
2608
+ path: path,
2609
+ params: params,
2610
+ hash: hash,
2611
+ escaped: escaped,
2612
+ strip: strip,
2613
+ loc: this.locInfo(locInfo)
2614
+ };
2615
+ }
2616
+
2617
+ function prepareRawBlock(openRawBlock, contents, close, locInfo) {
2618
+ validateClose(openRawBlock, close);
2619
+
2620
+ locInfo = this.locInfo(locInfo);
2621
+ var program = {
2622
+ type: 'Program',
2623
+ body: contents,
2624
+ strip: {},
2625
+ loc: locInfo
2626
+ };
2627
+
2628
+ return {
2629
+ type: 'BlockStatement',
2630
+ path: openRawBlock.path,
2631
+ params: openRawBlock.params,
2632
+ hash: openRawBlock.hash,
2633
+ program: program,
2634
+ openStrip: {},
2635
+ inverseStrip: {},
2636
+ closeStrip: {},
2637
+ loc: locInfo
2638
+ };
2639
+ }
2640
+
2641
+ function prepareBlock(openBlock, program, inverseAndProgram, close, inverted, locInfo) {
2642
+ if (close && close.path) {
2643
+ validateClose(openBlock, close);
2644
+ }
2645
+
2646
+ var decorator = /\*/.test(openBlock.open);
2647
+
2648
+ program.blockParams = openBlock.blockParams;
2649
+
2650
+ var inverse = undefined,
2651
+ inverseStrip = undefined;
2652
+
2653
+ if (inverseAndProgram) {
2654
+ if (decorator) {
2655
+ throw new _exception2['default']('Unexpected inverse block on decorator', inverseAndProgram);
2656
+ }
2657
+
2658
+ if (inverseAndProgram.chain) {
2659
+ inverseAndProgram.program.body[0].closeStrip = close.strip;
2660
+ }
2661
+
2662
+ inverseStrip = inverseAndProgram.strip;
2663
+ inverse = inverseAndProgram.program;
2664
+ }
2665
+
2666
+ if (inverted) {
2667
+ inverted = inverse;
2668
+ inverse = program;
2669
+ program = inverted;
2670
+ }
2671
+
2672
+ return {
2673
+ type: decorator ? 'DecoratorBlock' : 'BlockStatement',
2674
+ path: openBlock.path,
2675
+ params: openBlock.params,
2676
+ hash: openBlock.hash,
2677
+ program: program,
2678
+ inverse: inverse,
2679
+ openStrip: openBlock.strip,
2680
+ inverseStrip: inverseStrip,
2681
+ closeStrip: close && close.strip,
2682
+ loc: this.locInfo(locInfo)
2683
+ };
2684
+ }
2685
+
2686
+ function prepareProgram(statements, loc) {
2687
+ if (!loc && statements.length) {
2688
+ var firstLoc = statements[0].loc,
2689
+ lastLoc = statements[statements.length - 1].loc;
2690
+
2691
+ /* istanbul ignore else */
2692
+ if (firstLoc && lastLoc) {
2693
+ loc = {
2694
+ source: firstLoc.source,
2695
+ start: {
2696
+ line: firstLoc.start.line,
2697
+ column: firstLoc.start.column
2698
+ },
2699
+ end: {
2700
+ line: lastLoc.end.line,
2701
+ column: lastLoc.end.column
2702
+ }
2703
+ };
2704
+ }
2705
+ }
2706
+
2707
+ return {
2708
+ type: 'Program',
2709
+ body: statements,
2710
+ strip: {},
2711
+ loc: loc
2712
+ };
2713
+ }
2714
+
2715
+ function preparePartialBlock(open, program, close, locInfo) {
2716
+ validateClose(open, close);
2717
+
2718
+ return {
2719
+ type: 'PartialBlockStatement',
2720
+ name: open.path,
2721
+ params: open.params,
2722
+ hash: open.hash,
2723
+ program: program,
2724
+ openStrip: open.strip,
2725
+ closeStrip: close && close.strip,
2726
+ loc: this.locInfo(locInfo)
2727
+ };
2728
+ }
2729
+
2730
+ /***/ },
2731
+ /* 27 */
2732
+ /***/ function(module, exports, __webpack_require__) {
2733
+
2734
+ /* eslint-disable new-cap */
2735
+
2736
+ 'use strict';
2737
+
2738
+ var _interopRequireDefault = __webpack_require__(1)['default'];
2739
+
2740
+ exports.__esModule = true;
2741
+ exports.Compiler = Compiler;
2742
+ exports.precompile = precompile;
2743
+ exports.compile = compile;
2744
+
2745
+ var _exception = __webpack_require__(6);
2746
+
2747
+ var _exception2 = _interopRequireDefault(_exception);
2748
+
2749
+ var _utils = __webpack_require__(5);
2750
+
2751
+ var _ast = __webpack_require__(21);
2752
+
2753
+ var _ast2 = _interopRequireDefault(_ast);
2754
+
2755
+ var slice = [].slice;
2756
+
2757
+ function Compiler() {}
2758
+
2759
+ // the foundHelper register will disambiguate helper lookup from finding a
2760
+ // function in a context. This is necessary for mustache compatibility, which
2761
+ // requires that context functions in blocks are evaluated by blockHelperMissing,
2762
+ // and then proceed as if the resulting value was provided to blockHelperMissing.
2763
+
2764
+ Compiler.prototype = {
2765
+ compiler: Compiler,
2766
+
2767
+ equals: function equals(other) {
2768
+ var len = this.opcodes.length;
2769
+ if (other.opcodes.length !== len) {
2770
+ return false;
2771
+ }
2772
+
2773
+ for (var i = 0; i < len; i++) {
2774
+ var opcode = this.opcodes[i],
2775
+ otherOpcode = other.opcodes[i];
2776
+ if (opcode.opcode !== otherOpcode.opcode || !argEquals(opcode.args, otherOpcode.args)) {
2777
+ return false;
2778
+ }
2779
+ }
2780
+
2781
+ // We know that length is the same between the two arrays because they are directly tied
2782
+ // to the opcode behavior above.
2783
+ len = this.children.length;
2784
+ for (var i = 0; i < len; i++) {
2785
+ if (!this.children[i].equals(other.children[i])) {
2786
+ return false;
2787
+ }
2788
+ }
2789
+
2790
+ return true;
2791
+ },
2792
+
2793
+ guid: 0,
2794
+
2795
+ compile: function compile(program, options) {
2796
+ this.sourceNode = [];
2797
+ this.opcodes = [];
2798
+ this.children = [];
2799
+ this.options = options;
2800
+ this.stringParams = options.stringParams;
2801
+ this.trackIds = options.trackIds;
2802
+
2803
+ options.blockParams = options.blockParams || [];
2804
+
2805
+ // These changes will propagate to the other compiler components
2806
+ var knownHelpers = options.knownHelpers;
2807
+ options.knownHelpers = {
2808
+ 'helperMissing': true,
2809
+ 'blockHelperMissing': true,
2810
+ 'each': true,
2811
+ 'if': true,
2812
+ 'unless': true,
2813
+ 'with': true,
2814
+ 'log': true,
2815
+ 'lookup': true
2816
+ };
2817
+ if (knownHelpers) {
2818
+ for (var _name in knownHelpers) {
2819
+ /* istanbul ignore else */
2820
+ if (_name in knownHelpers) {
2821
+ options.knownHelpers[_name] = knownHelpers[_name];
2822
+ }
2823
+ }
2824
+ }
2825
+
2826
+ return this.accept(program);
2827
+ },
2828
+
2829
+ compileProgram: function compileProgram(program) {
2830
+ var childCompiler = new this.compiler(),
2831
+ // eslint-disable-line new-cap
2832
+ result = childCompiler.compile(program, this.options),
2833
+ guid = this.guid++;
2834
+
2835
+ this.usePartial = this.usePartial || result.usePartial;
2836
+
2837
+ this.children[guid] = result;
2838
+ this.useDepths = this.useDepths || result.useDepths;
2839
+
2840
+ return guid;
2841
+ },
2842
+
2843
+ accept: function accept(node) {
2844
+ /* istanbul ignore next: Sanity code */
2845
+ if (!this[node.type]) {
2846
+ throw new _exception2['default']('Unknown type: ' + node.type, node);
2847
+ }
2848
+
2849
+ this.sourceNode.unshift(node);
2850
+ var ret = this[node.type](node);
2851
+ this.sourceNode.shift();
2852
+ return ret;
2853
+ },
2854
+
2855
+ Program: function Program(program) {
2856
+ this.options.blockParams.unshift(program.blockParams);
2857
+
2858
+ var body = program.body,
2859
+ bodyLength = body.length;
2860
+ for (var i = 0; i < bodyLength; i++) {
2861
+ this.accept(body[i]);
2862
+ }
2863
+
2864
+ this.options.blockParams.shift();
2865
+
2866
+ this.isSimple = bodyLength === 1;
2867
+ this.blockParams = program.blockParams ? program.blockParams.length : 0;
2868
+
2869
+ return this;
2870
+ },
2871
+
2872
+ BlockStatement: function BlockStatement(block) {
2873
+ transformLiteralToPath(block);
2874
+
2875
+ var program = block.program,
2876
+ inverse = block.inverse;
2877
+
2878
+ program = program && this.compileProgram(program);
2879
+ inverse = inverse && this.compileProgram(inverse);
2880
+
2881
+ var type = this.classifySexpr(block);
2882
+
2883
+ if (type === 'helper') {
2884
+ this.helperSexpr(block, program, inverse);
2885
+ } else if (type === 'simple') {
2886
+ this.simpleSexpr(block);
2887
+
2888
+ // now that the simple mustache is resolved, we need to
2889
+ // evaluate it by executing `blockHelperMissing`
2890
+ this.opcode('pushProgram', program);
2891
+ this.opcode('pushProgram', inverse);
2892
+ this.opcode('emptyHash');
2893
+ this.opcode('blockValue', block.path.original);
2894
+ } else {
2895
+ this.ambiguousSexpr(block, program, inverse);
2896
+
2897
+ // now that the simple mustache is resolved, we need to
2898
+ // evaluate it by executing `blockHelperMissing`
2899
+ this.opcode('pushProgram', program);
2900
+ this.opcode('pushProgram', inverse);
2901
+ this.opcode('emptyHash');
2902
+ this.opcode('ambiguousBlockValue');
2903
+ }
2904
+
2905
+ this.opcode('append');
2906
+ },
2907
+
2908
+ DecoratorBlock: function DecoratorBlock(decorator) {
2909
+ var program = decorator.program && this.compileProgram(decorator.program);
2910
+ var params = this.setupFullMustacheParams(decorator, program, undefined),
2911
+ path = decorator.path;
2912
+
2913
+ this.useDecorators = true;
2914
+ this.opcode('registerDecorator', params.length, path.original);
2915
+ },
2916
+
2917
+ PartialStatement: function PartialStatement(partial) {
2918
+ this.usePartial = true;
2919
+
2920
+ var program = partial.program;
2921
+ if (program) {
2922
+ program = this.compileProgram(partial.program);
2923
+ }
2924
+
2925
+ var params = partial.params;
2926
+ if (params.length > 1) {
2927
+ throw new _exception2['default']('Unsupported number of partial arguments: ' + params.length, partial);
2928
+ } else if (!params.length) {
2929
+ if (this.options.explicitPartialContext) {
2930
+ this.opcode('pushLiteral', 'undefined');
2931
+ } else {
2932
+ params.push({ type: 'PathExpression', parts: [], depth: 0 });
2933
+ }
2934
+ }
2935
+
2936
+ var partialName = partial.name.original,
2937
+ isDynamic = partial.name.type === 'SubExpression';
2938
+ if (isDynamic) {
2939
+ this.accept(partial.name);
2940
+ }
2941
+
2942
+ this.setupFullMustacheParams(partial, program, undefined, true);
2943
+
2944
+ var indent = partial.indent || '';
2945
+ if (this.options.preventIndent && indent) {
2946
+ this.opcode('appendContent', indent);
2947
+ indent = '';
2948
+ }
2949
+
2950
+ this.opcode('invokePartial', isDynamic, partialName, indent);
2951
+ this.opcode('append');
2952
+ },
2953
+ PartialBlockStatement: function PartialBlockStatement(partialBlock) {
2954
+ this.PartialStatement(partialBlock);
2955
+ },
2956
+
2957
+ MustacheStatement: function MustacheStatement(mustache) {
2958
+ this.SubExpression(mustache);
2959
+
2960
+ if (mustache.escaped && !this.options.noEscape) {
2961
+ this.opcode('appendEscaped');
2962
+ } else {
2963
+ this.opcode('append');
2964
+ }
2965
+ },
2966
+ Decorator: function Decorator(decorator) {
2967
+ this.DecoratorBlock(decorator);
2968
+ },
2969
+
2970
+ ContentStatement: function ContentStatement(content) {
2971
+ if (content.value) {
2972
+ this.opcode('appendContent', content.value);
2973
+ }
2974
+ },
2975
+
2976
+ CommentStatement: function CommentStatement() {},
2977
+
2978
+ SubExpression: function SubExpression(sexpr) {
2979
+ transformLiteralToPath(sexpr);
2980
+ var type = this.classifySexpr(sexpr);
2981
+
2982
+ if (type === 'simple') {
2983
+ this.simpleSexpr(sexpr);
2984
+ } else if (type === 'helper') {
2985
+ this.helperSexpr(sexpr);
2986
+ } else {
2987
+ this.ambiguousSexpr(sexpr);
2988
+ }
2989
+ },
2990
+ ambiguousSexpr: function ambiguousSexpr(sexpr, program, inverse) {
2991
+ var path = sexpr.path,
2992
+ name = path.parts[0],
2993
+ isBlock = program != null || inverse != null;
2994
+
2995
+ this.opcode('getContext', path.depth);
2996
+
2997
+ this.opcode('pushProgram', program);
2998
+ this.opcode('pushProgram', inverse);
2999
+
3000
+ path.strict = true;
3001
+ this.accept(path);
3002
+
3003
+ this.opcode('invokeAmbiguous', name, isBlock);
3004
+ },
3005
+
3006
+ simpleSexpr: function simpleSexpr(sexpr) {
3007
+ var path = sexpr.path;
3008
+ path.strict = true;
3009
+ this.accept(path);
3010
+ this.opcode('resolvePossibleLambda');
3011
+ },
3012
+
3013
+ helperSexpr: function helperSexpr(sexpr, program, inverse) {
3014
+ var params = this.setupFullMustacheParams(sexpr, program, inverse),
3015
+ path = sexpr.path,
3016
+ name = path.parts[0];
3017
+
3018
+ if (this.options.knownHelpers[name]) {
3019
+ this.opcode('invokeKnownHelper', params.length, name);
3020
+ } else if (this.options.knownHelpersOnly) {
3021
+ throw new _exception2['default']('You specified knownHelpersOnly, but used the unknown helper ' + name, sexpr);
3022
+ } else {
3023
+ path.strict = true;
3024
+ path.falsy = true;
3025
+
3026
+ this.accept(path);
3027
+ this.opcode('invokeHelper', params.length, path.original, _ast2['default'].helpers.simpleId(path));
3028
+ }
3029
+ },
3030
+
3031
+ PathExpression: function PathExpression(path) {
3032
+ this.addDepth(path.depth);
3033
+ this.opcode('getContext', path.depth);
3034
+
3035
+ var name = path.parts[0],
3036
+ scoped = _ast2['default'].helpers.scopedId(path),
3037
+ blockParamId = !path.depth && !scoped && this.blockParamIndex(name);
3038
+
3039
+ if (blockParamId) {
3040
+ this.opcode('lookupBlockParam', blockParamId, path.parts);
3041
+ } else if (!name) {
3042
+ // Context reference, i.e. `{{foo .}}` or `{{foo ..}}`
3043
+ this.opcode('pushContext');
3044
+ } else if (path.data) {
3045
+ this.options.data = true;
3046
+ this.opcode('lookupData', path.depth, path.parts, path.strict);
3047
+ } else {
3048
+ this.opcode('lookupOnContext', path.parts, path.falsy, path.strict, scoped);
3049
+ }
3050
+ },
3051
+
3052
+ StringLiteral: function StringLiteral(string) {
3053
+ this.opcode('pushString', string.value);
3054
+ },
3055
+
3056
+ NumberLiteral: function NumberLiteral(number) {
3057
+ this.opcode('pushLiteral', number.value);
3058
+ },
3059
+
3060
+ BooleanLiteral: function BooleanLiteral(bool) {
3061
+ this.opcode('pushLiteral', bool.value);
3062
+ },
3063
+
3064
+ UndefinedLiteral: function UndefinedLiteral() {
3065
+ this.opcode('pushLiteral', 'undefined');
3066
+ },
3067
+
3068
+ NullLiteral: function NullLiteral() {
3069
+ this.opcode('pushLiteral', 'null');
3070
+ },
3071
+
3072
+ Hash: function Hash(hash) {
3073
+ var pairs = hash.pairs,
3074
+ i = 0,
3075
+ l = pairs.length;
3076
+
3077
+ this.opcode('pushHash');
3078
+
3079
+ for (; i < l; i++) {
3080
+ this.pushParam(pairs[i].value);
3081
+ }
3082
+ while (i--) {
3083
+ this.opcode('assignToHash', pairs[i].key);
3084
+ }
3085
+ this.opcode('popHash');
3086
+ },
3087
+
3088
+ // HELPERS
3089
+ opcode: function opcode(name) {
3090
+ this.opcodes.push({ opcode: name, args: slice.call(arguments, 1), loc: this.sourceNode[0].loc });
3091
+ },
3092
+
3093
+ addDepth: function addDepth(depth) {
3094
+ if (!depth) {
3095
+ return;
3096
+ }
3097
+
3098
+ this.useDepths = true;
3099
+ },
3100
+
3101
+ classifySexpr: function classifySexpr(sexpr) {
3102
+ var isSimple = _ast2['default'].helpers.simpleId(sexpr.path);
3103
+
3104
+ var isBlockParam = isSimple && !!this.blockParamIndex(sexpr.path.parts[0]);
3105
+
3106
+ // a mustache is an eligible helper if:
3107
+ // * its id is simple (a single part, not `this` or `..`)
3108
+ var isHelper = !isBlockParam && _ast2['default'].helpers.helperExpression(sexpr);
3109
+
3110
+ // if a mustache is an eligible helper but not a definite
3111
+ // helper, it is ambiguous, and will be resolved in a later
3112
+ // pass or at runtime.
3113
+ var isEligible = !isBlockParam && (isHelper || isSimple);
3114
+
3115
+ // if ambiguous, we can possibly resolve the ambiguity now
3116
+ // An eligible helper is one that does not have a complex path, i.e. `this.foo`, `../foo` etc.
3117
+ if (isEligible && !isHelper) {
3118
+ var _name2 = sexpr.path.parts[0],
3119
+ options = this.options;
3120
+
3121
+ if (options.knownHelpers[_name2]) {
3122
+ isHelper = true;
3123
+ } else if (options.knownHelpersOnly) {
3124
+ isEligible = false;
3125
+ }
3126
+ }
3127
+
3128
+ if (isHelper) {
3129
+ return 'helper';
3130
+ } else if (isEligible) {
3131
+ return 'ambiguous';
3132
+ } else {
3133
+ return 'simple';
3134
+ }
3135
+ },
3136
+
3137
+ pushParams: function pushParams(params) {
3138
+ for (var i = 0, l = params.length; i < l; i++) {
3139
+ this.pushParam(params[i]);
3140
+ }
3141
+ },
3142
+
3143
+ pushParam: function pushParam(val) {
3144
+ var value = val.value != null ? val.value : val.original || '';
3145
+
3146
+ if (this.stringParams) {
3147
+ if (value.replace) {
3148
+ value = value.replace(/^(\.?\.\/)*/g, '').replace(/\//g, '.');
3149
+ }
3150
+
3151
+ if (val.depth) {
3152
+ this.addDepth(val.depth);
3153
+ }
3154
+ this.opcode('getContext', val.depth || 0);
3155
+ this.opcode('pushStringParam', value, val.type);
3156
+
3157
+ if (val.type === 'SubExpression') {
3158
+ // SubExpressions get evaluated and passed in
3159
+ // in string params mode.
3160
+ this.accept(val);
3161
+ }
3162
+ } else {
3163
+ if (this.trackIds) {
3164
+ var blockParamIndex = undefined;
3165
+ if (val.parts && !_ast2['default'].helpers.scopedId(val) && !val.depth) {
3166
+ blockParamIndex = this.blockParamIndex(val.parts[0]);
3167
+ }
3168
+ if (blockParamIndex) {
3169
+ var blockParamChild = val.parts.slice(1).join('.');
3170
+ this.opcode('pushId', 'BlockParam', blockParamIndex, blockParamChild);
3171
+ } else {
3172
+ value = val.original || value;
3173
+ if (value.replace) {
3174
+ value = value.replace(/^this(?:\.|$)/, '').replace(/^\.\//, '').replace(/^\.$/, '');
3175
+ }
3176
+
3177
+ this.opcode('pushId', val.type, value);
3178
+ }
3179
+ }
3180
+ this.accept(val);
3181
+ }
3182
+ },
3183
+
3184
+ setupFullMustacheParams: function setupFullMustacheParams(sexpr, program, inverse, omitEmpty) {
3185
+ var params = sexpr.params;
3186
+ this.pushParams(params);
3187
+
3188
+ this.opcode('pushProgram', program);
3189
+ this.opcode('pushProgram', inverse);
3190
+
3191
+ if (sexpr.hash) {
3192
+ this.accept(sexpr.hash);
3193
+ } else {
3194
+ this.opcode('emptyHash', omitEmpty);
3195
+ }
3196
+
3197
+ return params;
3198
+ },
3199
+
3200
+ blockParamIndex: function blockParamIndex(name) {
3201
+ for (var depth = 0, len = this.options.blockParams.length; depth < len; depth++) {
3202
+ var blockParams = this.options.blockParams[depth],
3203
+ param = blockParams && _utils.indexOf(blockParams, name);
3204
+ if (blockParams && param >= 0) {
3205
+ return [depth, param];
3206
+ }
3207
+ }
3208
+ }
3209
+ };
3210
+
3211
+ function precompile(input, options, env) {
3212
+ if (input == null || typeof input !== 'string' && input.type !== 'Program') {
3213
+ throw new _exception2['default']('You must pass a string or Handlebars AST to Handlebars.precompile. You passed ' + input);
3214
+ }
3215
+
3216
+ options = options || {};
3217
+ if (!('data' in options)) {
3218
+ options.data = true;
3219
+ }
3220
+ if (options.compat) {
3221
+ options.useDepths = true;
3222
+ }
3223
+
3224
+ var ast = env.parse(input, options),
3225
+ environment = new env.Compiler().compile(ast, options);
3226
+ return new env.JavaScriptCompiler().compile(environment, options);
3227
+ }
3228
+
3229
+ function compile(input, options, env) {
3230
+ if (options === undefined) options = {};
3231
+
3232
+ if (input == null || typeof input !== 'string' && input.type !== 'Program') {
3233
+ throw new _exception2['default']('You must pass a string or Handlebars AST to Handlebars.compile. You passed ' + input);
3234
+ }
3235
+
3236
+ if (!('data' in options)) {
3237
+ options.data = true;
3238
+ }
3239
+ if (options.compat) {
3240
+ options.useDepths = true;
3241
+ }
3242
+
3243
+ var compiled = undefined;
3244
+
3245
+ function compileInput() {
3246
+ var ast = env.parse(input, options),
3247
+ environment = new env.Compiler().compile(ast, options),
3248
+ templateSpec = new env.JavaScriptCompiler().compile(environment, options, undefined, true);
3249
+ return env.template(templateSpec);
3250
+ }
3251
+
3252
+ // Template is only compiled on first use and cached after that point.
3253
+ function ret(context, execOptions) {
3254
+ if (!compiled) {
3255
+ compiled = compileInput();
3256
+ }
3257
+ return compiled.call(this, context, execOptions);
3258
+ }
3259
+ ret._setup = function (setupOptions) {
3260
+ if (!compiled) {
3261
+ compiled = compileInput();
3262
+ }
3263
+ return compiled._setup(setupOptions);
3264
+ };
3265
+ ret._child = function (i, data, blockParams, depths) {
3266
+ if (!compiled) {
3267
+ compiled = compileInput();
3268
+ }
3269
+ return compiled._child(i, data, blockParams, depths);
3270
+ };
3271
+ return ret;
3272
+ }
3273
+
3274
+ function argEquals(a, b) {
3275
+ if (a === b) {
3276
+ return true;
3277
+ }
3278
+
3279
+ if (_utils.isArray(a) && _utils.isArray(b) && a.length === b.length) {
3280
+ for (var i = 0; i < a.length; i++) {
3281
+ if (!argEquals(a[i], b[i])) {
3282
+ return false;
3283
+ }
3284
+ }
3285
+ return true;
3286
+ }
3287
+ }
3288
+
3289
+ function transformLiteralToPath(sexpr) {
3290
+ if (!sexpr.path.parts) {
3291
+ var literal = sexpr.path;
3292
+ // Casting to string here to make false and 0 literal values play nicely with the rest
3293
+ // of the system.
3294
+ sexpr.path = {
3295
+ type: 'PathExpression',
3296
+ data: false,
3297
+ depth: 0,
3298
+ parts: [literal.original + ''],
3299
+ original: literal.original + '',
3300
+ loc: literal.loc
3301
+ };
3302
+ }
3303
+ }
3304
+
3305
+ /***/ },
3306
+ /* 28 */
3307
+ /***/ function(module, exports, __webpack_require__) {
3308
+
3309
+ 'use strict';
3310
+
3311
+ var _interopRequireDefault = __webpack_require__(1)['default'];
3312
+
3313
+ exports.__esModule = true;
3314
+
3315
+ var _base = __webpack_require__(4);
3316
+
3317
+ var _exception = __webpack_require__(6);
3318
+
3319
+ var _exception2 = _interopRequireDefault(_exception);
3320
+
3321
+ var _utils = __webpack_require__(5);
3322
+
3323
+ var _codeGen = __webpack_require__(29);
3324
+
3325
+ var _codeGen2 = _interopRequireDefault(_codeGen);
3326
+
3327
+ function Literal(value) {
3328
+ this.value = value;
3329
+ }
3330
+
3331
+ function JavaScriptCompiler() {}
3332
+
3333
+ JavaScriptCompiler.prototype = {
3334
+ // PUBLIC API: You can override these methods in a subclass to provide
3335
+ // alternative compiled forms for name lookup and buffering semantics
3336
+ nameLookup: function nameLookup(parent, name /* , type*/) {
3337
+ if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
3338
+ return [parent, '.', name];
3339
+ } else {
3340
+ return [parent, '[', JSON.stringify(name), ']'];
3341
+ }
3342
+ },
3343
+ depthedLookup: function depthedLookup(name) {
3344
+ return [this.aliasable('container.lookup'), '(depths, "', name, '")'];
3345
+ },
3346
+
3347
+ compilerInfo: function compilerInfo() {
3348
+ var revision = _base.COMPILER_REVISION,
3349
+ versions = _base.REVISION_CHANGES[revision];
3350
+ return [revision, versions];
3351
+ },
3352
+
3353
+ appendToBuffer: function appendToBuffer(source, location, explicit) {
3354
+ // Force a source as this simplifies the merge logic.
3355
+ if (!_utils.isArray(source)) {
3356
+ source = [source];
3357
+ }
3358
+ source = this.source.wrap(source, location);
3359
+
3360
+ if (this.environment.isSimple) {
3361
+ return ['return ', source, ';'];
3362
+ } else if (explicit) {
3363
+ // This is a case where the buffer operation occurs as a child of another
3364
+ // construct, generally braces. We have to explicitly output these buffer
3365
+ // operations to ensure that the emitted code goes in the correct location.
3366
+ return ['buffer += ', source, ';'];
3367
+ } else {
3368
+ source.appendToBuffer = true;
3369
+ return source;
3370
+ }
3371
+ },
3372
+
3373
+ initializeBuffer: function initializeBuffer() {
3374
+ return this.quotedString('');
3375
+ },
3376
+ // END PUBLIC API
3377
+
3378
+ compile: function compile(environment, options, context, asObject) {
3379
+ this.environment = environment;
3380
+ this.options = options;
3381
+ this.stringParams = this.options.stringParams;
3382
+ this.trackIds = this.options.trackIds;
3383
+ this.precompile = !asObject;
3384
+
3385
+ this.name = this.environment.name;
3386
+ this.isChild = !!context;
3387
+ this.context = context || {
3388
+ decorators: [],
3389
+ programs: [],
3390
+ environments: []
3391
+ };
3392
+
3393
+ this.preamble();
3394
+
3395
+ this.stackSlot = 0;
3396
+ this.stackVars = [];
3397
+ this.aliases = {};
3398
+ this.registers = { list: [] };
3399
+ this.hashes = [];
3400
+ this.compileStack = [];
3401
+ this.inlineStack = [];
3402
+ this.blockParams = [];
3403
+
3404
+ this.compileChildren(environment, options);
3405
+
3406
+ this.useDepths = this.useDepths || environment.useDepths || environment.useDecorators || this.options.compat;
3407
+ this.useBlockParams = this.useBlockParams || environment.useBlockParams;
3408
+
3409
+ var opcodes = environment.opcodes,
3410
+ opcode = undefined,
3411
+ firstLoc = undefined,
3412
+ i = undefined,
3413
+ l = undefined;
3414
+
3415
+ for (i = 0, l = opcodes.length; i < l; i++) {
3416
+ opcode = opcodes[i];
3417
+
3418
+ this.source.currentLocation = opcode.loc;
3419
+ firstLoc = firstLoc || opcode.loc;
3420
+ this[opcode.opcode].apply(this, opcode.args);
3421
+ }
3422
+
3423
+ // Flush any trailing content that might be pending.
3424
+ this.source.currentLocation = firstLoc;
3425
+ this.pushSource('');
3426
+
3427
+ /* istanbul ignore next */
3428
+ if (this.stackSlot || this.inlineStack.length || this.compileStack.length) {
3429
+ throw new _exception2['default']('Compile completed with content left on stack');
3430
+ }
3431
+
3432
+ if (!this.decorators.isEmpty()) {
3433
+ this.useDecorators = true;
3434
+
3435
+ this.decorators.prepend('var decorators = container.decorators;\n');
3436
+ this.decorators.push('return fn;');
3437
+
3438
+ if (asObject) {
3439
+ this.decorators = Function.apply(this, ['fn', 'props', 'container', 'depth0', 'data', 'blockParams', 'depths', this.decorators.merge()]);
3440
+ } else {
3441
+ this.decorators.prepend('function(fn, props, container, depth0, data, blockParams, depths) {\n');
3442
+ this.decorators.push('}\n');
3443
+ this.decorators = this.decorators.merge();
3444
+ }
3445
+ } else {
3446
+ this.decorators = undefined;
3447
+ }
3448
+
3449
+ var fn = this.createFunctionContext(asObject);
3450
+ if (!this.isChild) {
3451
+ var ret = {
3452
+ compiler: this.compilerInfo(),
3453
+ main: fn
3454
+ };
3455
+
3456
+ if (this.decorators) {
3457
+ ret.main_d = this.decorators; // eslint-disable-line camelcase
3458
+ ret.useDecorators = true;
3459
+ }
3460
+
3461
+ var _context = this.context;
3462
+ var programs = _context.programs;
3463
+ var decorators = _context.decorators;
3464
+
3465
+ for (i = 0, l = programs.length; i < l; i++) {
3466
+ if (programs[i]) {
3467
+ ret[i] = programs[i];
3468
+ if (decorators[i]) {
3469
+ ret[i + '_d'] = decorators[i];
3470
+ ret.useDecorators = true;
3471
+ }
3472
+ }
3473
+ }
3474
+
3475
+ if (this.environment.usePartial) {
3476
+ ret.usePartial = true;
3477
+ }
3478
+ if (this.options.data) {
3479
+ ret.useData = true;
3480
+ }
3481
+ if (this.useDepths) {
3482
+ ret.useDepths = true;
3483
+ }
3484
+ if (this.useBlockParams) {
3485
+ ret.useBlockParams = true;
3486
+ }
3487
+ if (this.options.compat) {
3488
+ ret.compat = true;
3489
+ }
3490
+
3491
+ if (!asObject) {
3492
+ ret.compiler = JSON.stringify(ret.compiler);
3493
+
3494
+ this.source.currentLocation = { start: { line: 1, column: 0 } };
3495
+ ret = this.objectLiteral(ret);
3496
+
3497
+ if (options.srcName) {
3498
+ ret = ret.toStringWithSourceMap({ file: options.destName });
3499
+ ret.map = ret.map && ret.map.toString();
3500
+ } else {
3501
+ ret = ret.toString();
3502
+ }
3503
+ } else {
3504
+ ret.compilerOptions = this.options;
3505
+ }
3506
+
3507
+ return ret;
3508
+ } else {
3509
+ return fn;
3510
+ }
3511
+ },
3512
+
3513
+ preamble: function preamble() {
3514
+ // track the last context pushed into place to allow skipping the
3515
+ // getContext opcode when it would be a noop
3516
+ this.lastContext = 0;
3517
+ this.source = new _codeGen2['default'](this.options.srcName);
3518
+ this.decorators = new _codeGen2['default'](this.options.srcName);
3519
+ },
3520
+
3521
+ createFunctionContext: function createFunctionContext(asObject) {
3522
+ var varDeclarations = '';
3523
+
3524
+ var locals = this.stackVars.concat(this.registers.list);
3525
+ if (locals.length > 0) {
3526
+ varDeclarations += ', ' + locals.join(', ');
3527
+ }
3528
+
3529
+ // Generate minimizer alias mappings
3530
+ //
3531
+ // When using true SourceNodes, this will update all references to the given alias
3532
+ // as the source nodes are reused in situ. For the non-source node compilation mode,
3533
+ // aliases will not be used, but this case is already being run on the client and
3534
+ // we aren't concern about minimizing the template size.
3535
+ var aliasCount = 0;
3536
+ for (var alias in this.aliases) {
3537
+ // eslint-disable-line guard-for-in
3538
+ var node = this.aliases[alias];
3539
+
3540
+ if (this.aliases.hasOwnProperty(alias) && node.children && node.referenceCount > 1) {
3541
+ varDeclarations += ', alias' + ++aliasCount + '=' + alias;
3542
+ node.children[0] = 'alias' + aliasCount;
3543
+ }
3544
+ }
3545
+
3546
+ var params = ['container', 'depth0', 'helpers', 'partials', 'data'];
3547
+
3548
+ if (this.useBlockParams || this.useDepths) {
3549
+ params.push('blockParams');
3550
+ }
3551
+ if (this.useDepths) {
3552
+ params.push('depths');
3553
+ }
3554
+
3555
+ // Perform a second pass over the output to merge content when possible
3556
+ var source = this.mergeSource(varDeclarations);
3557
+
3558
+ if (asObject) {
3559
+ params.push(source);
3560
+
3561
+ return Function.apply(this, params);
3562
+ } else {
3563
+ return this.source.wrap(['function(', params.join(','), ') {\n ', source, '}']);
3564
+ }
3565
+ },
3566
+ mergeSource: function mergeSource(varDeclarations) {
3567
+ var isSimple = this.environment.isSimple,
3568
+ appendOnly = !this.forceBuffer,
3569
+ appendFirst = undefined,
3570
+ sourceSeen = undefined,
3571
+ bufferStart = undefined,
3572
+ bufferEnd = undefined;
3573
+ this.source.each(function (line) {
3574
+ if (line.appendToBuffer) {
3575
+ if (bufferStart) {
3576
+ line.prepend(' + ');
3577
+ } else {
3578
+ bufferStart = line;
3579
+ }
3580
+ bufferEnd = line;
3581
+ } else {
3582
+ if (bufferStart) {
3583
+ if (!sourceSeen) {
3584
+ appendFirst = true;
3585
+ } else {
3586
+ bufferStart.prepend('buffer += ');
3587
+ }
3588
+ bufferEnd.add(';');
3589
+ bufferStart = bufferEnd = undefined;
3590
+ }
3591
+
3592
+ sourceSeen = true;
3593
+ if (!isSimple) {
3594
+ appendOnly = false;
3595
+ }
3596
+ }
3597
+ });
3598
+
3599
+ if (appendOnly) {
3600
+ if (bufferStart) {
3601
+ bufferStart.prepend('return ');
3602
+ bufferEnd.add(';');
3603
+ } else if (!sourceSeen) {
3604
+ this.source.push('return "";');
3605
+ }
3606
+ } else {
3607
+ varDeclarations += ', buffer = ' + (appendFirst ? '' : this.initializeBuffer());
3608
+
3609
+ if (bufferStart) {
3610
+ bufferStart.prepend('return buffer + ');
3611
+ bufferEnd.add(';');
3612
+ } else {
3613
+ this.source.push('return buffer;');
3614
+ }
3615
+ }
3616
+
3617
+ if (varDeclarations) {
3618
+ this.source.prepend('var ' + varDeclarations.substring(2) + (appendFirst ? '' : ';\n'));
3619
+ }
3620
+
3621
+ return this.source.merge();
3622
+ },
3623
+
3624
+ // [blockValue]
3625
+ //
3626
+ // On stack, before: hash, inverse, program, value
3627
+ // On stack, after: return value of blockHelperMissing
3628
+ //
3629
+ // The purpose of this opcode is to take a block of the form
3630
+ // `{{#this.foo}}...{{/this.foo}}`, resolve the value of `foo`, and
3631
+ // replace it on the stack with the result of properly
3632
+ // invoking blockHelperMissing.
3633
+ blockValue: function blockValue(name) {
3634
+ var blockHelperMissing = this.aliasable('helpers.blockHelperMissing'),
3635
+ params = [this.contextName(0)];
3636
+ this.setupHelperArgs(name, 0, params);
3637
+
3638
+ var blockName = this.popStack();
3639
+ params.splice(1, 0, blockName);
3640
+
3641
+ this.push(this.source.functionCall(blockHelperMissing, 'call', params));
3642
+ },
3643
+
3644
+ // [ambiguousBlockValue]
3645
+ //
3646
+ // On stack, before: hash, inverse, program, value
3647
+ // Compiler value, before: lastHelper=value of last found helper, if any
3648
+ // On stack, after, if no lastHelper: same as [blockValue]
3649
+ // On stack, after, if lastHelper: value
3650
+ ambiguousBlockValue: function ambiguousBlockValue() {
3651
+ // We're being a bit cheeky and reusing the options value from the prior exec
3652
+ var blockHelperMissing = this.aliasable('helpers.blockHelperMissing'),
3653
+ params = [this.contextName(0)];
3654
+ this.setupHelperArgs('', 0, params, true);
3655
+
3656
+ this.flushInline();
3657
+
3658
+ var current = this.topStack();
3659
+ params.splice(1, 0, current);
3660
+
3661
+ this.pushSource(['if (!', this.lastHelper, ') { ', current, ' = ', this.source.functionCall(blockHelperMissing, 'call', params), '}']);
3662
+ },
3663
+
3664
+ // [appendContent]
3665
+ //
3666
+ // On stack, before: ...
3667
+ // On stack, after: ...
3668
+ //
3669
+ // Appends the string value of `content` to the current buffer
3670
+ appendContent: function appendContent(content) {
3671
+ if (this.pendingContent) {
3672
+ content = this.pendingContent + content;
3673
+ } else {
3674
+ this.pendingLocation = this.source.currentLocation;
3675
+ }
3676
+
3677
+ this.pendingContent = content;
3678
+ },
3679
+
3680
+ // [append]
3681
+ //
3682
+ // On stack, before: value, ...
3683
+ // On stack, after: ...
3684
+ //
3685
+ // Coerces `value` to a String and appends it to the current buffer.
3686
+ //
3687
+ // If `value` is truthy, or 0, it is coerced into a string and appended
3688
+ // Otherwise, the empty string is appended
3689
+ append: function append() {
3690
+ if (this.isInline()) {
3691
+ this.replaceStack(function (current) {
3692
+ return [' != null ? ', current, ' : ""'];
3693
+ });
3694
+
3695
+ this.pushSource(this.appendToBuffer(this.popStack()));
3696
+ } else {
3697
+ var local = this.popStack();
3698
+ this.pushSource(['if (', local, ' != null) { ', this.appendToBuffer(local, undefined, true), ' }']);
3699
+ if (this.environment.isSimple) {
3700
+ this.pushSource(['else { ', this.appendToBuffer("''", undefined, true), ' }']);
3701
+ }
3702
+ }
3703
+ },
3704
+
3705
+ // [appendEscaped]
3706
+ //
3707
+ // On stack, before: value, ...
3708
+ // On stack, after: ...
3709
+ //
3710
+ // Escape `value` and append it to the buffer
3711
+ appendEscaped: function appendEscaped() {
3712
+ this.pushSource(this.appendToBuffer([this.aliasable('container.escapeExpression'), '(', this.popStack(), ')']));
3713
+ },
3714
+
3715
+ // [getContext]
3716
+ //
3717
+ // On stack, before: ...
3718
+ // On stack, after: ...
3719
+ // Compiler value, after: lastContext=depth
3720
+ //
3721
+ // Set the value of the `lastContext` compiler value to the depth
3722
+ getContext: function getContext(depth) {
3723
+ this.lastContext = depth;
3724
+ },
3725
+
3726
+ // [pushContext]
3727
+ //
3728
+ // On stack, before: ...
3729
+ // On stack, after: currentContext, ...
3730
+ //
3731
+ // Pushes the value of the current context onto the stack.
3732
+ pushContext: function pushContext() {
3733
+ this.pushStackLiteral(this.contextName(this.lastContext));
3734
+ },
3735
+
3736
+ // [lookupOnContext]
3737
+ //
3738
+ // On stack, before: ...
3739
+ // On stack, after: currentContext[name], ...
3740
+ //
3741
+ // Looks up the value of `name` on the current context and pushes
3742
+ // it onto the stack.
3743
+ lookupOnContext: function lookupOnContext(parts, falsy, strict, scoped) {
3744
+ var i = 0;
3745
+
3746
+ if (!scoped && this.options.compat && !this.lastContext) {
3747
+ // The depthed query is expected to handle the undefined logic for the root level that
3748
+ // is implemented below, so we evaluate that directly in compat mode
3749
+ this.push(this.depthedLookup(parts[i++]));
3750
+ } else {
3751
+ this.pushContext();
3752
+ }
3753
+
3754
+ this.resolvePath('context', parts, i, falsy, strict);
3755
+ },
3756
+
3757
+ // [lookupBlockParam]
3758
+ //
3759
+ // On stack, before: ...
3760
+ // On stack, after: blockParam[name], ...
3761
+ //
3762
+ // Looks up the value of `parts` on the given block param and pushes
3763
+ // it onto the stack.
3764
+ lookupBlockParam: function lookupBlockParam(blockParamId, parts) {
3765
+ this.useBlockParams = true;
3766
+
3767
+ this.push(['blockParams[', blockParamId[0], '][', blockParamId[1], ']']);
3768
+ this.resolvePath('context', parts, 1);
3769
+ },
3770
+
3771
+ // [lookupData]
3772
+ //
3773
+ // On stack, before: ...
3774
+ // On stack, after: data, ...
3775
+ //
3776
+ // Push the data lookup operator
3777
+ lookupData: function lookupData(depth, parts, strict) {
3778
+ if (!depth) {
3779
+ this.pushStackLiteral('data');
3780
+ } else {
3781
+ this.pushStackLiteral('container.data(data, ' + depth + ')');
3782
+ }
3783
+
3784
+ this.resolvePath('data', parts, 0, true, strict);
3785
+ },
3786
+
3787
+ resolvePath: function resolvePath(type, parts, i, falsy, strict) {
3788
+ // istanbul ignore next
3789
+
3790
+ var _this = this;
3791
+
3792
+ if (this.options.strict || this.options.assumeObjects) {
3793
+ this.push(strictLookup(this.options.strict && strict, this, parts, type));
3794
+ return;
3795
+ }
3796
+
3797
+ var len = parts.length;
3798
+ for (; i < len; i++) {
3799
+ /* eslint-disable no-loop-func */
3800
+ this.replaceStack(function (current) {
3801
+ var lookup = _this.nameLookup(current, parts[i], type);
3802
+ // We want to ensure that zero and false are handled properly if the context (falsy flag)
3803
+ // needs to have the special handling for these values.
3804
+ if (!falsy) {
3805
+ return [' != null ? ', lookup, ' : ', current];
3806
+ } else {
3807
+ // Otherwise we can use generic falsy handling
3808
+ return [' && ', lookup];
3809
+ }
3810
+ });
3811
+ /* eslint-enable no-loop-func */
3812
+ }
3813
+ },
3814
+
3815
+ // [resolvePossibleLambda]
3816
+ //
3817
+ // On stack, before: value, ...
3818
+ // On stack, after: resolved value, ...
3819
+ //
3820
+ // If the `value` is a lambda, replace it on the stack by
3821
+ // the return value of the lambda
3822
+ resolvePossibleLambda: function resolvePossibleLambda() {
3823
+ this.push([this.aliasable('container.lambda'), '(', this.popStack(), ', ', this.contextName(0), ')']);
3824
+ },
3825
+
3826
+ // [pushStringParam]
3827
+ //
3828
+ // On stack, before: ...
3829
+ // On stack, after: string, currentContext, ...
3830
+ //
3831
+ // This opcode is designed for use in string mode, which
3832
+ // provides the string value of a parameter along with its
3833
+ // depth rather than resolving it immediately.
3834
+ pushStringParam: function pushStringParam(string, type) {
3835
+ this.pushContext();
3836
+ this.pushString(type);
3837
+
3838
+ // If it's a subexpression, the string result
3839
+ // will be pushed after this opcode.
3840
+ if (type !== 'SubExpression') {
3841
+ if (typeof string === 'string') {
3842
+ this.pushString(string);
3843
+ } else {
3844
+ this.pushStackLiteral(string);
3845
+ }
3846
+ }
3847
+ },
3848
+
3849
+ emptyHash: function emptyHash(omitEmpty) {
3850
+ if (this.trackIds) {
3851
+ this.push('{}'); // hashIds
3852
+ }
3853
+ if (this.stringParams) {
3854
+ this.push('{}'); // hashContexts
3855
+ this.push('{}'); // hashTypes
3856
+ }
3857
+ this.pushStackLiteral(omitEmpty ? 'undefined' : '{}');
3858
+ },
3859
+ pushHash: function pushHash() {
3860
+ if (this.hash) {
3861
+ this.hashes.push(this.hash);
3862
+ }
3863
+ this.hash = { values: [], types: [], contexts: [], ids: [] };
3864
+ },
3865
+ popHash: function popHash() {
3866
+ var hash = this.hash;
3867
+ this.hash = this.hashes.pop();
3868
+
3869
+ if (this.trackIds) {
3870
+ this.push(this.objectLiteral(hash.ids));
3871
+ }
3872
+ if (this.stringParams) {
3873
+ this.push(this.objectLiteral(hash.contexts));
3874
+ this.push(this.objectLiteral(hash.types));
3875
+ }
3876
+
3877
+ this.push(this.objectLiteral(hash.values));
3878
+ },
3879
+
3880
+ // [pushString]
3881
+ //
3882
+ // On stack, before: ...
3883
+ // On stack, after: quotedString(string), ...
3884
+ //
3885
+ // Push a quoted version of `string` onto the stack
3886
+ pushString: function pushString(string) {
3887
+ this.pushStackLiteral(this.quotedString(string));
3888
+ },
3889
+
3890
+ // [pushLiteral]
3891
+ //
3892
+ // On stack, before: ...
3893
+ // On stack, after: value, ...
3894
+ //
3895
+ // Pushes a value onto the stack. This operation prevents
3896
+ // the compiler from creating a temporary variable to hold
3897
+ // it.
3898
+ pushLiteral: function pushLiteral(value) {
3899
+ this.pushStackLiteral(value);
3900
+ },
3901
+
3902
+ // [pushProgram]
3903
+ //
3904
+ // On stack, before: ...
3905
+ // On stack, after: program(guid), ...
3906
+ //
3907
+ // Push a program expression onto the stack. This takes
3908
+ // a compile-time guid and converts it into a runtime-accessible
3909
+ // expression.
3910
+ pushProgram: function pushProgram(guid) {
3911
+ if (guid != null) {
3912
+ this.pushStackLiteral(this.programExpression(guid));
3913
+ } else {
3914
+ this.pushStackLiteral(null);
3915
+ }
3916
+ },
3917
+
3918
+ // [registerDecorator]
3919
+ //
3920
+ // On stack, before: hash, program, params..., ...
3921
+ // On stack, after: ...
3922
+ //
3923
+ // Pops off the decorator's parameters, invokes the decorator,
3924
+ // and inserts the decorator into the decorators list.
3925
+ registerDecorator: function registerDecorator(paramSize, name) {
3926
+ var foundDecorator = this.nameLookup('decorators', name, 'decorator'),
3927
+ options = this.setupHelperArgs(name, paramSize);
3928
+
3929
+ this.decorators.push(['fn = ', this.decorators.functionCall(foundDecorator, '', ['fn', 'props', 'container', options]), ' || fn;']);
3930
+ },
3931
+
3932
+ // [invokeHelper]
3933
+ //
3934
+ // On stack, before: hash, inverse, program, params..., ...
3935
+ // On stack, after: result of helper invocation
3936
+ //
3937
+ // Pops off the helper's parameters, invokes the helper,
3938
+ // and pushes the helper's return value onto the stack.
3939
+ //
3940
+ // If the helper is not found, `helperMissing` is called.
3941
+ invokeHelper: function invokeHelper(paramSize, name, isSimple) {
3942
+ var nonHelper = this.popStack(),
3943
+ helper = this.setupHelper(paramSize, name),
3944
+ simple = isSimple ? [helper.name, ' || '] : '';
3945
+
3946
+ var lookup = ['('].concat(simple, nonHelper);
3947
+ if (!this.options.strict) {
3948
+ lookup.push(' || ', this.aliasable('helpers.helperMissing'));
3949
+ }
3950
+ lookup.push(')');
3951
+
3952
+ this.push(this.source.functionCall(lookup, 'call', helper.callParams));
3953
+ },
3954
+
3955
+ // [invokeKnownHelper]
3956
+ //
3957
+ // On stack, before: hash, inverse, program, params..., ...
3958
+ // On stack, after: result of helper invocation
3959
+ //
3960
+ // This operation is used when the helper is known to exist,
3961
+ // so a `helperMissing` fallback is not required.
3962
+ invokeKnownHelper: function invokeKnownHelper(paramSize, name) {
3963
+ var helper = this.setupHelper(paramSize, name);
3964
+ this.push(this.source.functionCall(helper.name, 'call', helper.callParams));
3965
+ },
3966
+
3967
+ // [invokeAmbiguous]
3968
+ //
3969
+ // On stack, before: hash, inverse, program, params..., ...
3970
+ // On stack, after: result of disambiguation
3971
+ //
3972
+ // This operation is used when an expression like `{{foo}}`
3973
+ // is provided, but we don't know at compile-time whether it
3974
+ // is a helper or a path.
3975
+ //
3976
+ // This operation emits more code than the other options,
3977
+ // and can be avoided by passing the `knownHelpers` and
3978
+ // `knownHelpersOnly` flags at compile-time.
3979
+ invokeAmbiguous: function invokeAmbiguous(name, helperCall) {
3980
+ this.useRegister('helper');
3981
+
3982
+ var nonHelper = this.popStack();
3983
+
3984
+ this.emptyHash();
3985
+ var helper = this.setupHelper(0, name, helperCall);
3986
+
3987
+ var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');
3988
+
3989
+ var lookup = ['(', '(helper = ', helperName, ' || ', nonHelper, ')'];
3990
+ if (!this.options.strict) {
3991
+ lookup[0] = '(helper = ';
3992
+ lookup.push(' != null ? helper : ', this.aliasable('helpers.helperMissing'));
3993
+ }
3994
+
3995
+ this.push(['(', lookup, helper.paramsInit ? ['),(', helper.paramsInit] : [], '),', '(typeof helper === ', this.aliasable('"function"'), ' ? ', this.source.functionCall('helper', 'call', helper.callParams), ' : helper))']);
3996
+ },
3997
+
3998
+ // [invokePartial]
3999
+ //
4000
+ // On stack, before: context, ...
4001
+ // On stack after: result of partial invocation
4002
+ //
4003
+ // This operation pops off a context, invokes a partial with that context,
4004
+ // and pushes the result of the invocation back.
4005
+ invokePartial: function invokePartial(isDynamic, name, indent) {
4006
+ var params = [],
4007
+ options = this.setupParams(name, 1, params);
4008
+
4009
+ if (isDynamic) {
4010
+ name = this.popStack();
4011
+ delete options.name;
4012
+ }
4013
+
4014
+ if (indent) {
4015
+ options.indent = JSON.stringify(indent);
4016
+ }
4017
+ options.helpers = 'helpers';
4018
+ options.partials = 'partials';
4019
+ options.decorators = 'container.decorators';
4020
+
4021
+ if (!isDynamic) {
4022
+ params.unshift(this.nameLookup('partials', name, 'partial'));
4023
+ } else {
4024
+ params.unshift(name);
4025
+ }
4026
+
4027
+ if (this.options.compat) {
4028
+ options.depths = 'depths';
4029
+ }
4030
+ options = this.objectLiteral(options);
4031
+ params.push(options);
4032
+
4033
+ this.push(this.source.functionCall('container.invokePartial', '', params));
4034
+ },
4035
+
4036
+ // [assignToHash]
4037
+ //
4038
+ // On stack, before: value, ..., hash, ...
4039
+ // On stack, after: ..., hash, ...
4040
+ //
4041
+ // Pops a value off the stack and assigns it to the current hash
4042
+ assignToHash: function assignToHash(key) {
4043
+ var value = this.popStack(),
4044
+ context = undefined,
4045
+ type = undefined,
4046
+ id = undefined;
4047
+
4048
+ if (this.trackIds) {
4049
+ id = this.popStack();
4050
+ }
4051
+ if (this.stringParams) {
4052
+ type = this.popStack();
4053
+ context = this.popStack();
4054
+ }
4055
+
4056
+ var hash = this.hash;
4057
+ if (context) {
4058
+ hash.contexts[key] = context;
4059
+ }
4060
+ if (type) {
4061
+ hash.types[key] = type;
4062
+ }
4063
+ if (id) {
4064
+ hash.ids[key] = id;
4065
+ }
4066
+ hash.values[key] = value;
4067
+ },
4068
+
4069
+ pushId: function pushId(type, name, child) {
4070
+ if (type === 'BlockParam') {
4071
+ this.pushStackLiteral('blockParams[' + name[0] + '].path[' + name[1] + ']' + (child ? ' + ' + JSON.stringify('.' + child) : ''));
4072
+ } else if (type === 'PathExpression') {
4073
+ this.pushString(name);
4074
+ } else if (type === 'SubExpression') {
4075
+ this.pushStackLiteral('true');
4076
+ } else {
4077
+ this.pushStackLiteral('null');
4078
+ }
4079
+ },
4080
+
4081
+ // HELPERS
4082
+
4083
+ compiler: JavaScriptCompiler,
4084
+
4085
+ compileChildren: function compileChildren(environment, options) {
4086
+ var children = environment.children,
4087
+ child = undefined,
4088
+ compiler = undefined;
4089
+
4090
+ for (var i = 0, l = children.length; i < l; i++) {
4091
+ child = children[i];
4092
+ compiler = new this.compiler(); // eslint-disable-line new-cap
4093
+
4094
+ var index = this.matchExistingProgram(child);
4095
+
4096
+ if (index == null) {
4097
+ this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children
4098
+ index = this.context.programs.length;
4099
+ child.index = index;
4100
+ child.name = 'program' + index;
4101
+ this.context.programs[index] = compiler.compile(child, options, this.context, !this.precompile);
4102
+ this.context.decorators[index] = compiler.decorators;
4103
+ this.context.environments[index] = child;
4104
+
4105
+ this.useDepths = this.useDepths || compiler.useDepths;
4106
+ this.useBlockParams = this.useBlockParams || compiler.useBlockParams;
4107
+ } else {
4108
+ child.index = index;
4109
+ child.name = 'program' + index;
4110
+
4111
+ this.useDepths = this.useDepths || child.useDepths;
4112
+ this.useBlockParams = this.useBlockParams || child.useBlockParams;
4113
+ }
4114
+ }
4115
+ },
4116
+ matchExistingProgram: function matchExistingProgram(child) {
4117
+ for (var i = 0, len = this.context.environments.length; i < len; i++) {
4118
+ var environment = this.context.environments[i];
4119
+ if (environment && environment.equals(child)) {
4120
+ return i;
4121
+ }
4122
+ }
4123
+ },
4124
+
4125
+ programExpression: function programExpression(guid) {
4126
+ var child = this.environment.children[guid],
4127
+ programParams = [child.index, 'data', child.blockParams];
4128
+
4129
+ if (this.useBlockParams || this.useDepths) {
4130
+ programParams.push('blockParams');
4131
+ }
4132
+ if (this.useDepths) {
4133
+ programParams.push('depths');
4134
+ }
4135
+
4136
+ return 'container.program(' + programParams.join(', ') + ')';
4137
+ },
4138
+
4139
+ useRegister: function useRegister(name) {
4140
+ if (!this.registers[name]) {
4141
+ this.registers[name] = true;
4142
+ this.registers.list.push(name);
4143
+ }
4144
+ },
4145
+
4146
+ push: function push(expr) {
4147
+ if (!(expr instanceof Literal)) {
4148
+ expr = this.source.wrap(expr);
4149
+ }
4150
+
4151
+ this.inlineStack.push(expr);
4152
+ return expr;
4153
+ },
4154
+
4155
+ pushStackLiteral: function pushStackLiteral(item) {
4156
+ this.push(new Literal(item));
4157
+ },
4158
+
4159
+ pushSource: function pushSource(source) {
4160
+ if (this.pendingContent) {
4161
+ this.source.push(this.appendToBuffer(this.source.quotedString(this.pendingContent), this.pendingLocation));
4162
+ this.pendingContent = undefined;
4163
+ }
4164
+
4165
+ if (source) {
4166
+ this.source.push(source);
4167
+ }
4168
+ },
4169
+
4170
+ replaceStack: function replaceStack(callback) {
4171
+ var prefix = ['('],
4172
+ stack = undefined,
4173
+ createdStack = undefined,
4174
+ usedLiteral = undefined;
4175
+
4176
+ /* istanbul ignore next */
4177
+ if (!this.isInline()) {
4178
+ throw new _exception2['default']('replaceStack on non-inline');
4179
+ }
4180
+
4181
+ // We want to merge the inline statement into the replacement statement via ','
4182
+ var top = this.popStack(true);
4183
+
4184
+ if (top instanceof Literal) {
4185
+ // Literals do not need to be inlined
4186
+ stack = [top.value];
4187
+ prefix = ['(', stack];
4188
+ usedLiteral = true;
4189
+ } else {
4190
+ // Get or create the current stack name for use by the inline
4191
+ createdStack = true;
4192
+ var _name = this.incrStack();
4193
+
4194
+ prefix = ['((', this.push(_name), ' = ', top, ')'];
4195
+ stack = this.topStack();
4196
+ }
4197
+
4198
+ var item = callback.call(this, stack);
4199
+
4200
+ if (!usedLiteral) {
4201
+ this.popStack();
4202
+ }
4203
+ if (createdStack) {
4204
+ this.stackSlot--;
4205
+ }
4206
+ this.push(prefix.concat(item, ')'));
4207
+ },
4208
+
4209
+ incrStack: function incrStack() {
4210
+ this.stackSlot++;
4211
+ if (this.stackSlot > this.stackVars.length) {
4212
+ this.stackVars.push('stack' + this.stackSlot);
4213
+ }
4214
+ return this.topStackName();
4215
+ },
4216
+ topStackName: function topStackName() {
4217
+ return 'stack' + this.stackSlot;
4218
+ },
4219
+ flushInline: function flushInline() {
4220
+ var inlineStack = this.inlineStack;
4221
+ this.inlineStack = [];
4222
+ for (var i = 0, len = inlineStack.length; i < len; i++) {
4223
+ var entry = inlineStack[i];
4224
+ /* istanbul ignore if */
4225
+ if (entry instanceof Literal) {
4226
+ this.compileStack.push(entry);
4227
+ } else {
4228
+ var stack = this.incrStack();
4229
+ this.pushSource([stack, ' = ', entry, ';']);
4230
+ this.compileStack.push(stack);
4231
+ }
4232
+ }
4233
+ },
4234
+ isInline: function isInline() {
4235
+ return this.inlineStack.length;
4236
+ },
4237
+
4238
+ popStack: function popStack(wrapped) {
4239
+ var inline = this.isInline(),
4240
+ item = (inline ? this.inlineStack : this.compileStack).pop();
4241
+
4242
+ if (!wrapped && item instanceof Literal) {
4243
+ return item.value;
4244
+ } else {
4245
+ if (!inline) {
4246
+ /* istanbul ignore next */
4247
+ if (!this.stackSlot) {
4248
+ throw new _exception2['default']('Invalid stack pop');
4249
+ }
4250
+ this.stackSlot--;
4251
+ }
4252
+ return item;
4253
+ }
4254
+ },
4255
+
4256
+ topStack: function topStack() {
4257
+ var stack = this.isInline() ? this.inlineStack : this.compileStack,
4258
+ item = stack[stack.length - 1];
4259
+
4260
+ /* istanbul ignore if */
4261
+ if (item instanceof Literal) {
4262
+ return item.value;
4263
+ } else {
4264
+ return item;
4265
+ }
4266
+ },
4267
+
4268
+ contextName: function contextName(context) {
4269
+ if (this.useDepths && context) {
4270
+ return 'depths[' + context + ']';
4271
+ } else {
4272
+ return 'depth' + context;
4273
+ }
4274
+ },
4275
+
4276
+ quotedString: function quotedString(str) {
4277
+ return this.source.quotedString(str);
4278
+ },
4279
+
4280
+ objectLiteral: function objectLiteral(obj) {
4281
+ return this.source.objectLiteral(obj);
4282
+ },
4283
+
4284
+ aliasable: function aliasable(name) {
4285
+ var ret = this.aliases[name];
4286
+ if (ret) {
4287
+ ret.referenceCount++;
4288
+ return ret;
4289
+ }
4290
+
4291
+ ret = this.aliases[name] = this.source.wrap(name);
4292
+ ret.aliasable = true;
4293
+ ret.referenceCount = 1;
4294
+
4295
+ return ret;
4296
+ },
4297
+
4298
+ setupHelper: function setupHelper(paramSize, name, blockHelper) {
4299
+ var params = [],
4300
+ paramsInit = this.setupHelperArgs(name, paramSize, params, blockHelper);
4301
+ var foundHelper = this.nameLookup('helpers', name, 'helper'),
4302
+ callContext = this.aliasable(this.contextName(0) + ' != null ? ' + this.contextName(0) + ' : {}');
4303
+
4304
+ return {
4305
+ params: params,
4306
+ paramsInit: paramsInit,
4307
+ name: foundHelper,
4308
+ callParams: [callContext].concat(params)
4309
+ };
4310
+ },
4311
+
4312
+ setupParams: function setupParams(helper, paramSize, params) {
4313
+ var options = {},
4314
+ contexts = [],
4315
+ types = [],
4316
+ ids = [],
4317
+ objectArgs = !params,
4318
+ param = undefined;
4319
+
4320
+ if (objectArgs) {
4321
+ params = [];
4322
+ }
4323
+
4324
+ options.name = this.quotedString(helper);
4325
+ options.hash = this.popStack();
4326
+
4327
+ if (this.trackIds) {
4328
+ options.hashIds = this.popStack();
4329
+ }
4330
+ if (this.stringParams) {
4331
+ options.hashTypes = this.popStack();
4332
+ options.hashContexts = this.popStack();
4333
+ }
4334
+
4335
+ var inverse = this.popStack(),
4336
+ program = this.popStack();
4337
+
4338
+ // Avoid setting fn and inverse if neither are set. This allows
4339
+ // helpers to do a check for `if (options.fn)`
4340
+ if (program || inverse) {
4341
+ options.fn = program || 'container.noop';
4342
+ options.inverse = inverse || 'container.noop';
4343
+ }
4344
+
4345
+ // The parameters go on to the stack in order (making sure that they are evaluated in order)
4346
+ // so we need to pop them off the stack in reverse order
4347
+ var i = paramSize;
4348
+ while (i--) {
4349
+ param = this.popStack();
4350
+ params[i] = param;
4351
+
4352
+ if (this.trackIds) {
4353
+ ids[i] = this.popStack();
4354
+ }
4355
+ if (this.stringParams) {
4356
+ types[i] = this.popStack();
4357
+ contexts[i] = this.popStack();
4358
+ }
4359
+ }
4360
+
4361
+ if (objectArgs) {
4362
+ options.args = this.source.generateArray(params);
4363
+ }
4364
+
4365
+ if (this.trackIds) {
4366
+ options.ids = this.source.generateArray(ids);
4367
+ }
4368
+ if (this.stringParams) {
4369
+ options.types = this.source.generateArray(types);
4370
+ options.contexts = this.source.generateArray(contexts);
4371
+ }
4372
+
4373
+ if (this.options.data) {
4374
+ options.data = 'data';
4375
+ }
4376
+ if (this.useBlockParams) {
4377
+ options.blockParams = 'blockParams';
4378
+ }
4379
+ return options;
4380
+ },
4381
+
4382
+ setupHelperArgs: function setupHelperArgs(helper, paramSize, params, useRegister) {
4383
+ var options = this.setupParams(helper, paramSize, params);
4384
+ options = this.objectLiteral(options);
4385
+ if (useRegister) {
4386
+ this.useRegister('options');
4387
+ params.push('options');
4388
+ return ['options=', options];
4389
+ } else if (params) {
4390
+ params.push(options);
4391
+ return '';
4392
+ } else {
4393
+ return options;
4394
+ }
4395
+ }
4396
+ };
4397
+
4398
+ (function () {
4399
+ var reservedWords = ('break else new var' + ' case finally return void' + ' catch for switch while' + ' continue function this with' + ' default if throw' + ' delete in try' + ' do instanceof typeof' + ' abstract enum int short' + ' boolean export interface static' + ' byte extends long super' + ' char final native synchronized' + ' class float package throws' + ' const goto private transient' + ' debugger implements protected volatile' + ' double import public let yield await' + ' null true false').split(' ');
4400
+
4401
+ var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
4402
+
4403
+ for (var i = 0, l = reservedWords.length; i < l; i++) {
4404
+ compilerWords[reservedWords[i]] = true;
4405
+ }
4406
+ })();
4407
+
4408
+ JavaScriptCompiler.isValidJavaScriptVariableName = function (name) {
4409
+ return !JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name);
4410
+ };
4411
+
4412
+ function strictLookup(requireTerminal, compiler, parts, type) {
4413
+ var stack = compiler.popStack(),
4414
+ i = 0,
4415
+ len = parts.length;
4416
+ if (requireTerminal) {
4417
+ len--;
4418
+ }
4419
+
4420
+ for (; i < len; i++) {
4421
+ stack = compiler.nameLookup(stack, parts[i], type);
4422
+ }
4423
+
4424
+ if (requireTerminal) {
4425
+ return [compiler.aliasable('container.strict'), '(', stack, ', ', compiler.quotedString(parts[i]), ')'];
4426
+ } else {
4427
+ return stack;
4428
+ }
4429
+ }
4430
+
4431
+ exports['default'] = JavaScriptCompiler;
4432
+ module.exports = exports['default'];
4433
+
4434
+ /***/ },
4435
+ /* 29 */
4436
+ /***/ function(module, exports, __webpack_require__) {
4437
+
4438
+ /* global define */
4439
+ 'use strict';
4440
+
4441
+ exports.__esModule = true;
4442
+
4443
+ var _utils = __webpack_require__(5);
4444
+
4445
+ var SourceNode = undefined;
4446
+
4447
+ try {
4448
+ /* istanbul ignore next */
4449
+ if (false) {
4450
+ // We don't support this in AMD environments. For these environments, we asusme that
4451
+ // they are running on the browser and thus have no need for the source-map library.
4452
+ var SourceMap = require('source-map');
4453
+ SourceNode = SourceMap.SourceNode;
4454
+ }
4455
+ } catch (err) {}
4456
+ /* NOP */
4457
+
4458
+ /* istanbul ignore if: tested but not covered in istanbul due to dist build */
4459
+ if (!SourceNode) {
4460
+ SourceNode = function (line, column, srcFile, chunks) {
4461
+ this.src = '';
4462
+ if (chunks) {
4463
+ this.add(chunks);
4464
+ }
4465
+ };
4466
+ /* istanbul ignore next */
4467
+ SourceNode.prototype = {
4468
+ add: function add(chunks) {
4469
+ if (_utils.isArray(chunks)) {
4470
+ chunks = chunks.join('');
4471
+ }
4472
+ this.src += chunks;
4473
+ },
4474
+ prepend: function prepend(chunks) {
4475
+ if (_utils.isArray(chunks)) {
4476
+ chunks = chunks.join('');
4477
+ }
4478
+ this.src = chunks + this.src;
4479
+ },
4480
+ toStringWithSourceMap: function toStringWithSourceMap() {
4481
+ return { code: this.toString() };
4482
+ },
4483
+ toString: function toString() {
4484
+ return this.src;
4485
+ }
4486
+ };
4487
+ }
4488
+
4489
+ function castChunk(chunk, codeGen, loc) {
4490
+ if (_utils.isArray(chunk)) {
4491
+ var ret = [];
4492
+
4493
+ for (var i = 0, len = chunk.length; i < len; i++) {
4494
+ ret.push(codeGen.wrap(chunk[i], loc));
4495
+ }
4496
+ return ret;
4497
+ } else if (typeof chunk === 'boolean' || typeof chunk === 'number') {
4498
+ // Handle primitives that the SourceNode will throw up on
4499
+ return chunk + '';
4500
+ }
4501
+ return chunk;
4502
+ }
4503
+
4504
+ function CodeGen(srcFile) {
4505
+ this.srcFile = srcFile;
4506
+ this.source = [];
4507
+ }
4508
+
4509
+ CodeGen.prototype = {
4510
+ isEmpty: function isEmpty() {
4511
+ return !this.source.length;
4512
+ },
4513
+ prepend: function prepend(source, loc) {
4514
+ this.source.unshift(this.wrap(source, loc));
4515
+ },
4516
+ push: function push(source, loc) {
4517
+ this.source.push(this.wrap(source, loc));
4518
+ },
4519
+
4520
+ merge: function merge() {
4521
+ var source = this.empty();
4522
+ this.each(function (line) {
4523
+ source.add([' ', line, '\n']);
4524
+ });
4525
+ return source;
4526
+ },
4527
+
4528
+ each: function each(iter) {
4529
+ for (var i = 0, len = this.source.length; i < len; i++) {
4530
+ iter(this.source[i]);
4531
+ }
4532
+ },
4533
+
4534
+ empty: function empty() {
4535
+ var loc = this.currentLocation || { start: {} };
4536
+ return new SourceNode(loc.start.line, loc.start.column, this.srcFile);
4537
+ },
4538
+ wrap: function wrap(chunk) {
4539
+ var loc = arguments.length <= 1 || arguments[1] === undefined ? this.currentLocation || { start: {} } : arguments[1];
4540
+
4541
+ if (chunk instanceof SourceNode) {
4542
+ return chunk;
4543
+ }
4544
+
4545
+ chunk = castChunk(chunk, this, loc);
4546
+
4547
+ return new SourceNode(loc.start.line, loc.start.column, this.srcFile, chunk);
4548
+ },
4549
+
4550
+ functionCall: function functionCall(fn, type, params) {
4551
+ params = this.generateList(params);
4552
+ return this.wrap([fn, type ? '.' + type + '(' : '(', params, ')']);
4553
+ },
4554
+
4555
+ quotedString: function quotedString(str) {
4556
+ return '"' + (str + '').replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n').replace(/\r/g, '\\r').replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4
4557
+ .replace(/\u2029/g, '\\u2029') + '"';
4558
+ },
4559
+
4560
+ objectLiteral: function objectLiteral(obj) {
4561
+ var pairs = [];
4562
+
4563
+ for (var key in obj) {
4564
+ if (obj.hasOwnProperty(key)) {
4565
+ var value = castChunk(obj[key], this);
4566
+ if (value !== 'undefined') {
4567
+ pairs.push([this.quotedString(key), ':', value]);
4568
+ }
4569
+ }
4570
+ }
4571
+
4572
+ var ret = this.generateList(pairs);
4573
+ ret.prepend('{');
4574
+ ret.add('}');
4575
+ return ret;
4576
+ },
4577
+
4578
+ generateList: function generateList(entries) {
4579
+ var ret = this.empty();
4580
+
4581
+ for (var i = 0, len = entries.length; i < len; i++) {
4582
+ if (i) {
4583
+ ret.add(',');
4584
+ }
4585
+
4586
+ ret.add(castChunk(entries[i], this));
4587
+ }
4588
+
4589
+ return ret;
4590
+ },
4591
+
4592
+ generateArray: function generateArray(entries) {
4593
+ var ret = this.generateList(entries);
4594
+ ret.prepend('[');
4595
+ ret.add(']');
4596
+
4597
+ return ret;
4598
+ }
4599
+ };
4600
+
4601
+ exports['default'] = CodeGen;
4602
+ module.exports = exports['default'];
4603
+
4604
+ /***/ }
4605
+ /******/ ])
4606
+ });
4607
+ ;
php-compatibility-checker/src/js/run.js ADDED
@@ -0,0 +1,364 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Global variables.
2
+ var test_version, only_active, timer, runAction;
3
+
4
+ jQuery( document ).ready(function($) {
5
+ //runAction();
6
+ checkStatus();
7
+
8
+ $( '#developermode' ).change(function() {
9
+ if ( $(this).is( ':checked' ) ) {
10
+ $( '#developerMode' ).show();
11
+ $( '#standardMode' ).hide();
12
+ } else {
13
+ $( '#developerMode' ).hide();
14
+ $( '#standardMode' ).show();
15
+ }
16
+ });
17
+ $( '#downloadReport' ).on( 'click', function() {
18
+ download( $( '#testResults' ).val(), 'report.txt', 'text/plain' );
19
+ });
20
+ $( document ).on( 'click', '.view-details', function() {
21
+ // Get the textarea with is on the same (dom) level.
22
+ var textarea = $( this ).siblings( 'textarea' );
23
+ if ( 'none' === textarea.css( 'display' ) ) {
24
+ textarea.css( 'display' , '' );
25
+ } else {
26
+ textarea.css( 'display', 'none' );
27
+ }
28
+ });
29
+
30
+
31
+
32
+ $( '#runButton' ).on( 'click', function() {
33
+ runAction();
34
+ });
35
+
36
+
37
+
38
+ $( '#upgradeButton' ).on( 'click', function() {
39
+ $( '#upgradeButton' ).blur();
40
+
41
+ // Show the ajax spinner.
42
+ $( '#upgradeButton' ).val(window.sg_wpephpcompat.loading);
43
+ jQuery('#runButton').addClass( "sgloading" );
44
+ //$( '.spinner' ).show();
45
+
46
+ upgradeTo($( '#recommended_php_version' ).val());
47
+ });
48
+
49
+ $( '#changeVersionButton' ).on( 'click', function() {
50
+ upgradeTo($( '#manualVersionValue' ).val());
51
+ });
52
+
53
+ $( '#cleanupButton' ).on( 'click', function() {
54
+ cleanupAction();
55
+ });
56
+
57
+ function cleanupAction() {
58
+ clearTimeout( timer );
59
+ jQuery.get( ajaxurl, { 'action': 'sg_wpephpcompat_clean_up' }, function() {
60
+ resetDisplay();
61
+ checkStatus();
62
+ });
63
+ };
64
+ //
65
+
66
+ runAction = function runAction() {
67
+ $( '#phpVersionCheckerFooterMsg' ).html('');
68
+ jQuery('#runButton')
69
+ .show()
70
+ .attr('disabled', true)
71
+ .attr('value', sgCachePressL10n.phpversion_checking)
72
+ .addClass( "sgloading" )
73
+ .blur();
74
+
75
+ // Empty the results textarea.
76
+ resetDisplay();
77
+ test_version = $( 'input[name=phptest_version]:checked' ).val();
78
+ only_active = $( 'input[name=active_plugins]:checked' ).val();
79
+ var data = {
80
+ 'action': 'sg_wpephpcompat_start_test',
81
+ 'test_version': test_version,
82
+ 'only_active': only_active,
83
+ 'startScan': 1
84
+ };
85
+
86
+ // Start the test!
87
+ jQuery.post( ajaxurl, data ).always(function() {
88
+ // Start timer to check scan status.
89
+ checkStatus();
90
+ });
91
+ };
92
+ });
93
+
94
+
95
+
96
+
97
+ function cleanupReport() {
98
+ jQuery.get( ajaxurl, { 'action': 'sg_wpephpcompat_clean_up' }, function() {
99
+ });
100
+ }
101
+
102
+ function upgradeTo(version) {
103
+ var data = {
104
+ 'action': 'sg_wpephpcompat_change_version',
105
+ 'version': version
106
+ };
107
+
108
+ // Start the upgrade!
109
+ jQuery.post( ajaxurl, data, function(res) {
110
+ //setTimeout(function() {
111
+ window.location.reload();
112
+ //}, 1000);
113
+
114
+ });
115
+ }
116
+ /**
117
+ * Check the scan status and display results if scan is done.
118
+ * onDocumentReady
119
+ */
120
+ function checkStatus() {
121
+ var $ = jQuery;
122
+ $( '#phpVersionCheckerContainer' ).show();
123
+ // show default message
124
+ //$( '#phpVersionCheckerText' ).html(window.sg_wpephpcompat.check_your_php_version);
125
+
126
+ var data = {
127
+ 'action': 'sg_wpephpcompat_check_status'
128
+ };
129
+
130
+ var noReport = true;
131
+
132
+ var obj;
133
+ jQuery.post( ajaxurl, data, function( obj ) {
134
+ /*
135
+ * Status false: the test is not running and has not been run yet
136
+ * Status 1: the test is currently running
137
+ * Status 0: the test as completed but is not currently running
138
+ */
139
+ jQuery( '#runButton' ).show();
140
+ if ( false === obj.results ) {
141
+ jQuery( '#runButton' ).val( window.sg_wpephpcompat.run );
142
+ } else {
143
+ //jQuery( '#runButton' ).val( window.sg_wpephpcompat.rerun );
144
+ jQuery( '#runButton' ).hide();
145
+ jQuery( '#phpVersionCheckerHeaderMsgNotUpToDate' ).hide();
146
+
147
+
148
+
149
+ jQuery('#runButton').removeClass( "sgloading" );
150
+ //jQuery( '#runButton' ).hide();
151
+ }
152
+
153
+ jQuery('#runButton').removeAttr('disabled');
154
+
155
+ if ( '1' === obj.status ) {
156
+ //jQuery( '.spinner' ).show();
157
+ jQuery('#runButton').attr('disabled', true).attr('value', sgCachePressL10n.phpversion_checking);
158
+ } else {
159
+ jQuery( '.spinner' ).hide();
160
+ }
161
+
162
+ if ( '0' !== obj.results ) {
163
+ if( false !== obj.results ) {
164
+ noReport = false;
165
+ test_version = obj.version;
166
+ displayReport( obj.results );
167
+ }
168
+ // cron finished
169
+ } else {
170
+ // cron in progress
171
+ jQuery('#runButton')
172
+ .show()
173
+ .attr('disabled', true)
174
+ .attr('value', sgCachePressL10n.phpversion_checking)
175
+ .addClass( "sgloading" )
176
+ .blur();
177
+
178
+ jQuery( '#progressbar' ).progressbar({
179
+ value: obj.progress
180
+ });
181
+
182
+ // Display the current plugin count.
183
+ jQuery( '#wpe-progress-count' ).text( ( obj.total - obj.count + 1 ) + '/' + obj.total );
184
+
185
+ // Display the object being scanned.
186
+ jQuery( '#wpe-progress-active' ).text( obj.activeJob );
187
+
188
+ // Requeue the checkStatus call.
189
+ timer = setTimeout(function() {
190
+ checkStatus();
191
+ }, 5000);
192
+ }
193
+
194
+ // if (noReport) {
195
+ // // show default message
196
+ // }
197
+
198
+ }, 'json' ).fail(function ( xhr, status, error )
199
+ {
200
+ // Server responded correctly, but the response wasn't valid.
201
+ if ( 200 === xhr.status ) {
202
+ alert( "Error: " + error + "\nResponse: " + xhr.responseText );
203
+ }
204
+ else { // Server didn't respond correctly.
205
+ alert( "Error: Plase, do not close this tab or refresh the page while the plugin is running!" );
206
+ }
207
+ });
208
+ }
209
+ /**
210
+ * Clear previous results.
211
+ */
212
+ function resetDisplay() {
213
+ jQuery( '#progressbar' ).progressbar({
214
+ value: 0
215
+ });
216
+ jQuery( '#testResults' ).text('');
217
+ jQuery( '#standardMode' ).html('');
218
+ jQuery( '#wpe-progress-count' ).text('');
219
+ jQuery( '#wpe-progress-active' ).text('');
220
+ jQuery( '#footer' ).hide();
221
+ jQuery( '#upgradeButton' ).hide();
222
+ jQuery( '#phpVersionCheckerTextBelow' ).text('');
223
+
224
+ }
225
+ /**
226
+ * Loop through a string and count the total matches.
227
+ * @param {RegExp} regex Regex to execute.
228
+ * @param {string} log String to loop through.
229
+ * @return {int} The total number of matches.
230
+ */
231
+ function findAll( regex, log ) {
232
+ var m;
233
+ var count = 0;
234
+ while ( ( m = regex.exec( log ) ) !== null ) {
235
+ if ( m.index === regex.lastIndex ) {
236
+ regex.lastIndex++;
237
+ }
238
+ if ( parseInt( m[1] ) > 0 ) {
239
+ count += parseInt( m[1] );
240
+ }
241
+ }
242
+ return count;
243
+ }
244
+ /**
245
+ * Display the pretty report.
246
+ * @param {string} response Full test results.
247
+ */
248
+ function displayReport( response ) {
249
+ // Clean up before displaying results.
250
+ resetDisplay();
251
+ var $ = jQuery;
252
+ var compatible = 1;
253
+
254
+ // Keep track of the number of failed plugins/themes.
255
+ var failedCount = 0;
256
+ var errorsRegex = /(\d*) ERRORS?/g;
257
+ var warningRegex = /(\d*) WARNINGS?/g;
258
+ var updateVersionRegex = /e: (.*?);/g;
259
+ var currentVersionRegex = /n: (.*?);/g;
260
+
261
+ // Grab and compile our template.
262
+ var source = $( '#result-template' ).html();
263
+ var template = Handlebars.compile( source );
264
+
265
+ $( '#testResults' ).text( response );
266
+ $( '#footer' ).show();
267
+
268
+ // Separate plugins/themes.
269
+ var plugins = response.replace( /^\s+|\s+$/g, '' ).split( window.sg_wpephpcompat.name + ':' );
270
+
271
+ // Remove the first item, it's empty.
272
+ plugins.shift();
273
+
274
+ // Loop through them.
275
+ for ( var x in plugins ) {
276
+ var updateVersion;
277
+ var updateAvailable = 0;
278
+ var passed = 1;
279
+ var skipped = 0;
280
+ // Extract plugin/theme name.
281
+ var name = plugins[x].substring( 0, plugins[x].indexOf( '\n' ) );
282
+ // Extract results.
283
+ var log = plugins[x].substring( plugins[x].indexOf('\n'), plugins[x].length );
284
+ // Find number of errors and warnings.
285
+ var errors = findAll( errorsRegex, log );
286
+ var warnings = findAll( warningRegex, log );
287
+ // Check to see if there are any plugin/theme updates.
288
+ if ( updateVersionRegex.exec( log ) ) {
289
+ updateAvailable = 1;
290
+ }
291
+ // Update plugin and global compatibility flags.
292
+ if ( parseInt( errors ) > 0 || parseInt( warnings ) > 0) {
293
+ compatible = 0;
294
+ passed = 0;
295
+ failedCount++;
296
+ }
297
+
298
+ // Trim whitespace and newlines from report.
299
+ log = log.replace( /^\s+|\s+$/g, '' );
300
+
301
+ if ( log.search('skipped') !== -1 ) {
302
+ skipped = 1;
303
+ }
304
+
305
+ // only if warnings or errors
306
+ if (errors || warnings) {
307
+ // Use handlebars to build our template.
308
+ var context = {
309
+ plugin_name: name,
310
+ warnings: warnings,
311
+ errors: errors,
312
+ logs: log,
313
+ passed: passed,
314
+ skipped: skipped,
315
+ test_version: test_version,
316
+ updateAvailable: updateAvailable
317
+ };
318
+
319
+ var html = template( context );
320
+ $('#standardMode').append( html );
321
+ }
322
+
323
+ }
324
+
325
+ var recommendedVersionNumber = parseInt(test_version.replace(/\./, ''));
326
+ var current_version = $( '#current_php_version' ).val();
327
+ var currentVersionNumber = parseInt(current_version.replace(/\./, ''));
328
+ // Display global compatibility status.
329
+ if ( compatible ) {
330
+ // is compatible and ready to upgrade
331
+ if (currentVersionNumber < recommendedVersionNumber) {
332
+ $( '#phpVersionCheckerFooterMsg' ).html('');
333
+ jQuery( '#runButton' ).hide();
334
+ cleanupReport();
335
+ $( '#phpVersionCheckerHeaderMsgCompatible' ).html( '<font color="green">' + window.sg_wpephpcompat.your_wp +
336
+ ' PHP ' + test_version + ' ' +
337
+ window.sg_wpephpcompat.compatible + '. </font>');
338
+
339
+ $( '#upgradeButton' ).show();
340
+ $( '#upgradeButton' ).val(window.sg_wpephpcompat.upgrade_to + ' PHP ' + test_version);
341
+
342
+ // Up to Date
343
+ } else {
344
+ // $( '#phpVersionCheckerHeaderMsgUpToDate' ).html(window.sg_wpephpcompat.you_running_running_on + ' ' +
345
+ // current_version + ' ' +
346
+ // window.sg_wpephpcompat.recommended_or_higher);
347
+ }
348
+
349
+ } else {
350
+ $( '#phpVersionCheckerTextBelow' ).html(
351
+ window.sg_wpephpcompat.not_compatible +
352
+ test_version + '. ' +
353
+ window.sg_wpephpcompat.see_details_below);
354
+
355
+ var message = '';
356
+ message = window.sg_wpephpcompat.if_you_fixed_retry;
357
+
358
+ if (currentVersionNumber < 56) {
359
+ message = message + window.sg_wpephpcompat.recommend_to_switch;
360
+ }
361
+
362
+ $( '#phpVersionCheckerFooterMsg' ).html(message);
363
+ }
364
+ }
php-compatibility-checker/src/ruleset-wordpress.xml ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <ruleset name="WordPress-Core Custom">
3
+
4
+ <description>WordPress-Core Custom</description>
5
+
6
+ <!-- Include WordPress-Core standards. -->
7
+ <rule ref="WordPress-Core"/>
8
+
9
+ <!-- Whitelist member variables from core. -->
10
+ <rule ref="WordPress.NamingConventions.ValidVariableName">
11
+ <properties>
12
+ <property name="whitelisted_mixed_case_member_var_names" value="Name,ID" type="array"/>
13
+ </properties>
14
+ </rule>
15
+
16
+ </ruleset>
php-compatibility-checker/src/sg-wpephpcompat.php ADDED
@@ -0,0 +1,636 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Exit if this file is directly accessed
3
+ if ( ! defined( 'ABSPATH' ) ) { exit; }
4
+
5
+ require_once( __DIR__ . '/../vendor/autoload.php' );
6
+
7
+ /**
8
+ * Summary.
9
+ *
10
+ * Description.
11
+ *
12
+ * @since 1.0.0
13
+ */
14
+ class SG_WPEPHPCompat {
15
+ /**
16
+ * The PHP_CodeSniffer_CLI object.
17
+ *
18
+ * @since 1.0.0
19
+ * @access public
20
+ * @var object
21
+ */
22
+ public $cli = null;
23
+
24
+ /**
25
+ * Default values for PHP_CodeSniffer scan.
26
+ *
27
+ * @since 1.0.0
28
+ * @access public
29
+ * @var array
30
+ */
31
+ public $values = array();
32
+
33
+ /**
34
+ * Version of PHP to test.
35
+ *
36
+ * @since 1.0.0
37
+ * @access public
38
+ * @var string
39
+ */
40
+ public $test_version = null;
41
+
42
+ /**
43
+ * Scan only active plugins or all?
44
+ *
45
+ * @since 1.0.0
46
+ * @access public
47
+ * @var string
48
+ */
49
+ public $only_active = null;
50
+
51
+ /**
52
+ * The base directory for the plugin.
53
+ *
54
+ * @since 1.0.0
55
+ * @access public
56
+ * @var string
57
+ */
58
+ public $base = null;
59
+
60
+ private $whitelistUrl = 'http://updates.sgvps.net/plugins_whitelist.json';
61
+
62
+ private $errorsIgnorelistUrl = 'http://updates.sgvps.net/errors_ignorelist.json';
63
+
64
+ private $whitelist = null;
65
+
66
+ private $errorsIgnorelist = null;
67
+
68
+ private $errorsIgnorelistFallback = array(
69
+ array("rx" => "/WARNING\s+\|\s+INI\s+directive\s+'safe_mode'\s+is\s+deprecated\s+since\s+PHP\s+5\.3\s+and\s+removed\s+since\s+PHP\s+5\.4/"),
70
+ array("str" => "WARNING | INI directive 'safe_mode' is deprecated since PHP 5.3 and removed since PHP 5.4"),
71
+ array("str" => "File has mixed line endings; this may cause incorrect results")
72
+ );
73
+
74
+ /**
75
+ * Array of "directory name" => "latest PHP version it's compatible with".
76
+ *
77
+ * @todo Using the directory name is brittle, we shouldn't use it.
78
+ * @since 1.0.3
79
+ * @var array
80
+ */
81
+ public $whitelistFallback = array(
82
+ // https://wordpress.org/support/topic/false-positive-showing-bbpress-as-not-php-7-compatible/
83
+ "*/bbpress/*" => array( "bbPress", "2.5.12", "7.0"),
84
+
85
+ // https://wordpress.org/support/topic/false-positive-comet-cache/
86
+ "*/comet-cache/*" => array( "Comet Cache", "161221", "7.0"),
87
+
88
+ // https://wordpress.org/support/topic/false-positive-comment-mail/
89
+ "*/comment-mail/*" => array( "Comment Mail", "161213", "7.0",),
90
+
91
+ // https://github.com/wpengine/phpcompat/issues/84
92
+ "*/download-monitor/*" => array( "Download Monitor" , "1.9.5", "7.0",),
93
+
94
+ // https://github.com/wpengine/phpcompat/wiki/Results#easy-digital-downloads
95
+ "*/easy-digital-downloads/*" => array( "Easy Digital Downloads" , "2.6.17","7.0",),
96
+
97
+ // https://github.com/wpengine/phpcompat/issues/85
98
+ "*/gravityforms/*" => array( "GravityForm to Post" , "0.9" ,"7.0",),
99
+
100
+ // https://github.com/wpengine/phpcompat/wiki/Results#jetpack
101
+ "*/jetpack/*" => array( "Jetpack by WordPress.com" , "4.5" ,"7.0",),
102
+
103
+ // https://wordpress.org/support/topic/false-positive-mailpoet-3-not-compatible-with-php7/
104
+ "*/mailpoet/*" => array( "MailPoet" , "3.0.0-beta.15" ,"7.0",),
105
+
106
+ "*/megamenu/*" => array( "Max Mega Menu" , "2.3.4" ,"7.0",),
107
+
108
+ "*/myMail/*" => array( "MyMail - Email Newsletter Plugin for WordPress" , "2.1.32", "7.0",),
109
+
110
+ // https://wordpress.org/support/topic/false-positive-showing-query-monitor-as-not-php-7-compatible/
111
+ "*/query-monitor/*" => array( "Query Monitor" , "2.13.2", "7.0",),
112
+ "*/sg-cachepress/*" => array( array("SG CachePress", "SG Optimizer") , "3.0.0", "7.0",),
113
+ // https://wordpress.org/plugins/social-networks-auto-poster-facebook-twitter-g/
114
+ "*/social-networks-auto-poster-facebook-twitter-g/*" => array( "NextScripts: Social Networks Auto-Poster" , "3.7.14", "7.0",),
115
+ "*/tablepress/*" => array( "TablePress" , "1.7", "7.0",),
116
+ "*/updraftplus/*" => array( "UpdraftPlus" , "1.12.32", "7.0",),
117
+ "*/vendor/stripe/stripe-php/lib/StripeObject.php" => array( '*' , '*', "7.0",),
118
+
119
+ // https://github.com/wpengine/phpcompat/wiki/Results#woocommerce
120
+ "*/woocommerce/*" => array( "WooCommerce" , "2.6.13", "7.0",),
121
+
122
+ // https://github.com/wpengine/phpcompat/wiki/Results#wordfence-security
123
+ "*/wordfence/*" => array( "Wordfence Security" , "6.3.0", "7.0",),
124
+
125
+ // https://github.com/wpengine/phpcompat/wiki/Results#wp-migrate-db
126
+ "*/wp-migrate-db/*" => array( "WP Migrate DB" , "0.9.2", "7.0",),
127
+ "*/wp-spamshield/*" => array( "WP-SpamShield" , "1.9.9.8.7", "7.0",),
128
+ );
129
+
130
+ public function get_list($listName) {
131
+ if ($this->$listName !== null) {
132
+ return $this->$listName;
133
+ }
134
+
135
+ ini_set('default_socket_timeout', 10);
136
+ $listJson = file_get_contents($this->{$listName . 'Url'});
137
+ $listArray = json_decode($listJson, true);
138
+
139
+ if (json_last_error() === JSON_ERROR_NONE) {
140
+ $this->$listName = $listArray;
141
+ } else {
142
+ $this->$listName = $this->{$listName . 'Fallback'};
143
+ }
144
+
145
+ return $this->$listName;
146
+ }
147
+
148
+ /**
149
+ * @param string $dir Base plugin directory.
150
+ */
151
+ function __construct( $dir ) {
152
+ $this->base = $dir;
153
+ $this->cli = new PHP_CodeSniffer_CLI();
154
+ }
155
+
156
+ /**
157
+ * Start the testing process.
158
+ *
159
+ * @since 1.0.0
160
+ * @return null
161
+ */
162
+ public function start_test() {
163
+ $this->debug_log( 'startScan: ' . isset( $_POST['startScan'] ) );
164
+
165
+ /**
166
+ * Filters the scan timeout.
167
+ *
168
+ * Lets you change the timeout of the scan. The value is how long the scan
169
+ * runs before dying and picking back up on a cron. You can set $timeout to
170
+ * 0 to disable the timeout and the cron.
171
+ *
172
+ * @since 1.0.4
173
+ *
174
+ * @param int $timeout The timeout in seconds.
175
+ */
176
+ $timeout = apply_filters( 'sg_wpephpcompat_scan_timeout', 29 );
177
+ $this->debug_log( 'timeout: ' . $timeout );
178
+
179
+ // No reason to lock if there's no timeout.
180
+ if ( 0 !== $timeout ) {
181
+ // Try to lock.
182
+ $lock_result = add_option( 'sg_wpephpcompat.lock', time(), '', 'no' );
183
+
184
+ $this->debug_log( 'lock: ' . $lock_result );
185
+
186
+ if ( ! $lock_result ) {
187
+ $lock_result = get_option( 'sg_wpephpcompat.lock' );
188
+
189
+ // Bail if we were unable to create a lock, or if the existing lock is still valid.
190
+ if ( ! $lock_result || ( $lock_result > ( time() - $timeout ) ) ) {
191
+ $this->debug_log( 'Process already running (locked), returning.' );
192
+
193
+ $timestamp = wp_next_scheduled( 'sg_wpephpcompat_start_test_cron' );
194
+
195
+ if ( false == $timestamp ) {
196
+ wp_schedule_single_event( time() + $timeout, 'sg_wpephpcompat_start_test_cron' );
197
+ }
198
+ return;
199
+ }
200
+ }
201
+ update_option( 'sg_wpephpcompat.lock', time(), false );
202
+ }
203
+
204
+ // Check to see if scan has already started.
205
+ $scan_status = get_option( 'sg_wpephpcompat.status' );
206
+ $this->debug_log( 'scan status: ' . $scan_status );
207
+ if ( ! $scan_status ) {
208
+
209
+ // Clear the previous results.
210
+ delete_option( 'sg_wpephpcompat.scan_results' );
211
+
212
+ update_option( 'sg_wpephpcompat.status', '1', false );
213
+ update_option( 'sg_wpephpcompat.test_version', $this->test_version, false );
214
+ update_option( 'sg_wpephpcompat.only_active', $this->only_active, false );
215
+
216
+ $this->debug_log( 'Generating directory list.' );
217
+ //Add plugins and themes.
218
+ $this->generate_directory_list();
219
+
220
+ $count_jobs = wp_count_posts( 'sg_optimizer_jobs' );
221
+ update_option( 'sg_wpephpcompat.numdirs', $count_jobs->publish, false );
222
+ } else {
223
+ // Get scan settings from database.
224
+ $this->test_version = get_option( 'sg_wpephpcompat.test_version' );
225
+ $this->only_active = get_option( 'sg_wpephpcompat.only_active' );
226
+ }
227
+
228
+ $args = array(
229
+ 'posts_per_page' => -1,
230
+ 'post_type' => 'sg_optimizer_jobs',
231
+ 'orderby' => 'title',
232
+ 'order' => 'ASC',
233
+ );
234
+ $directories = get_posts( $args );
235
+ $this->debug_log( count( $directories ) . ' plugins left to process.' );
236
+
237
+ // If there are no directories to scan, we're finished!
238
+ if ( ! $directories ) {
239
+ $this->debug_log( 'No more plugins to process.' );
240
+ update_option( 'sg_wpephpcompat.status', '0', false );
241
+
242
+ return;
243
+ }
244
+ if ( 0 !== $timeout ) {
245
+ wp_schedule_single_event( time() + $timeout, 'sg_wpephpcompat_start_test_cron' );
246
+ }
247
+
248
+ if ( ! $this->is_command_line() ) {
249
+ // Close the connection to the browser.
250
+ $this->close_connection( 'started' );
251
+
252
+ /**
253
+ * Kill cron after a configurable timeout.
254
+ * Subtract 5 from the timeout if we can to avoid race conditions.
255
+ */
256
+ set_time_limit( ( $timeout > 5 ? $timeout - 5 : $timeout ) );
257
+ }
258
+
259
+ $scan_results = get_option( 'sg_wpephpcompat.scan_results' );
260
+
261
+ foreach ( $directories as $directory ) {
262
+ $data = json_decode($directory->post_excerpt, true);
263
+ $myVersion = isset($data['Version']) && strlen($data['Version']) ? $data['Version'] : 'XXX';
264
+ $ts = time();
265
+ $this->debug_log( 'Processing: ' . $directory->post_title );
266
+
267
+ // Add the plugin/theme name to the results.
268
+ $scan_results .= __( 'Name', 'sg-cachepress' ) . ': ' . $directory->post_title . "\n\n";
269
+
270
+ // Keep track of the number of times we've attempted to scan the plugin.
271
+ $count = get_post_meta( $directory->ID, 'count', true ) ?: 1;
272
+ $this->debug_log( 'Attempted scan count: ' . $count );
273
+
274
+ if ( $count > 2 ) { // If we've already tried twice, skip it.
275
+ $scan_results .= __( 'The plugin/theme was skipped as it was too large to scan before the server killed the process.', 'sg-cachepress' ) . "\n\n";
276
+ update_option( 'sg_wpephpcompat.scan_results', $scan_results , false );
277
+ wp_delete_post( $directory->ID );
278
+ $count = 0;
279
+ $this->debug_log( 'Skipped: ' . $directory->post_title );
280
+ continue;
281
+ }
282
+
283
+ // Increment and save the count.
284
+ $count++;
285
+ update_post_meta( $directory->ID, 'count', $count );
286
+
287
+ // Start the scan.
288
+ $report = $this->process_file( $directory->post_content, $directory->post_title, $data );
289
+
290
+ if ( ! $report ) {
291
+ $report = 'PHP ' . $this->test_version . __( ' compatible.', 'sg-cachepress' );
292
+ }
293
+
294
+ $scan_results .= $report . "\n";
295
+
296
+ $update = get_post_meta( $directory->ID, 'update', true );
297
+
298
+ if ( ! empty( $update ) ) {
299
+ $version = get_post_meta( $directory->ID, 'version', true );
300
+ $scan_results .= 'Update Available: ' . $update . '; Current Version: ' . $version . ";\n";
301
+ }
302
+
303
+ $scan_results .= "\n";
304
+
305
+ update_option( 'sg_wpephpcompat.scan_results', $scan_results , false );
306
+
307
+ wp_delete_post( $directory->ID );
308
+ }
309
+
310
+ update_option( 'sg_wpephpcompat.status', '0', false );
311
+
312
+ $this->debug_log( 'Scan finished.' );
313
+
314
+ $lines = array();
315
+ $i = 0;
316
+
317
+ foreach(explode(PHP_EOL, $scan_results) as $line) {
318
+ $lines[$i] = $line;
319
+ $isIgnored = false;
320
+
321
+ // check if this row match some of the whitelisted (ignored) warnings
322
+ foreach ($this->get_list('errorsIgnorelist') as $ignoredErr) {
323
+ if (isset($ignoredErr['str']) && strpos($line, $ignoredErr['str']) !== false) {
324
+ $isIgnored = true;
325
+ }
326
+
327
+ if (isset($ignoredErr['rx']) && preg_match($ignoredErr['rx'], $line)) {
328
+ $isIgnored = true;
329
+ }
330
+ }
331
+
332
+ // delete the whole block
333
+ if ($isIgnored) {
334
+ foreach (range(0, 4) as $num) {
335
+ if (strlen($lines[$i - $num])) {
336
+ $lines[$i - $num] = '';
337
+ }
338
+ }
339
+ }
340
+
341
+ $i++;
342
+ }
343
+
344
+ $scan_results = implode(PHP_EOL, $lines);
345
+
346
+ $scan_results .= 'End Report ';
347
+ $scan_results .= time();
348
+ update_option( 'sg_wpephpcompat.scan_results', $scan_results , false );
349
+ return $scan_results;
350
+ }
351
+
352
+ /**
353
+ * Runs the actual PHPCompatibility test.
354
+ *
355
+ * @since 1.0.0
356
+ * @return string Scan results.
357
+ */
358
+ public function process_file( $dir, $plugin_name, $plugin_data ) {
359
+ $plugin_version = isset($plugin_data['Version']) ? $plugin_data['Version'] : false;
360
+
361
+ $this->values['files'] = $dir;
362
+ $this->values['testVersion'] = $this->test_version;
363
+ $this->values['standard'] = 'PHPCompatibility';
364
+ $this->values['reportWidth'] = '9999';
365
+ $this->values['extensions'] = array( 'php' );
366
+
367
+ // Whitelist.
368
+ $this->values['ignored'] = $this->generate_ignored_list($plugin_name, $plugin_version);
369
+
370
+ PHP_CodeSniffer::setConfigData( 'testVersion', $this->test_version, true );
371
+
372
+ ob_start();
373
+
374
+ $this->cli->process( $this->values );
375
+
376
+ $report = ob_get_clean();
377
+
378
+ return $this->clean_report( $report );
379
+ }
380
+
381
+ /**
382
+ * Generate a list of ignored files and directories.
383
+ *
384
+ * @since 1.0.3
385
+ * @return array An array containing files and directories that should be ignored.
386
+ */
387
+ public function generate_ignored_list($plugin_name, $current_plugin_version) {
388
+ // Default ignored list.
389
+ $ignored = array(
390
+ '*/tests/*', // No reason to scan tests.
391
+ '*/test/*', // Another common test directory.
392
+ '*/node_modules/*', // Commonly used for development but not in production.
393
+ '*/tmp/*', // Temporary files.
394
+ );
395
+
396
+ //print_r(json_encode($this->get_list('whitelist')));exit;
397
+ foreach ( $this->get_list('whitelist') as $plugin => $whitelistData ) {
398
+ $whitelisted_plugin_name = $whitelistData[0];
399
+ $whitelisted_plugin_version = $whitelistData[1];
400
+ $whitelisted_php_version = $whitelistData[2];
401
+
402
+ // plugin name not mtach (array)
403
+ if ($whitelisted_plugin_version !== '*' && // is not wildcard
404
+ is_array($whitelisted_plugin_name) &&
405
+ !in_array( $plugin_name, $whitelisted_plugin_name )
406
+ ) {
407
+ continue;
408
+ }
409
+
410
+ // plugin name not mtach (string)
411
+ if ($whitelisted_plugin_version !== '*' && // is not wildcard
412
+ !is_array($whitelisted_plugin_name) &&
413
+ $plugin_name !== $whitelisted_plugin_name) {
414
+ continue;
415
+ }
416
+
417
+ // compare plugin version
418
+ if ($whitelisted_plugin_version !== null && !version_compare( $current_plugin_version, $whitelisted_plugin_version, '>=' )) {
419
+ continue;
420
+ }
421
+
422
+
423
+ // Check to see if the plugin is compatible with the tested PHP version.
424
+ if ( version_compare( $this->test_version, $whitelisted_php_version, '<=' ) ) {
425
+ array_push( $ignored, $plugin );
426
+ }
427
+ }
428
+
429
+ return apply_filters( 'phpcompat_whitelist', $ignored );
430
+ }
431
+
432
+ /**
433
+ * Generate a list of directories to scan and populate the queue.
434
+ *
435
+ * @since 1.0.0
436
+ * @return null
437
+ */
438
+ public function generate_directory_list() {
439
+ if ( ! function_exists( 'get_plugins' ) ) {
440
+
441
+ require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
442
+ }
443
+
444
+ $plugin_base = dirname( $this->base ) . DIRECTORY_SEPARATOR;
445
+
446
+ $all_plugins = get_plugins();
447
+
448
+ $update_plugins = get_site_transient( 'update_plugins' );
449
+
450
+ foreach ( $all_plugins as $k => $v ) {
451
+ //Exclude our plugin.
452
+ if ( 'PHP Compatibility Checker' === $v['Name'] ) {
453
+ continue;
454
+ }
455
+
456
+ // Exclude active plugins if only_active = "yes".
457
+ if ( 'yes' === $this->only_active ) {
458
+ // Get array of active plugins.
459
+ $active_plugins = get_option( 'active_plugins' );
460
+
461
+ if ( ! in_array( $k, $active_plugins ) ) {
462
+ continue;
463
+ }
464
+ }
465
+
466
+ $plugin_file = plugin_dir_path( $k );
467
+
468
+ // Plugin in root directory (like Hello Dolly).
469
+ if ( './' === $plugin_file ) {
470
+ $plugin_path = $plugin_base . $k;
471
+ } else {
472
+ $plugin_path = $plugin_base . $plugin_file;
473
+ }
474
+
475
+ $data = isset($v['Version']) ? array( 'Version' => $v['Version']) : false;
476
+ $id = $this->add_directory( $v['Name'], $plugin_path, $data );
477
+
478
+ if ( is_object( $update_plugins ) && is_array( $update_plugins->response ) ) {
479
+ // Check for plugin updates.
480
+ foreach ( $update_plugins->response as $uk => $uv ) {
481
+ // If we have a match.
482
+ if ( $uk === $k ) {
483
+ $this->debug_log( 'An update exists for: ' . $v['Name'] );
484
+ // Save the update version.
485
+ update_post_meta( $id, 'update', $uv->new_version );
486
+ // Save the current version.
487
+ update_post_meta( $id, 'version', $v['Version'] );
488
+ }
489
+ }
490
+ }
491
+ }
492
+
493
+ // Add themes.
494
+ $all_themes = wp_get_themes();
495
+
496
+ foreach ( $all_themes as $k => $v ) {
497
+ if ( 'yes' === $this->only_active ) {
498
+ $current_theme = wp_get_theme();
499
+ if ( $all_themes[ $k ]->Name != $current_theme->Name ) {
500
+ continue;
501
+ }
502
+ }
503
+
504
+ $theme_path = $all_themes[ $k ]->theme_root . DIRECTORY_SEPARATOR . $k . DIRECTORY_SEPARATOR;
505
+
506
+ $data = isset($all_themes[ $k ]->Version) ? array( 'Version' => $all_themes[ $k ]->Version) : false;
507
+ $this->add_directory( $all_themes[ $k ]->Name, $theme_path, $data );
508
+ }
509
+
510
+ // Add parent theme if the current theme is a child theme.
511
+ if ( 'yes' === $this->only_active && is_child_theme() ) {
512
+ $parent_theme_path = get_template_directory();
513
+ $theme_data = wp_get_theme();
514
+ $parent_theme_name = $theme_data->parent()->Name;
515
+
516
+ $parent_theme_version = $theme_data->parent()->Version;
517
+ $data = isset($parent_theme_version) ? array( 'Version' => $parent_theme_version) : false;
518
+ $this->add_directory( $parent_theme_name, $parent_theme_path, $data );
519
+ }
520
+ }
521
+
522
+ /**
523
+ * Cleans and formats the final report.
524
+ *
525
+ * @param string $report The full report.
526
+ * @return string The cleaned report.
527
+ */
528
+ public function clean_report( $report ) {
529
+ // Remove unnecessary overview.
530
+ $report = preg_replace( '/Time:.+\n/si', '', $report );
531
+
532
+ // Remove whitespace.
533
+ $report = trim( $report );
534
+
535
+ return $report;
536
+ }
537
+
538
+ /**
539
+ * Remove all database entries created by the scan.
540
+ *
541
+ * @since 1.0.0
542
+ * @return null
543
+ */
544
+ public function clean_after_scan() {
545
+ // Delete options created during the scan.
546
+ delete_option( 'sg_wpephpcompat.lock' );
547
+ delete_option( 'sg_wpephpcompat.status' );
548
+ delete_option( 'sg_wpephpcompat.numdirs' );
549
+
550
+ // Clear scheduled cron.
551
+ wp_clear_scheduled_hook( 'sg_wpephpcompat_start_test_cron' );
552
+
553
+ //Make sure all directories are removed from the queue.
554
+ $args = array(
555
+ 'posts_per_page' => -1,
556
+ 'post_type' => 'sg_optimizer_jobs',
557
+ );
558
+ $directories = get_posts( $args );
559
+
560
+ foreach ( $directories as $directory ) {
561
+ wp_delete_post( $directory->ID );
562
+ }
563
+ }
564
+
565
+ /**
566
+ * Add a path to the sg_optimizer_jobs custom post type.
567
+ *
568
+ * @param string $name Plugin or theme name.
569
+ * @param string $path Full path to the plugin or theme directory.
570
+ * @return null
571
+ */
572
+ private function add_directory( $name, $path, $data=array() ) {
573
+ $dir = array(
574
+ 'post_title' => $name,
575
+ 'post_content' => $path,
576
+ 'post_excerpt' => json_encode($data),
577
+ 'post_status' => 'publish',
578
+ 'post_author' => 1,
579
+ 'post_type' => 'sg_optimizer_jobs',
580
+ );
581
+
582
+ return wp_insert_post( $dir );
583
+ }
584
+
585
+ /**
586
+ * Log to the error log if WP_DEBUG is enabled.
587
+ *
588
+ * @since 1.0.0
589
+ * @param string $message Message to log.
590
+ * @return null
591
+ */
592
+ private function debug_log( $message ) {
593
+ if ( defined( 'WP_DEBUG' ) && WP_DEBUG === true && ! $this->is_command_line() ) {
594
+ if ( is_array( $message ) || is_object( $message ) ) {
595
+ error_log( print_r( $message , true ) );
596
+ } else {
597
+ error_log( 'WPE PHP Compatibility: ' . $message );
598
+ }
599
+ }
600
+ }
601
+
602
+ /**
603
+ * Are we running on the command line?
604
+ *
605
+ * @since 1.0.0
606
+ * @return boolean Returns true if the request came from the command line.
607
+ */
608
+ private function is_command_line() {
609
+ return defined( 'WP_CLI' ) || defined( 'PHPUNIT_TEST' ) || php_sapi_name() == 'cli';
610
+ }
611
+
612
+ /**
613
+ * Close the connection to the browser but continue processing the operation.
614
+ * @since 1.0.0
615
+ * @param string $body The message to send to the client.
616
+ * @return null
617
+ */
618
+ private function close_connection( $body ) {
619
+ ignore_user_abort( true );
620
+ if ( ob_get_length() ) { ob_end_clean(); }
621
+ // Start buffering.
622
+ ob_start();
623
+ // Echo our response.
624
+ //echo $body;
625
+ // Get the length of the buffer.
626
+ $size = ob_get_length();
627
+ // Close the connection.
628
+ header( 'Connection: close\r\n' );
629
+ header( 'Content-Encoding: none\r\n' );
630
+ header( 'Content-Length: $size' );
631
+ // Flush and close the buffer.
632
+ ob_end_flush();
633
+ // Flush the system output buffer.
634
+ flush();
635
+ }
636
+ }
php-compatibility-checker/src/wpcli.php ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once( __DIR__ . '/../vendor/autoload.php' );
3
+
4
+ /**
5
+ * PHPCompat WP-CLI command.
6
+ *
7
+ * Test compatibility with different PHP versions.
8
+ *
9
+ * @since 1.0.0
10
+ */
11
+ class SGPHPCompat_Command extends WP_CLI_Command {
12
+
13
+ /**
14
+ * Test compatibility with different PHP versions.
15
+ *
16
+ * ## EXAMPLES
17
+ *
18
+ * wp phpcompat 5.5 --scan=active
19
+ */
20
+ function __invoke( $args, $assoc_args ) {
21
+
22
+ // Get the PHP test version.
23
+ $test_version = $args[0];
24
+
25
+ WP_CLI::log( 'Testing compatibility with PHP ' . $test_version . '.' );
26
+ // Add empty line.
27
+ WP_CLI::log( '' );
28
+
29
+ $root_dir = realpath( __DIR__ . '/../' );
30
+
31
+ $wpephpc = new \SG_WPEPHPCompat( $root_dir );
32
+
33
+ $wpephpc->clean_after_scan();
34
+
35
+ $wpephpc->test_version = $test_version;
36
+
37
+ // Set scan type if 'scan' was passed in.
38
+ if ( isset( $assoc_args['scan'] ) && 'active' === $assoc_args['scan'] ) {
39
+ $wpephpc->only_active = 'yes';
40
+ }
41
+
42
+ $results = $wpephpc->start_test();
43
+
44
+ WP_CLI::log( $results );
45
+
46
+ $wpephpc->clean_after_scan();
47
+ delete_option( 'sg_wpephpcompat.scan_results' );
48
+
49
+ if ( preg_match( '/(\d*) ERRORS?/i', $results ) ) {
50
+ WP_CLI::error( 'Your WordPress install is not compatible.' );
51
+ } else {
52
+ WP_CLI::success( 'Your WordPress install is compatible.' );
53
+ }
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Using this for now since there are issues with the PHPDoc syntax.
59
+ * TODO: Use PHPDoc syntax.
60
+ */
61
+ WP_CLI::add_command( 'sgphpcompat', 'SGPHPCompat_Command', array(
62
+ 'shortdesc' => 'Test compatibility with different PHP versions.',
63
+ 'synopsis' => array(
64
+ array(
65
+ 'type' => 'positional',
66
+ 'name' => 'version',
67
+ 'optional' => false,
68
+ 'multiple' => false,
69
+ ),
70
+ array(
71
+ 'type' => 'assoc',
72
+ 'name' => 'scan',
73
+ 'optional' => true,
74
+ 'default' => 'active',
75
+ 'options' => array( 'active', 'all' ),
76
+ ),
77
+ ),
78
+ ));
php-compatibility-checker/vendor/autoload.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload.php @generated by Composer
4
+
5
+ require_once __DIR__ . '/composer' . '/autoload_real.php';
6
+
7
+ return ComposerAutoloaderInit40c259fa07cfee03e82e5f2dswm504zz::getLoader();
php-compatibility-checker/vendor/composer/ClassLoader.php ADDED
@@ -0,0 +1,413 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Composer.
5
+ *
6
+ * (c) Nils Adermann <naderman@naderman.de>
7
+ * Jordi Boggiano <j.boggiano@seld.be>
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Composer\Autoload;
14
+
15
+ /**
16
+ * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
17
+ *
18
+ * $loader = new \Composer\Autoload\ClassLoader();
19
+ *
20
+ * // register classes with namespaces
21
+ * $loader->add('Symfony\Component', __DIR__.'/component');
22
+ * $loader->add('Symfony', __DIR__.'/framework');
23
+ *
24
+ * // activate the autoloader
25
+ * $loader->register();
26
+ *
27
+ * // to enable searching the include path (eg. for PEAR packages)
28
+ * $loader->setUseIncludePath(true);
29
+ *
30
+ * In this example, if you try to use a class in the Symfony\Component
31
+ * namespace or one of its children (Symfony\Component\Console for instance),
32
+ * the autoloader will first look for the class under the component/
33
+ * directory, and it will then fallback to the framework/ directory if not
34
+ * found before giving up.
35
+ *
36
+ * This class is loosely based on the Symfony UniversalClassLoader.
37
+ *
38
+ * @author Fabien Potencier <fabien@symfony.com>
39
+ * @author Jordi Boggiano <j.boggiano@seld.be>
40
+ * @see http://www.php-fig.org/psr/psr-0/
41
+ * @see http://www.php-fig.org/psr/psr-4/
42
+ */
43
+ class ClassLoader
44
+ {
45
+ // PSR-4
46
+ private $prefixLengthsPsr4 = array();
47
+ private $prefixDirsPsr4 = array();
48
+ private $fallbackDirsPsr4 = array();
49
+
50
+ // PSR-0
51
+ private $prefixesPsr0 = array();
52
+ private $fallbackDirsPsr0 = array();
53
+
54
+ private $useIncludePath = false;
55
+ private $classMap = array();
56
+
57
+ private $classMapAuthoritative = false;
58
+
59
+ public function getPrefixes()
60
+ {
61
+ if (!empty($this->prefixesPsr0)) {
62
+ return call_user_func_array('array_merge', $this->prefixesPsr0);
63
+ }
64
+
65
+ return array();
66
+ }
67
+
68
+ public function getPrefixesPsr4()
69
+ {
70
+ return $this->prefixDirsPsr4;
71
+ }
72
+
73
+ public function getFallbackDirs()
74
+ {
75
+ return $this->fallbackDirsPsr0;
76
+ }
77
+
78
+ public function getFallbackDirsPsr4()
79
+ {
80
+ return $this->fallbackDirsPsr4;
81
+ }
82
+
83
+ public function getClassMap()
84
+ {
85
+ return $this->classMap;
86
+ }
87
+
88
+ /**
89
+ * @param array $classMap Class to filename map
90
+ */
91
+ public function addClassMap(array $classMap)
92
+ {
93
+ if ($this->classMap) {
94
+ $this->classMap = array_merge($this->classMap, $classMap);
95
+ } else {
96
+ $this->classMap = $classMap;
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Registers a set of PSR-0 directories for a given prefix, either
102
+ * appending or prepending to the ones previously set for this prefix.
103
+ *
104
+ * @param string $prefix The prefix
105
+ * @param array|string $paths The PSR-0 root directories
106
+ * @param bool $prepend Whether to prepend the directories
107
+ */
108
+ public function add($prefix, $paths, $prepend = false)
109
+ {
110
+ if (!$prefix) {
111
+ if ($prepend) {
112
+ $this->fallbackDirsPsr0 = array_merge(
113
+ (array) $paths,
114
+ $this->fallbackDirsPsr0
115
+ );
116
+ } else {
117
+ $this->fallbackDirsPsr0 = array_merge(
118
+ $this->fallbackDirsPsr0,
119
+ (array) $paths
120
+ );
121
+ }
122
+
123
+ return;
124
+ }
125
+
126
+ $first = $prefix[0];
127
+ if (!isset($this->prefixesPsr0[$first][$prefix])) {
128
+ $this->prefixesPsr0[$first][$prefix] = (array) $paths;
129
+
130
+ return;
131
+ }
132
+ if ($prepend) {
133
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
134
+ (array) $paths,
135
+ $this->prefixesPsr0[$first][$prefix]
136
+ );
137
+ } else {
138
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
139
+ $this->prefixesPsr0[$first][$prefix],
140
+ (array) $paths
141
+ );
142
+ }
143
+ }
144
+
145
+ /**
146
+ * Registers a set of PSR-4 directories for a given namespace, either
147
+ * appending or prepending to the ones previously set for this namespace.
148
+ *
149
+ * @param string $prefix The prefix/namespace, with trailing '\\'
150
+ * @param array|string $paths The PSR-4 base directories
151
+ * @param bool $prepend Whether to prepend the directories
152
+ *
153
+ * @throws \InvalidArgumentException
154
+ */
155
+ public function addPsr4($prefix, $paths, $prepend = false)
156
+ {
157
+ if (!$prefix) {
158
+ // Register directories for the root namespace.
159
+ if ($prepend) {
160
+ $this->fallbackDirsPsr4 = array_merge(
161
+ (array) $paths,
162
+ $this->fallbackDirsPsr4
163
+ );
164
+ } else {
165
+ $this->fallbackDirsPsr4 = array_merge(
166
+ $this->fallbackDirsPsr4,
167
+ (array) $paths
168
+ );
169
+ }
170
+ } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
171
+ // Register directories for a new namespace.
172
+ $length = strlen($prefix);
173
+ if ('\\' !== $prefix[$length - 1]) {
174
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
175
+ }
176
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
177
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
178
+ } elseif ($prepend) {
179
+ // Prepend directories for an already registered namespace.
180
+ $this->prefixDirsPsr4[$prefix] = array_merge(
181
+ (array) $paths,
182
+ $this->prefixDirsPsr4[$prefix]
183
+ );
184
+ } else {
185
+ // Append directories for an already registered namespace.
186
+ $this->prefixDirsPsr4[$prefix] = array_merge(
187
+ $this->prefixDirsPsr4[$prefix],
188
+ (array) $paths
189
+ );
190
+ }
191
+ }
192
+
193
+ /**
194
+ * Registers a set of PSR-0 directories for a given prefix,
195
+ * replacing any others previously set for this prefix.
196
+ *
197
+ * @param string $prefix The prefix
198
+ * @param array|string $paths The PSR-0 base directories
199
+ */
200
+ public function set($prefix, $paths)
201
+ {
202
+ if (!$prefix) {
203
+ $this->fallbackDirsPsr0 = (array) $paths;
204
+ } else {
205
+ $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
206
+ }
207
+ }
208
+
209
+ /**
210
+ * Registers a set of PSR-4 directories for a given namespace,
211
+ * replacing any others previously set for this namespace.
212
+ *
213
+ * @param string $prefix The prefix/namespace, with trailing '\\'
214
+ * @param array|string $paths The PSR-4 base directories
215
+ *
216
+ * @throws \InvalidArgumentException
217
+ */
218
+ public function setPsr4($prefix, $paths)
219
+ {
220
+ if (!$prefix) {
221
+ $this->fallbackDirsPsr4 = (array) $paths;
222
+ } else {
223
+ $length = strlen($prefix);
224
+ if ('\\' !== $prefix[$length - 1]) {
225
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
226
+ }
227
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
228
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
229
+ }
230
+ }
231
+
232
+ /**
233
+ * Turns on searching the include path for class files.
234
+ *
235
+ * @param bool $useIncludePath
236
+ */
237
+ public function setUseIncludePath($useIncludePath)
238
+ {
239
+ $this->useIncludePath = $useIncludePath;
240
+ }
241
+
242
+ /**
243
+ * Can be used to check if the autoloader uses the include path to check
244
+ * for classes.
245
+ *
246
+ * @return bool
247
+ */
248
+ public function getUseIncludePath()
249
+ {
250
+ return $this->useIncludePath;
251
+ }
252
+
253
+ /**
254
+ * Turns off searching the prefix and fallback directories for classes
255
+ * that have not been registered with the class map.
256
+ *
257
+ * @param bool $classMapAuthoritative
258
+ */
259
+ public function setClassMapAuthoritative($classMapAuthoritative)
260
+ {
261
+ $this->classMapAuthoritative = $classMapAuthoritative;
262
+ }
263
+
264
+ /**
265
+ * Should class lookup fail if not found in the current class map?
266
+ *
267
+ * @return bool
268
+ */
269
+ public function isClassMapAuthoritative()
270
+ {
271
+ return $this->classMapAuthoritative;
272
+ }
273
+
274
+ /**
275
+ * Registers this instance as an autoloader.
276
+ *
277
+ * @param bool $prepend Whether to prepend the autoloader or not
278
+ */
279
+ public function register($prepend = false)
280
+ {
281
+ spl_autoload_register(array($this, 'loadClass'), true, $prepend);
282
+ }
283
+
284
+ /**
285
+ * Unregisters this instance as an autoloader.
286
+ */
287
+ public function unregister()
288
+ {
289
+ spl_autoload_unregister(array($this, 'loadClass'));
290
+ }
291
+
292
+ /**
293
+ * Loads the given class or interface.
294
+ *
295
+ * @param string $class The name of the class
296
+ * @return bool|null True if loaded, null otherwise
297
+ */
298
+ public function loadClass($class)
299
+ {
300
+ if ($file = $this->findFile($class)) {
301
+ includeFile($file);
302
+
303
+ return true;
304
+ }
305
+ }
306
+
307
+ /**
308
+ * Finds the path to the file where the class is defined.
309
+ *
310
+ * @param string $class The name of the class
311
+ *
312
+ * @return string|false The path if found, false otherwise
313
+ */
314
+ public function findFile($class)
315
+ {
316
+ // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
317
+ if ('\\' == $class[0]) {
318
+ $class = substr($class, 1);
319
+ }
320
+
321
+ // class map lookup
322
+ if (isset($this->classMap[$class])) {
323
+ return $this->classMap[$class];
324
+ }
325
+ if ($this->classMapAuthoritative) {
326
+ return false;
327
+ }
328
+
329
+ $file = $this->findFileWithExtension($class, '.php');
330
+
331
+ // Search for Hack files if we are running on HHVM
332
+ if ($file === null && defined('HHVM_VERSION')) {
333
+ $file = $this->findFileWithExtension($class, '.hh');
334
+ }
335
+
336
+ if ($file === null) {
337
+ // Remember that this class does not exist.
338
+ return $this->classMap[$class] = false;
339
+ }
340
+
341
+ return $file;
342
+ }
343
+
344
+ private function findFileWithExtension($class, $ext)
345
+ {
346
+ // PSR-4 lookup
347
+ $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
348
+
349
+ $first = $class[0];
350
+ if (isset($this->prefixLengthsPsr4[$first])) {
351
+ foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
352
+ if (0 === strpos($class, $prefix)) {
353
+ foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
354
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
355
+ return $file;
356
+ }
357
+ }
358
+ }
359
+ }
360
+ }
361
+
362
+ // PSR-4 fallback dirs
363
+ foreach ($this->fallbackDirsPsr4 as $dir) {
364
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
365
+ return $file;
366
+ }
367
+ }
368
+
369
+ // PSR-0 lookup
370
+ if (false !== $pos = strrpos($class, '\\')) {
371
+ // namespaced class name
372
+ $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
373
+ . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
374
+ } else {
375
+ // PEAR-like class name
376
+ $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
377
+ }
378
+
379
+ if (isset($this->prefixesPsr0[$first])) {
380
+ foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
381
+ if (0 === strpos($class, $prefix)) {
382
+ foreach ($dirs as $dir) {
383
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
384
+ return $file;
385
+ }
386
+ }
387
+ }
388
+ }
389
+ }
390
+
391
+ // PSR-0 fallback dirs
392
+ foreach ($this->fallbackDirsPsr0 as $dir) {
393
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
394
+ return $file;
395
+ }
396
+ }
397
+
398
+ // PSR-0 include paths.
399
+ if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
400
+ return $file;
401
+ }
402
+ }
403
+ }
404
+
405
+ /**
406
+ * Scope isolated include.
407
+ *
408
+ * Prevents access to $this/self from included files.
409
+ */
410
+ function includeFile($file)
411
+ {
412
+ include $file;
413
+ }
php-compatibility-checker/vendor/composer/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ Copyright (c) 2015 Nils Adermann, Jordi Boggiano
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is furnished
9
+ to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ THE SOFTWARE.
21
+
php-compatibility-checker/vendor/composer/autoload_classmap.php ADDED
@@ -0,0 +1,258 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_classmap.php @generated by Composer
4
+
5
+ $vendorDir = dirname(dirname(__FILE__));
6
+ $baseDir = dirname($vendorDir);
7
+
8
+ return array(
9
+ 'Generic_Sniffs_Arrays_DisallowLongArraySyntaxSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Arrays/DisallowLongArraySyntaxSniff.php',
10
+ 'Generic_Sniffs_Arrays_DisallowShortArraySyntaxSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Arrays/DisallowShortArraySyntaxSniff.php',
11
+ 'Generic_Sniffs_Classes_DuplicateClassNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Classes/DuplicateClassNameSniff.php',
12
+ 'Generic_Sniffs_CodeAnalysis_EmptyStatementSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/EmptyStatementSniff.php',
13
+ 'Generic_Sniffs_CodeAnalysis_ForLoopShouldBeWhileLoopSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/ForLoopShouldBeWhileLoopSniff.php',
14
+ 'Generic_Sniffs_CodeAnalysis_ForLoopWithTestFunctionCallSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/ForLoopWithTestFunctionCallSniff.php',
15
+ 'Generic_Sniffs_CodeAnalysis_JumbledIncrementerSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/JumbledIncrementerSniff.php',
16
+ 'Generic_Sniffs_CodeAnalysis_UnconditionalIfStatementSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/UnconditionalIfStatementSniff.php',
17
+ 'Generic_Sniffs_CodeAnalysis_UnnecessaryFinalModifierSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/UnnecessaryFinalModifierSniff.php',
18
+ 'Generic_Sniffs_CodeAnalysis_UnusedFunctionParameterSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/UnusedFunctionParameterSniff.php',
19
+ 'Generic_Sniffs_CodeAnalysis_UselessOverridingMethodSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/UselessOverridingMethodSniff.php',
20
+ 'Generic_Sniffs_Commenting_DocCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Commenting/DocCommentSniff.php',
21
+ 'Generic_Sniffs_Commenting_FixmeSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Commenting/FixmeSniff.php',
22
+ 'Generic_Sniffs_Commenting_TodoSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Commenting/TodoSniff.php',
23
+ 'Generic_Sniffs_ControlStructures_InlineControlStructureSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/ControlStructures/InlineControlStructureSniff.php',
24
+ 'Generic_Sniffs_Debug_CSSLintSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Debug/CSSLintSniff.php',
25
+ 'Generic_Sniffs_Debug_ClosureLinterSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Debug/ClosureLinterSniff.php',
26
+ 'Generic_Sniffs_Debug_JSHintSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Debug/JSHintSniff.php',
27
+ 'Generic_Sniffs_Files_ByteOrderMarkSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/ByteOrderMarkSniff.php',
28
+ 'Generic_Sniffs_Files_EndFileNewlineSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/EndFileNewlineSniff.php',
29
+ 'Generic_Sniffs_Files_EndFileNoNewlineSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/EndFileNoNewlineSniff.php',
30
+ 'Generic_Sniffs_Files_InlineHTMLSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/InlineHTMLSniff.php',
31
+ 'Generic_Sniffs_Files_LineEndingsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/LineEndingsSniff.php',
32
+ 'Generic_Sniffs_Files_LineLengthSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/LineLengthSniff.php',
33
+ 'Generic_Sniffs_Files_LowercasedFilenameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/LowercasedFilenameSniff.php',
34
+ 'Generic_Sniffs_Files_OneClassPerFileSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/OneClassPerFileSniff.php',
35
+ 'Generic_Sniffs_Files_OneInterfacePerFileSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/OneInterfacePerFileSniff.php',
36
+ 'Generic_Sniffs_Files_OneTraitPerFileSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/OneTraitPerFileSniff.php',
37
+ 'Generic_Sniffs_Formatting_DisallowMultipleStatementsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Formatting/DisallowMultipleStatementsSniff.php',
38
+ 'Generic_Sniffs_Formatting_MultipleStatementAlignmentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Formatting/MultipleStatementAlignmentSniff.php',
39
+ 'Generic_Sniffs_Formatting_NoSpaceAfterCastSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Formatting/NoSpaceAfterCastSniff.php',
40
+ 'Generic_Sniffs_Formatting_SpaceAfterCastSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Formatting/SpaceAfterCastSniff.php',
41
+ 'Generic_Sniffs_Formatting_SpaceAfterNotSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Formatting/SpaceAfterNotSniff.php',
42
+ 'Generic_Sniffs_Functions_CallTimePassByReferenceSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Functions/CallTimePassByReferenceSniff.php',
43
+ 'Generic_Sniffs_Functions_FunctionCallArgumentSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Functions/FunctionCallArgumentSpacingSniff.php',
44
+ 'Generic_Sniffs_Functions_OpeningFunctionBraceBsdAllmanSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Functions/OpeningFunctionBraceBsdAllmanSniff.php',
45
+ 'Generic_Sniffs_Functions_OpeningFunctionBraceKernighanRitchieSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Functions/OpeningFunctionBraceKernighanRitchieSniff.php',
46
+ 'Generic_Sniffs_Metrics_CyclomaticComplexitySniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Metrics/CyclomaticComplexitySniff.php',
47
+ 'Generic_Sniffs_Metrics_NestingLevelSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Metrics/NestingLevelSniff.php',
48
+ 'Generic_Sniffs_NamingConventions_CamelCapsFunctionNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/NamingConventions/CamelCapsFunctionNameSniff.php',
49
+ 'Generic_Sniffs_NamingConventions_ConstructorNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/NamingConventions/ConstructorNameSniff.php',
50
+ 'Generic_Sniffs_NamingConventions_UpperCaseConstantNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/NamingConventions/UpperCaseConstantNameSniff.php',
51
+ 'Generic_Sniffs_PHP_CharacterBeforePHPOpeningTagSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/CharacterBeforePHPOpeningTagSniff.php',
52
+ 'Generic_Sniffs_PHP_ClosingPHPTagSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/ClosingPHPTagSniff.php',
53
+ 'Generic_Sniffs_PHP_DeprecatedFunctionsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/DeprecatedFunctionsSniff.php',
54
+ 'Generic_Sniffs_PHP_DisallowShortOpenTagSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/DisallowShortOpenTagSniff.php',
55
+ 'Generic_Sniffs_PHP_ForbiddenFunctionsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/ForbiddenFunctionsSniff.php',
56
+ 'Generic_Sniffs_PHP_LowerCaseConstantSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/LowerCaseConstantSniff.php',
57
+ 'Generic_Sniffs_PHP_LowerCaseKeywordSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/LowerCaseKeywordSniff.php',
58
+ 'Generic_Sniffs_PHP_NoSilencedErrorsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/NoSilencedErrorsSniff.php',
59
+ 'Generic_Sniffs_PHP_SAPIUsageSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/SAPIUsageSniff.php',
60
+ 'Generic_Sniffs_PHP_SyntaxSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/SyntaxSniff.php',
61
+ 'Generic_Sniffs_PHP_UpperCaseConstantSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/PHP/UpperCaseConstantSniff.php',
62
+ 'Generic_Sniffs_Strings_UnnecessaryStringConcatSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Strings/UnnecessaryStringConcatSniff.php',
63
+ 'Generic_Sniffs_VersionControl_SubversionPropertiesSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/VersionControl/SubversionPropertiesSniff.php',
64
+ 'Generic_Sniffs_WhiteSpace_DisallowSpaceIndentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/WhiteSpace/DisallowSpaceIndentSniff.php',
65
+ 'Generic_Sniffs_WhiteSpace_DisallowTabIndentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/WhiteSpace/DisallowTabIndentSniff.php',
66
+ 'Generic_Sniffs_WhiteSpace_ScopeIndentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/WhiteSpace/ScopeIndentSniff.php',
67
+ 'MySource_Sniffs_CSS_BrowserSpecificStylesSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/CSS/BrowserSpecificStylesSniff.php',
68
+ 'MySource_Sniffs_Channels_DisallowSelfActionsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Channels/DisallowSelfActionsSniff.php',
69
+ 'MySource_Sniffs_Channels_IncludeOwnSystemSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Channels/IncludeOwnSystemSniff.php',
70
+ 'MySource_Sniffs_Channels_IncludeSystemSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Channels/IncludeSystemSniff.php',
71
+ 'MySource_Sniffs_Channels_UnusedSystemSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Channels/UnusedSystemSniff.php',
72
+ 'MySource_Sniffs_Commenting_FunctionCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Commenting/FunctionCommentSniff.php',
73
+ 'MySource_Sniffs_Debug_DebugCodeSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Debug/DebugCodeSniff.php',
74
+ 'MySource_Sniffs_Debug_FirebugConsoleSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Debug/FirebugConsoleSniff.php',
75
+ 'MySource_Sniffs_Objects_AssignThisSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Objects/AssignThisSniff.php',
76
+ 'MySource_Sniffs_Objects_CreateWidgetTypeCallbackSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Objects/CreateWidgetTypeCallbackSniff.php',
77
+ 'MySource_Sniffs_Objects_DisallowNewWidgetSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Objects/DisallowNewWidgetSniff.php',
78
+ 'MySource_Sniffs_PHP_AjaxNullComparisonSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/PHP/AjaxNullComparisonSniff.php',
79
+ 'MySource_Sniffs_PHP_EvalObjectFactorySniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/PHP/EvalObjectFactorySniff.php',
80
+ 'MySource_Sniffs_PHP_GetRequestDataSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/PHP/GetRequestDataSniff.php',
81
+ 'MySource_Sniffs_PHP_ReturnFunctionValueSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/PHP/ReturnFunctionValueSniff.php',
82
+ 'MySource_Sniffs_Strings_JoinStringsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/MySource/Sniffs/Strings/JoinStringsSniff.php',
83
+ 'PEAR_Sniffs_Classes_ClassDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Classes/ClassDeclarationSniff.php',
84
+ 'PEAR_Sniffs_Commenting_ClassCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Commenting/ClassCommentSniff.php',
85
+ 'PEAR_Sniffs_Commenting_FileCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Commenting/FileCommentSniff.php',
86
+ 'PEAR_Sniffs_Commenting_FunctionCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Commenting/FunctionCommentSniff.php',
87
+ 'PEAR_Sniffs_Commenting_InlineCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Commenting/InlineCommentSniff.php',
88
+ 'PEAR_Sniffs_ControlStructures_ControlSignatureSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/ControlStructures/ControlSignatureSniff.php',
89
+ 'PEAR_Sniffs_ControlStructures_MultiLineConditionSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/ControlStructures/MultiLineConditionSniff.php',
90
+ 'PEAR_Sniffs_Files_IncludingFileSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Files/IncludingFileSniff.php',
91
+ 'PEAR_Sniffs_Formatting_MultiLineAssignmentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Formatting/MultiLineAssignmentSniff.php',
92
+ 'PEAR_Sniffs_Functions_FunctionCallSignatureSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Functions/FunctionCallSignatureSniff.php',
93
+ 'PEAR_Sniffs_Functions_FunctionDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Functions/FunctionDeclarationSniff.php',
94
+ 'PEAR_Sniffs_Functions_ValidDefaultValueSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/Functions/ValidDefaultValueSniff.php',
95
+ 'PEAR_Sniffs_NamingConventions_ValidClassNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/NamingConventions/ValidClassNameSniff.php',
96
+ 'PEAR_Sniffs_NamingConventions_ValidFunctionNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/NamingConventions/ValidFunctionNameSniff.php',
97
+ 'PEAR_Sniffs_NamingConventions_ValidVariableNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/NamingConventions/ValidVariableNameSniff.php',
98
+ 'PEAR_Sniffs_WhiteSpace_ObjectOperatorIndentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/WhiteSpace/ObjectOperatorIndentSniff.php',
99
+ 'PEAR_Sniffs_WhiteSpace_ScopeClosingBraceSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/WhiteSpace/ScopeClosingBraceSniff.php',
100
+ 'PEAR_Sniffs_WhiteSpace_ScopeIndentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PEAR/Sniffs/WhiteSpace/ScopeIndentSniff.php',
101
+ 'PHP_CodeSniffer' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer.php',
102
+ 'PHP_CodeSniffer_CLI' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/CLI.php',
103
+ 'PHP_CodeSniffer_DocGenerators_Generator' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/Generator.php',
104
+ 'PHP_CodeSniffer_DocGenerators_HTML' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/HTML.php',
105
+ 'PHP_CodeSniffer_DocGenerators_Markdown' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/Markdown.php',
106
+ 'PHP_CodeSniffer_DocGenerators_Text' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/Text.php',
107
+ 'PHP_CodeSniffer_Exception' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Exception.php',
108
+ 'PHP_CodeSniffer_File' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/File.php',
109
+ 'PHP_CodeSniffer_Fixer' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Fixer.php',
110
+ 'PHP_CodeSniffer_Report' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Report.php',
111
+ 'PHP_CodeSniffer_Reporting' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reporting.php',
112
+ 'PHP_CodeSniffer_Reports_Cbf' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Cbf.php',
113
+ 'PHP_CodeSniffer_Reports_Checkstyle' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Checkstyle.php',
114
+ 'PHP_CodeSniffer_Reports_Csv' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Csv.php',
115
+ 'PHP_CodeSniffer_Reports_Diff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Diff.php',
116
+ 'PHP_CodeSniffer_Reports_Emacs' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Emacs.php',
117
+ 'PHP_CodeSniffer_Reports_Full' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Full.php',
118
+ 'PHP_CodeSniffer_Reports_Gitblame' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Gitblame.php',
119
+ 'PHP_CodeSniffer_Reports_Hgblame' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Hgblame.php',
120
+ 'PHP_CodeSniffer_Reports_Info' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Info.php',
121
+ 'PHP_CodeSniffer_Reports_Json' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Json.php',
122
+ 'PHP_CodeSniffer_Reports_Junit' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Junit.php',
123
+ 'PHP_CodeSniffer_Reports_Notifysend' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Notifysend.php',
124
+ 'PHP_CodeSniffer_Reports_Source' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Source.php',
125
+ 'PHP_CodeSniffer_Reports_Summary' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Summary.php',
126
+ 'PHP_CodeSniffer_Reports_Svnblame' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Svnblame.php',
127
+ 'PHP_CodeSniffer_Reports_VersionControl' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/VersionControl.php',
128
+ 'PHP_CodeSniffer_Reports_Xml' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Reports/Xml.php',
129
+ 'PHP_CodeSniffer_Sniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Sniff.php',
130
+ 'PHP_CodeSniffer_Standards_AbstractPatternSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/AbstractPatternSniff.php',
131
+ 'PHP_CodeSniffer_Standards_AbstractScopeSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/AbstractScopeSniff.php',
132
+ 'PHP_CodeSniffer_Standards_AbstractVariableSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/AbstractVariableSniff.php',
133
+ 'PHP_CodeSniffer_Standards_IncorrectPatternException' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/IncorrectPatternException.php',
134
+ 'PHP_CodeSniffer_Tokenizers_CSS' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Tokenizers/CSS.php',
135
+ 'PHP_CodeSniffer_Tokenizers_Comment' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Tokenizers/Comment.php',
136
+ 'PHP_CodeSniffer_Tokenizers_JS' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Tokenizers/JS.php',
137
+ 'PHP_CodeSniffer_Tokenizers_PHP' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Tokenizers/PHP.php',
138
+ 'PHP_CodeSniffer_Tokens' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Tokens.php',
139
+ 'PSR1_Sniffs_Classes_ClassDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR1/Sniffs/Classes/ClassDeclarationSniff.php',
140
+ 'PSR1_Sniffs_Files_SideEffectsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR1/Sniffs/Files/SideEffectsSniff.php',
141
+ 'PSR1_Sniffs_Methods_CamelCapsMethodNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR1/Sniffs/Methods/CamelCapsMethodNameSniff.php',
142
+ 'PSR2_Sniffs_Classes_ClassDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Classes/ClassDeclarationSniff.php',
143
+ 'PSR2_Sniffs_Classes_PropertyDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Classes/PropertyDeclarationSniff.php',
144
+ 'PSR2_Sniffs_ControlStructures_ControlStructureSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/ControlStructures/ControlStructureSpacingSniff.php',
145
+ 'PSR2_Sniffs_ControlStructures_ElseIfDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/ControlStructures/ElseIfDeclarationSniff.php',
146
+ 'PSR2_Sniffs_ControlStructures_SwitchDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/ControlStructures/SwitchDeclarationSniff.php',
147
+ 'PSR2_Sniffs_Files_ClosingTagSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Files/ClosingTagSniff.php',
148
+ 'PSR2_Sniffs_Files_EndFileNewlineSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Files/EndFileNewlineSniff.php',
149
+ 'PSR2_Sniffs_Methods_FunctionCallSignatureSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Methods/FunctionCallSignatureSniff.php',
150
+ 'PSR2_Sniffs_Methods_FunctionClosingBraceSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Methods/FunctionClosingBraceSniff.php',
151
+ 'PSR2_Sniffs_Methods_MethodDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Methods/MethodDeclarationSniff.php',
152
+ 'PSR2_Sniffs_Namespaces_NamespaceDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Namespaces/NamespaceDeclarationSniff.php',
153
+ 'PSR2_Sniffs_Namespaces_UseDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/PSR2/Sniffs/Namespaces/UseDeclarationSniff.php',
154
+ 'Squiz_Sniffs_Arrays_ArrayBracketSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Arrays/ArrayBracketSpacingSniff.php',
155
+ 'Squiz_Sniffs_Arrays_ArrayDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Arrays/ArrayDeclarationSniff.php',
156
+ 'Squiz_Sniffs_CSS_ClassDefinitionClosingBraceSpaceSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/ClassDefinitionClosingBraceSpaceSniff.php',
157
+ 'Squiz_Sniffs_CSS_ClassDefinitionNameSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/ClassDefinitionNameSpacingSniff.php',
158
+ 'Squiz_Sniffs_CSS_ClassDefinitionOpeningBraceSpaceSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/ClassDefinitionOpeningBraceSpaceSniff.php',
159
+ 'Squiz_Sniffs_CSS_ColonSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/ColonSpacingSniff.php',
160
+ 'Squiz_Sniffs_CSS_ColourDefinitionSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/ColourDefinitionSniff.php',
161
+ 'Squiz_Sniffs_CSS_DisallowMultipleStyleDefinitionsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/DisallowMultipleStyleDefinitionsSniff.php',
162
+ 'Squiz_Sniffs_CSS_DuplicateClassDefinitionSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/DuplicateClassDefinitionSniff.php',
163
+ 'Squiz_Sniffs_CSS_DuplicateStyleDefinitionSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/DuplicateStyleDefinitionSniff.php',
164
+ 'Squiz_Sniffs_CSS_EmptyClassDefinitionSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/EmptyClassDefinitionSniff.php',
165
+ 'Squiz_Sniffs_CSS_EmptyStyleDefinitionSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/EmptyStyleDefinitionSniff.php',
166
+ 'Squiz_Sniffs_CSS_ForbiddenStylesSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/ForbiddenStylesSniff.php',
167
+ 'Squiz_Sniffs_CSS_IndentationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/IndentationSniff.php',
168
+ 'Squiz_Sniffs_CSS_LowercaseStyleDefinitionSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/LowercaseStyleDefinitionSniff.php',
169
+ 'Squiz_Sniffs_CSS_MissingColonSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/MissingColonSniff.php',
170
+ 'Squiz_Sniffs_CSS_NamedColoursSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/NamedColoursSniff.php',
171
+ 'Squiz_Sniffs_CSS_OpacitySniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/OpacitySniff.php',
172
+ 'Squiz_Sniffs_CSS_SemicolonSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/SemicolonSpacingSniff.php',
173
+ 'Squiz_Sniffs_CSS_ShorthandSizeSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/CSS/ShorthandSizeSniff.php',
174
+ 'Squiz_Sniffs_Classes_ClassDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Classes/ClassDeclarationSniff.php',
175
+ 'Squiz_Sniffs_Classes_ClassFileNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Classes/ClassFileNameSniff.php',
176
+ 'Squiz_Sniffs_Classes_DuplicatePropertySniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Classes/DuplicatePropertySniff.php',
177
+ 'Squiz_Sniffs_Classes_LowercaseClassKeywordsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Classes/LowercaseClassKeywordsSniff.php',
178
+ 'Squiz_Sniffs_Classes_SelfMemberReferenceSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Classes/SelfMemberReferenceSniff.php',
179
+ 'Squiz_Sniffs_Classes_ValidClassNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Classes/ValidClassNameSniff.php',
180
+ 'Squiz_Sniffs_Commenting_BlockCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/BlockCommentSniff.php',
181
+ 'Squiz_Sniffs_Commenting_ClassCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/ClassCommentSniff.php',
182
+ 'Squiz_Sniffs_Commenting_ClosingDeclarationCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/ClosingDeclarationCommentSniff.php',
183
+ 'Squiz_Sniffs_Commenting_DocCommentAlignmentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/DocCommentAlignmentSniff.php',
184
+ 'Squiz_Sniffs_Commenting_EmptyCatchCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/EmptyCatchCommentSniff.php',
185
+ 'Squiz_Sniffs_Commenting_FileCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/FileCommentSniff.php',
186
+ 'Squiz_Sniffs_Commenting_FunctionCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/FunctionCommentSniff.php',
187
+ 'Squiz_Sniffs_Commenting_FunctionCommentThrowTagSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/FunctionCommentThrowTagSniff.php',
188
+ 'Squiz_Sniffs_Commenting_InlineCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/InlineCommentSniff.php',
189
+ 'Squiz_Sniffs_Commenting_LongConditionClosingCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/LongConditionClosingCommentSniff.php',
190
+ 'Squiz_Sniffs_Commenting_PostStatementCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/PostStatementCommentSniff.php',
191
+ 'Squiz_Sniffs_Commenting_VariableCommentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Commenting/VariableCommentSniff.php',
192
+ 'Squiz_Sniffs_ControlStructures_ControlSignatureSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/ControlSignatureSniff.php',
193
+ 'Squiz_Sniffs_ControlStructures_ElseIfDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/ElseIfDeclarationSniff.php',
194
+ 'Squiz_Sniffs_ControlStructures_ForEachLoopDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/ForEachLoopDeclarationSniff.php',
195
+ 'Squiz_Sniffs_ControlStructures_ForLoopDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/ForLoopDeclarationSniff.php',
196
+ 'Squiz_Sniffs_ControlStructures_InlineIfDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/InlineIfDeclarationSniff.php',
197
+ 'Squiz_Sniffs_ControlStructures_LowercaseDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/LowercaseDeclarationSniff.php',
198
+ 'Squiz_Sniffs_ControlStructures_SwitchDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/ControlStructures/SwitchDeclarationSniff.php',
199
+ 'Squiz_Sniffs_Debug_JSLintSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Debug/JSLintSniff.php',
200
+ 'Squiz_Sniffs_Debug_JavaScriptLintSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Debug/JavaScriptLintSniff.php',
201
+ 'Squiz_Sniffs_Files_FileExtensionSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Files/FileExtensionSniff.php',
202
+ 'Squiz_Sniffs_Formatting_OperatorBracketSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Formatting/OperatorBracketSniff.php',
203
+ 'Squiz_Sniffs_Functions_FunctionDeclarationArgumentSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Functions/FunctionDeclarationArgumentSpacingSniff.php',
204
+ 'Squiz_Sniffs_Functions_FunctionDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Functions/FunctionDeclarationSniff.php',
205
+ 'Squiz_Sniffs_Functions_FunctionDuplicateArgumentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Functions/FunctionDuplicateArgumentSniff.php',
206
+ 'Squiz_Sniffs_Functions_GlobalFunctionSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Functions/GlobalFunctionSniff.php',
207
+ 'Squiz_Sniffs_Functions_LowercaseFunctionKeywordsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Functions/LowercaseFunctionKeywordsSniff.php',
208
+ 'Squiz_Sniffs_Functions_MultiLineFunctionDeclarationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Functions/MultiLineFunctionDeclarationSniff.php',
209
+ 'Squiz_Sniffs_NamingConventions_ValidFunctionNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/NamingConventions/ValidFunctionNameSniff.php',
210
+ 'Squiz_Sniffs_NamingConventions_ValidVariableNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/NamingConventions/ValidVariableNameSniff.php',
211
+ 'Squiz_Sniffs_Objects_DisallowObjectStringIndexSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Objects/DisallowObjectStringIndexSniff.php',
212
+ 'Squiz_Sniffs_Objects_ObjectInstantiationSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Objects/ObjectInstantiationSniff.php',
213
+ 'Squiz_Sniffs_Objects_ObjectMemberCommaSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Objects/ObjectMemberCommaSniff.php',
214
+ 'Squiz_Sniffs_Operators_ComparisonOperatorUsageSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Operators/ComparisonOperatorUsageSniff.php',
215
+ 'Squiz_Sniffs_Operators_IncrementDecrementUsageSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Operators/IncrementDecrementUsageSniff.php',
216
+ 'Squiz_Sniffs_Operators_ValidLogicalOperatorsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Operators/ValidLogicalOperatorsSniff.php',
217
+ 'Squiz_Sniffs_PHP_CommentedOutCodeSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/CommentedOutCodeSniff.php',
218
+ 'Squiz_Sniffs_PHP_DisallowBooleanStatementSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/DisallowBooleanStatementSniff.php',
219
+ 'Squiz_Sniffs_PHP_DisallowComparisonAssignmentSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/DisallowComparisonAssignmentSniff.php',
220
+ 'Squiz_Sniffs_PHP_DisallowInlineIfSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/DisallowInlineIfSniff.php',
221
+ 'Squiz_Sniffs_PHP_DisallowMultipleAssignmentsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/DisallowMultipleAssignmentsSniff.php',
222
+ 'Squiz_Sniffs_PHP_DisallowObEndFlushSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/DisallowObEndFlushSniff.php',
223
+ 'Squiz_Sniffs_PHP_DisallowSizeFunctionsInLoopsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/DisallowSizeFunctionsInLoopsSniff.php',
224
+ 'Squiz_Sniffs_PHP_DiscouragedFunctionsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/DiscouragedFunctionsSniff.php',
225
+ 'Squiz_Sniffs_PHP_EmbeddedPhpSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/EmbeddedPhpSniff.php',
226
+ 'Squiz_Sniffs_PHP_EvalSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/EvalSniff.php',
227
+ 'Squiz_Sniffs_PHP_ForbiddenFunctionsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/ForbiddenFunctionsSniff.php',
228
+ 'Squiz_Sniffs_PHP_GlobalKeywordSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/GlobalKeywordSniff.php',
229
+ 'Squiz_Sniffs_PHP_HeredocSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/HeredocSniff.php',
230
+ 'Squiz_Sniffs_PHP_InnerFunctionsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/InnerFunctionsSniff.php',
231
+ 'Squiz_Sniffs_PHP_LowercasePHPFunctionsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/LowercasePHPFunctionsSniff.php',
232
+ 'Squiz_Sniffs_PHP_NonExecutableCodeSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/PHP/NonExecutableCodeSniff.php',
233
+ 'Squiz_Sniffs_Scope_MemberVarScopeSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Scope/MemberVarScopeSniff.php',
234
+ 'Squiz_Sniffs_Scope_MethodScopeSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Scope/MethodScopeSniff.php',
235
+ 'Squiz_Sniffs_Scope_StaticThisUsageSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Scope/StaticThisUsageSniff.php',
236
+ 'Squiz_Sniffs_Strings_ConcatenationSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Strings/ConcatenationSpacingSniff.php',
237
+ 'Squiz_Sniffs_Strings_DoubleQuoteUsageSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Strings/DoubleQuoteUsageSniff.php',
238
+ 'Squiz_Sniffs_Strings_EchoedStringsSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/Strings/EchoedStringsSniff.php',
239
+ 'Squiz_Sniffs_WhiteSpace_CastSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/CastSpacingSniff.php',
240
+ 'Squiz_Sniffs_WhiteSpace_ControlStructureSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/ControlStructureSpacingSniff.php',
241
+ 'Squiz_Sniffs_WhiteSpace_FunctionClosingBraceSpaceSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/FunctionClosingBraceSpaceSniff.php',
242
+ 'Squiz_Sniffs_WhiteSpace_FunctionOpeningBraceSpaceSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/FunctionOpeningBraceSpaceSniff.php',
243
+ 'Squiz_Sniffs_WhiteSpace_FunctionSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/FunctionSpacingSniff.php',
244
+ 'Squiz_Sniffs_WhiteSpace_LanguageConstructSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/LanguageConstructSpacingSniff.php',
245
+ 'Squiz_Sniffs_WhiteSpace_LogicalOperatorSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/LogicalOperatorSpacingSniff.php',
246
+ 'Squiz_Sniffs_WhiteSpace_MemberVarSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/MemberVarSpacingSniff.php',
247
+ 'Squiz_Sniffs_WhiteSpace_ObjectOperatorSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/ObjectOperatorSpacingSniff.php',
248
+ 'Squiz_Sniffs_WhiteSpace_OperatorSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/OperatorSpacingSniff.php',
249
+ 'Squiz_Sniffs_WhiteSpace_PropertyLabelSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/PropertyLabelSpacingSniff.php',
250
+ 'Squiz_Sniffs_WhiteSpace_ScopeClosingBraceSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/ScopeClosingBraceSniff.php',
251
+ 'Squiz_Sniffs_WhiteSpace_ScopeKeywordSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/ScopeKeywordSpacingSniff.php',
252
+ 'Squiz_Sniffs_WhiteSpace_SemicolonSpacingSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/SemicolonSpacingSniff.php',
253
+ 'Squiz_Sniffs_WhiteSpace_SuperfluousWhitespaceSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Squiz/Sniffs/WhiteSpace/SuperfluousWhitespaceSniff.php',
254
+ 'SG_WPEPHPCompat' => $baseDir . '/src/sg-wpephpcompat.php',
255
+ 'Zend_Sniffs_Debug_CodeAnalyzerSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Zend/Sniffs/Debug/CodeAnalyzerSniff.php',
256
+ 'Zend_Sniffs_Files_ClosingTagSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Zend/Sniffs/Files/ClosingTagSniff.php',
257
+ 'Zend_Sniffs_NamingConventions_ValidVariableNameSniff' => $vendorDir . '/squizlabs/php_codesniffer/CodeSniffer/Standards/Zend/Sniffs/NamingConventions/ValidVariableNameSniff.php',
258
+ );
php-compatibility-checker/vendor/composer/autoload_namespaces.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_namespaces.php @generated by Composer
4
+
5
+ $vendorDir = dirname(dirname(__FILE__));
6
+ $baseDir = dirname($vendorDir);
7
+
8
+ return array(
9
+ 'SimplyAdmire\\ComposerPlugins' => array($vendorDir . '/simplyadmire/composer-plugins'),
10
+ );
php-compatibility-checker/vendor/composer/autoload_psr4.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_psr4.php @generated by Composer
4
+
5
+ $vendorDir = dirname(dirname(__FILE__));
6
+ $baseDir = dirname($vendorDir);
7
+
8
+ return array(
9
+ 'PHPCompatibility\\' => array($vendorDir . '/wimg/php-compatibility'),
10
+ );
php-compatibility-checker/vendor/composer/autoload_real.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_real.php @generated by Composer
4
+
5
+ class ComposerAutoloaderInit40c259fa07cfee03e82e5f2dswm504zz
6
+ {
7
+ private static $loader;
8
+
9
+ public static function loadClassLoader($class)
10
+ {
11
+ if ('Composer\Autoload\ClassLoader' === $class) {
12
+ require __DIR__ . '/ClassLoader.php';
13
+ }
14
+ }
15
+
16
+ public static function getLoader()
17
+ {
18
+ if (null !== self::$loader) {
19
+ return self::$loader;
20
+ }
21
+
22
+ spl_autoload_register(array('ComposerAutoloaderInit40c259fa07cfee03e82e5f2dswm504zz', 'loadClassLoader'), true, true);
23
+ self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInit40c259fa07cfee03e82e5f2dswm504zz', 'loadClassLoader'));
25
+
26
+ $map = require __DIR__ . '/autoload_namespaces.php';
27
+ foreach ($map as $namespace => $path) {
28
+ $loader->set($namespace, $path);
29
+ }
30
+
31
+ $map = require __DIR__ . '/autoload_psr4.php';
32
+ foreach ($map as $namespace => $path) {
33
+ $loader->setPsr4($namespace, $path);
34
+ }
35
+
36
+ $classMap = require __DIR__ . '/autoload_classmap.php';
37
+ if ($classMap) {
38
+ $loader->addClassMap($classMap);
39
+ }
40
+
41
+ $loader->register(true);
42
+
43
+ return $loader;
44
+ }
45
+ }
php-compatibility-checker/vendor/composer/installed.json ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "name": "squizlabs/php_codesniffer",
4
+ "version": "2.6.2",
5
+ "version_normalized": "2.6.2.0",
6
+ "source": {
7
+ "type": "git",
8
+ "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
9
+ "reference": "4edb770cb853def6e60c93abb088ad5ac2010c83"
10
+ },
11
+ "dist": {
12
+ "type": "zip",
13
+ "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/4edb770cb853def6e60c93abb088ad5ac2010c83",
14
+ "reference": "4edb770cb853def6e60c93abb088ad5ac2010c83",
15
+ "shasum": ""
16
+ },
17
+ "require": {
18
+ "ext-simplexml": "*",
19
+ "ext-tokenizer": "*",
20
+ "ext-xmlwriter": "*",
21
+ "php": ">=5.1.2"
22
+ },
23
+ "require-dev": {
24
+ "phpunit/phpunit": "~4.0"
25
+ },
26
+ "time": "2016-07-13 23:29:13",
27
+ "bin": [
28
+ "scripts/phpcs",
29
+ "scripts/phpcbf"
30
+ ],
31
+ "type": "library",
32
+ "extra": {
33
+ "branch-alias": {
34
+ "dev-master": "2.x-dev"
35
+ }
36
+ },
37
+ "installation-source": "dist",
38
+ "autoload": {
39
+ "classmap": [
40
+ "CodeSniffer.php",
41
+ "CodeSniffer/CLI.php",
42
+ "CodeSniffer/Exception.php",
43
+ "CodeSniffer/File.php",
44
+ "CodeSniffer/Fixer.php",
45
+ "CodeSniffer/Report.php",
46
+ "CodeSniffer/Reporting.php",
47
+ "CodeSniffer/Sniff.php",
48
+ "CodeSniffer/Tokens.php",
49
+ "CodeSniffer/Reports/",
50
+ "CodeSniffer/Tokenizers/",
51
+ "CodeSniffer/DocGenerators/",
52
+ "CodeSniffer/Standards/AbstractPatternSniff.php",
53
+ "CodeSniffer/Standards/AbstractScopeSniff.php",
54
+ "CodeSniffer/Standards/AbstractVariableSniff.php",
55
+ "CodeSniffer/Standards/IncorrectPatternException.php",
56
+ "CodeSniffer/Standards/Generic/Sniffs/",
57
+ "CodeSniffer/Standards/MySource/Sniffs/",
58
+ "CodeSniffer/Standards/PEAR/Sniffs/",
59
+ "CodeSniffer/Standards/PSR1/Sniffs/",
60
+ "CodeSniffer/Standards/PSR2/Sniffs/",
61
+ "CodeSniffer/Standards/Squiz/Sniffs/",
62
+ "CodeSniffer/Standards/Zend/Sniffs/"
63
+ ]
64
+ },
65
+ "notification-url": "https://packagist.org/downloads/",
66
+ "license": [
67
+ "BSD-3-Clause"
68
+ ],
69
+ "authors": [
70
+ {
71
+ "name": "Greg Sherwood",
72
+ "role": "lead"
73
+ }
74
+ ],
75
+ "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
76
+ "homepage": "http://www.squizlabs.com/php-codesniffer",
77
+ "keywords": [
78
+ "phpcs",
79
+ "standards"
80
+ ]
81
+ },
82
+ {
83
+ "name": "simplyadmire/composer-plugins",
84
+ "version": "dev-master",
85
+ "version_normalized": "9999999-dev",
86
+ "source": {
87
+ "type": "git",
88
+ "url": "https://github.com/SimplyAdmire/ComposerPlugins.git",
89
+ "reference": "d8380f670694c1c2330b22591ca74adc82cffe19"
90
+ },
91
+ "dist": {
92
+ "type": "zip",
93
+ "url": "https://api.github.com/repos/SimplyAdmire/ComposerPlugins/zipball/d8380f670694c1c2330b22591ca74adc82cffe19",
94
+ "reference": "d8380f670694c1c2330b22591ca74adc82cffe19",
95
+ "shasum": ""
96
+ },
97
+ "require": {
98
+ "composer-plugin-api": "^1.0",
99
+ "squizlabs/php_codesniffer": "*"
100
+ },
101
+ "time": "2016-05-12 11:58:38",
102
+ "type": "composer-plugin",
103
+ "extra": {
104
+ "class": [
105
+ "SimplyAdmire\\ComposerPlugins\\PhpCodesnifferStandardInstallerPlugin"
106
+ ]
107
+ },
108
+ "installation-source": "source",
109
+ "autoload": {
110
+ "psr-0": {
111
+ "SimplyAdmire\\ComposerPlugins": ""
112
+ }
113
+ },
114
+ "notification-url": "https://packagist.org/downloads/",
115
+ "license": [
116
+ "LGPL-3.0+"
117
+ ],
118
+ "authors": [
119
+ {
120
+ "name": "Rens Admiraal",
121
+ "email": "rens@simplyadmire.com",
122
+ "role": "lead"
123
+ }
124
+ ],
125
+ "description": "Composer plugin for installing PHP_CodeSniffer standards",
126
+ "keywords": [
127
+ "PHP_CodeSniffer",
128
+ "TYPO3 CMS",
129
+ "TYPO3 Flow",
130
+ "TYPO3 Neos",
131
+ "phpcs",
132
+ "standards",
133
+ "typo3"
134
+ ]
135
+ },
136
+ {
137
+ "name": "wimg/php-compatibility",
138
+ "version": "dev-master",
139
+ "version_normalized": "9999999-dev",
140
+ "source": {
141
+ "type": "git",
142
+ "url": "https://github.com/wimg/PHPCompatibility.git",
143
+ "reference": "a3263259daa3629d174d1ac25657466222d6607e"
144
+ },
145
+ "dist": {
146
+ "type": "zip",
147
+ "url": "https://api.github.com/repos/wimg/PHPCompatibility/zipball/a3263259daa3629d174d1ac25657466222d6607e",
148
+ "reference": "a3263259daa3629d174d1ac25657466222d6607e",
149
+ "shasum": ""
150
+ },
151
+ "require": {
152
+ "ext-tokenizer": "*",
153
+ "php": ">=5.1.2",
154
+ "squizlabs/php_codesniffer": "~2.0"
155
+ },
156
+ "require-dev": {
157
+ "satooshi/php-coveralls": "dev-master"
158
+ },
159
+ "time": "2016-10-30 14:34:26",
160
+ "type": "phpcodesniffer-standard",
161
+ "installation-source": "source",
162
+ "autoload": {
163
+ "psr-4": {
164
+ "PHPCompatibility\\": ""
165
+ }
166
+ },
167
+ "notification-url": "https://packagist.org/downloads/",
168
+ "license": [
169
+ "LGPL-3.0"
170
+ ],
171
+ "authors": [
172
+ {
173
+ "name": "Wim Godden",
174
+ "role": "lead"
175
+ }
176
+ ],
177
+ "description": "This is a set of sniffs for PHP_CodeSniffer that checks for PHP version compatibility.",
178
+ "homepage": "http://techblog.wimgodden.be/tag/codesniffer/",
179
+ "keywords": [
180
+ "compatibility",
181
+ "phpcs",
182
+ "standards"
183
+ ]
184
+ }
185
+ ]
php-compatibility-checker/vendor/simplyadmire/composer-plugins/Configuration/Settings.yaml ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ TYPO3:
2
+ Flow:
3
+ object:
4
+ excludeClasses:
5
+ 'simplyadmire.composerplugins': ['.*']
php-compatibility-checker/vendor/simplyadmire/composer-plugins/LICENSE ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ GNU LESSER GENERAL PUBLIC LICENSE
2
+ Version 3, 29 June 2007
3
+
4
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
5
+
6
+ Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
7
+
8
+ This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below.
9
+
10
+ 0. Additional Definitions.
11
+ As used herein, “this License” refers to version 3 of the GNU Lesser General Public License, and the “GNU GPL” refers to version 3 of the GNU General Public License.
12
+
13
+ “The Library” refers to a covered work governed by this License, other than an Application or a Combined Work as defined below.
14
+
15
+ An “Application” is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library.
16
+
17
+ A “Combined Work” is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the “Linked Version”.
18
+
19
+ The “Minimal Corresponding Source” for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version.
20
+
21
+ The “Corresponding Application Code” for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work.
22
+
23
+ 1. Exception to Section 3 of the GNU GPL.
24
+ You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL.
25
+
26
+ 2. Conveying Modified Versions.
27
+ If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version:
28
+
29
+ a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or
30
+ b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy.
31
+ 3. Object Code Incorporating Material from Library Header Files.
32
+ The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following:
33
+
34
+ a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License.
35
+ b) Accompany the object code with a copy of the GNU GPL and this license document.
36
+ 4. Combined Works.
37
+ You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following:
38
+
39
+ a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License.
40
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license document.
41
+ c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document.
42
+ d) Do one of the following:
43
+ 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.
44
+ 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version.
45
+ e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.)
46
+ 5. Combined Libraries.
47
+ You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following:
48
+
49
+ a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License.
50
+ b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work.
51
+ 6. Revised Versions of the GNU Lesser General Public License.
52
+ The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
53
+
54
+ Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation.
55
+
56
+ If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library.
php-compatibility-checker/vendor/simplyadmire/composer-plugins/README.md ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Composer Plugins
2
+ ================
3
+
4
+ A collection of composer plugins for specific installation instruction
5
+ for composer packages.
6
+
7
+ Important: if you are running on Flow 3+ and have the typo3/ci-flow package installed
8
+ using your main distributions composer.json you should remove it there and install
9
+ the codesniffer in a separate folder, like for example: https://git.typo3.org/Neos/Distributions/Base.git/tree/refs/heads/master:/Build/PhpCodesniffer
10
+
11
+ PHP Codesniffer Standard installer
12
+ ----------------------------------
13
+
14
+ The PHP Codesniffer Standard installer is able to install phpcs codesniffer
15
+ standards into the `<vendor>/squizlabs/php_codesniffer/CodeSniffer/Standards/`
16
+ folder. By doing so the standard will be usable by calling `bin/phpcs --standard <standard>`.
17
+
18
+ ### How To Use
19
+
20
+ * Find the package containing the codesniffs you want to use. This package should be
21
+ a normal Codesniffing package containing a `ruleset.xml` and a `composer.json`.
22
+ * The composer package type has to be `phpcodesniffer-standard`
23
+ * The name of the package has to reflect the name of the standard (explained below)
24
+ * It's best if the package has a requirement to `simplyadmire/composer-plugins`. This
25
+ is the only way to be sure the installer is available before the package is installed.
26
+ * Now add the package as a development dependency to your project
27
+ * Run `bin/phpcs -i` and see your standard listed
28
+
29
+ ### Naming Rules
30
+
31
+ The name of the standard is derived from the composer packagekey. The part after the `/`
32
+ is taken as standard name. The first character is made uppercase, and all characters after
33
+ a `-` will be uppercased. So:
34
+
35
+ * `vendor/mysniffs` becomes `Mysniffs`
36
+ * `vendor/some-more-words` becomes `SomeMoreWords`
37
+
38
+ TYPO3 Specific
39
+ --------------
40
+
41
+ The TYPO3 community already has packages available on packagist, and as renaming packagenames
42
+ would be a bad practice we added 3 hardcoded standard names. Also the vendor name `TYPO3` will
43
+ always be enforced to be uppercase.
44
+
45
+ To include the TYPO3 CGL to your project you can use one of the following commands (depending
46
+ on the CGL you want to use, TYPO3 Flow or TYPO3 CMS):
47
+
48
+ TYPO3 Flow:
49
+ ```
50
+ composer require --dev typo3-ci/typo3flow=dev-master
51
+ ```
52
+
53
+ TYPO3 CMS:
54
+ ```
55
+ composer require --dev typo3-ci/typo3cms=dev-master
56
+ ```
57
+
58
+ Now you can sniff your packages with for example:
59
+
60
+ ```
61
+ bin/phpcs --extensions=php --standard=TYPO3Flow Packages/Application/My.Package
62
+ ```
php-compatibility-checker/vendor/simplyadmire/composer-plugins/SimplyAdmire/ComposerPlugins/Installers/PhpCodesnifferStandardInstaller.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace SimplyAdmire\ComposerPlugins\Installers;
3
+
4
+ use Composer\Package\PackageInterface;
5
+ use Composer\Installer\LibraryInstaller;
6
+
7
+ /**
8
+ * This installer installs code sniffing standards in the Standards/ folder
9
+ * of the squizlabs/php_codesniffer package
10
+ */
11
+ class PhpCodesnifferStandardInstaller extends LibraryInstaller {
12
+
13
+ /**
14
+ * @param PackageInterface $package
15
+ * @return string
16
+ */
17
+ protected function getPackageBasePath(PackageInterface $package) {
18
+ $this->initializeVendorDir();
19
+
20
+ $targetPath = $this->vendorDir ? $this->vendorDir . '/' : '';
21
+
22
+ $codeSnifferStandardsPathParts = array('squizlabs', 'php_codesniffer', 'CodeSniffer', 'Standards');
23
+ $targetPath .= implode(DIRECTORY_SEPARATOR, $codeSnifferStandardsPathParts) . DIRECTORY_SEPARATOR;
24
+
25
+ $packageKeyParts = explode('/', $package->getPrettyName(), 2);
26
+
27
+ $codeStandardName = str_replace('Typo3', 'TYPO3', ucfirst($packageKeyParts[1]));
28
+ $codeStandardName = preg_replace_callback('/-([a-z]{1})/', function($matches) { return strtoupper($matches[1]); }, $codeStandardName);
29
+
30
+ // Fixed mapping for TYPO3 codesniffers
31
+ $codeStandardName = str_replace('TYPO3sniffpool', 'TYPO3SniffPool', $codeStandardName);
32
+ $codeStandardName = str_replace('TYPO3cms', 'TYPO3CMS', $codeStandardName);
33
+ $codeStandardName = str_replace('TYPO3flow', 'TYPO3Flow', $codeStandardName);
34
+
35
+ // Fixed mapping for PrestaShop coding standard
36
+ $codeStandardName = str_replace('PrestashopCodingstandard', 'Prestashop', $codeStandardName);
37
+
38
+ return $targetPath . $codeStandardName;
39
+ }
40
+
41
+ /**
42
+ * @param string $packageType
43
+ * @return boolean
44
+ */
45
+ public function supports($packageType) {
46
+ return $packageType === 'phpcodesniffer-standard';
47
+ }
48
+
49
+ }
php-compatibility-checker/vendor/simplyadmire/composer-plugins/SimplyAdmire/ComposerPlugins/PhpCodesnifferStandardInstallerPlugin.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace SimplyAdmire\ComposerPlugins;
3
+
4
+ use Composer\Composer;
5
+ use Composer\IO\IOInterface;
6
+ use Composer\Plugin\PluginInterface;
7
+ use SimplyAdmire\ComposerPlugins\Installers\PhpCodesnifferStandardInstaller;
8
+
9
+ class PhpCodesnifferStandardInstallerPlugin implements PluginInterface {
10
+
11
+ /**
12
+ * @param Composer $composer
13
+ * @param IOInterface $io
14
+ * @return void
15
+ */
16
+ public function activate(Composer $composer, IOInterface $io) {
17
+ $installer = new PhpCodesnifferStandardInstaller($io, $composer);
18
+ $composer->getInstallationManager()->addInstaller($installer);
19
+ }
20
+ }
php-compatibility-checker/vendor/simplyadmire/composer-plugins/composer.json ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "simplyadmire/composer-plugins",
3
+ "type": "composer-plugin",
4
+ "description": "Composer plugin for installing PHP_CodeSniffer standards",
5
+ "keywords": ["PHP_CodeSniffer", "phpcs", "standards", "TYPO3", "TYPO3 Flow", "TYPO3 CMS", "TYPO3 Neos"],
6
+ "license": "LGPL-3.0+",
7
+ "authors": [
8
+ {
9
+ "name": "Rens Admiraal",
10
+ "email": "rens@simplyadmire.com",
11
+ "role": "lead"
12
+ }
13
+ ],
14
+ "autoload": {
15
+ "psr-0": {
16
+ "SimplyAdmire\\ComposerPlugins": ""
17
+ }
18
+ },
19
+ "extra": {
20
+ "class": [
21
+ "SimplyAdmire\\ComposerPlugins\\PhpCodesnifferStandardInstallerPlugin"
22
+ ]
23
+ },
24
+ "require": {
25
+ "composer-plugin-api": "^1.0",
26
+ "squizlabs/php_codesniffer": "*"
27
+ },
28
+ "support": {
29
+ "issues": "https://github.com/SimplyAdmire/ComposerPlugins/issues",
30
+ "wiki": "https://github.com/SimplyAdmire/ComposerPlugins/wiki",
31
+ "source": "https://github.com/SimplyAdmire/ComposerPlugins.git"
32
+ }
33
+ }
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CONTRIBUTING.md ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Contributing
2
+ -------------
3
+
4
+ Before you contribute code to PHP\_CodeSniffer, please make sure it conforms to the PHPCS coding standard and that the PHP\_CodeSniffer unit tests still pass. The easiest way to contribute is to work on a checkout of the repository, or your own fork, rather than an installed PEAR version. If you do this, you can run the following commands to check if everything is ready to submit:
5
+
6
+ cd PHP_CodeSniffer
7
+ php scripts/phpcs . --standard=PHPCS -np
8
+
9
+ Which should give you no output, indicating that there are no coding standard errors. And then:
10
+
11
+ phpunit
12
+
13
+ Which should give you no failures or errors. You can ignore any skipped tests as these are for external tools.
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer.conf.dist ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $phpCodeSnifferConfig = array (
3
+ 'default_standard' => 'PSR2',
4
+ 'report_format' => 'summary',
5
+ 'show_warnings' => '0',
6
+ 'show_progress' => '1',
7
+ 'report_width' => '120',
8
+ )
9
+ ?>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer.php ADDED
@@ -0,0 +1,2557 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PHP_CodeSniffer tokenizes PHP code and detects violations of a
4
+ * defined set of coding standards.
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * @category PHP
9
+ * @package PHP_CodeSniffer
10
+ * @author Greg Sherwood <gsherwood@squiz.net>
11
+ * @author Marc McIntyre <mmcintyre@squiz.net>
12
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
13
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
14
+ * @link http://pear.php.net/package/PHP_CodeSniffer
15
+ */
16
+
17
+ spl_autoload_register(array('PHP_CodeSniffer', 'autoload'));
18
+
19
+ if (class_exists('PHP_CodeSniffer_Exception', true) === false) {
20
+ throw new Exception('Class PHP_CodeSniffer_Exception not found');
21
+ }
22
+
23
+ if (class_exists('PHP_CodeSniffer_File', true) === false) {
24
+ throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_File not found');
25
+ }
26
+
27
+ if (class_exists('PHP_CodeSniffer_Fixer', true) === false) {
28
+ throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_Fixer not found');
29
+ }
30
+
31
+ if (class_exists('PHP_CodeSniffer_Tokens', true) === false) {
32
+ throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_Tokens not found');
33
+ }
34
+
35
+ if (class_exists('PHP_CodeSniffer_CLI', true) === false) {
36
+ throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_CLI not found');
37
+ }
38
+
39
+ if (interface_exists('PHP_CodeSniffer_Sniff', true) === false) {
40
+ throw new PHP_CodeSniffer_Exception('Interface PHP_CodeSniffer_Sniff not found');
41
+ }
42
+
43
+ /**
44
+ * PHP_CodeSniffer tokenizes PHP code and detects violations of a
45
+ * defined set of coding standards.
46
+ *
47
+ * Standards are specified by classes that implement the PHP_CodeSniffer_Sniff
48
+ * interface. A sniff registers what token types it wishes to listen for, then
49
+ * PHP_CodeSniffer encounters that token, the sniff is invoked and passed
50
+ * information about where the token was found in the stack, and the token stack
51
+ * itself.
52
+ *
53
+ * Sniff files and their containing class must be prefixed with Sniff, and
54
+ * have an extension of .php.
55
+ *
56
+ * Multiple PHP_CodeSniffer operations can be performed by re-calling the
57
+ * process function with different parameters.
58
+ *
59
+ * @category PHP
60
+ * @package PHP_CodeSniffer
61
+ * @author Greg Sherwood <gsherwood@squiz.net>
62
+ * @author Marc McIntyre <mmcintyre@squiz.net>
63
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
64
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
65
+ * @version Release: @package_version@
66
+ * @link http://pear.php.net/package/PHP_CodeSniffer
67
+ */
68
+ class PHP_CodeSniffer
69
+ {
70
+
71
+ /**
72
+ * The current version.
73
+ *
74
+ * @var string
75
+ */
76
+ const VERSION = '2.6.2';
77
+
78
+ /**
79
+ * Package stability; either stable, beta or alpha.
80
+ *
81
+ * @var string
82
+ */
83
+ const STABILITY = 'stable';
84
+
85
+ /**
86
+ * The file or directory that is currently being processed.
87
+ *
88
+ * @var string
89
+ */
90
+ protected $file = '';
91
+
92
+ /**
93
+ * The directories that the processed rulesets are in.
94
+ *
95
+ * This is declared static because it is also used in the
96
+ * autoloader to look for sniffs outside the PHPCS install.
97
+ * This way, standards designed to be installed inside PHPCS can
98
+ * also be used from outside the PHPCS Standards directory.
99
+ *
100
+ * @var string
101
+ */
102
+ protected static $rulesetDirs = array();
103
+
104
+ /**
105
+ * The CLI object controlling the run.
106
+ *
107
+ * @var PHP_CodeSniffer_CLI
108
+ */
109
+ public $cli = null;
110
+
111
+ /**
112
+ * The Reporting object controlling report generation.
113
+ *
114
+ * @var PHP_CodeSniffer_Reporting
115
+ */
116
+ public $reporting = null;
117
+
118
+ /**
119
+ * An array of sniff objects that are being used to check files.
120
+ *
121
+ * @var array(PHP_CodeSniffer_Sniff)
122
+ */
123
+ protected $listeners = array();
124
+
125
+ /**
126
+ * An array of sniffs that are being used to check files.
127
+ *
128
+ * @var array(string)
129
+ */
130
+ protected $sniffs = array();
131
+
132
+ /**
133
+ * A mapping of sniff codes to fully qualified class names.
134
+ *
135
+ * The key is the sniff code and the value
136
+ * is the fully qualified name of the sniff class.
137
+ *
138
+ * @var array<string, string>
139
+ */
140
+ public $sniffCodes = array();
141
+
142
+ /**
143
+ * The listeners array, indexed by token type.
144
+ *
145
+ * @var array
146
+ */
147
+ private $_tokenListeners = array();
148
+
149
+ /**
150
+ * An array of rules from the ruleset.xml file.
151
+ *
152
+ * It may be empty, indicating that the ruleset does not override
153
+ * any of the default sniff settings.
154
+ *
155
+ * @var array
156
+ */
157
+ protected $ruleset = array();
158
+
159
+ /**
160
+ * An array of patterns to use for skipping files.
161
+ *
162
+ * @var array
163
+ */
164
+ protected $ignorePatterns = array();
165
+
166
+ /**
167
+ * An array of extensions for files we will check.
168
+ *
169
+ * @var array
170
+ */
171
+ public $allowedFileExtensions = array();
172
+
173
+ /**
174
+ * An array of default extensions and associated tokenizers.
175
+ *
176
+ * If no extensions are set, these will be used as the defaults.
177
+ * If extensions are set, these will be used when the correct tokenizer
178
+ * can not be determined, such as when checking a passed filename instead
179
+ * of files in a directory.
180
+ *
181
+ * @var array
182
+ */
183
+ public $defaultFileExtensions = array(
184
+ 'php' => 'PHP',
185
+ 'inc' => 'PHP',
186
+ 'js' => 'JS',
187
+ 'css' => 'CSS',
188
+ );
189
+
190
+ /**
191
+ * An array of variable types for param/var we will check.
192
+ *
193
+ * @var array(string)
194
+ */
195
+ public static $allowedTypes = array(
196
+ 'array',
197
+ 'boolean',
198
+ 'float',
199
+ 'integer',
200
+ 'mixed',
201
+ 'object',
202
+ 'string',
203
+ 'resource',
204
+ 'callable',
205
+ );
206
+
207
+
208
+ /**
209
+ * Constructs a PHP_CodeSniffer object.
210
+ *
211
+ * @param int $verbosity The verbosity level.
212
+ * 1: Print progress information.
213
+ * 2: Print tokenizer debug information.
214
+ * 3: Print sniff debug information.
215
+ * @param int $tabWidth The number of spaces each tab represents.
216
+ * If greater than zero, tabs will be replaced
217
+ * by spaces before testing each file.
218
+ * @param string $encoding The charset of the sniffed files.
219
+ * This is important for some reports that output
220
+ * with utf-8 encoding as you don't want it double
221
+ * encoding messages.
222
+ * @param bool $interactive If TRUE, will stop after each file with errors
223
+ * and wait for user input.
224
+ *
225
+ * @see process()
226
+ */
227
+ public function __construct(
228
+ $verbosity=0,
229
+ $tabWidth=0,
230
+ $encoding='iso-8859-1',
231
+ $interactive=false
232
+ ) {
233
+ if ($verbosity !== null) {
234
+ $this->setVerbosity($verbosity);
235
+ }
236
+
237
+ if ($tabWidth !== null) {
238
+ $this->setTabWidth($tabWidth);
239
+ }
240
+
241
+ if ($encoding !== null) {
242
+ $this->setEncoding($encoding);
243
+ }
244
+
245
+ if ($interactive !== null) {
246
+ $this->setInteractive($interactive);
247
+ }
248
+
249
+ if (defined('PHPCS_DEFAULT_ERROR_SEV') === false) {
250
+ define('PHPCS_DEFAULT_ERROR_SEV', 5);
251
+ }
252
+
253
+ if (defined('PHPCS_DEFAULT_WARN_SEV') === false) {
254
+ define('PHPCS_DEFAULT_WARN_SEV', 5);
255
+ }
256
+
257
+ if (defined('PHP_CODESNIFFER_CBF') === false) {
258
+ define('PHP_CODESNIFFER_CBF', false);
259
+ }
260
+
261
+ // Set default CLI object in case someone is running us
262
+ // without using the command line script.
263
+ $this->cli = new PHP_CodeSniffer_CLI();
264
+ $this->cli->errorSeverity = PHPCS_DEFAULT_ERROR_SEV;
265
+ $this->cli->warningSeverity = PHPCS_DEFAULT_WARN_SEV;
266
+ $this->cli->dieOnUnknownArg = false;
267
+
268
+ $this->reporting = new PHP_CodeSniffer_Reporting();
269
+
270
+ }//end __construct()
271
+
272
+
273
+ /**
274
+ * Autoload static method for loading classes and interfaces.
275
+ *
276
+ * @param string $className The name of the class or interface.
277
+ *
278
+ * @return void
279
+ */
280
+ public static function autoload($className)
281
+ {
282
+ if (substr($className, 0, 4) === 'PHP_') {
283
+ $newClassName = substr($className, 4);
284
+ } else {
285
+ $newClassName = $className;
286
+ }
287
+
288
+ $path = str_replace(array('_', '\\'), DIRECTORY_SEPARATOR, $newClassName).'.php';
289
+
290
+ if (is_file(dirname(__FILE__).DIRECTORY_SEPARATOR.$path) === true) {
291
+ // Check standard file locations based on class name.
292
+ include dirname(__FILE__).DIRECTORY_SEPARATOR.$path;
293
+ return;
294
+ } else {
295
+ // Check for included sniffs.
296
+ $installedPaths = PHP_CodeSniffer::getInstalledStandardPaths();
297
+ foreach ($installedPaths as $installedPath) {
298
+ if (is_file($installedPath.DIRECTORY_SEPARATOR.$path) === true) {
299
+ include $installedPath.DIRECTORY_SEPARATOR.$path;
300
+ return;
301
+ }
302
+ }
303
+
304
+ // Check standard file locations based on the loaded rulesets.
305
+ foreach (self::$rulesetDirs as $rulesetDir) {
306
+ if (is_file(dirname($rulesetDir).DIRECTORY_SEPARATOR.$path) === true) {
307
+ include_once dirname($rulesetDir).DIRECTORY_SEPARATOR.$path;
308
+ return;
309
+ }
310
+ }
311
+ }//end if
312
+
313
+ // Everything else.
314
+ @include $path;
315
+
316
+ }//end autoload()
317
+
318
+
319
+ /**
320
+ * Sets the verbosity level.
321
+ *
322
+ * @param int $verbosity The verbosity level.
323
+ * 1: Print progress information.
324
+ * 2: Print tokenizer debug information.
325
+ * 3: Print sniff debug information.
326
+ *
327
+ * @return void
328
+ */
329
+ public function setVerbosity($verbosity)
330
+ {
331
+ if (defined('PHP_CODESNIFFER_VERBOSITY') === false) {
332
+ define('PHP_CODESNIFFER_VERBOSITY', $verbosity);
333
+ }
334
+
335
+ }//end setVerbosity()
336
+
337
+
338
+ /**
339
+ * Sets the tab width.
340
+ *
341
+ * @param int $tabWidth The number of spaces each tab represents.
342
+ * If greater than zero, tabs will be replaced
343
+ * by spaces before testing each file.
344
+ *
345
+ * @return void
346
+ */
347
+ public function setTabWidth($tabWidth)
348
+ {
349
+ if (defined('PHP_CODESNIFFER_TAB_WIDTH') === false) {
350
+ define('PHP_CODESNIFFER_TAB_WIDTH', $tabWidth);
351
+ }
352
+
353
+ }//end setTabWidth()
354
+
355
+
356
+ /**
357
+ * Sets the encoding.
358
+ *
359
+ * @param string $encoding The charset of the sniffed files.
360
+ * This is important for some reports that output
361
+ * with utf-8 encoding as you don't want it double
362
+ * encoding messages.
363
+ *
364
+ * @return void
365
+ */
366
+ public function setEncoding($encoding)
367
+ {
368
+ if (defined('PHP_CODESNIFFER_ENCODING') === false) {
369
+ define('PHP_CODESNIFFER_ENCODING', $encoding);
370
+ }
371
+
372
+ }//end setEncoding()
373
+
374
+
375
+ /**
376
+ * Sets the interactive flag.
377
+ *
378
+ * @param bool $interactive If TRUE, will stop after each file with errors
379
+ * and wait for user input.
380
+ *
381
+ * @return void
382
+ */
383
+ public function setInteractive($interactive)
384
+ {
385
+ if (defined('PHP_CODESNIFFER_INTERACTIVE') === false) {
386
+ define('PHP_CODESNIFFER_INTERACTIVE', $interactive);
387
+ }
388
+
389
+ }//end setInteractive()
390
+
391
+
392
+ /**
393
+ * Sets an array of file extensions that we will allow checking of.
394
+ *
395
+ * If the extension is one of the defaults, a specific tokenizer
396
+ * will be used. Otherwise, the PHP tokenizer will be used for
397
+ * all extensions passed.
398
+ *
399
+ * @param array $extensions An array of file extensions.
400
+ *
401
+ * @return void
402
+ */
403
+ public function setAllowedFileExtensions(array $extensions)
404
+ {
405
+ $newExtensions = array();
406
+ foreach ($extensions as $ext) {
407
+ $slash = strpos($ext, '/');
408
+ if ($slash !== false) {
409
+ // They specified the tokenizer too.
410
+ list($ext, $tokenizer) = explode('/', $ext);
411
+ $newExtensions[$ext] = strtoupper($tokenizer);
412
+ continue;
413
+ }
414
+
415
+ if (isset($this->allowedFileExtensions[$ext]) === true) {
416
+ $newExtensions[$ext] = $this->allowedFileExtensions[$ext];
417
+ } else if (isset($this->defaultFileExtensions[$ext]) === true) {
418
+ $newExtensions[$ext] = $this->defaultFileExtensions[$ext];
419
+ } else {
420
+ $newExtensions[$ext] = 'PHP';
421
+ }
422
+ }
423
+
424
+ $this->allowedFileExtensions = $newExtensions;
425
+
426
+ }//end setAllowedFileExtensions()
427
+
428
+
429
+ /**
430
+ * Sets an array of ignore patterns that we use to skip files and folders.
431
+ *
432
+ * Patterns are not case sensitive.
433
+ *
434
+ * @param array $patterns An array of ignore patterns. The pattern is the key
435
+ * and the value is either "absolute" or "relative",
436
+ * depending on how the pattern should be applied to a
437
+ * file path.
438
+ *
439
+ * @return void
440
+ */
441
+ public function setIgnorePatterns(array $patterns)
442
+ {
443
+ $this->ignorePatterns = $patterns;
444
+
445
+ }//end setIgnorePatterns()
446
+
447
+
448
+ /**
449
+ * Gets the array of ignore patterns.
450
+ *
451
+ * Optionally takes a listener to get ignore patterns specified
452
+ * for that sniff only.
453
+ *
454
+ * @param string $listener The listener to get patterns for. If NULL, all
455
+ * patterns are returned.
456
+ *
457
+ * @return array
458
+ */
459
+ public function getIgnorePatterns($listener=null)
460
+ {
461
+ if ($listener === null) {
462
+ return $this->ignorePatterns;
463
+ }
464
+
465
+ if (isset($this->ignorePatterns[$listener]) === true) {
466
+ return $this->ignorePatterns[$listener];
467
+ }
468
+
469
+ return array();
470
+
471
+ }//end getIgnorePatterns()
472
+
473
+
474
+ /**
475
+ * Sets the internal CLI object.
476
+ *
477
+ * @param object $cli The CLI object controlling the run.
478
+ *
479
+ * @return void
480
+ */
481
+ public function setCli($cli)
482
+ {
483
+ $this->cli = $cli;
484
+
485
+ }//end setCli()
486
+
487
+
488
+ /**
489
+ * Start a PHP_CodeSniffer run.
490
+ *
491
+ * @param string|array $files The files and directories to process. For
492
+ * directories, each sub directory will also
493
+ * be traversed for source files.
494
+ * @param string|array $standards The set of code sniffs we are testing
495
+ * against.
496
+ * @param array $restrictions The sniff codes to restrict the
497
+ * violations to.
498
+ * @param boolean $local If true, don't recurse into directories.
499
+ *
500
+ * @return void
501
+ */
502
+ public function process($files, $standards, array $restrictions=array(), $local=false)
503
+ {
504
+ $files = (array) $files;
505
+ $this->initStandard($standards, $restrictions);
506
+ $this->processFiles($files, $local);
507
+
508
+ }//end process()
509
+
510
+
511
+ /**
512
+ * Initialise the standard that the run will use.
513
+ *
514
+ * @param string|array $standards The set of code sniffs we are testing
515
+ * against.
516
+ * @param array $restrictions The sniff codes to restrict the testing to.
517
+ * @param array $exclusions The sniff codes to exclude from testing.
518
+ *
519
+ * @return void
520
+ */
521
+ public function initStandard($standards, array $restrictions=array(), array $exclusions=array())
522
+ {
523
+ $standards = (array) $standards;
524
+
525
+ // Reset the members.
526
+ $this->listeners = array();
527
+ $this->sniffs = array();
528
+ $this->ruleset = array();
529
+ $this->_tokenListeners = array();
530
+ self::$rulesetDirs = array();
531
+
532
+ // Ensure this option is enabled or else line endings will not always
533
+ // be detected properly for files created on a Mac with the /r line ending.
534
+ ini_set('auto_detect_line_endings', true);
535
+
536
+ $sniffs = array();
537
+ foreach ($standards as $standard) {
538
+ $installed = $this->getInstalledStandardPath($standard);
539
+ if ($installed !== null) {
540
+ $standard = $installed;
541
+ } else {
542
+ $standard = self::realpath($standard);
543
+ if (is_dir($standard) === true
544
+ && is_file(self::realpath($standard.DIRECTORY_SEPARATOR.'ruleset.xml')) === true
545
+ ) {
546
+ $standard = self::realpath($standard.DIRECTORY_SEPARATOR.'ruleset.xml');
547
+ }
548
+ }
549
+
550
+ if (PHP_CODESNIFFER_VERBOSITY === 1) {
551
+ $ruleset = simplexml_load_file($standard);
552
+ if ($ruleset !== false) {
553
+ $standardName = (string) $ruleset['name'];
554
+ }
555
+
556
+ echo "Registering sniffs in the $standardName standard... ";
557
+ if (count($standards) > 1 || PHP_CODESNIFFER_VERBOSITY > 2) {
558
+ echo PHP_EOL;
559
+ }
560
+ }
561
+
562
+ $sniffs = array_merge($sniffs, $this->processRuleset($standard));
563
+ }//end foreach
564
+
565
+ $sniffRestrictions = array();
566
+ foreach ($restrictions as $sniffCode) {
567
+ $parts = explode('.', strtolower($sniffCode));
568
+ $sniffRestrictions[] = $parts[0].'_sniffs_'.$parts[1].'_'.$parts[2].'sniff';
569
+ }
570
+
571
+ $sniffExclusions = array();
572
+ foreach ($exclusions as $sniffCode) {
573
+ $parts = explode('.', strtolower($sniffCode));
574
+ $sniffExclusions[] = $parts[0].'_sniffs_'.$parts[1].'_'.$parts[2].'sniff';
575
+ }
576
+
577
+ $this->registerSniffs($sniffs, $sniffRestrictions, $sniffExclusions);
578
+ $this->populateTokenListeners();
579
+
580
+ if (PHP_CODESNIFFER_VERBOSITY === 1) {
581
+ $numSniffs = count($this->sniffs);
582
+ echo "DONE ($numSniffs sniffs registered)".PHP_EOL;
583
+ }
584
+
585
+ }//end initStandard()
586
+
587
+
588
+ /**
589
+ * Processes the files/directories that PHP_CodeSniffer was constructed with.
590
+ *
591
+ * @param string|array $files The files and directories to process. For
592
+ * directories, each sub directory will also
593
+ * be traversed for source files.
594
+ * @param boolean $local If true, don't recurse into directories.
595
+ *
596
+ * @return void
597
+ * @throws PHP_CodeSniffer_Exception If files are invalid.
598
+ */
599
+ public function processFiles($files, $local=false)
600
+ {
601
+ $files = (array) $files;
602
+ $cliValues = $this->cli->getCommandLineValues();
603
+ $showProgress = $cliValues['showProgress'];
604
+ $useColors = $cliValues['colors'];
605
+
606
+ if (PHP_CODESNIFFER_VERBOSITY > 0) {
607
+ echo 'Creating file list... ';
608
+ }
609
+
610
+ if (empty($this->allowedFileExtensions) === true) {
611
+ $this->allowedFileExtensions = $this->defaultFileExtensions;
612
+ }
613
+
614
+ $todo = $this->getFilesToProcess($files, $local);
615
+ $numFiles = count($todo);
616
+
617
+ if (PHP_CODESNIFFER_VERBOSITY > 0) {
618
+ echo "DONE ($numFiles files in queue)".PHP_EOL;
619
+ }
620
+
621
+ $numProcessed = 0;
622
+ $dots = 0;
623
+ $maxLength = strlen($numFiles);
624
+ $lastDir = '';
625
+ foreach ($todo as $file) {
626
+ $this->file = $file;
627
+ $currDir = dirname($file);
628
+ if ($lastDir !== $currDir) {
629
+ if (PHP_CODESNIFFER_VERBOSITY > 0 || PHP_CODESNIFFER_CBF === true) {
630
+ echo 'Changing into directory '.$currDir.PHP_EOL;
631
+ }
632
+
633
+ $lastDir = $currDir;
634
+ }
635
+
636
+ $phpcsFile = $this->processFile($file, null);
637
+ $numProcessed++;
638
+
639
+ if (PHP_CODESNIFFER_VERBOSITY > 0
640
+ || PHP_CODESNIFFER_INTERACTIVE === true
641
+ || $showProgress === false
642
+ ) {
643
+ continue;
644
+ }
645
+
646
+ // Show progress information.
647
+ if ($phpcsFile === null) {
648
+ echo 'S';
649
+ } else {
650
+ $errors = $phpcsFile->getErrorCount();
651
+ $warnings = $phpcsFile->getWarningCount();
652
+ if ($errors > 0) {
653
+ if ($useColors === true) {
654
+ echo "\033[31m";
655
+ }
656
+
657
+ echo 'E';
658
+ } else if ($warnings > 0) {
659
+ if ($useColors === true) {
660
+ echo "\033[33m";
661
+ }
662
+
663
+ echo 'W';
664
+ } else {
665
+ echo '.';
666
+ }
667
+
668
+ if ($useColors === true) {
669
+ echo "\033[0m";
670
+ }
671
+ }//end if
672
+
673
+ $dots++;
674
+ if ($dots === 60) {
675
+ $padding = ($maxLength - strlen($numProcessed));
676
+ echo str_repeat(' ', $padding);
677
+ $percent = round(($numProcessed / $numFiles) * 100);
678
+ echo " $numProcessed / $numFiles ($percent%)".PHP_EOL;
679
+ $dots = 0;
680
+ }
681
+ }//end foreach
682
+
683
+ if (PHP_CODESNIFFER_VERBOSITY === 0
684
+ && PHP_CODESNIFFER_INTERACTIVE === false
685
+ && $showProgress === true
686
+ ) {
687
+ echo PHP_EOL.PHP_EOL;
688
+ }
689
+
690
+ }//end processFiles()
691
+
692
+
693
+ /**
694
+ * Processes a single ruleset and returns a list of the sniffs it represents.
695
+ *
696
+ * Rules founds within the ruleset are processed immediately, but sniff classes
697
+ * are not registered by this method.
698
+ *
699
+ * @param string $rulesetPath The path to a ruleset XML file.
700
+ * @param int $depth How many nested processing steps we are in. This
701
+ * is only used for debug output.
702
+ *
703
+ * @return array
704
+ * @throws PHP_CodeSniffer_Exception If the ruleset path is invalid.
705
+ */
706
+ public function processRuleset($rulesetPath, $depth=0)
707
+ {
708
+ $rulesetPath = self::realpath($rulesetPath);
709
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
710
+ echo str_repeat("\t", $depth);
711
+ echo "Processing ruleset $rulesetPath".PHP_EOL;
712
+ }
713
+
714
+ $ruleset = simplexml_load_file($rulesetPath);
715
+ if ($ruleset === false) {
716
+ throw new PHP_CodeSniffer_Exception("Ruleset $rulesetPath is not valid");
717
+ }
718
+
719
+ $ownSniffs = array();
720
+ $includedSniffs = array();
721
+ $excludedSniffs = array();
722
+ $cliValues = $this->cli->getCommandLineValues();
723
+
724
+ $rulesetDir = dirname($rulesetPath);
725
+ self::$rulesetDirs[] = $rulesetDir;
726
+
727
+ if (is_dir($rulesetDir.DIRECTORY_SEPARATOR.'Sniffs') === true) {
728
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
729
+ echo str_repeat("\t", $depth);
730
+ echo "\tAdding sniff files from \"/.../".basename($rulesetDir)."/Sniffs/\" directory".PHP_EOL;
731
+ }
732
+
733
+ $ownSniffs = $this->_expandSniffDirectory($rulesetDir.DIRECTORY_SEPARATOR.'Sniffs', $depth);
734
+ }
735
+
736
+ // Process custom sniff config settings.
737
+ foreach ($ruleset->{'config'} as $config) {
738
+ if ($this->_shouldProcessElement($config) === false) {
739
+ continue;
740
+ }
741
+
742
+ $this->setConfigData((string) $config['name'], (string) $config['value'], true);
743
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
744
+ echo str_repeat("\t", $depth);
745
+ echo "\t=> set config value ".(string) $config['name'].': '.(string) $config['value'].PHP_EOL;
746
+ }
747
+ }
748
+
749
+ foreach ($ruleset->rule as $rule) {
750
+ if (isset($rule['ref']) === false
751
+ || $this->_shouldProcessElement($rule) === false
752
+ ) {
753
+ continue;
754
+ }
755
+
756
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
757
+ echo str_repeat("\t", $depth);
758
+ echo "\tProcessing rule \"".$rule['ref'].'"'.PHP_EOL;
759
+ }
760
+
761
+ $includedSniffs = array_merge(
762
+ $includedSniffs,
763
+ $this->_expandRulesetReference($rule['ref'], $rulesetDir, $depth)
764
+ );
765
+
766
+ if (isset($rule->exclude) === true) {
767
+ foreach ($rule->exclude as $exclude) {
768
+ if ($this->_shouldProcessElement($exclude) === false) {
769
+ continue;
770
+ }
771
+
772
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
773
+ echo str_repeat("\t", $depth);
774
+ echo "\t\tExcluding rule \"".$exclude['name'].'"'.PHP_EOL;
775
+ }
776
+
777
+ // Check if a single code is being excluded, which is a shortcut
778
+ // for setting the severity of the message to 0.
779
+ $parts = explode('.', $exclude['name']);
780
+ if (count($parts) === 4) {
781
+ $this->ruleset[(string) $exclude['name']]['severity'] = 0;
782
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
783
+ echo str_repeat("\t", $depth);
784
+ echo "\t\t=> severity set to 0".PHP_EOL;
785
+ }
786
+ } else {
787
+ $excludedSniffs = array_merge(
788
+ $excludedSniffs,
789
+ $this->_expandRulesetReference($exclude['name'], $rulesetDir, ($depth + 1))
790
+ );
791
+ }
792
+ }//end foreach
793
+ }//end if
794
+
795
+ $this->_processRule($rule, $depth);
796
+ }//end foreach
797
+
798
+ // Process custom command line arguments.
799
+ $cliArgs = array();
800
+ foreach ($ruleset->{'arg'} as $arg) {
801
+ if ($this->_shouldProcessElement($arg) === false) {
802
+ continue;
803
+ }
804
+
805
+ if (isset($arg['name']) === true) {
806
+ $argString = '--'.(string) $arg['name'];
807
+ if (isset($arg['value']) === true) {
808
+ $argString .= '='.(string) $arg['value'];
809
+ }
810
+ } else {
811
+ $argString = '-'.(string) $arg['value'];
812
+ }
813
+
814
+ $cliArgs[] = $argString;
815
+
816
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
817
+ echo str_repeat("\t", $depth);
818
+ echo "\t=> set command line value $argString".PHP_EOL;
819
+ }
820
+ }//end foreach
821
+
822
+ // Set custom php ini values as CLI args.
823
+ foreach ($ruleset->{'ini'} as $arg) {
824
+ if ($this->_shouldProcessElement($arg) === false) {
825
+ continue;
826
+ }
827
+
828
+ if (isset($arg['name']) === false) {
829
+ continue;
830
+ }
831
+
832
+ $name = (string) $arg['name'];
833
+ $argString = $name;
834
+ if (isset($arg['value']) === true) {
835
+ $value = (string) $arg['value'];
836
+ $argString .= "=$value";
837
+ } else {
838
+ $value = 'true';
839
+ }
840
+
841
+ $cliArgs[] = '-d';
842
+ $cliArgs[] = $argString;
843
+
844
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
845
+ echo str_repeat("\t", $depth);
846
+ echo "\t=> set PHP ini value $name to $value".PHP_EOL;
847
+ }
848
+ }//end foreach
849
+
850
+ if (empty($cliValues['files']) === true && $cliValues['stdin'] === null) {
851
+ // Process hard-coded file paths.
852
+ foreach ($ruleset->{'file'} as $file) {
853
+ $file = (string) $file;
854
+ $cliArgs[] = $file;
855
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
856
+ echo str_repeat("\t", $depth);
857
+ echo "\t=> added \"$file\" to the file list".PHP_EOL;
858
+ }
859
+ }
860
+ }
861
+
862
+ if (empty($cliArgs) === false) {
863
+ // Change the directory so all relative paths are worked
864
+ // out based on the location of the ruleset instead of
865
+ // the location of the user.
866
+ $inPhar = self::isPharFile($rulesetDir);
867
+ if ($inPhar === false) {
868
+ $currentDir = getcwd();
869
+ chdir($rulesetDir);
870
+ }
871
+
872
+ $this->cli->setCommandLineValues($cliArgs);
873
+
874
+ if ($inPhar === false) {
875
+ chdir($currentDir);
876
+ }
877
+ }
878
+
879
+ // Process custom ignore pattern rules.
880
+ foreach ($ruleset->{'exclude-pattern'} as $pattern) {
881
+ if ($this->_shouldProcessElement($pattern) === false) {
882
+ continue;
883
+ }
884
+
885
+ if (isset($pattern['type']) === false) {
886
+ $pattern['type'] = 'absolute';
887
+ }
888
+
889
+ $this->ignorePatterns[(string) $pattern] = (string) $pattern['type'];
890
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
891
+ echo str_repeat("\t", $depth);
892
+ echo "\t=> added global ".(string) $pattern['type'].' ignore pattern: '.(string) $pattern.PHP_EOL;
893
+ }
894
+ }
895
+
896
+ $includedSniffs = array_unique(array_merge($ownSniffs, $includedSniffs));
897
+ $excludedSniffs = array_unique($excludedSniffs);
898
+
899
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
900
+ $included = count($includedSniffs);
901
+ $excluded = count($excludedSniffs);
902
+ echo str_repeat("\t", $depth);
903
+ echo "=> Ruleset processing complete; included $included sniffs and excluded $excluded".PHP_EOL;
904
+ }
905
+
906
+ // Merge our own sniff list with our externally included
907
+ // sniff list, but filter out any excluded sniffs.
908
+ $files = array();
909
+ foreach ($includedSniffs as $sniff) {
910
+ if (in_array($sniff, $excludedSniffs) === true) {
911
+ continue;
912
+ } else {
913
+ $files[] = self::realpath($sniff);
914
+ }
915
+ }
916
+
917
+ return $files;
918
+
919
+ }//end processRuleset()
920
+
921
+
922
+ /**
923
+ * Expands a directory into a list of sniff files within.
924
+ *
925
+ * @param string $directory The path to a directory.
926
+ * @param int $depth How many nested processing steps we are in. This
927
+ * is only used for debug output.
928
+ *
929
+ * @return array
930
+ */
931
+ private function _expandSniffDirectory($directory, $depth=0)
932
+ {
933
+ $sniffs = array();
934
+
935
+ if (defined('RecursiveDirectoryIterator::FOLLOW_SYMLINKS') === true) {
936
+ $rdi = new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::FOLLOW_SYMLINKS);
937
+ } else {
938
+ $rdi = new RecursiveDirectoryIterator($directory);
939
+ }
940
+
941
+ $di = new RecursiveIteratorIterator($rdi, 0, RecursiveIteratorIterator::CATCH_GET_CHILD);
942
+
943
+ $dirLen = strlen($directory);
944
+
945
+ foreach ($di as $file) {
946
+ $filename = $file->getFilename();
947
+
948
+ // Skip hidden files.
949
+ if (substr($filename, 0, 1) === '.') {
950
+ continue;
951
+ }
952
+
953
+ // We are only interested in PHP and sniff files.
954
+ $fileParts = explode('.', $filename);
955
+ if (array_pop($fileParts) !== 'php') {
956
+ continue;
957
+ }
958
+
959
+ $basename = basename($filename, '.php');
960
+ if (substr($basename, -5) !== 'Sniff') {
961
+ continue;
962
+ }
963
+
964
+ $path = $file->getPathname();
965
+
966
+ // Skip files in hidden directories within the Sniffs directory of this
967
+ // standard. We use the offset with strpos() to allow hidden directories
968
+ // before, valid example:
969
+ // /home/foo/.composer/vendor/drupal/coder/coder_sniffer/Drupal/Sniffs/...
970
+ if (strpos($path, DIRECTORY_SEPARATOR.'.', $dirLen) !== false) {
971
+ continue;
972
+ }
973
+
974
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
975
+ echo str_repeat("\t", $depth);
976
+ echo "\t\t=> $path".PHP_EOL;
977
+ }
978
+
979
+ $sniffs[] = $path;
980
+ }//end foreach
981
+
982
+ return $sniffs;
983
+
984
+ }//end _expandSniffDirectory()
985
+
986
+
987
+ /**
988
+ * Expands a ruleset reference into a list of sniff files.
989
+ *
990
+ * @param string $ref The reference from the ruleset XML file.
991
+ * @param string $rulesetDir The directory of the ruleset XML file, used to
992
+ * evaluate relative paths.
993
+ * @param int $depth How many nested processing steps we are in. This
994
+ * is only used for debug output.
995
+ *
996
+ * @return array
997
+ * @throws PHP_CodeSniffer_Exception If the reference is invalid.
998
+ */
999
+ private function _expandRulesetReference($ref, $rulesetDir, $depth=0)
1000
+ {
1001
+ // Ignore internal sniffs codes as they are used to only
1002
+ // hide and change internal messages.
1003
+ if (substr($ref, 0, 9) === 'Internal.') {
1004
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1005
+ echo str_repeat("\t", $depth);
1006
+ echo "\t\t* ignoring internal sniff code *".PHP_EOL;
1007
+ }
1008
+
1009
+ return array();
1010
+ }
1011
+
1012
+ // As sniffs can't begin with a full stop, assume references in
1013
+ // this format are relative paths and attempt to convert them
1014
+ // to absolute paths. If this fails, let the reference run through
1015
+ // the normal checks and have it fail as normal.
1016
+ if (substr($ref, 0, 1) === '.') {
1017
+ $realpath = self::realpath($rulesetDir.'/'.$ref);
1018
+ if ($realpath !== false) {
1019
+ $ref = $realpath;
1020
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1021
+ echo str_repeat("\t", $depth);
1022
+ echo "\t\t=> $ref".PHP_EOL;
1023
+ }
1024
+ }
1025
+ }
1026
+
1027
+ // As sniffs can't begin with a tilde, assume references in
1028
+ // this format at relative to the user's home directory.
1029
+ if (substr($ref, 0, 2) === '~/') {
1030
+ $realpath = self::realpath($ref);
1031
+ if ($realpath !== false) {
1032
+ $ref = $realpath;
1033
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1034
+ echo str_repeat("\t", $depth);
1035
+ echo "\t\t=> $ref".PHP_EOL;
1036
+ }
1037
+ }
1038
+ }
1039
+
1040
+ if (is_file($ref) === true) {
1041
+ if (substr($ref, -9) === 'Sniff.php') {
1042
+ // A single external sniff.
1043
+ self::$rulesetDirs[] = dirname(dirname(dirname($ref)));
1044
+ return array($ref);
1045
+ }
1046
+ } else {
1047
+ // See if this is a whole standard being referenced.
1048
+ $path = $this->getInstalledStandardPath($ref);
1049
+ if (self::isPharFile($path) === true && strpos($path, 'ruleset.xml') === false) {
1050
+ // If the ruleset exists inside the phar file, use it.
1051
+ if (file_exists($path.DIRECTORY_SEPARATOR.'ruleset.xml') === true) {
1052
+ $path = $path.DIRECTORY_SEPARATOR.'ruleset.xml';
1053
+ } else {
1054
+ $path = null;
1055
+ }
1056
+ }
1057
+
1058
+ if ($path !== null) {
1059
+ $ref = $path;
1060
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1061
+ echo str_repeat("\t", $depth);
1062
+ echo "\t\t=> $ref".PHP_EOL;
1063
+ }
1064
+ } else if (is_dir($ref) === false) {
1065
+ // Work out the sniff path.
1066
+ $sepPos = strpos($ref, DIRECTORY_SEPARATOR);
1067
+ if ($sepPos !== false) {
1068
+ $stdName = substr($ref, 0, $sepPos);
1069
+ $path = substr($ref, $sepPos);
1070
+ } else {
1071
+ $parts = explode('.', $ref);
1072
+ $stdName = $parts[0];
1073
+ if (count($parts) === 1) {
1074
+ // A whole standard?
1075
+ $path = '';
1076
+ } else if (count($parts) === 2) {
1077
+ // A directory of sniffs?
1078
+ $path = DIRECTORY_SEPARATOR.'Sniffs'.DIRECTORY_SEPARATOR.$parts[1];
1079
+ } else {
1080
+ // A single sniff?
1081
+ $path = DIRECTORY_SEPARATOR.'Sniffs'.DIRECTORY_SEPARATOR.$parts[1].DIRECTORY_SEPARATOR.$parts[2].'Sniff.php';
1082
+ }
1083
+ }
1084
+
1085
+ $newRef = false;
1086
+ $stdPath = $this->getInstalledStandardPath($stdName);
1087
+ if ($stdPath !== null && $path !== '') {
1088
+ if (self::isPharFile($stdPath) === true
1089
+ && strpos($stdPath, 'ruleset.xml') === false
1090
+ ) {
1091
+ // Phar files can only return the directory,
1092
+ // since ruleset can be omitted if building one standard.
1093
+ $newRef = self::realpath($stdPath.$path);
1094
+ } else {
1095
+ $newRef = self::realpath(dirname($stdPath).$path);
1096
+ }
1097
+ }
1098
+
1099
+ if ($newRef === false) {
1100
+ // The sniff is not locally installed, so check if it is being
1101
+ // referenced as a remote sniff outside the install. We do this
1102
+ // by looking through all directories where we have found ruleset
1103
+ // files before, looking for ones for this particular standard,
1104
+ // and seeing if it is in there.
1105
+ foreach (self::$rulesetDirs as $dir) {
1106
+ if (strtolower(basename($dir)) !== strtolower($stdName)) {
1107
+ continue;
1108
+ }
1109
+
1110
+ $newRef = self::realpath($dir.$path);
1111
+
1112
+ if ($newRef !== false) {
1113
+ $ref = $newRef;
1114
+ }
1115
+ }
1116
+ } else {
1117
+ $ref = $newRef;
1118
+ }
1119
+
1120
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1121
+ echo str_repeat("\t", $depth);
1122
+ echo "\t\t=> $ref".PHP_EOL;
1123
+ }
1124
+ }//end if
1125
+ }//end if
1126
+
1127
+ if (is_dir($ref) === true) {
1128
+ if (is_file($ref.DIRECTORY_SEPARATOR.'ruleset.xml') === true) {
1129
+ // We are referencing an external coding standard.
1130
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1131
+ echo str_repeat("\t", $depth);
1132
+ echo "\t\t* rule is referencing a standard using directory name; processing *".PHP_EOL;
1133
+ }
1134
+
1135
+ return $this->processRuleset($ref.DIRECTORY_SEPARATOR.'ruleset.xml', ($depth + 2));
1136
+ } else {
1137
+ // We are referencing a whole directory of sniffs.
1138
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1139
+ echo str_repeat("\t", $depth);
1140
+ echo "\t\t* rule is referencing a directory of sniffs *".PHP_EOL;
1141
+ echo str_repeat("\t", $depth);
1142
+ echo "\t\tAdding sniff files from directory".PHP_EOL;
1143
+ }
1144
+
1145
+ return $this->_expandSniffDirectory($ref, ($depth + 1));
1146
+ }
1147
+ } else {
1148
+ if (is_file($ref) === false) {
1149
+ $error = "Referenced sniff \"$ref\" does not exist";
1150
+ throw new PHP_CodeSniffer_Exception($error);
1151
+ }
1152
+
1153
+ if (substr($ref, -9) === 'Sniff.php') {
1154
+ // A single sniff.
1155
+ return array($ref);
1156
+ } else {
1157
+ // Assume an external ruleset.xml file.
1158
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1159
+ echo str_repeat("\t", $depth);
1160
+ echo "\t\t* rule is referencing a standard using ruleset path; processing *".PHP_EOL;
1161
+ }
1162
+
1163
+ return $this->processRuleset($ref, ($depth + 2));
1164
+ }
1165
+ }//end if
1166
+
1167
+ }//end _expandRulesetReference()
1168
+
1169
+
1170
+ /**
1171
+ * Processes a rule from a ruleset XML file, overriding built-in defaults.
1172
+ *
1173
+ * @param SimpleXMLElement $rule The rule object from a ruleset XML file.
1174
+ * @param int $depth How many nested processing steps we are in.
1175
+ * This is only used for debug output.
1176
+ *
1177
+ * @return void
1178
+ */
1179
+ private function _processRule($rule, $depth=0)
1180
+ {
1181
+ $code = (string) $rule['ref'];
1182
+
1183
+ // Custom severity.
1184
+ if (isset($rule->severity) === true
1185
+ && $this->_shouldProcessElement($rule->severity) === true
1186
+ ) {
1187
+ if (isset($this->ruleset[$code]) === false) {
1188
+ $this->ruleset[$code] = array();
1189
+ }
1190
+
1191
+ $this->ruleset[$code]['severity'] = (int) $rule->severity;
1192
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1193
+ echo str_repeat("\t", $depth);
1194
+ echo "\t\t=> severity set to ".(int) $rule->severity.PHP_EOL;
1195
+ }
1196
+ }
1197
+
1198
+ // Custom message type.
1199
+ if (isset($rule->type) === true
1200
+ && $this->_shouldProcessElement($rule->type) === true
1201
+ ) {
1202
+ if (isset($this->ruleset[$code]) === false) {
1203
+ $this->ruleset[$code] = array();
1204
+ }
1205
+
1206
+ $this->ruleset[$code]['type'] = (string) $rule->type;
1207
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1208
+ echo str_repeat("\t", $depth);
1209
+ echo "\t\t=> message type set to ".(string) $rule->type.PHP_EOL;
1210
+ }
1211
+ }
1212
+
1213
+ // Custom message.
1214
+ if (isset($rule->message) === true
1215
+ && $this->_shouldProcessElement($rule->message) === true
1216
+ ) {
1217
+ if (isset($this->ruleset[$code]) === false) {
1218
+ $this->ruleset[$code] = array();
1219
+ }
1220
+
1221
+ $this->ruleset[$code]['message'] = (string) $rule->message;
1222
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1223
+ echo str_repeat("\t", $depth);
1224
+ echo "\t\t=> message set to ".(string) $rule->message.PHP_EOL;
1225
+ }
1226
+ }
1227
+
1228
+ // Custom properties.
1229
+ if (isset($rule->properties) === true
1230
+ && $this->_shouldProcessElement($rule->properties) === true
1231
+ ) {
1232
+ foreach ($rule->properties->property as $prop) {
1233
+ if ($this->_shouldProcessElement($prop) === false) {
1234
+ continue;
1235
+ }
1236
+
1237
+ if (isset($this->ruleset[$code]) === false) {
1238
+ $this->ruleset[$code] = array(
1239
+ 'properties' => array(),
1240
+ );
1241
+ } else if (isset($this->ruleset[$code]['properties']) === false) {
1242
+ $this->ruleset[$code]['properties'] = array();
1243
+ }
1244
+
1245
+ $name = (string) $prop['name'];
1246
+ if (isset($prop['type']) === true
1247
+ && (string) $prop['type'] === 'array'
1248
+ ) {
1249
+ $value = (string) $prop['value'];
1250
+ $values = array();
1251
+ foreach (explode(',', $value) as $val) {
1252
+ $v = '';
1253
+
1254
+ list($k,$v) = explode('=>', $val.'=>');
1255
+ if ($v !== '') {
1256
+ $values[$k] = $v;
1257
+ } else {
1258
+ $values[] = $k;
1259
+ }
1260
+ }
1261
+
1262
+ $this->ruleset[$code]['properties'][$name] = $values;
1263
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1264
+ echo str_repeat("\t", $depth);
1265
+ echo "\t\t=> array property \"$name\" set to \"$value\"".PHP_EOL;
1266
+ }
1267
+ } else {
1268
+ $this->ruleset[$code]['properties'][$name] = (string) $prop['value'];
1269
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1270
+ echo str_repeat("\t", $depth);
1271
+ echo "\t\t=> property \"$name\" set to \"".(string) $prop['value'].'"'.PHP_EOL;
1272
+ }
1273
+ }//end if
1274
+ }//end foreach
1275
+ }//end if
1276
+
1277
+ // Ignore patterns.
1278
+ foreach ($rule->{'exclude-pattern'} as $pattern) {
1279
+ if ($this->_shouldProcessElement($pattern) === false) {
1280
+ continue;
1281
+ }
1282
+
1283
+ if (isset($this->ignorePatterns[$code]) === false) {
1284
+ $this->ignorePatterns[$code] = array();
1285
+ }
1286
+
1287
+ if (isset($pattern['type']) === false) {
1288
+ $pattern['type'] = 'absolute';
1289
+ }
1290
+
1291
+ $this->ignorePatterns[$code][(string) $pattern] = (string) $pattern['type'];
1292
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1293
+ echo str_repeat("\t", $depth);
1294
+ echo "\t\t=> added sniff-specific ".(string) $pattern['type'].' ignore pattern: '.(string) $pattern.PHP_EOL;
1295
+ }
1296
+ }
1297
+
1298
+ }//end _processRule()
1299
+
1300
+
1301
+ /**
1302
+ * Determine if an element should be processed or ignored.
1303
+ *
1304
+ * @param SimpleXMLElement $element An object from a ruleset XML file.
1305
+ * @param int $depth How many nested processing steps we are in.
1306
+ * This is only used for debug output.
1307
+ *
1308
+ * @return bool
1309
+ */
1310
+ private function _shouldProcessElement($element, $depth=0)
1311
+ {
1312
+ if (isset($element['phpcbf-only']) === false
1313
+ && isset($element['phpcs-only']) === false
1314
+ ) {
1315
+ // No exceptions are being made.
1316
+ return true;
1317
+ }
1318
+
1319
+ if (PHP_CODESNIFFER_CBF === true
1320
+ && isset($element['phpcbf-only']) === true
1321
+ && (string) $element['phpcbf-only'] === 'true'
1322
+ ) {
1323
+ return true;
1324
+ }
1325
+
1326
+ if (PHP_CODESNIFFER_CBF === false
1327
+ && isset($element['phpcs-only']) === true
1328
+ && (string) $element['phpcs-only'] === 'true'
1329
+ ) {
1330
+ return true;
1331
+ }
1332
+
1333
+ return false;
1334
+
1335
+ }//end _shouldProcessElement()
1336
+
1337
+
1338
+ /**
1339
+ * Loads and stores sniffs objects used for sniffing files.
1340
+ *
1341
+ * @param array $files Paths to the sniff files to register.
1342
+ * @param array $restrictions The sniff class names to restrict the allowed
1343
+ * listeners to.
1344
+ * @param array $exclusions The sniff class names to exclude from the
1345
+ * listeners list.
1346
+ *
1347
+ * @return void
1348
+ * @throws PHP_CodeSniffer_Exception If a sniff file path is invalid.
1349
+ */
1350
+ public function registerSniffs($files, $restrictions, $exclusions)
1351
+ {
1352
+ $listeners = array();
1353
+
1354
+ foreach ($files as $file) {
1355
+ // Work out where the position of /StandardName/Sniffs/... is
1356
+ // so we can determine what the class will be called.
1357
+ $sniffPos = strrpos($file, DIRECTORY_SEPARATOR.'Sniffs'.DIRECTORY_SEPARATOR);
1358
+ if ($sniffPos === false) {
1359
+ continue;
1360
+ }
1361
+
1362
+ $slashPos = strrpos(substr($file, 0, $sniffPos), DIRECTORY_SEPARATOR);
1363
+ if ($slashPos === false) {
1364
+ continue;
1365
+ }
1366
+
1367
+ $className = substr($file, ($slashPos + 1));
1368
+
1369
+ if (substr_count($className, DIRECTORY_SEPARATOR) !== 3) {
1370
+ throw new PHP_CodeSniffer_Exception("Sniff file $className is not valid; sniff files must be located in a .../StandardName/Sniffs/CategoryName/ directory");
1371
+ }
1372
+
1373
+ $className = substr($className, 0, -4);
1374
+ $className = str_replace(DIRECTORY_SEPARATOR, '_', $className);
1375
+
1376
+ // If they have specified a list of sniffs to restrict to, check
1377
+ // to see if this sniff is allowed.
1378
+ if (empty($restrictions) === false
1379
+ && in_array(strtolower($className), $restrictions) === false
1380
+ ) {
1381
+ continue;
1382
+ }
1383
+
1384
+ // If they have specified a list of sniffs to exclude, check
1385
+ // to see if this sniff is allowed.
1386
+ if (empty($exclusions) === false
1387
+ && in_array(strtolower($className), $exclusions) === true
1388
+ ) {
1389
+ continue;
1390
+ }
1391
+
1392
+ include_once $file;
1393
+
1394
+ // Support the use of PHP namespaces. If the class name we included
1395
+ // contains namespace separators instead of underscores, use this as the
1396
+ // class name from now on.
1397
+ $classNameNS = str_replace('_', '\\', $className);
1398
+ if (class_exists($classNameNS, false) === true) {
1399
+ $className = $classNameNS;
1400
+ }
1401
+
1402
+ // Skip abstract classes.
1403
+ $reflection = new ReflectionClass($className);
1404
+ if ($reflection->isAbstract() === true) {
1405
+ continue;
1406
+ }
1407
+
1408
+ $listeners[$className] = $className;
1409
+
1410
+ if (PHP_CODESNIFFER_VERBOSITY > 2) {
1411
+ echo "Registered $className".PHP_EOL;
1412
+ }
1413
+ }//end foreach
1414
+
1415
+ $this->sniffs = $listeners;
1416
+
1417
+ }//end registerSniffs()
1418
+
1419
+
1420
+ /**
1421
+ * Populates the array of PHP_CodeSniffer_Sniff's for this file.
1422
+ *
1423
+ * @return void
1424
+ * @throws PHP_CodeSniffer_Exception If sniff registration fails.
1425
+ */
1426
+ public function populateTokenListeners()
1427
+ {
1428
+ // Construct a list of listeners indexed by token being listened for.
1429
+ $this->_tokenListeners = array();
1430
+
1431
+ foreach ($this->sniffs as $listenerClass) {
1432
+ // Work out the internal code for this sniff. Detect usage of namespace
1433
+ // separators instead of underscores to support PHP namespaces.
1434
+ if (strstr($listenerClass, '\\') === false) {
1435
+ $parts = explode('_', $listenerClass);
1436
+ } else {
1437
+ $parts = explode('\\', $listenerClass);
1438
+ }
1439
+
1440
+ $code = $parts[0].'.'.$parts[2].'.'.$parts[3];
1441
+ $code = substr($code, 0, -5);
1442
+
1443
+ $this->listeners[$listenerClass] = new $listenerClass();
1444
+ $this->sniffCodes[$code] = $listenerClass;
1445
+
1446
+ // Set custom properties.
1447
+ if (isset($this->ruleset[$code]['properties']) === true) {
1448
+ foreach ($this->ruleset[$code]['properties'] as $name => $value) {
1449
+ $this->setSniffProperty($listenerClass, $name, $value);
1450
+ }
1451
+ }
1452
+
1453
+ $tokenizers = array();
1454
+ $vars = get_class_vars($listenerClass);
1455
+ if (isset($vars['supportedTokenizers']) === true) {
1456
+ foreach ($vars['supportedTokenizers'] as $tokenizer) {
1457
+ $tokenizers[$tokenizer] = $tokenizer;
1458
+ }
1459
+ } else {
1460
+ $tokenizers = array('PHP' => 'PHP');
1461
+ }
1462
+
1463
+ $tokens = $this->listeners[$listenerClass]->register();
1464
+ if (is_array($tokens) === false) {
1465
+ $msg = "Sniff $listenerClass register() method must return an array";
1466
+ throw new PHP_CodeSniffer_Exception($msg);
1467
+ }
1468
+
1469
+ $parts = explode('_', str_replace('\\', '_', $listenerClass));
1470
+ $listenerSource = $parts[0].'.'.$parts[2].'.'.substr($parts[3], 0, -5);
1471
+ $ignorePatterns = array();
1472
+ $patterns = $this->getIgnorePatterns($listenerSource);
1473
+ foreach ($patterns as $pattern => $type) {
1474
+ // While there is support for a type of each pattern
1475
+ // (absolute or relative) we don't actually support it here.
1476
+ $replacements = array(
1477
+ '\\,' => ',',
1478
+ '*' => '.*',
1479
+ );
1480
+
1481
+ $ignorePatterns[] = strtr($pattern, $replacements);
1482
+ }
1483
+
1484
+ foreach ($tokens as $token) {
1485
+ if (isset($this->_tokenListeners[$token]) === false) {
1486
+ $this->_tokenListeners[$token] = array();
1487
+ }
1488
+
1489
+ if (isset($this->_tokenListeners[$token][$listenerClass]) === false) {
1490
+ $this->_tokenListeners[$token][$listenerClass] = array(
1491
+ 'class' => $listenerClass,
1492
+ 'source' => $listenerSource,
1493
+ 'tokenizers' => $tokenizers,
1494
+ 'ignore' => $ignorePatterns,
1495
+ );
1496
+ }
1497
+ }
1498
+ }//end foreach
1499
+
1500
+ }//end populateTokenListeners()
1501
+
1502
+
1503
+ /**
1504
+ * Set a single property for a sniff.
1505
+ *
1506
+ * @param string $listenerClass The class name of the sniff.
1507
+ * @param string $name The name of the property to change.
1508
+ * @param string $value The new value of the property.
1509
+ *
1510
+ * @return void
1511
+ */
1512
+ public function setSniffProperty($listenerClass, $name, $value)
1513
+ {
1514
+ // Setting a property for a sniff we are not using.
1515
+ if (isset($this->listeners[$listenerClass]) === false) {
1516
+ return;
1517
+ }
1518
+
1519
+ $name = trim($name);
1520
+ if (is_string($value) === true) {
1521
+ $value = trim($value);
1522
+ }
1523
+
1524
+ // Special case for booleans.
1525
+ if ($value === 'true') {
1526
+ $value = true;
1527
+ } else if ($value === 'false') {
1528
+ $value = false;
1529
+ }
1530
+
1531
+ $this->listeners[$listenerClass]->$name = $value;
1532
+
1533
+ }//end setSniffProperty()
1534
+
1535
+
1536
+ /**
1537
+ * Get a list of files that will be processed.
1538
+ *
1539
+ * If passed directories, this method will find all files within them.
1540
+ * The method will also perform file extension and ignore pattern filtering.
1541
+ *
1542
+ * @param string $paths A list of file or directory paths to process.
1543
+ * @param boolean $local If true, only process 1 level of files in directories
1544
+ *
1545
+ * @return array
1546
+ * @throws Exception If there was an error opening a directory.
1547
+ * @see shouldProcessFile()
1548
+ */
1549
+ public function getFilesToProcess($paths, $local=false)
1550
+ {
1551
+ $files = array();
1552
+
1553
+ foreach ($paths as $path) {
1554
+ if (is_dir($path) === true || self::isPharFile($path) === true) {
1555
+ if (self::isPharFile($path) === true) {
1556
+ $path = 'phar://'.$path;
1557
+ }
1558
+
1559
+ if ($local === true) {
1560
+ $di = new DirectoryIterator($path);
1561
+ } else {
1562
+ $di = new RecursiveIteratorIterator(
1563
+ new RecursiveDirectoryIterator($path),
1564
+ 0,
1565
+ RecursiveIteratorIterator::CATCH_GET_CHILD
1566
+ );
1567
+ }
1568
+
1569
+ foreach ($di as $file) {
1570
+ // Check if the file exists after all symlinks are resolved.
1571
+ $filePath = self::realpath($file->getPathname());
1572
+ if ($filePath === false) {
1573
+ continue;
1574
+ }
1575
+
1576
+ if (is_dir($filePath) === true) {
1577
+ continue;
1578
+ }
1579
+
1580
+ if ($this->shouldProcessFile($file->getPathname(), $path) === false) {
1581
+ continue;
1582
+ }
1583
+
1584
+ $files[] = $file->getPathname();
1585
+ }//end foreach
1586
+ } else {
1587
+ if ($this->shouldIgnoreFile($path, dirname($path)) === true) {
1588
+ continue;
1589
+ }
1590
+
1591
+ $files[] = $path;
1592
+ }//end if
1593
+ }//end foreach
1594
+
1595
+ return $files;
1596
+
1597
+ }//end getFilesToProcess()
1598
+
1599
+
1600
+ /**
1601
+ * Checks filtering rules to see if a file should be checked.
1602
+ *
1603
+ * Checks both file extension filters and path ignore filters.
1604
+ *
1605
+ * @param string $path The path to the file being checked.
1606
+ * @param string $basedir The directory to use for relative path checks.
1607
+ *
1608
+ * @return bool
1609
+ */
1610
+ public function shouldProcessFile($path, $basedir)
1611
+ {
1612
+ // Check that the file's extension is one we are checking.
1613
+ // We are strict about checking the extension and we don't
1614
+ // let files through with no extension or that start with a dot.
1615
+ $fileName = basename($path);
1616
+ $fileParts = explode('.', $fileName);
1617
+ if ($fileParts[0] === $fileName || $fileParts[0] === '') {
1618
+ return false;
1619
+ }
1620
+
1621
+ // Checking multi-part file extensions, so need to create a
1622
+ // complete extension list and make sure one is allowed.
1623
+ $extensions = array();
1624
+ array_shift($fileParts);
1625
+ foreach ($fileParts as $part) {
1626
+ $extensions[implode('.', $fileParts)] = 1;
1627
+ array_shift($fileParts);
1628
+ }
1629
+
1630
+ $matches = array_intersect_key($extensions, $this->allowedFileExtensions);
1631
+ if (empty($matches) === true) {
1632
+ return false;
1633
+ }
1634
+
1635
+ // If the file's path matches one of our ignore patterns, skip it.
1636
+ if ($this->shouldIgnoreFile($path, $basedir) === true) {
1637
+ return false;
1638
+ }
1639
+
1640
+ return true;
1641
+
1642
+ }//end shouldProcessFile()
1643
+
1644
+
1645
+ /**
1646
+ * Checks filtering rules to see if a file should be ignored.
1647
+ *
1648
+ * @param string $path The path to the file being checked.
1649
+ * @param string $basedir The directory to use for relative path checks.
1650
+ *
1651
+ * @return bool
1652
+ */
1653
+ public function shouldIgnoreFile($path, $basedir)
1654
+ {
1655
+ $relativePath = $path;
1656
+ if (strpos($path, $basedir) === 0) {
1657
+ // The +1 cuts off the directory separator as well.
1658
+ $relativePath = substr($path, (strlen($basedir) + 1));
1659
+ }
1660
+
1661
+ foreach ($this->ignorePatterns as $pattern => $type) {
1662
+ if (is_array($type) === true) {
1663
+ // A sniff specific ignore pattern.
1664
+ continue;
1665
+ }
1666
+
1667
+ // Maintains backwards compatibility in case the ignore pattern does
1668
+ // not have a relative/absolute value.
1669
+ if (is_int($pattern) === true) {
1670
+ $pattern = $type;
1671
+ $type = 'absolute';
1672
+ }
1673
+
1674
+ $replacements = array(
1675
+ '\\,' => ',',
1676
+ '*' => '.*',
1677
+ );
1678
+
1679
+ // We assume a / directory separator, as do the exclude rules
1680
+ // most developers write, so we need a special case for any system
1681
+ // that is different.
1682
+ if (DIRECTORY_SEPARATOR === '\\') {
1683
+ $replacements['/'] = '\\\\';
1684
+ }
1685
+
1686
+ $pattern = strtr($pattern, $replacements);
1687
+
1688
+ if ($type === 'relative') {
1689
+ $testPath = $relativePath;
1690
+ } else {
1691
+ $testPath = $path;
1692
+ }
1693
+
1694
+ $pattern = '`'.$pattern.'`i';
1695
+ if (preg_match($pattern, $testPath) === 1) {
1696
+ return true;
1697
+ }
1698
+ }//end foreach
1699
+
1700
+ return false;
1701
+
1702
+ }//end shouldIgnoreFile()
1703
+
1704
+
1705
+ /**
1706
+ * Run the code sniffs over a single given file.
1707
+ *
1708
+ * Processes the file and runs the PHP_CodeSniffer sniffs to verify that it
1709
+ * conforms with the standard. Returns the processed file object, or NULL
1710
+ * if no file was processed due to error.
1711
+ *
1712
+ * @param string $file The file to process.
1713
+ * @param string $contents The contents to parse. If NULL, the content
1714
+ * is taken from the file system.
1715
+ *
1716
+ * @return PHP_CodeSniffer_File
1717
+ * @throws PHP_CodeSniffer_Exception If the file could not be processed.
1718
+ * @see _processFile()
1719
+ */
1720
+ public function processFile($file, $contents=null)
1721
+ {
1722
+ if ($contents === null && file_exists($file) === false) {
1723
+ throw new PHP_CodeSniffer_Exception("Source file $file does not exist");
1724
+ }
1725
+
1726
+ $filePath = self::realpath($file);
1727
+ if ($filePath === false) {
1728
+ $filePath = $file;
1729
+ }
1730
+
1731
+ // Before we go and spend time tokenizing this file, just check
1732
+ // to see if there is a tag up top to indicate that the whole
1733
+ // file should be ignored. It must be on one of the first two lines.
1734
+ $firstContent = $contents;
1735
+ if ($contents === null && is_readable($filePath) === true) {
1736
+ $handle = fopen($filePath, 'r');
1737
+ stream_set_blocking($handle, true);
1738
+ if ($handle !== false) {
1739
+ $firstContent = fgets($handle);
1740
+ $firstContent .= fgets($handle);
1741
+ fclose($handle);
1742
+
1743
+ if (strpos($firstContent, '@codingStandardsIgnoreFile') !== false) {
1744
+ // We are ignoring the whole file.
1745
+ if (PHP_CODESNIFFER_VERBOSITY > 0) {
1746
+ echo 'Ignoring '.basename($filePath).PHP_EOL;
1747
+ }
1748
+
1749
+ return null;
1750
+ }
1751
+ }
1752
+ }//end if
1753
+
1754
+ try {
1755
+ $phpcsFile = $this->_processFile($file, $contents);
1756
+ } catch (Exception $e) {
1757
+ $trace = $e->getTrace();
1758
+
1759
+ $filename = $trace[0]['args'][0];
1760
+ if (is_object($filename) === true
1761
+ && get_class($filename) === 'PHP_CodeSniffer_File'
1762
+ ) {
1763
+ $filename = $filename->getFilename();
1764
+ } else if (is_numeric($filename) === true) {
1765
+ // See if we can find the PHP_CodeSniffer_File object.
1766
+ foreach ($trace as $data) {
1767
+ if (isset($data['args'][0]) === true
1768
+ && ($data['args'][0] instanceof PHP_CodeSniffer_File) === true
1769
+ ) {
1770
+ $filename = $data['args'][0]->getFilename();
1771
+ }
1772
+ }
1773
+ } else if (is_string($filename) === false) {
1774
+ $filename = (string) $filename;
1775
+ }
1776
+
1777
+ $errorMessage = '"'.$e->getMessage().'" at '.$e->getFile().':'.$e->getLine();
1778
+ $error = "An error occurred during processing; checking has been aborted. The error message was: $errorMessage";
1779
+
1780
+ $phpcsFile = new PHP_CodeSniffer_File(
1781
+ $filename,
1782
+ $this->_tokenListeners,
1783
+ $this->ruleset,
1784
+ $this
1785
+ );
1786
+
1787
+ $phpcsFile->addError($error, null);
1788
+ }//end try
1789
+
1790
+ $cliValues = $this->cli->getCommandLineValues();
1791
+
1792
+ if (PHP_CODESNIFFER_INTERACTIVE === false) {
1793
+ // Cache the report data for this file so we can unset it to save memory.
1794
+ $this->reporting->cacheFileReport($phpcsFile, $cliValues);
1795
+ $phpcsFile->cleanUp();
1796
+ return $phpcsFile;
1797
+ }
1798
+
1799
+ /*
1800
+ Running interactively.
1801
+ Print the error report for the current file and then wait for user input.
1802
+ */
1803
+
1804
+ // Get current violations and then clear the list to make sure
1805
+ // we only print violations for a single file each time.
1806
+ $numErrors = null;
1807
+ while ($numErrors !== 0) {
1808
+ $numErrors = ($phpcsFile->getErrorCount() + $phpcsFile->getWarningCount());
1809
+ if ($numErrors === 0) {
1810
+ continue;
1811
+ }
1812
+
1813
+ $reportClass = $this->reporting->factory('full');
1814
+ $reportData = $this->reporting->prepareFileReport($phpcsFile);
1815
+ $reportClass->generateFileReport($reportData, $phpcsFile, $cliValues['showSources'], $cliValues['reportWidth']);
1816
+
1817
+ echo '<ENTER> to recheck, [s] to skip or [q] to quit : ';
1818
+ $input = fgets(STDIN);
1819
+ $input = trim($input);
1820
+
1821
+ switch ($input) {
1822
+ case 's':
1823
+ break(2);
1824
+ case 'q':
1825
+ exit(0);
1826
+ break;
1827
+ default:
1828
+ // Repopulate the sniffs because some of them save their state
1829
+ // and only clear it when the file changes, but we are rechecking
1830
+ // the same file.
1831
+ $this->populateTokenListeners();
1832
+ $phpcsFile = $this->_processFile($file, $contents);
1833
+ break;
1834
+ }
1835
+ }//end while
1836
+
1837
+ return $phpcsFile;
1838
+
1839
+ }//end processFile()
1840
+
1841
+
1842
+ /**
1843
+ * Process the sniffs for a single file.
1844
+ *
1845
+ * Does raw processing only. No interactive support or error checking.
1846
+ *
1847
+ * @param string $file The file to process.
1848
+ * @param string $contents The contents to parse. If NULL, the content
1849
+ * is taken from the file system.
1850
+ *
1851
+ * @return PHP_CodeSniffer_File
1852
+ * @see processFile()
1853
+ */
1854
+ private function _processFile($file, $contents)
1855
+ {
1856
+ $stdin = false;
1857
+ $cliValues = $this->cli->getCommandLineValues();
1858
+ if (empty($cliValues['files']) === true) {
1859
+ $stdin = true;
1860
+ }
1861
+
1862
+ if (PHP_CODESNIFFER_VERBOSITY > 0 || (PHP_CODESNIFFER_CBF === true && $stdin === false)) {
1863
+ $startTime = microtime(true);
1864
+ echo 'Processing '.basename($file).' ';
1865
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1866
+ echo PHP_EOL;
1867
+ }
1868
+ }
1869
+
1870
+ $phpcsFile = new PHP_CodeSniffer_File(
1871
+ $file,
1872
+ $this->_tokenListeners,
1873
+ $this->ruleset,
1874
+ $this
1875
+ );
1876
+
1877
+ $phpcsFile->start($contents);
1878
+
1879
+ if (PHP_CODESNIFFER_VERBOSITY > 0 || (PHP_CODESNIFFER_CBF === true && $stdin === false)) {
1880
+ $timeTaken = ((microtime(true) - $startTime) * 1000);
1881
+ if ($timeTaken < 1000) {
1882
+ $timeTaken = round($timeTaken);
1883
+ echo "DONE in {$timeTaken}ms";
1884
+ } else {
1885
+ $timeTaken = round(($timeTaken / 1000), 2);
1886
+ echo "DONE in $timeTaken secs";
1887
+ }
1888
+
1889
+ if (PHP_CODESNIFFER_CBF === true) {
1890
+ $errors = $phpcsFile->getFixableCount();
1891
+ echo " ($errors fixable violations)".PHP_EOL;
1892
+ } else {
1893
+ $errors = $phpcsFile->getErrorCount();
1894
+ $warnings = $phpcsFile->getWarningCount();
1895
+ echo " ($errors errors, $warnings warnings)".PHP_EOL;
1896
+ }
1897
+ }
1898
+
1899
+ return $phpcsFile;
1900
+
1901
+ }//end _processFile()
1902
+
1903
+
1904
+ /**
1905
+ * Generates documentation for a coding standard.
1906
+ *
1907
+ * @param string $standard The standard to generate docs for
1908
+ * @param array $sniffs A list of sniffs to limit the docs to.
1909
+ * @param string $generator The name of the generator class to use.
1910
+ *
1911
+ * @return void
1912
+ */
1913
+ public function generateDocs($standard, array $sniffs=array(), $generator='Text')
1914
+ {
1915
+ if (class_exists('PHP_CodeSniffer_DocGenerators_'.$generator, true) === false) {
1916
+ throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_DocGenerators_'.$generator.' not found');
1917
+ }
1918
+
1919
+ $class = "PHP_CodeSniffer_DocGenerators_$generator";
1920
+ $generator = new $class($standard, $sniffs);
1921
+
1922
+ $generator->generate();
1923
+
1924
+ }//end generateDocs()
1925
+
1926
+
1927
+ /**
1928
+ * Gets the array of PHP_CodeSniffer_Sniff's.
1929
+ *
1930
+ * @return PHP_CodeSniffer_Sniff[]
1931
+ */
1932
+ public function getSniffs()
1933
+ {
1934
+ return $this->listeners;
1935
+
1936
+ }//end getSniffs()
1937
+
1938
+
1939
+ /**
1940
+ * Gets the array of PHP_CodeSniffer_Sniff's indexed by token type.
1941
+ *
1942
+ * @return array
1943
+ */
1944
+ public function getTokenSniffs()
1945
+ {
1946
+ return $this->_tokenListeners;
1947
+
1948
+ }//end getTokenSniffs()
1949
+
1950
+
1951
+ /**
1952
+ * Returns true if the specified string is in the camel caps format.
1953
+ *
1954
+ * @param string $string The string the verify.
1955
+ * @param boolean $classFormat If true, check to see if the string is in the
1956
+ * class format. Class format strings must start
1957
+ * with a capital letter and contain no
1958
+ * underscores.
1959
+ * @param boolean $public If true, the first character in the string
1960
+ * must be an a-z character. If false, the
1961
+ * character must be an underscore. This
1962
+ * argument is only applicable if $classFormat
1963
+ * is false.
1964
+ * @param boolean $strict If true, the string must not have two capital
1965
+ * letters next to each other. If false, a
1966
+ * relaxed camel caps policy is used to allow
1967
+ * for acronyms.
1968
+ *
1969
+ * @return boolean
1970
+ */
1971
+ public static function isCamelCaps(
1972
+ $string,
1973
+ $classFormat=false,
1974
+ $public=true,
1975
+ $strict=true
1976
+ ) {
1977
+ // Check the first character first.
1978
+ if ($classFormat === false) {
1979
+ $legalFirstChar = '';
1980
+ if ($public === false) {
1981
+ $legalFirstChar = '[_]';
1982
+ }
1983
+
1984
+ if ($strict === false) {
1985
+ // Can either start with a lowercase letter, or multiple uppercase
1986
+ // in a row, representing an acronym.
1987
+ $legalFirstChar .= '([A-Z]{2,}|[a-z])';
1988
+ } else {
1989
+ $legalFirstChar .= '[a-z]';
1990
+ }
1991
+ } else {
1992
+ $legalFirstChar = '[A-Z]';
1993
+ }
1994
+
1995
+ if (preg_match("/^$legalFirstChar/", $string) === 0) {
1996
+ return false;
1997
+ }
1998
+
1999
+ // Check that the name only contains legal characters.
2000
+ $legalChars = 'a-zA-Z0-9';
2001
+ if (preg_match("|[^$legalChars]|", substr($string, 1)) > 0) {
2002
+ return false;
2003
+ }
2004
+
2005
+ if ($strict === true) {
2006
+ // Check that there are not two capital letters next to each other.
2007
+ $length = strlen($string);
2008
+ $lastCharWasCaps = $classFormat;
2009
+
2010
+ for ($i = 1; $i < $length; $i++) {
2011
+ $ascii = ord($string{$i});
2012
+ if ($ascii >= 48 && $ascii <= 57) {
2013
+ // The character is a number, so it cant be a capital.
2014
+ $isCaps = false;
2015
+ } else {
2016
+ if (strtoupper($string{$i}) === $string{$i}) {
2017
+ $isCaps = true;
2018
+ } else {
2019
+ $isCaps = false;
2020
+ }
2021
+ }
2022
+
2023
+ if ($isCaps === true && $lastCharWasCaps === true) {
2024
+ return false;
2025
+ }
2026
+
2027
+ $lastCharWasCaps = $isCaps;
2028
+ }
2029
+ }//end if
2030
+
2031
+ return true;
2032
+
2033
+ }//end isCamelCaps()
2034
+
2035
+
2036
+ /**
2037
+ * Returns true if the specified string is in the underscore caps format.
2038
+ *
2039
+ * @param string $string The string to verify.
2040
+ *
2041
+ * @return boolean
2042
+ */
2043
+ public static function isUnderscoreName($string)
2044
+ {
2045
+ // If there are space in the name, it can't be valid.
2046
+ if (strpos($string, ' ') !== false) {
2047
+ return false;
2048
+ }
2049
+
2050
+ $validName = true;
2051
+ $nameBits = explode('_', $string);
2052
+
2053
+ if (preg_match('|^[A-Z]|', $string) === 0) {
2054
+ // Name does not begin with a capital letter.
2055
+ $validName = false;
2056
+ } else {
2057
+ foreach ($nameBits as $bit) {
2058
+ if ($bit === '') {
2059
+ continue;
2060
+ }
2061
+
2062
+ if ($bit{0} !== strtoupper($bit{0})) {
2063
+ $validName = false;
2064
+ break;
2065
+ }
2066
+ }
2067
+ }
2068
+
2069
+ return $validName;
2070
+
2071
+ }//end isUnderscoreName()
2072
+
2073
+
2074
+ /**
2075
+ * Returns a valid variable type for param/var tag.
2076
+ *
2077
+ * If type is not one of the standard type, it must be a custom type.
2078
+ * Returns the correct type name suggestion if type name is invalid.
2079
+ *
2080
+ * @param string $varType The variable type to process.
2081
+ *
2082
+ * @return string
2083
+ */
2084
+ public static function suggestType($varType)
2085
+ {
2086
+ if ($varType === '') {
2087
+ return '';
2088
+ }
2089
+
2090
+ if (in_array($varType, self::$allowedTypes) === true) {
2091
+ return $varType;
2092
+ } else {
2093
+ $lowerVarType = strtolower($varType);
2094
+ switch ($lowerVarType) {
2095
+ case 'bool':
2096
+ return 'boolean';
2097
+ case 'double':
2098
+ case 'real':
2099
+ return 'float';
2100
+ case 'int':
2101
+ return 'integer';
2102
+ case 'array()':
2103
+ return 'array';
2104
+ }//end switch
2105
+
2106
+ if (strpos($lowerVarType, 'array(') !== false) {
2107
+ // Valid array declaration:
2108
+ // array, array(type), array(type1 => type2).
2109
+ $matches = array();
2110
+ $pattern = '/^array\(\s*([^\s^=^>]*)(\s*=>\s*(.*))?\s*\)/i';
2111
+ if (preg_match($pattern, $varType, $matches) !== 0) {
2112
+ $type1 = '';
2113
+ if (isset($matches[1]) === true) {
2114
+ $type1 = $matches[1];
2115
+ }
2116
+
2117
+ $type2 = '';
2118
+ if (isset($matches[3]) === true) {
2119
+ $type2 = $matches[3];
2120
+ }
2121
+
2122
+ $type1 = self::suggestType($type1);
2123
+ $type2 = self::suggestType($type2);
2124
+ if ($type2 !== '') {
2125
+ $type2 = ' => '.$type2;
2126
+ }
2127
+
2128
+ return "array($type1$type2)";
2129
+ } else {
2130
+ return 'array';
2131
+ }//end if
2132
+ } else if (in_array($lowerVarType, self::$allowedTypes) === true) {
2133
+ // A valid type, but not lower cased.
2134
+ return $lowerVarType;
2135
+ } else {
2136
+ // Must be a custom type name.
2137
+ return $varType;
2138
+ }//end if
2139
+ }//end if
2140
+
2141
+ }//end suggestType()
2142
+
2143
+
2144
+ /**
2145
+ * Prepares token content for output to screen.
2146
+ *
2147
+ * Replaces invisible characters so they are visible. On non-Windows
2148
+ * OSes it will also colour the invisible characters.
2149
+ *
2150
+ * @param string $content The content to prepare.
2151
+ *
2152
+ * @return string
2153
+ */
2154
+ public static function prepareForOutput($content)
2155
+ {
2156
+ if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
2157
+ $content = str_replace("\r", '\r', $content);
2158
+ $content = str_replace("\n", '\n', $content);
2159
+ $content = str_replace("\t", '\t', $content);
2160
+ } else {
2161
+ $content = str_replace("\r", "\033[30;1m\\r\033[0m", $content);
2162
+ $content = str_replace("\n", "\033[30;1m\\n\033[0m", $content);
2163
+ $content = str_replace("\t", "\033[30;1m\\t\033[0m", $content);
2164
+ $content = str_replace(' ', "\033[30;1m·\033[0m", $content);
2165
+ }
2166
+
2167
+ return $content;
2168
+
2169
+ }//end prepareForOutput()
2170
+
2171
+
2172
+ /**
2173
+ * Get a list paths where standards are installed.
2174
+ *
2175
+ * @return array
2176
+ */
2177
+ public static function getInstalledStandardPaths()
2178
+ {
2179
+ $installedPaths = array(dirname(__FILE__).DIRECTORY_SEPARATOR.'CodeSniffer'.DIRECTORY_SEPARATOR.'Standards');
2180
+ $configPaths = PHP_CodeSniffer::getConfigData('installed_paths');
2181
+ if ($configPaths !== null) {
2182
+ $installedPaths = array_merge($installedPaths, explode(',', $configPaths));
2183
+ }
2184
+
2185
+ $resolvedInstalledPaths = array();
2186
+ foreach ($installedPaths as $installedPath) {
2187
+ if (substr($installedPath, 0, 1) === '.') {
2188
+ $installedPath = dirname(__FILE__).DIRECTORY_SEPARATOR.$installedPath;
2189
+ }
2190
+
2191
+ $resolvedInstalledPaths[] = $installedPath;
2192
+ }
2193
+
2194
+ return $resolvedInstalledPaths;
2195
+
2196
+ }//end getInstalledStandardPaths()
2197
+
2198
+
2199
+ /**
2200
+ * Get a list of all coding standards installed.
2201
+ *
2202
+ * Coding standards are directories located in the
2203
+ * CodeSniffer/Standards directory. Valid coding standards
2204
+ * include a Sniffs subdirectory.
2205
+ *
2206
+ * @param boolean $includeGeneric If true, the special "Generic"
2207
+ * coding standard will be included
2208
+ * if installed.
2209
+ * @param string $standardsDir A specific directory to look for standards
2210
+ * in. If not specified, PHP_CodeSniffer will
2211
+ * look in its default locations.
2212
+ *
2213
+ * @return array
2214
+ * @see isInstalledStandard()
2215
+ */
2216
+ public static function getInstalledStandards(
2217
+ $includeGeneric=false,
2218
+ $standardsDir=''
2219
+ ) {
2220
+ $installedStandards = array();
2221
+
2222
+ if ($standardsDir === '') {
2223
+ $installedPaths = self::getInstalledStandardPaths();
2224
+ } else {
2225
+ $installedPaths = array($standardsDir);
2226
+ }
2227
+
2228
+ foreach ($installedPaths as $standardsDir) {
2229
+ $di = new DirectoryIterator($standardsDir);
2230
+ foreach ($di as $file) {
2231
+ if ($file->isDir() === true && $file->isDot() === false) {
2232
+ $filename = $file->getFilename();
2233
+
2234
+ // Ignore the special "Generic" standard.
2235
+ if ($includeGeneric === false && $filename === 'Generic') {
2236
+ continue;
2237
+ }
2238
+
2239
+ // Valid coding standard dirs include a ruleset.
2240
+ $csFile = $file->getPathname().'/ruleset.xml';
2241
+ if (is_file($csFile) === true) {
2242
+ $installedStandards[] = $filename;
2243
+ }
2244
+ }
2245
+ }
2246
+ }//end foreach
2247
+
2248
+ return $installedStandards;
2249
+
2250
+ }//end getInstalledStandards()
2251
+
2252
+
2253
+ /**
2254
+ * Determine if a standard is installed.
2255
+ *
2256
+ * Coding standards are directories located in the
2257
+ * CodeSniffer/Standards directory. Valid coding standards
2258
+ * include a ruleset.xml file.
2259
+ *
2260
+ * @param string $standard The name of the coding standard.
2261
+ *
2262
+ * @return boolean
2263
+ * @see getInstalledStandards()
2264
+ */
2265
+ public static function isInstalledStandard($standard)
2266
+ {
2267
+ $path = self::getInstalledStandardPath($standard);
2268
+ if ($path !== null && strpos($path, 'ruleset.xml') !== false) {
2269
+ return true;
2270
+ } else {
2271
+ // This could be a custom standard, installed outside our
2272
+ // standards directory.
2273
+ $standard = self::realPath($standard);
2274
+
2275
+ // Might be an actual ruleset file itself.
2276
+ // If it has an XML extension, let's at least try it.
2277
+ if (is_file($standard) === true
2278
+ && (substr(strtolower($standard), -4) === '.xml'
2279
+ || substr(strtolower($standard), -9) === '.xml.dist')
2280
+ ) {
2281
+ return true;
2282
+ }
2283
+
2284
+ // If it is a directory with a ruleset.xml file in it,
2285
+ // it is a standard.
2286
+ $ruleset = rtrim($standard, ' /\\').DIRECTORY_SEPARATOR.'ruleset.xml';
2287
+ if (is_file($ruleset) === true) {
2288
+ return true;
2289
+ }
2290
+ }//end if
2291
+
2292
+ return false;
2293
+
2294
+ }//end isInstalledStandard()
2295
+
2296
+
2297
+ /**
2298
+ * Return the path of an installed coding standard.
2299
+ *
2300
+ * Coding standards are directories located in the
2301
+ * CodeSniffer/Standards directory. Valid coding standards
2302
+ * include a ruleset.xml file.
2303
+ *
2304
+ * @param string $standard The name of the coding standard.
2305
+ *
2306
+ * @return string|null
2307
+ */
2308
+ public static function getInstalledStandardPath($standard)
2309
+ {
2310
+ $installedPaths = self::getInstalledStandardPaths();
2311
+ foreach ($installedPaths as $installedPath) {
2312
+ $standardPath = $installedPath.DIRECTORY_SEPARATOR.$standard;
2313
+ $path = self::realpath($standardPath.DIRECTORY_SEPARATOR.'ruleset.xml');
2314
+ if (is_file($path) === true) {
2315
+ return $path;
2316
+ } else if (self::isPharFile($standardPath) === true) {
2317
+ $path = self::realpath($standardPath);
2318
+ if ($path !== false) {
2319
+ return $path;
2320
+ }
2321
+ }
2322
+ }
2323
+
2324
+ return null;
2325
+
2326
+ }//end getInstalledStandardPath()
2327
+
2328
+
2329
+ /**
2330
+ * Get a single config value.
2331
+ *
2332
+ * Config data is stored in the data dir, in a file called
2333
+ * CodeSniffer.conf. It is a simple PHP array.
2334
+ *
2335
+ * @param string $key The name of the config value.
2336
+ *
2337
+ * @return string|null
2338
+ * @see setConfigData()
2339
+ * @see getAllConfigData()
2340
+ */
2341
+ public static function getConfigData($key)
2342
+ {
2343
+ $phpCodeSnifferConfig = self::getAllConfigData();
2344
+
2345
+ if ($phpCodeSnifferConfig === null) {
2346
+ return null;
2347
+ }
2348
+
2349
+ if (isset($phpCodeSnifferConfig[$key]) === false) {
2350
+ return null;
2351
+ }
2352
+
2353
+ return $phpCodeSnifferConfig[$key];
2354
+
2355
+ }//end getConfigData()
2356
+
2357
+
2358
+ /**
2359
+ * Set a single config value.
2360
+ *
2361
+ * Config data is stored in the data dir, in a file called
2362
+ * CodeSniffer.conf. It is a simple PHP array.
2363
+ *
2364
+ * @param string $key The name of the config value.
2365
+ * @param string|null $value The value to set. If null, the config
2366
+ * entry is deleted, reverting it to the
2367
+ * default value.
2368
+ * @param boolean $temp Set this config data temporarily for this
2369
+ * script run. This will not write the config
2370
+ * data to the config file.
2371
+ *
2372
+ * @return boolean
2373
+ * @see getConfigData()
2374
+ * @throws PHP_CodeSniffer_Exception If the config file can not be written.
2375
+ */
2376
+ public static function setConfigData($key, $value, $temp=false)
2377
+ {
2378
+ if ($temp === false) {
2379
+ $path = '';
2380
+ if (is_callable('Phar::running') === true) {
2381
+ $path = Phar::running(false);
2382
+ }
2383
+
2384
+ if ($path !== '') {
2385
+ $configFile = dirname($path).'/CodeSniffer.conf';
2386
+ } else {
2387
+ $configFile = dirname(__FILE__).'/CodeSniffer.conf';
2388
+ if (is_file($configFile) === false
2389
+ && strpos('@data_dir@', '@data_dir') === false
2390
+ ) {
2391
+ // If data_dir was replaced, this is a PEAR install and we can
2392
+ // use the PEAR data dir to store the conf file.
2393
+ $configFile = '@data_dir@/PHP_CodeSniffer/CodeSniffer.conf';
2394
+ }
2395
+ }
2396
+
2397
+ if (is_file($configFile) === true
2398
+ && is_writable($configFile) === false
2399
+ ) {
2400
+ $error = 'Config file '.$configFile.' is not writable';
2401
+ throw new PHP_CodeSniffer_Exception($error);
2402
+ }
2403
+ }//end if
2404
+
2405
+ $phpCodeSnifferConfig = self::getAllConfigData();
2406
+
2407
+ if ($value === null) {
2408
+ if (isset($phpCodeSnifferConfig[$key]) === true) {
2409
+ unset($phpCodeSnifferConfig[$key]);
2410
+ }
2411
+ } else {
2412
+ $phpCodeSnifferConfig[$key] = $value;
2413
+ }
2414
+
2415
+ if ($temp === false) {
2416
+ $output = '<'.'?php'."\n".' $phpCodeSnifferConfig = ';
2417
+ $output .= var_export($phpCodeSnifferConfig, true);
2418
+ $output .= "\n?".'>';
2419
+
2420
+ if (file_put_contents($configFile, $output) === false) {
2421
+ return false;
2422
+ }
2423
+ }
2424
+
2425
+ $GLOBALS['PHP_CODESNIFFER_CONFIG_DATA'] = $phpCodeSnifferConfig;
2426
+
2427
+ return true;
2428
+
2429
+ }//end setConfigData()
2430
+
2431
+
2432
+ /**
2433
+ * Get all config data in an array.
2434
+ *
2435
+ * @return array<string, string>
2436
+ * @see getConfigData()
2437
+ */
2438
+ public static function getAllConfigData()
2439
+ {
2440
+ if (isset($GLOBALS['PHP_CODESNIFFER_CONFIG_DATA']) === true) {
2441
+ return $GLOBALS['PHP_CODESNIFFER_CONFIG_DATA'];
2442
+ }
2443
+
2444
+ $path = '';
2445
+ if (is_callable('Phar::running') === true) {
2446
+ $path = Phar::running(false);
2447
+ }
2448
+
2449
+ if ($path !== '') {
2450
+ $configFile = dirname($path).'/CodeSniffer.conf';
2451
+ } else {
2452
+ $configFile = dirname(__FILE__).'/CodeSniffer.conf';
2453
+ if (is_file($configFile) === false) {
2454
+ $configFile = '@data_dir@/PHP_CodeSniffer/CodeSniffer.conf';
2455
+ }
2456
+ }
2457
+
2458
+ if (is_file($configFile) === false) {
2459
+ $GLOBALS['PHP_CODESNIFFER_CONFIG_DATA'] = array();
2460
+ return array();
2461
+ }
2462
+
2463
+ include $configFile;
2464
+ $GLOBALS['PHP_CODESNIFFER_CONFIG_DATA'] = $phpCodeSnifferConfig;
2465
+ return $GLOBALS['PHP_CODESNIFFER_CONFIG_DATA'];
2466
+
2467
+ }//end getAllConfigData()
2468
+
2469
+
2470
+ /**
2471
+ * Return TRUE, if the path is a phar file.
2472
+ *
2473
+ * @param string $path The path to use.
2474
+ *
2475
+ * @return mixed
2476
+ */
2477
+ public static function isPharFile($path)
2478
+ {
2479
+ if (strpos($path, 'phar://') === 0) {
2480
+ return true;
2481
+ }
2482
+
2483
+ return false;
2484
+
2485
+ }//end isPharFile()
2486
+
2487
+
2488
+ /**
2489
+ * CodeSniffer alternative for realpath.
2490
+ *
2491
+ * Allows for phar support.
2492
+ *
2493
+ * @param string $path The path to use.
2494
+ *
2495
+ * @return mixed
2496
+ */
2497
+ public static function realpath($path)
2498
+ {
2499
+ // Support the path replacement of ~ with the user's home directory.
2500
+ if (substr($path, 0, 2) === '~/') {
2501
+ $homeDir = getenv('HOME');
2502
+ if ($homeDir !== false) {
2503
+ $path = $homeDir.substr($path, 1);
2504
+ }
2505
+ }
2506
+
2507
+ // No extra work needed if this is not a phar file.
2508
+ if (self::isPharFile($path) === false) {
2509
+ return realpath($path);
2510
+ }
2511
+
2512
+ // Before trying to break down the file path,
2513
+ // check if it exists first because it will mostly not
2514
+ // change after running the below code.
2515
+ if (file_exists($path) === true) {
2516
+ return $path;
2517
+ }
2518
+
2519
+ $phar = Phar::running(false);
2520
+ $extra = str_replace('phar://'.$phar, '', $path);
2521
+ $path = realpath($phar);
2522
+ if ($path === false) {
2523
+ return false;
2524
+ }
2525
+
2526
+ $path = 'phar://'.$path.$extra;
2527
+ if (file_exists($path) === true) {
2528
+ return $path;
2529
+ }
2530
+
2531
+ return false;
2532
+
2533
+ }//end realpath()
2534
+
2535
+
2536
+ /**
2537
+ * CodeSniffer alternative for chdir().
2538
+ *
2539
+ * Allows for phar support.
2540
+ *
2541
+ * @param string $path The path to use.
2542
+ *
2543
+ * @return void
2544
+ */
2545
+ public static function chdir($path)
2546
+ {
2547
+ if (self::isPharFile($path) === true) {
2548
+ $phar = Phar::running(false);
2549
+ chdir(dirname($phar));
2550
+ } else {
2551
+ chdir($path);
2552
+ }
2553
+
2554
+ }//end chdir()
2555
+
2556
+
2557
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/CLI.php ADDED
@@ -0,0 +1,1390 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * A class to process command line phpcs scripts.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Greg Sherwood <gsherwood@squiz.net>
10
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
11
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
12
+ * @link http://pear.php.net/package/PHP_CodeSniffer
13
+ */
14
+
15
+ error_reporting(E_ALL | E_STRICT);
16
+
17
+ // Make sure that we autoload all dependencies if running via Composer.
18
+ if (version_compare(PHP_VERSION, '5.3.2', '>=') === true) {
19
+ if (file_exists($a = dirname(__FILE__).'/../../../autoload.php') === true) {
20
+ include_once $a;
21
+ } else if (file_exists($a = dirname(__FILE__).'/../vendor/autoload.php') === true) {
22
+ include_once $a;
23
+ }
24
+ }
25
+
26
+ if (file_exists($a = dirname(__FILE__).'/../CodeSniffer.php') === true) {
27
+ // Running from a git clone.
28
+ include_once $a;
29
+ } else {
30
+ // PEAR installed.
31
+ include_once 'PHP/CodeSniffer.php';
32
+ }
33
+
34
+ /**
35
+ * A class to process command line phpcs scripts.
36
+ *
37
+ * @category PHP
38
+ * @package PHP_CodeSniffer
39
+ * @author Greg Sherwood <gsherwood@squiz.net>
40
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
41
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
42
+ * @version Release: @package_version@
43
+ * @link http://pear.php.net/package/PHP_CodeSniffer
44
+ */
45
+ class PHP_CodeSniffer_CLI
46
+ {
47
+
48
+ /**
49
+ * An array of all values specified on the command line.
50
+ *
51
+ * @var array
52
+ */
53
+ protected $values = array();
54
+
55
+ /**
56
+ * The minimum severity level errors must have to be displayed.
57
+ *
58
+ * @var bool
59
+ */
60
+ public $errorSeverity = 0;
61
+
62
+ /**
63
+ * The minimum severity level warnings must have to be displayed.
64
+ *
65
+ * @var bool
66
+ */
67
+ public $warningSeverity = 0;
68
+
69
+ /**
70
+ * Whether or not to kill the process when an unknown command line arg is found.
71
+ *
72
+ * If FALSE, arguments that are not command line options or file/directory paths
73
+ * will be ignored and execution will continue.
74
+ *
75
+ * @var bool
76
+ */
77
+ public $dieOnUnknownArg = true;
78
+
79
+ /**
80
+ * An array of the current command line arguments we are processing.
81
+ *
82
+ * @var array
83
+ */
84
+ private $_cliArgs = array();
85
+
86
+
87
+ /**
88
+ * Run the PHPCS script.
89
+ *
90
+ * @return array
91
+ */
92
+ public function runphpcs()
93
+ {
94
+ if (defined('PHP_CODESNIFFER_CBF') === false) {
95
+ define('PHP_CODESNIFFER_CBF', false);
96
+ }
97
+
98
+ if (is_file(dirname(__FILE__).'/../CodeSniffer/Reporting.php') === true) {
99
+ include_once dirname(__FILE__).'/../CodeSniffer/Reporting.php';
100
+ } else {
101
+ include_once 'PHP/CodeSniffer/Reporting.php';
102
+ }
103
+
104
+ PHP_CodeSniffer_Reporting::startTiming();
105
+ $this->checkRequirements();
106
+ $numErrors = $this->process();
107
+ if ($numErrors === 0) {
108
+ exit(0);
109
+ } else {
110
+ exit(1);
111
+ }
112
+
113
+ }//end runphpcs()
114
+
115
+
116
+ /**
117
+ * Run the PHPCBF script.
118
+ *
119
+ * @return array
120
+ */
121
+ public function runphpcbf()
122
+ {
123
+ if (defined('PHP_CODESNIFFER_CBF') === false) {
124
+ define('PHP_CODESNIFFER_CBF', true);
125
+ }
126
+
127
+ if (is_file(dirname(__FILE__).'/../CodeSniffer/Reporting.php') === true) {
128
+ include_once dirname(__FILE__).'/../CodeSniffer/Reporting.php';
129
+ } else {
130
+ include_once 'PHP/CodeSniffer/Reporting.php';
131
+ }
132
+
133
+ PHP_CodeSniffer_Reporting::startTiming();
134
+ $this->checkRequirements();
135
+
136
+ $this->dieOnUnknownArg = false;
137
+
138
+ // Override some of the command line settings that might break the fixes.
139
+ $cliValues = $this->getCommandLineValues();
140
+ $cliValues['verbosity'] = 0;
141
+ $cliValues['showProgress'] = false;
142
+ $cliValues['generator'] = '';
143
+ $cliValues['explain'] = false;
144
+ $cliValues['interactive'] = false;
145
+ $cliValues['showSources'] = false;
146
+ $cliValues['reportFile'] = null;
147
+ $cliValues['reports'] = array();
148
+
149
+ $suffix = '';
150
+ if (isset($cliValues['suffix']) === true) {
151
+ $suffix = $cliValues['suffix'];
152
+ }
153
+
154
+ $allowPatch = true;
155
+ if (isset($cliValues['no-patch']) === true || empty($cliValues['files']) === true) {
156
+ // They either asked for this,
157
+ // or they are using STDIN, which can't use diff.
158
+ $allowPatch = false;
159
+ }
160
+
161
+ if ($suffix === '' && $allowPatch === true) {
162
+ // Using the diff/patch tools.
163
+ $diffFile = getcwd().'/phpcbf-fixed.diff';
164
+ $cliValues['reports'] = array('diff' => $diffFile);
165
+ if (file_exists($diffFile) === true) {
166
+ unlink($diffFile);
167
+ }
168
+ } else {
169
+ // Replace the file without the patch command
170
+ // or writing to a file with a new suffix.
171
+ $cliValues['reports'] = array('cbf' => null);
172
+ $cliValues['phpcbf-suffix'] = $suffix;
173
+ }
174
+
175
+ $numErrors = $this->process($cliValues);
176
+
177
+ if ($suffix === '' && $allowPatch === true) {
178
+ if (file_exists($diffFile) === false) {
179
+ // Nothing to fix.
180
+ if ($numErrors === 0) {
181
+ // And no errors reported.
182
+ $exit = 0;
183
+ } else {
184
+ // Errors we can't fix.
185
+ $exit = 2;
186
+ }
187
+ } else {
188
+ if (filesize($diffFile) < 10) {
189
+ // Empty or bad diff file.
190
+ if ($numErrors === 0) {
191
+ // And no errors reported.
192
+ $exit = 0;
193
+ } else {
194
+ // Errors we can't fix.
195
+ $exit = 2;
196
+ }
197
+ } else {
198
+ $cmd = "patch -p0 -ui \"$diffFile\"";
199
+ $output = array();
200
+ $retVal = null;
201
+ exec($cmd, $output, $retVal);
202
+
203
+ if ($retVal === 0) {
204
+ // Everything went well.
205
+ $filesPatched = count($output);
206
+ echo "Patched $filesPatched file";
207
+ if ($filesPatched > 1) {
208
+ echo 's';
209
+ }
210
+
211
+ echo PHP_EOL;
212
+ $exit = 1;
213
+ } else {
214
+ print_r($output);
215
+ echo "Returned: $retVal".PHP_EOL;
216
+ $exit = 3;
217
+ }
218
+ }//end if
219
+
220
+ unlink($diffFile);
221
+ }//end if
222
+ } else {
223
+ // File are being patched manually, so we can't tell
224
+ // how many errors were fixed.
225
+ $exit = 1;
226
+ }//end if
227
+
228
+ if ($exit === 0) {
229
+ echo 'No fixable errors were found'.PHP_EOL;
230
+ } else if ($exit === 2) {
231
+ echo 'PHPCBF could not fix all the errors found'.PHP_EOL;
232
+ }
233
+
234
+ PHP_CodeSniffer_Reporting::printRunTime();
235
+ exit($exit);
236
+
237
+ }//end runphpcbf()
238
+
239
+
240
+ /**
241
+ * Exits if the minimum requirements of PHP_CodSniffer are not met.
242
+ *
243
+ * @return array
244
+ */
245
+ public function checkRequirements()
246
+ {
247
+ // Check the PHP version.
248
+ if (version_compare(PHP_VERSION, '5.1.2', '<') === true) {
249
+ echo 'ERROR: PHP_CodeSniffer requires PHP version 5.1.2 or greater.'.PHP_EOL;
250
+ exit(2);
251
+ }
252
+
253
+ if (extension_loaded('tokenizer') === false) {
254
+ echo 'ERROR: PHP_CodeSniffer requires the tokenizer extension to be enabled.'.PHP_EOL;
255
+ exit(2);
256
+ }
257
+
258
+ }//end checkRequirements()
259
+
260
+
261
+ /**
262
+ * Get a list of default values for all possible command line arguments.
263
+ *
264
+ * @return array
265
+ */
266
+ public function getDefaults()
267
+ {
268
+ if (defined('PHP_CODESNIFFER_IN_TESTS') === true) {
269
+ return array();
270
+ }
271
+
272
+ // The default values for config settings.
273
+ $defaults['files'] = array();
274
+ $defaults['standard'] = null;
275
+ $defaults['verbosity'] = 0;
276
+ $defaults['interactive'] = false;
277
+ $defaults['colors'] = false;
278
+ $defaults['explain'] = false;
279
+ $defaults['local'] = false;
280
+ $defaults['showSources'] = false;
281
+ $defaults['extensions'] = array();
282
+ $defaults['sniffs'] = array();
283
+ $defaults['exclude'] = array();
284
+ $defaults['ignored'] = array();
285
+ $defaults['reportFile'] = null;
286
+ $defaults['generator'] = '';
287
+ $defaults['reports'] = array();
288
+ $defaults['bootstrap'] = array();
289
+ $defaults['errorSeverity'] = null;
290
+ $defaults['warningSeverity'] = null;
291
+ $defaults['stdin'] = null;
292
+ $defaults['stdinPath'] = '';
293
+
294
+ $reportFormat = PHP_CodeSniffer::getConfigData('report_format');
295
+ if ($reportFormat !== null) {
296
+ $defaults['reports'][$reportFormat] = null;
297
+ }
298
+
299
+ $tabWidth = PHP_CodeSniffer::getConfigData('tab_width');
300
+ if ($tabWidth === null) {
301
+ $defaults['tabWidth'] = 0;
302
+ } else {
303
+ $defaults['tabWidth'] = (int) $tabWidth;
304
+ }
305
+
306
+ $encoding = PHP_CodeSniffer::getConfigData('encoding');
307
+ if ($encoding === null) {
308
+ $defaults['encoding'] = 'iso-8859-1';
309
+ } else {
310
+ $defaults['encoding'] = strtolower($encoding);
311
+ }
312
+
313
+ $severity = PHP_CodeSniffer::getConfigData('severity');
314
+ if ($severity !== null) {
315
+ $defaults['errorSeverity'] = (int) $severity;
316
+ $defaults['warningSeverity'] = (int) $severity;
317
+ }
318
+
319
+ $severity = PHP_CodeSniffer::getConfigData('error_severity');
320
+ if ($severity !== null) {
321
+ $defaults['errorSeverity'] = (int) $severity;
322
+ }
323
+
324
+ $severity = PHP_CodeSniffer::getConfigData('warning_severity');
325
+ if ($severity !== null) {
326
+ $defaults['warningSeverity'] = (int) $severity;
327
+ }
328
+
329
+ $showWarnings = PHP_CodeSniffer::getConfigData('show_warnings');
330
+ if ($showWarnings !== null) {
331
+ $showWarnings = (bool) $showWarnings;
332
+ if ($showWarnings === false) {
333
+ $defaults['warningSeverity'] = 0;
334
+ }
335
+ }
336
+
337
+ $reportWidth = PHP_CodeSniffer::getConfigData('report_width');
338
+ if ($reportWidth !== null) {
339
+ $defaults['reportWidth'] = $this->_validateReportWidth($reportWidth);
340
+ } else {
341
+ // Use function defaults.
342
+ $defaults['reportWidth'] = null;
343
+ }
344
+
345
+ $showProgress = PHP_CodeSniffer::getConfigData('show_progress');
346
+ if ($showProgress === null) {
347
+ $defaults['showProgress'] = false;
348
+ } else {
349
+ $defaults['showProgress'] = (bool) $showProgress;
350
+ }
351
+
352
+ $quiet = PHP_CodeSniffer::getConfigData('quiet');
353
+ if ($quiet === null) {
354
+ $defaults['quiet'] = false;
355
+ } else {
356
+ $defaults['quiet'] = (bool) $quiet;
357
+ }
358
+
359
+ $colors = PHP_CodeSniffer::getConfigData('colors');
360
+ if ($colors === null) {
361
+ $defaults['colors'] = false;
362
+ } else {
363
+ $defaults['colors'] = (bool) $colors;
364
+ }
365
+
366
+ if (PHP_CodeSniffer::isPharFile(dirname(dirname(__FILE__))) === true) {
367
+ // If this is a phar file, check for the standard in the config.
368
+ $standard = PHP_CodeSniffer::getConfigData('standard');
369
+ if ($standard !== null) {
370
+ $defaults['standard'] = $standard;
371
+ }
372
+ }
373
+
374
+ return $defaults;
375
+
376
+ }//end getDefaults()
377
+
378
+
379
+ /**
380
+ * Gets the processed command line values.
381
+ *
382
+ * If the values have not yet been set, the values will be sourced
383
+ * from the command line arguments.
384
+ *
385
+ * @return array
386
+ */
387
+ public function getCommandLineValues()
388
+ {
389
+ if (empty($this->values) === false) {
390
+ return $this->values;
391
+ }
392
+
393
+ $args = $_SERVER['argv'];
394
+ array_shift($args);
395
+
396
+ $this->setCommandLineValues($args);
397
+
398
+ // Check for content on STDIN.
399
+ $handle = fopen('php://stdin', 'r');
400
+ if (stream_set_blocking($handle, false) === true) {
401
+ $fileContents = '';
402
+ while (($line = fgets(STDIN)) !== false) {
403
+ $fileContents .= $line;
404
+ usleep(10);
405
+ }
406
+
407
+ stream_set_blocking($handle, true);
408
+ fclose($handle);
409
+ if (trim($fileContents) !== '') {
410
+ $this->values['stdin'] = $fileContents;
411
+ }
412
+ }
413
+
414
+ return $this->values;
415
+
416
+ }//end getCommandLineValues()
417
+
418
+
419
+ /**
420
+ * Set the command line values.
421
+ *
422
+ * @param array $args An array of command line arguments to process.
423
+ *
424
+ * @return void
425
+ */
426
+ public function setCommandLineValues($args)
427
+ {
428
+ if (defined('PHP_CODESNIFFER_IN_TESTS') === true) {
429
+ $this->values = array('stdin' => null);
430
+ } else if (empty($this->values) === true) {
431
+ $this->values = $this->getDefaults();
432
+ }
433
+
434
+ $this->_cliArgs = $args;
435
+ $numArgs = count($args);
436
+
437
+ for ($i = 0; $i < $numArgs; $i++) {
438
+ $arg = $this->_cliArgs[$i];
439
+ if ($arg === '') {
440
+ continue;
441
+ }
442
+
443
+ if ($arg{0} === '-') {
444
+ if ($arg === '-' || $arg === '--') {
445
+ // Empty argument, ignore it.
446
+ continue;
447
+ }
448
+
449
+ if ($arg{1} === '-') {
450
+ $this->processLongArgument(substr($arg, 2), $i);
451
+ } else {
452
+ $switches = str_split($arg);
453
+ foreach ($switches as $switch) {
454
+ if ($switch === '-') {
455
+ continue;
456
+ }
457
+
458
+ $this->processShortArgument($switch, $i);
459
+ }
460
+ }
461
+ } else {
462
+ $this->processUnknownArgument($arg, $i);
463
+ }//end if
464
+ }//end for
465
+
466
+ }//end setCommandLineValues()
467
+
468
+
469
+ /**
470
+ * Processes a short (-e) command line argument.
471
+ *
472
+ * @param string $arg The command line argument.
473
+ * @param int $pos The position of the argument on the command line.
474
+ *
475
+ * @return void
476
+ */
477
+ public function processShortArgument($arg, $pos)
478
+ {
479
+ switch ($arg) {
480
+ case 'h':
481
+ case '?':
482
+ $this->printUsage();
483
+ exit(0);
484
+ case 'i' :
485
+ $this->printInstalledStandards();
486
+ exit(0);
487
+ case 'v' :
488
+ if ($this->values['quiet'] === true) {
489
+ // Ignore when quiet mode is enabled.
490
+ break;
491
+ }
492
+
493
+ if (isset($this->values['verbosity']) === false) {
494
+ $this->values['verbosity'] = 1;
495
+ } else {
496
+ $this->values['verbosity']++;
497
+ }
498
+ break;
499
+ case 'l' :
500
+ $this->values['local'] = true;
501
+ break;
502
+ case 's' :
503
+ $this->values['showSources'] = true;
504
+ break;
505
+ case 'a' :
506
+ $this->values['interactive'] = true;
507
+ break;
508
+ case 'e':
509
+ $this->values['explain'] = true;
510
+ break;
511
+ case 'p' :
512
+ if ($this->values['quiet'] === true) {
513
+ // Ignore when quiet mode is enabled.
514
+ break;
515
+ }
516
+
517
+ $this->values['showProgress'] = true;
518
+ break;
519
+ case 'q' :
520
+ // Quiet mode disables a few other settings as well.
521
+ $this->values['quiet'] = true;
522
+ $this->values['showProgress'] = false;
523
+ $this->values['verbosity'] = 0;
524
+ break;
525
+ case 'd' :
526
+ $ini = explode('=', $this->_cliArgs[($pos + 1)]);
527
+ $this->_cliArgs[($pos + 1)] = '';
528
+ if (isset($ini[1]) === true) {
529
+ ini_set($ini[0], $ini[1]);
530
+ } else {
531
+ ini_set($ini[0], true);
532
+ }
533
+ break;
534
+ case 'n' :
535
+ $this->values['warningSeverity'] = 0;
536
+ break;
537
+ case 'w' :
538
+ $this->values['warningSeverity'] = null;
539
+ break;
540
+ default:
541
+ if ($this->dieOnUnknownArg === false) {
542
+ $this->values[$arg] = $arg;
543
+ } else {
544
+ $this->processUnknownArgument('-'.$arg, $pos);
545
+ }
546
+ }//end switch
547
+
548
+ }//end processShortArgument()
549
+
550
+
551
+ /**
552
+ * Processes a long (--example) command line argument.
553
+ *
554
+ * @param string $arg The command line argument.
555
+ * @param int $pos The position of the argument on the command line.
556
+ *
557
+ * @return void
558
+ */
559
+ public function processLongArgument($arg, $pos)
560
+ {
561
+ switch ($arg) {
562
+ case 'help':
563
+ $this->printUsage();
564
+ exit(0);
565
+ case 'version':
566
+ echo 'PHP_CodeSniffer version '.PHP_CodeSniffer::VERSION.' ('.PHP_CodeSniffer::STABILITY.') ';
567
+ echo 'by Squiz (http://www.squiz.net)'.PHP_EOL;
568
+ exit(0);
569
+ case 'colors':
570
+ $this->values['colors'] = true;
571
+ break;
572
+ case 'no-colors':
573
+ $this->values['colors'] = false;
574
+ break;
575
+ case 'config-set':
576
+ if (isset($this->_cliArgs[($pos + 1)]) === false
577
+ || isset($this->_cliArgs[($pos + 2)]) === false
578
+ ) {
579
+ echo 'ERROR: Setting a config option requires a name and value'.PHP_EOL.PHP_EOL;
580
+ $this->printUsage();
581
+ exit(0);
582
+ }
583
+
584
+ $key = $this->_cliArgs[($pos + 1)];
585
+ $value = $this->_cliArgs[($pos + 2)];
586
+ $current = PHP_CodeSniffer::getConfigData($key);
587
+
588
+ try {
589
+ PHP_CodeSniffer::setConfigData($key, $value);
590
+ } catch (Exception $e) {
591
+ echo $e->getMessage().PHP_EOL;
592
+ exit(2);
593
+ }
594
+
595
+ if ($current === null) {
596
+ echo "Config value \"$key\" added successfully".PHP_EOL;
597
+ } else {
598
+ echo "Config value \"$key\" updated successfully; old value was \"$current\"".PHP_EOL;
599
+ }
600
+ exit(0);
601
+ case 'config-delete':
602
+ if (isset($this->_cliArgs[($pos + 1)]) === false) {
603
+ echo 'ERROR: Deleting a config option requires the name of the option'.PHP_EOL.PHP_EOL;
604
+ $this->printUsage();
605
+ exit(0);
606
+ }
607
+
608
+ $key = $this->_cliArgs[($pos + 1)];
609
+ $current = PHP_CodeSniffer::getConfigData($key);
610
+ if ($current === null) {
611
+ echo "Config value \"$key\" has not been set".PHP_EOL;
612
+ } else {
613
+ try {
614
+ PHP_CodeSniffer::setConfigData($key, null);
615
+ } catch (Exception $e) {
616
+ echo $e->getMessage().PHP_EOL;
617
+ exit(2);
618
+ }
619
+
620
+ echo "Config value \"$key\" removed successfully; old value was \"$current\"".PHP_EOL;
621
+ }
622
+ exit(0);
623
+ case 'config-show':
624
+ $data = PHP_CodeSniffer::getAllConfigData();
625
+ $this->printConfigData($data);
626
+ exit(0);
627
+ case 'runtime-set':
628
+ if (isset($this->_cliArgs[($pos + 1)]) === false
629
+ || isset($this->_cliArgs[($pos + 2)]) === false
630
+ ) {
631
+ echo 'ERROR: Setting a runtime config option requires a name and value'.PHP_EOL.PHP_EOL;
632
+ $this->printUsage();
633
+ exit(0);
634
+ }
635
+
636
+ $key = $this->_cliArgs[($pos + 1)];
637
+ $value = $this->_cliArgs[($pos + 2)];
638
+ $this->_cliArgs[($pos + 1)] = '';
639
+ $this->_cliArgs[($pos + 2)] = '';
640
+ PHP_CodeSniffer::setConfigData($key, $value, true);
641
+ break;
642
+ default:
643
+ if (substr($arg, 0, 7) === 'sniffs=') {
644
+ $sniffs = explode(',', substr($arg, 7));
645
+ foreach ($sniffs as $sniff) {
646
+ if (substr_count($sniff, '.') !== 2) {
647
+ echo 'ERROR: The specified sniff code "'.$sniff.'" is invalid'.PHP_EOL.PHP_EOL;
648
+ $this->printUsage();
649
+ exit(2);
650
+ }
651
+ }
652
+
653
+ $this->values['sniffs'] = $sniffs;
654
+ } else if (substr($arg, 0, 8) === 'exclude=') {
655
+ $sniffs = explode(',', substr($arg, 8));
656
+ foreach ($sniffs as $sniff) {
657
+ if (substr_count($sniff, '.') !== 2) {
658
+ echo 'ERROR: The specified sniff code "'.$sniff.'" is invalid'.PHP_EOL.PHP_EOL;
659
+ $this->printUsage();
660
+ exit(2);
661
+ }
662
+ }
663
+
664
+ $this->values['exclude'] = $sniffs;
665
+ } else if (substr($arg, 0, 10) === 'bootstrap=') {
666
+ $files = explode(',', substr($arg, 10));
667
+ foreach ($files as $file) {
668
+ $path = PHP_CodeSniffer::realpath($file);
669
+ if ($path === false) {
670
+ echo 'ERROR: The specified bootstrap file "'.$file.'" does not exist'.PHP_EOL.PHP_EOL;
671
+ $this->printUsage();
672
+ exit(2);
673
+ }
674
+
675
+ $this->values['bootstrap'][] = $path;
676
+ }
677
+ } else if (substr($arg, 0, 11) === 'stdin-path=') {
678
+ $this->values['stdinPath'] = PHP_CodeSniffer::realpath(substr($arg, 11));
679
+
680
+ // It may not exist and return false instead, so just use whatever they gave us.
681
+ if ($this->values['stdinPath'] === false) {
682
+ $this->values['stdinPath'] = trim(substr($arg, 11));
683
+ }
684
+ } else if (substr($arg, 0, 12) === 'report-file=') {
685
+ $this->values['reportFile'] = PHP_CodeSniffer::realpath(substr($arg, 12));
686
+
687
+ // It may not exist and return false instead.
688
+ if ($this->values['reportFile'] === false) {
689
+ $this->values['reportFile'] = substr($arg, 12);
690
+
691
+ $dir = dirname($this->values['reportFile']);
692
+ if (is_dir($dir) === false) {
693
+ echo 'ERROR: The specified report file path "'.$this->values['reportFile'].'" points to a non-existent directory'.PHP_EOL.PHP_EOL;
694
+ $this->printUsage();
695
+ exit(2);
696
+ }
697
+
698
+ if ($dir === '.') {
699
+ // Passed report file is a file in the current directory.
700
+ $this->values['reportFile'] = getcwd().'/'.basename($this->values['reportFile']);
701
+ } else {
702
+ $dir = PHP_CodeSniffer::realpath(getcwd().'/'.$dir);
703
+ if ($dir !== false) {
704
+ // Report file path is relative.
705
+ $this->values['reportFile'] = $dir.'/'.basename($this->values['reportFile']);
706
+ }
707
+ }
708
+ }//end if
709
+
710
+ if (is_dir($this->values['reportFile']) === true) {
711
+ echo 'ERROR: The specified report file path "'.$this->values['reportFile'].'" is a directory'.PHP_EOL.PHP_EOL;
712
+ $this->printUsage();
713
+ exit(2);
714
+ }
715
+ } else if (substr($arg, 0, 13) === 'report-width=') {
716
+ $this->values['reportWidth'] = $this->_validateReportWidth(substr($arg, 13));
717
+ } else if (substr($arg, 0, 7) === 'report='
718
+ || substr($arg, 0, 7) === 'report-'
719
+ ) {
720
+ if ($arg[6] === '-') {
721
+ // This is a report with file output.
722
+ $split = strpos($arg, '=');
723
+ if ($split === false) {
724
+ $report = substr($arg, 7);
725
+ $output = null;
726
+ } else {
727
+ $report = substr($arg, 7, ($split - 7));
728
+ $output = substr($arg, ($split + 1));
729
+ if ($output === false) {
730
+ $output = null;
731
+ } else {
732
+ $dir = dirname($output);
733
+ if ($dir === '.') {
734
+ // Passed report file is a filename in the current directory.
735
+ $output = getcwd().'/'.basename($output);
736
+ } else {
737
+ $dir = PHP_CodeSniffer::realpath(getcwd().'/'.$dir);
738
+ if ($dir !== false) {
739
+ // Report file path is relative.
740
+ $output = $dir.'/'.basename($output);
741
+ }
742
+ }
743
+ }//end if
744
+ }//end if
745
+ } else {
746
+ // This is a single report.
747
+ $report = substr($arg, 7);
748
+ $output = null;
749
+ }//end if
750
+
751
+ $this->values['reports'][$report] = $output;
752
+ } else if (substr($arg, 0, 9) === 'standard=') {
753
+ $standards = trim(substr($arg, 9));
754
+ if ($standards !== '') {
755
+ $this->values['standard'] = explode(',', $standards);
756
+ }
757
+ } else if (substr($arg, 0, 11) === 'extensions=') {
758
+ if (isset($this->values['extensions']) === false) {
759
+ $this->values['extensions'] = array();
760
+ }
761
+
762
+ $this->values['extensions'] = array_merge($this->values['extensions'], explode(',', substr($arg, 11)));
763
+ } else if (substr($arg, 0, 9) === 'severity=') {
764
+ $this->values['errorSeverity'] = (int) substr($arg, 9);
765
+ $this->values['warningSeverity'] = $this->values['errorSeverity'];
766
+ } else if (substr($arg, 0, 15) === 'error-severity=') {
767
+ $this->values['errorSeverity'] = (int) substr($arg, 15);
768
+ } else if (substr($arg, 0, 17) === 'warning-severity=') {
769
+ $this->values['warningSeverity'] = (int) substr($arg, 17);
770
+ } else if (substr($arg, 0, 7) === 'ignore=') {
771
+ // Split the ignore string on commas, unless the comma is escaped
772
+ // using 1 or 3 slashes (\, or \\\,).
773
+ $ignored = preg_split(
774
+ '/(?<=(?<!\\\\)\\\\\\\\),|(?<!\\\\),/',
775
+ substr($arg, 7)
776
+ );
777
+ foreach ($ignored as $pattern) {
778
+ $pattern = trim($pattern);
779
+ if ($pattern === '') {
780
+ continue;
781
+ }
782
+
783
+ $this->values['ignored'][$pattern] = 'absolute';
784
+ }
785
+ } else if (substr($arg, 0, 10) === 'generator=') {
786
+ $this->values['generator'] = substr($arg, 10);
787
+ } else if (substr($arg, 0, 9) === 'encoding=') {
788
+ $this->values['encoding'] = strtolower(substr($arg, 9));
789
+ } else if (substr($arg, 0, 10) === 'tab-width=') {
790
+ $this->values['tabWidth'] = (int) substr($arg, 10);
791
+ } else {
792
+ if ($this->dieOnUnknownArg === false) {
793
+ $eqPos = strpos($arg, '=');
794
+ if ($eqPos === false) {
795
+ $this->values[$arg] = $arg;
796
+ } else {
797
+ $value = substr($arg, ($eqPos + 1));
798
+ $arg = substr($arg, 0, $eqPos);
799
+ $this->values[$arg] = $value;
800
+ }
801
+ } else {
802
+ $this->processUnknownArgument('--'.$arg, $pos);
803
+ }
804
+ }//end if
805
+
806
+ break;
807
+ }//end switch
808
+
809
+ }//end processLongArgument()
810
+
811
+
812
+ /**
813
+ * Processes an unknown command line argument.
814
+ *
815
+ * Assumes all unknown arguments are files and folders to check.
816
+ *
817
+ * @param string $arg The command line argument.
818
+ * @param int $pos The position of the argument on the command line.
819
+ *
820
+ * @return void
821
+ */
822
+ public function processUnknownArgument($arg, $pos)
823
+ {
824
+ // We don't know about any additional switches; just files.
825
+ if ($arg{0} === '-') {
826
+ if ($this->dieOnUnknownArg === false) {
827
+ return;
828
+ }
829
+
830
+ echo 'ERROR: option "'.$arg.'" not known.'.PHP_EOL.PHP_EOL;
831
+ $this->printUsage();
832
+ exit(2);
833
+ }
834
+
835
+ $file = PHP_CodeSniffer::realpath($arg);
836
+ if (file_exists($file) === false) {
837
+ if ($this->dieOnUnknownArg === false) {
838
+ return;
839
+ }
840
+
841
+ echo 'ERROR: The file "'.$arg.'" does not exist.'.PHP_EOL.PHP_EOL;
842
+ $this->printUsage();
843
+ exit(2);
844
+ } else {
845
+ $this->values['files'][] = $file;
846
+ }
847
+
848
+ }//end processUnknownArgument()
849
+
850
+
851
+ /**
852
+ * Runs PHP_CodeSniffer over files and directories.
853
+ *
854
+ * @param array $values An array of values determined from CLI args.
855
+ *
856
+ * @return int The number of error and warning messages shown.
857
+ * @see getCommandLineValues()
858
+ */
859
+ public function process($values=array())
860
+ {
861
+ if (empty($values) === true) {
862
+ $values = $this->getCommandLineValues();
863
+ } else {
864
+ $values = array_merge($this->getDefaults(), $values);
865
+ $this->values = $values;
866
+ }
867
+
868
+ if ($values['generator'] !== '') {
869
+ $phpcs = new PHP_CodeSniffer($values['verbosity']);
870
+ if ($values['standard'] === null) {
871
+ $values['standard'] = $this->validateStandard(null);
872
+ }
873
+
874
+ foreach ($values['standard'] as $standard) {
875
+ $phpcs->generateDocs(
876
+ $standard,
877
+ $values['sniffs'],
878
+ $values['generator']
879
+ );
880
+ }
881
+
882
+ exit(0);
883
+ }
884
+
885
+ // If no standard is supplied, get the default.
886
+ $values['standard'] = $this->validateStandard($values['standard']);
887
+ foreach ($values['standard'] as $standard) {
888
+ if (PHP_CodeSniffer::isInstalledStandard($standard) === false) {
889
+ // They didn't select a valid coding standard, so help them
890
+ // out by letting them know which standards are installed.
891
+ echo 'ERROR: the "'.$standard.'" coding standard is not installed. ';
892
+ $this->printInstalledStandards();
893
+ exit(2);
894
+ }
895
+ }
896
+
897
+ if ($values['explain'] === true) {
898
+ foreach ($values['standard'] as $standard) {
899
+ $this->explainStandard($standard);
900
+ }
901
+
902
+ exit(0);
903
+ }
904
+
905
+ $phpcs = new PHP_CodeSniffer($values['verbosity'], null, null, null);
906
+ $phpcs->setCli($this);
907
+ $phpcs->initStandard($values['standard'], $values['sniffs'], $values['exclude']);
908
+ $values = $this->values;
909
+
910
+ $phpcs->setTabWidth($values['tabWidth']);
911
+ $phpcs->setEncoding($values['encoding']);
912
+ $phpcs->setInteractive($values['interactive']);
913
+
914
+ // Set file extensions if they were specified. Otherwise,
915
+ // let PHP_CodeSniffer decide on the defaults.
916
+ if (empty($values['extensions']) === false) {
917
+ $phpcs->setAllowedFileExtensions($values['extensions']);
918
+ }
919
+
920
+ // Set ignore patterns if they were specified.
921
+ if (empty($values['ignored']) === false) {
922
+ $ignorePatterns = array_merge($phpcs->getIgnorePatterns(), $values['ignored']);
923
+ $phpcs->setIgnorePatterns($ignorePatterns);
924
+ }
925
+
926
+ // Set some convenience member vars.
927
+ if ($values['errorSeverity'] === null) {
928
+ $this->errorSeverity = PHPCS_DEFAULT_ERROR_SEV;
929
+ } else {
930
+ $this->errorSeverity = $values['errorSeverity'];
931
+ }
932
+
933
+ if ($values['warningSeverity'] === null) {
934
+ $this->warningSeverity = PHPCS_DEFAULT_WARN_SEV;
935
+ } else {
936
+ $this->warningSeverity = $values['warningSeverity'];
937
+ }
938
+
939
+ if (empty($values['reports']) === true) {
940
+ $values['reports']['full'] = $values['reportFile'];
941
+ $this->values['reports'] = $values['reports'];
942
+ }
943
+
944
+ // Include bootstrap files.
945
+ foreach ($values['bootstrap'] as $bootstrap) {
946
+ include $bootstrap;
947
+ }
948
+
949
+ $phpcs->processFiles($values['files'], $values['local']);
950
+
951
+ if (empty($values['files']) === true || $values['stdin'] !== null) {
952
+ $fileContents = $values['stdin'];
953
+ if ($fileContents === null) {
954
+ // Check if they are passing in the file contents.
955
+ $handle = fopen('php://stdin', 'r');
956
+ stream_set_blocking($handle, true);
957
+ $fileContents = stream_get_contents($handle);
958
+ fclose($handle);
959
+ }
960
+
961
+ if ($fileContents === '') {
962
+ // No files and no content passed in.
963
+ echo 'ERROR: You must supply at least one file or directory to process.'.PHP_EOL.PHP_EOL;
964
+ $this->printUsage();
965
+ exit(2);
966
+ } else {
967
+ $phpcs->processFile('STDIN', $fileContents);
968
+ }
969
+ }
970
+
971
+ // Interactive runs don't require a final report and it doesn't really
972
+ // matter what the retun value is because we know it isn't being read
973
+ // by a script.
974
+ if ($values['interactive'] === true) {
975
+ return 0;
976
+ }
977
+
978
+ return $this->printErrorReport(
979
+ $phpcs,
980
+ $values['reports'],
981
+ $values['showSources'],
982
+ $values['reportFile'],
983
+ $values['reportWidth']
984
+ );
985
+
986
+ }//end process()
987
+
988
+
989
+ /**
990
+ * Prints the error report for the run.
991
+ *
992
+ * Note that this function may actually print multiple reports
993
+ * as the user may have specified a number of output formats.
994
+ *
995
+ * @param PHP_CodeSniffer $phpcs The PHP_CodeSniffer object containing
996
+ * the errors.
997
+ * @param array $reports A list of reports to print.
998
+ * @param bool $showSources TRUE if report should show error sources
999
+ * (not used by all reports).
1000
+ * @param string $reportFile A default file to log report output to.
1001
+ * @param int $reportWidth How wide the screen reports should be.
1002
+ *
1003
+ * @return int The number of error and warning messages shown.
1004
+ */
1005
+ public function printErrorReport(
1006
+ PHP_CodeSniffer $phpcs,
1007
+ $reports,
1008
+ $showSources,
1009
+ $reportFile,
1010
+ $reportWidth
1011
+ ) {
1012
+ if (empty($reports) === true) {
1013
+ $reports['full'] = $reportFile;
1014
+ }
1015
+
1016
+ $errors = 0;
1017
+ $warnings = 0;
1018
+ $toScreen = false;
1019
+
1020
+ foreach ($reports as $report => $output) {
1021
+ if ($output === null) {
1022
+ $output = $reportFile;
1023
+ }
1024
+
1025
+ if ($reportFile === null) {
1026
+ $toScreen = true;
1027
+ }
1028
+
1029
+ // We don't add errors here because the number of
1030
+ // errors reported by each report type will always be the
1031
+ // same, so we really just need 1 number.
1032
+ $result = $phpcs->reporting->printReport(
1033
+ $report,
1034
+ $showSources,
1035
+ $this->values,
1036
+ $output,
1037
+ $reportWidth
1038
+ );
1039
+
1040
+ $errors = $result['errors'];
1041
+ $warnings = $result['warnings'];
1042
+ }//end foreach
1043
+
1044
+ // Only print timer output if no reports were
1045
+ // printed to the screen so we don't put additional output
1046
+ // in something like an XML report. If we are printing to screen,
1047
+ // the report types would have already worked out who should
1048
+ // print the timer info.
1049
+ if (PHP_CODESNIFFER_INTERACTIVE === false
1050
+ && ($toScreen === false
1051
+ || (($errors + $warnings) === 0 && $this->values['showProgress'] === true))
1052
+ ) {
1053
+ PHP_CodeSniffer_Reporting::printRunTime();
1054
+ }
1055
+
1056
+ // They should all return the same value, so it
1057
+ // doesn't matter which return value we end up using.
1058
+ $ignoreWarnings = PHP_CodeSniffer::getConfigData('ignore_warnings_on_exit');
1059
+ $ignoreErrors = PHP_CodeSniffer::getConfigData('ignore_errors_on_exit');
1060
+
1061
+ $return = ($errors + $warnings);
1062
+ if ($ignoreErrors !== null) {
1063
+ $ignoreErrors = (bool) $ignoreErrors;
1064
+ if ($ignoreErrors === true) {
1065
+ $return -= $errors;
1066
+ }
1067
+ }
1068
+
1069
+ if ($ignoreWarnings !== null) {
1070
+ $ignoreWarnings = (bool) $ignoreWarnings;
1071
+ if ($ignoreWarnings === true) {
1072
+ $return -= $warnings;
1073
+ }
1074
+ }
1075
+
1076
+ return $return;
1077
+
1078
+ }//end printErrorReport()
1079
+
1080
+
1081
+ /**
1082
+ * Convert the passed standards into valid standards.
1083
+ *
1084
+ * Checks things like default values and case.
1085
+ *
1086
+ * @param array $standards The standards to validate.
1087
+ *
1088
+ * @return array
1089
+ */
1090
+ public function validateStandard($standards)
1091
+ {
1092
+ if ($standards === null) {
1093
+ // They did not supply a standard to use.
1094
+ // Look for a default ruleset in the current directory or higher.
1095
+ $currentDir = getcwd();
1096
+
1097
+ do {
1098
+ $default = $currentDir.DIRECTORY_SEPARATOR.'phpcs.xml';
1099
+ if (is_file($default) === true) {
1100
+ return array($default);
1101
+ }
1102
+
1103
+ $default = $currentDir.DIRECTORY_SEPARATOR.'phpcs.xml.dist';
1104
+ if (is_file($default) === true) {
1105
+ return array($default);
1106
+ }
1107
+
1108
+ $lastDir = $currentDir;
1109
+ $currentDir = dirname($currentDir);
1110
+ } while ($currentDir !== '.' && $currentDir !== $lastDir);
1111
+
1112
+ // Try to get the default from the config system.
1113
+ $standard = PHP_CodeSniffer::getConfigData('default_standard');
1114
+ if ($standard === null) {
1115
+ // Product default standard.
1116
+ $standard = 'PEAR';
1117
+ }
1118
+
1119
+ return explode(',', $standard);
1120
+ }//end if
1121
+
1122
+ $cleaned = array();
1123
+ $standards = (array) $standards;
1124
+
1125
+ // Check if the standard name is valid, or if the case is invalid.
1126
+ $installedStandards = PHP_CodeSniffer::getInstalledStandards();
1127
+ foreach ($standards as $standard) {
1128
+ foreach ($installedStandards as $validStandard) {
1129
+ if (strtolower($standard) === strtolower($validStandard)) {
1130
+ $standard = $validStandard;
1131
+ break;
1132
+ }
1133
+ }
1134
+
1135
+ $cleaned[] = $standard;
1136
+ }
1137
+
1138
+ return $cleaned;
1139
+
1140
+ }//end validateStandard()
1141
+
1142
+
1143
+ /**
1144
+ * Prints a report showing the sniffs contained in a standard.
1145
+ *
1146
+ * @param string $standard The standard to validate.
1147
+ *
1148
+ * @return void
1149
+ */
1150
+ public function explainStandard($standard)
1151
+ {
1152
+ $phpcs = new PHP_CodeSniffer();
1153
+ $phpcs->process(array(), $standard);
1154
+ $sniffs = $phpcs->getSniffs();
1155
+ $sniffs = array_keys($sniffs);
1156
+ sort($sniffs);
1157
+
1158
+ ob_start();
1159
+
1160
+ $lastStandard = '';
1161
+ $lastCount = '';
1162
+ $sniffCount = count($sniffs);
1163
+ $sniffs[] = '___';
1164
+
1165
+ echo PHP_EOL."The $standard standard contains $sniffCount sniffs".PHP_EOL;
1166
+
1167
+ ob_start();
1168
+
1169
+ foreach ($sniffs as $sniff) {
1170
+ $parts = explode('_', str_replace('\\', '_', $sniff));
1171
+ if ($lastStandard === '') {
1172
+ $lastStandard = $parts[0];
1173
+ }
1174
+
1175
+ if ($parts[0] !== $lastStandard) {
1176
+ $sniffList = ob_get_contents();
1177
+ ob_end_clean();
1178
+
1179
+ echo PHP_EOL.$lastStandard.' ('.$lastCount.' sniffs)'.PHP_EOL;
1180
+ echo str_repeat('-', (strlen($lastStandard.$lastCount) + 10));
1181
+ echo PHP_EOL;
1182
+ echo $sniffList;
1183
+
1184
+ $lastStandard = $parts[0];
1185
+ $lastCount = 0;
1186
+
1187
+ ob_start();
1188
+ }
1189
+
1190
+ echo ' '.$parts[0].'.'.$parts[2].'.'.substr($parts[3], 0, -5).PHP_EOL;
1191
+ $lastCount++;
1192
+ }//end foreach
1193
+
1194
+ ob_end_clean();
1195
+
1196
+ }//end explainStandard()
1197
+
1198
+
1199
+ /**
1200
+ * Prints out the gathered config data.
1201
+ *
1202
+ * @param array $data The config data to print.
1203
+ *
1204
+ * @return void
1205
+ */
1206
+ public function printConfigData($data)
1207
+ {
1208
+ $max = 0;
1209
+ $keys = array_keys($data);
1210
+ foreach ($keys as $key) {
1211
+ $len = strlen($key);
1212
+ if (strlen($key) > $max) {
1213
+ $max = $len;
1214
+ }
1215
+ }
1216
+
1217
+ if ($max === 0) {
1218
+ return;
1219
+ }
1220
+
1221
+ $max += 2;
1222
+ ksort($data);
1223
+ foreach ($data as $name => $value) {
1224
+ echo str_pad($name.': ', $max).$value.PHP_EOL;
1225
+ }
1226
+
1227
+ }//end printConfigData()
1228
+
1229
+
1230
+ /**
1231
+ * Prints out the usage information for this script.
1232
+ *
1233
+ * @return void
1234
+ */
1235
+ public function printUsage()
1236
+ {
1237
+ if (PHP_CODESNIFFER_CBF === true) {
1238
+ $this->printPHPCBFUsage();
1239
+ } else {
1240
+ $this->printPHPCSUsage();
1241
+ }
1242
+
1243
+ }//end printUsage()
1244
+
1245
+
1246
+ /**
1247
+ * Prints out the usage information for PHPCS.
1248
+ *
1249
+ * @return void
1250
+ */
1251
+ public function printPHPCSUsage()
1252
+ {
1253
+ echo 'Usage: phpcs [-nwlsaepqvi] [-d key[=value]] [--colors] [--no-colors] [--stdin-path=<stdinPath>]'.PHP_EOL;
1254
+ echo ' [--report=<report>] [--report-file=<reportFile>] [--report-<report>=<reportFile>] ...'.PHP_EOL;
1255
+ echo ' [--report-width=<reportWidth>] [--generator=<generator>] [--tab-width=<tabWidth>]'.PHP_EOL;
1256
+ echo ' [--severity=<severity>] [--error-severity=<severity>] [--warning-severity=<severity>]'.PHP_EOL;
1257
+ echo ' [--runtime-set key value] [--config-set key value] [--config-delete key] [--config-show]'.PHP_EOL;
1258
+ echo ' [--standard=<standard>] [--sniffs=<sniffs>] [--exclude=<sniffs>] [--encoding=<encoding>]'.PHP_EOL;
1259
+ echo ' [--extensions=<extensions>] [--ignore=<patterns>] [--bootstrap=<bootstrap>] <file> ...'.PHP_EOL;
1260
+ echo ' Set runtime value (see --config-set) '.PHP_EOL;
1261
+ echo ' -n Do not print warnings (shortcut for --warning-severity=0)'.PHP_EOL;
1262
+ echo ' -w Print both warnings and errors (this is the default)'.PHP_EOL;
1263
+ echo ' -l Local directory only, no recursion'.PHP_EOL;
1264
+ echo ' -s Show sniff codes in all reports'.PHP_EOL;
1265
+ echo ' -a Run interactively'.PHP_EOL;
1266
+ echo ' -e Explain a standard by showing the sniffs it includes'.PHP_EOL;
1267
+ echo ' -p Show progress of the run'.PHP_EOL;
1268
+ echo ' -q Quiet mode; disables progress and verbose output'.PHP_EOL;
1269
+ echo ' -v[v][v] Print verbose output'.PHP_EOL;
1270
+ echo ' -i Show a list of installed coding standards'.PHP_EOL;
1271
+ echo ' -d Set the [key] php.ini value to [value] or [true] if value is omitted'.PHP_EOL;
1272
+ echo ' --help Print this help message'.PHP_EOL;
1273
+ echo ' --version Print version information'.PHP_EOL;
1274
+ echo ' --colors Use colors in output'.PHP_EOL;
1275
+ echo ' --no-colors Do not use colors in output (this is the default)'.PHP_EOL;
1276
+ echo ' <file> One or more files and/or directories to check'.PHP_EOL;
1277
+ echo ' <stdinPath> If processing STDIN, the file path that STDIN will be processed as '.PHP_EOL;
1278
+ echo ' <bootstrap> A comma separated list of files to run before processing starts'.PHP_EOL;
1279
+ echo ' <encoding> The encoding of the files being checked (default is iso-8859-1)'.PHP_EOL;
1280
+ echo ' <extensions> A comma separated list of file extensions to check'.PHP_EOL;
1281
+ echo ' (extension filtering only valid when checking a directory)'.PHP_EOL;
1282
+ echo ' The type of the file can be specified using: ext/type'.PHP_EOL;
1283
+ echo ' e.g., module/php,es/js'.PHP_EOL;
1284
+ echo ' <generator> Uses either the "HTML", "Markdown" or "Text" generator'.PHP_EOL;
1285
+ echo ' (forces documentation generation instead of checking)'.PHP_EOL;
1286
+ echo ' <patterns> A comma separated list of patterns to ignore files and directories'.PHP_EOL;
1287
+ echo ' <report> Print either the "full", "xml", "checkstyle", "csv"'.PHP_EOL;
1288
+ echo ' "json", "emacs", "source", "summary", "diff", "junit"'.PHP_EOL;
1289
+ echo ' "svnblame", "gitblame", "hgblame" or "notifysend" report'.PHP_EOL;
1290
+ echo ' (the "full" report is printed by default)'.PHP_EOL;
1291
+ echo ' <reportFile> Write the report to the specified file path'.PHP_EOL;
1292
+ echo ' <reportWidth> How many columns wide screen reports should be printed'.PHP_EOL;
1293
+ echo ' or set to "auto" to use current screen width, where supported'.PHP_EOL;
1294
+ echo ' <sniffs> A comma separated list of sniff codes to include or exclude during checking'.PHP_EOL;
1295
+ echo ' (all sniffs must be part of the specified standard)'.PHP_EOL;
1296
+ echo ' <severity> The minimum severity required to display an error or warning'.PHP_EOL;
1297
+ echo ' <standard> The name or path of the coding standard to use'.PHP_EOL;
1298
+ echo ' <tabWidth> The number of spaces each tab represents'.PHP_EOL;
1299
+
1300
+ }//end printPHPCSUsage()
1301
+
1302
+
1303
+ /**
1304
+ * Prints out the usage information for PHPCBF.
1305
+ *
1306
+ * @return void
1307
+ */
1308
+ public function printPHPCBFUsage()
1309
+ {
1310
+ echo 'Usage: phpcbf [-nwli] [-d key[=value]] [--stdin-path=<stdinPath>]'.PHP_EOL;
1311
+ echo ' [--standard=<standard>] [--sniffs=<sniffs>] [--exclude=<sniffs>] [--suffix=<suffix>]'.PHP_EOL;
1312
+ echo ' [--severity=<severity>] [--error-severity=<severity>] [--warning-severity=<severity>]'.PHP_EOL;
1313
+ echo ' [--tab-width=<tabWidth>] [--encoding=<encoding>]'.PHP_EOL;
1314
+ echo ' [--extensions=<extensions>] [--ignore=<patterns>] [--bootstrap=<bootstrap>] <file> ...'.PHP_EOL;
1315
+ echo ' -n Do not fix warnings (shortcut for --warning-severity=0)'.PHP_EOL;
1316
+ echo ' -w Fix both warnings and errors (on by default)'.PHP_EOL;
1317
+ echo ' -l Local directory only, no recursion'.PHP_EOL;
1318
+ echo ' -i Show a list of installed coding standards'.PHP_EOL;
1319
+ echo ' -d Set the [key] php.ini value to [value] or [true] if value is omitted'.PHP_EOL;
1320
+ echo ' --help Print this help message'.PHP_EOL;
1321
+ echo ' --version Print version information'.PHP_EOL;
1322
+ echo ' --no-patch Do not make use of the "diff" or "patch" programs'.PHP_EOL;
1323
+ echo ' <file> One or more files and/or directories to fix'.PHP_EOL;
1324
+ echo ' <stdinPath> If processing STDIN, the file path that STDIN will be processed as '.PHP_EOL;
1325
+ echo ' <bootstrap> A comma separated list of files to run before processing starts'.PHP_EOL;
1326
+ echo ' <encoding> The encoding of the files being fixed (default is iso-8859-1)'.PHP_EOL;
1327
+ echo ' <extensions> A comma separated list of file extensions to fix'.PHP_EOL;
1328
+ echo ' (extension filtering only valid when checking a directory)'.PHP_EOL;
1329
+ echo ' The type of the file can be specified using: ext/type'.PHP_EOL;
1330
+ echo ' e.g., module/php,es/js'.PHP_EOL;
1331
+ echo ' <patterns> A comma separated list of patterns to ignore files and directories'.PHP_EOL;
1332
+ echo ' <sniffs> A comma separated list of sniff codes to include or exclude during fixing'.PHP_EOL;
1333
+ echo ' (all sniffs must be part of the specified standard)'.PHP_EOL;
1334
+ echo ' <severity> The minimum severity required to fix an error or warning'.PHP_EOL;
1335
+ echo ' <standard> The name or path of the coding standard to use'.PHP_EOL;
1336
+ echo ' <suffix> Write modified files to a filename using this suffix'.PHP_EOL;
1337
+ echo ' ("diff" and "patch" are not used in this mode)'.PHP_EOL;
1338
+ echo ' <tabWidth> The number of spaces each tab represents'.PHP_EOL;
1339
+
1340
+ }//end printPHPCBFUsage()
1341
+
1342
+
1343
+ /**
1344
+ * Prints out a list of installed coding standards.
1345
+ *
1346
+ * @return void
1347
+ */
1348
+ public function printInstalledStandards()
1349
+ {
1350
+ $installedStandards = PHP_CodeSniffer::getInstalledStandards();
1351
+ $numStandards = count($installedStandards);
1352
+
1353
+ if ($numStandards === 0) {
1354
+ echo 'No coding standards are installed.'.PHP_EOL;
1355
+ } else {
1356
+ $lastStandard = array_pop($installedStandards);
1357
+ if ($numStandards === 1) {
1358
+ echo "The only coding standard installed is $lastStandard".PHP_EOL;
1359
+ } else {
1360
+ $standardList = implode(', ', $installedStandards);
1361
+ $standardList .= ' and '.$lastStandard;
1362
+ echo 'The installed coding standards are '.$standardList.PHP_EOL;
1363
+ }
1364
+ }
1365
+
1366
+ }//end printInstalledStandards()
1367
+
1368
+
1369
+ /**
1370
+ * Set report width based on terminal width.
1371
+ *
1372
+ * @param int $width The width of the report. If "auto" then will
1373
+ * be replaced by the terminal width.
1374
+ *
1375
+ * @return int
1376
+ */
1377
+ private function _validateReportWidth($width)
1378
+ {
1379
+ if ($width === 'auto'
1380
+ && preg_match('|\d+ (\d+)|', shell_exec('stty size 2>&1'), $matches) === 1
1381
+ ) {
1382
+ return (int) $matches[1];
1383
+ }
1384
+
1385
+ return (int) $width;
1386
+
1387
+ }//end _validateReportWidth()
1388
+
1389
+
1390
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/Generator.php ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The base class for all PHP_CodeSniffer documentation generators.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Greg Sherwood <gsherwood@squiz.net>
10
+ * @author Marc McIntyre <mmcintyre@squiz.net>
11
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
12
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
13
+ * @link http://pear.php.net/package/PHP_CodeSniffer
14
+ */
15
+
16
+ /**
17
+ * The base class for all PHP_CodeSniffer documentation generators.
18
+ *
19
+ * Documentation generators are used to print documentation about code sniffs
20
+ * in a standard.
21
+ *
22
+ * @category PHP
23
+ * @package PHP_CodeSniffer
24
+ * @author Greg Sherwood <gsherwood@squiz.net>
25
+ * @author Marc McIntyre <mmcintyre@squiz.net>
26
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
27
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
28
+ * @version Release: @package_version@
29
+ * @link http://pear.php.net/package/PHP_CodeSniffer
30
+ */
31
+ abstract class PHP_CodeSniffer_DocGenerators_Generator
32
+ {
33
+
34
+ /**
35
+ * The name of the coding standard we are generating docs for.
36
+ *
37
+ * @var string
38
+ */
39
+ private $_standard = '';
40
+
41
+ /**
42
+ * An array of sniffs that we are limiting the generated docs to.
43
+ *
44
+ * If this array is empty, docs are generated for all sniffs in the
45
+ * supplied coding standard.
46
+ *
47
+ * @var string
48
+ */
49
+ private $_sniffs = array();
50
+
51
+
52
+ /**
53
+ * Constructs a PHP_CodeSniffer_DocGenerators_Generator object.
54
+ *
55
+ * @param string $standard The name of the coding standard to generate
56
+ * docs for.
57
+ * @param array $sniffs An array of sniffs that we are limiting the
58
+ * generated docs to.
59
+ *
60
+ * @see generate()
61
+ */
62
+ public function __construct($standard, array $sniffs=array())
63
+ {
64
+ $this->_standard = $standard;
65
+ $this->_sniffs = $sniffs;
66
+
67
+ }//end __construct()
68
+
69
+
70
+ /**
71
+ * Retrieves the title of the sniff from the DOMNode supplied.
72
+ *
73
+ * @param DOMNode $doc The DOMNode object for the sniff.
74
+ * It represents the "documentation" tag in the XML
75
+ * standard file.
76
+ *
77
+ * @return string
78
+ */
79
+ protected function getTitle(DOMNode $doc)
80
+ {
81
+ return $doc->getAttribute('title');
82
+
83
+ }//end getTitle()
84
+
85
+
86
+ /**
87
+ * Retrieves the name of the standard we are generating docs for.
88
+ *
89
+ * @return string
90
+ */
91
+ protected function getStandard()
92
+ {
93
+ return $this->_standard;
94
+
95
+ }//end getStandard()
96
+
97
+
98
+ /**
99
+ * Generates the documentation for a standard.
100
+ *
101
+ * It's probably wise for doc generators to override this method so they
102
+ * have control over how the docs are produced. Otherwise, the processSniff
103
+ * method should be overridden to output content for each sniff.
104
+ *
105
+ * @return void
106
+ * @see processSniff()
107
+ */
108
+ public function generate()
109
+ {
110
+ $standardFiles = $this->getStandardFiles();
111
+
112
+ foreach ($standardFiles as $standard) {
113
+ $doc = new DOMDocument();
114
+ $doc->load($standard);
115
+ $documentation = $doc->getElementsByTagName('documentation')->item(0);
116
+ $this->processSniff($documentation);
117
+ }
118
+
119
+ }//end generate()
120
+
121
+
122
+ /**
123
+ * Returns a list of paths to XML standard files for all sniffs in a standard.
124
+ *
125
+ * Any sniffs that do not have an XML standard file are obviously not included
126
+ * in the returned array. If documentation is only being generated for some
127
+ * sniffs (ie. $this->_sniffs is not empty) then all others sniffs will
128
+ * be filtered from the results as well.
129
+ *
130
+ * @return string[]
131
+ */
132
+ protected function getStandardFiles()
133
+ {
134
+ $phpcs = new PHP_CodeSniffer();
135
+ $phpcs->process(array(), $this->_standard);
136
+ $sniffs = $phpcs->getSniffs();
137
+
138
+ $standardFiles = array();
139
+ foreach ($sniffs as $className => $sniffClass) {
140
+ $object = new ReflectionObject($sniffClass);
141
+ $sniff = $object->getFilename();
142
+ if (empty($this->_sniffs) === false) {
143
+ // We are limiting the docs to certain sniffs only, so filter
144
+ // out any unwanted sniffs.
145
+ $parts = explode('_', $className);
146
+ $sniffName = $parts[0].'.'.$parts[2].'.'.substr($parts[3], 0, -5);
147
+ if (in_array($sniffName, $this->_sniffs) === false) {
148
+ continue;
149
+ }
150
+ }
151
+
152
+ $standardFile = str_replace(
153
+ DIRECTORY_SEPARATOR.'Sniffs'.DIRECTORY_SEPARATOR,
154
+ DIRECTORY_SEPARATOR.'Docs'.DIRECTORY_SEPARATOR,
155
+ $sniff
156
+ );
157
+ $standardFile = str_replace('Sniff.php', 'Standard.xml', $standardFile);
158
+
159
+ if (is_file($standardFile) === true) {
160
+ $standardFiles[] = $standardFile;
161
+ }
162
+ }//end foreach
163
+
164
+ return $standardFiles;
165
+
166
+ }//end getStandardFiles()
167
+
168
+
169
+ /**
170
+ * Process the documentation for a single sniff.
171
+ *
172
+ * Doc generators must implement this function to produce output.
173
+ *
174
+ * @param DOMNode $doc The DOMNode object for the sniff.
175
+ * It represents the "documentation" tag in the XML
176
+ * standard file.
177
+ *
178
+ * @return void
179
+ * @see generate()
180
+ */
181
+ protected abstract function processSniff(DOMNode $doc);
182
+
183
+
184
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/HTML.php ADDED
@@ -0,0 +1,292 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * A doc generator that outputs documentation in one big HTML file.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Greg Sherwood <gsherwood@squiz.net>
10
+ * @author Marc McIntyre <mmcintyre@squiz.net>
11
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
12
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
13
+ * @link http://pear.php.net/package/PHP_CodeSniffer
14
+ */
15
+
16
+ if (class_exists('PHP_CodeSniffer_DocGenerators_Generator', true) === false) {
17
+ throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_DocGenerators_Generator not found');
18
+ }
19
+
20
+ /**
21
+ * A doc generator that outputs documentation in one big HTML file.
22
+ *
23
+ * Output is in one large HTML file and is designed for you to style with
24
+ * your own stylesheet. It contains a table of contents at the top with anchors
25
+ * to each sniff.
26
+ *
27
+ * @category PHP
28
+ * @package PHP_CodeSniffer
29
+ * @author Greg Sherwood <gsherwood@squiz.net>
30
+ * @author Marc McIntyre <mmcintyre@squiz.net>
31
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
32
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
33
+ * @version Release: @package_version@
34
+ * @link http://pear.php.net/package/PHP_CodeSniffer
35
+ */
36
+ class PHP_CodeSniffer_DocGenerators_HTML extends PHP_CodeSniffer_DocGenerators_Generator
37
+ {
38
+
39
+
40
+ /**
41
+ * Generates the documentation for a standard.
42
+ *
43
+ * @return void
44
+ * @see processSniff()
45
+ */
46
+ public function generate()
47
+ {
48
+ ob_start();
49
+ $this->printHeader();
50
+
51
+ $standardFiles = $this->getStandardFiles();
52
+ $this->printToc($standardFiles);
53
+
54
+ foreach ($standardFiles as $standard) {
55
+ $doc = new DOMDocument();
56
+ $doc->load($standard);
57
+ $documentation = $doc->getElementsByTagName('documentation')->item(0);
58
+ $this->processSniff($documentation);
59
+ }
60
+
61
+ $this->printFooter();
62
+
63
+ $content = ob_get_contents();
64
+ ob_end_clean();
65
+
66
+ echo $content;
67
+
68
+ }//end generate()
69
+
70
+
71
+ /**
72
+ * Print the header of the HTML page.
73
+ *
74
+ * @return void
75
+ */
76
+ protected function printHeader()
77
+ {
78
+ $standard = $this->getStandard();
79
+ echo '<html>'.PHP_EOL;
80
+ echo ' <head>'.PHP_EOL;
81
+ echo " <title>$standard Coding Standards</title>".PHP_EOL;
82
+ echo ' <style>
83
+ body {
84
+ background-color: #FFFFFF;
85
+ font-size: 14px;
86
+ font-family: Arial, Helvetica, sans-serif;
87
+ color: #000000;
88
+ }
89
+
90
+ h1 {
91
+ color: #666666;
92
+ font-size: 20px;
93
+ font-weight: bold;
94
+ margin-top: 0px;
95
+ background-color: #E6E7E8;
96
+ padding: 20px;
97
+ border: 1px solid #BBBBBB;
98
+ }
99
+
100
+ h2 {
101
+ color: #00A5E3;
102
+ font-size: 16px;
103
+ font-weight: normal;
104
+ margin-top: 50px;
105
+ }
106
+
107
+ .code-comparison {
108
+ width: 100%;
109
+ }
110
+
111
+ .code-comparison td {
112
+ border: 1px solid #CCCCCC;
113
+ }
114
+
115
+ .code-comparison-title, .code-comparison-code {
116
+ font-family: Arial, Helvetica, sans-serif;
117
+ font-size: 12px;
118
+ color: #000000;
119
+ vertical-align: top;
120
+ padding: 4px;
121
+ width: 50%;
122
+ background-color: #F1F1F1;
123
+ line-height: 15px;
124
+ }
125
+
126
+ .code-comparison-code {
127
+ font-family: Courier;
128
+ background-color: #F9F9F9;
129
+ }
130
+
131
+ .code-comparison-highlight {
132
+ background-color: #DDF1F7;
133
+ border: 1px solid #00A5E3;
134
+ line-height: 15px;
135
+ }
136
+
137
+ .tag-line {
138
+ text-align: center;
139
+ width: 100%;
140
+ margin-top: 30px;
141
+ font-size: 12px;
142
+ }
143
+
144
+ .tag-line a {
145
+ color: #000000;
146
+ }
147
+ </style>'.PHP_EOL;
148
+ echo ' </head>'.PHP_EOL;
149
+ echo ' <body>'.PHP_EOL;
150
+ echo " <h1>$standard Coding Standards</h1>".PHP_EOL;
151
+
152
+ }//end printHeader()
153
+
154
+
155
+ /**
156
+ * Print the table of contents for the standard.
157
+ *
158
+ * The TOC is just an unordered list of bookmarks to sniffs on the page.
159
+ *
160
+ * @param array $standardFiles An array of paths to the XML standard files.
161
+ *
162
+ * @return void
163
+ */
164
+ protected function printToc($standardFiles)
165
+ {
166
+ echo ' <h2>Table of Contents</h2>'.PHP_EOL;
167
+ echo ' <ul class="toc">'.PHP_EOL;
168
+
169
+ foreach ($standardFiles as $standard) {
170
+ $doc = new DOMDocument();
171
+ $doc->load($standard);
172
+ $documentation = $doc->getElementsByTagName('documentation')->item(0);
173
+ $title = $this->getTitle($documentation);
174
+ echo ' <li><a href="#'.str_replace(' ', '-', $title)."\">$title</a></li>".PHP_EOL;
175
+ }
176
+
177
+ echo ' </ul>'.PHP_EOL;
178
+
179
+ }//end printToc()
180
+
181
+
182
+ /**
183
+ * Print the footer of the HTML page.
184
+ *
185
+ * @return void
186
+ */
187
+ protected function printFooter()
188
+ {
189
+ // Turn off errors so we don't get timezone warnings if people
190
+ // don't have their timezone set.
191
+ $errorLevel = error_reporting(0);
192
+ echo ' <div class="tag-line">';
193
+ echo 'Documentation generated on '.date('r');
194
+ echo ' by <a href="https://github.com/squizlabs/PHP_CodeSniffer">PHP_CodeSniffer '.PHP_CodeSniffer::VERSION.'</a>';
195
+ echo '</div>'.PHP_EOL;
196
+ error_reporting($errorLevel);
197
+
198
+ echo ' </body>'.PHP_EOL;
199
+ echo '</html>'.PHP_EOL;
200
+
201
+ }//end printFooter()
202
+
203
+
204
+ /**
205
+ * Process the documentation for a single sniff.
206
+ *
207
+ * @param DOMNode $doc The DOMNode object for the sniff.
208
+ * It represents the "documentation" tag in the XML
209
+ * standard file.
210
+ *
211
+ * @return void
212
+ */
213
+ public function processSniff(DOMNode $doc)
214
+ {
215
+ $title = $this->getTitle($doc);
216
+ echo ' <a name="'.str_replace(' ', '-', $title).'" />'.PHP_EOL;
217
+ echo " <h2>$title</h2>".PHP_EOL;
218
+
219
+ foreach ($doc->childNodes as $node) {
220
+ if ($node->nodeName === 'standard') {
221
+ $this->printTextBlock($node);
222
+ } else if ($node->nodeName === 'code_comparison') {
223
+ $this->printCodeComparisonBlock($node);
224
+ }
225
+ }
226
+
227
+ }//end processSniff()
228
+
229
+
230
+ /**
231
+ * Print a text block found in a standard.
232
+ *
233
+ * @param DOMNode $node The DOMNode object for the text block.
234
+ *
235
+ * @return void
236
+ */
237
+ protected function printTextBlock($node)
238
+ {
239
+ $content = trim($node->nodeValue);
240
+ $content = htmlspecialchars($content);
241
+
242
+ // Allow em tags only.
243
+ $content = str_replace('&lt;em&gt;', '<em>', $content);
244
+ $content = str_replace('&lt;/em&gt;', '</em>', $content);
245
+
246
+ echo " <p class=\"text\">$content</p>".PHP_EOL;
247
+
248
+ }//end printTextBlock()
249
+
250
+
251
+ /**
252
+ * Print a code comparison block found in a standard.
253
+ *
254
+ * @param DOMNode $node The DOMNode object for the code comparison block.
255
+ *
256
+ * @return void
257
+ */
258
+ protected function printCodeComparisonBlock($node)
259
+ {
260
+ $codeBlocks = $node->getElementsByTagName('code');
261
+
262
+ $firstTitle = $codeBlocks->item(0)->getAttribute('title');
263
+ $first = trim($codeBlocks->item(0)->nodeValue);
264
+ $first = str_replace('<?php', '&lt;?php', $first);
265
+ $first = str_replace("\n", '</br>', $first);
266
+ $first = str_replace(' ', '&nbsp;', $first);
267
+ $first = str_replace('<em>', '<span class="code-comparison-highlight">', $first);
268
+ $first = str_replace('</em>', '</span>', $first);
269
+
270
+ $secondTitle = $codeBlocks->item(1)->getAttribute('title');
271
+ $second = trim($codeBlocks->item(1)->nodeValue);
272
+ $second = str_replace('<?php', '&lt;?php', $second);
273
+ $second = str_replace("\n", '</br>', $second);
274
+ $second = str_replace(' ', '&nbsp;', $second);
275
+ $second = str_replace('<em>', '<span class="code-comparison-highlight">', $second);
276
+ $second = str_replace('</em>', '</span>', $second);
277
+
278
+ echo ' <table class="code-comparison">'.PHP_EOL;
279
+ echo ' <tr>'.PHP_EOL;
280
+ echo " <td class=\"code-comparison-title\">$firstTitle</td>".PHP_EOL;
281
+ echo " <td class=\"code-comparison-title\">$secondTitle</td>".PHP_EOL;
282
+ echo ' </tr>'.PHP_EOL;
283
+ echo ' <tr>'.PHP_EOL;
284
+ echo " <td class=\"code-comparison-code\">$first</td>".PHP_EOL;
285
+ echo " <td class=\"code-comparison-code\">$second</td>".PHP_EOL;
286
+ echo ' </tr>'.PHP_EOL;
287
+ echo ' </table>'.PHP_EOL;
288
+
289
+ }//end printCodeComparisonBlock()
290
+
291
+
292
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/Markdown.php ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * A doc generator that outputs documentation in Markdown format.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Stefano Kowalke <blueduck@gmx.net>
10
+ * @copyright 2014 Arroba IT
11
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
12
+ * @link http://pear.php.net/package/PHP_CodeSniffer
13
+ */
14
+
15
+ if (class_exists('PHP_CodeSniffer_DocGenerators_Generator', true) === false) {
16
+ throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_DocGenerators_Generator not found');
17
+ }
18
+
19
+ /**
20
+ * A doc generator that outputs documentation in Markdown format.
21
+ *
22
+ * @category PHP
23
+ * @package PHP_CodeSniffer
24
+ * @author Stefano Kowalke <blueduck@gmx.net>
25
+ * @copyright 2014 Arroba IT
26
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
27
+ * @version Release: @package_version@
28
+ * @link http://pear.php.net/package/PHP_CodeSniffer
29
+ */
30
+ class PHP_CodeSniffer_DocGenerators_Markdown extends PHP_CodeSniffer_DocGenerators_Generator
31
+ {
32
+
33
+
34
+ /**
35
+ * Generates the documentation for a standard.
36
+ *
37
+ * @return void
38
+ * @see processSniff()
39
+ */
40
+ public function generate()
41
+ {
42
+ ob_start();
43
+ $this->printHeader();
44
+
45
+ $standardFiles = $this->getStandardFiles();
46
+
47
+ foreach ($standardFiles as $standard) {
48
+ $doc = new DOMDocument();
49
+ $doc->load($standard);
50
+ $documentation = $doc->getElementsByTagName('documentation')->item(0);
51
+ $this->processSniff($documentation);
52
+ }
53
+
54
+ $this->printFooter();
55
+ $content = ob_get_contents();
56
+ ob_end_clean();
57
+
58
+ echo $content;
59
+
60
+ }//end generate()
61
+
62
+
63
+ /**
64
+ * Print the markdown header.
65
+ *
66
+ * @return void
67
+ */
68
+ protected function printHeader()
69
+ {
70
+ $standard = $this->getStandard();
71
+
72
+ echo "# $standard Coding Standard".PHP_EOL;
73
+
74
+ }//end printHeader()
75
+
76
+
77
+ /**
78
+ * Print the markdown footer.
79
+ *
80
+ * @return void
81
+ */
82
+ protected function printFooter()
83
+ {
84
+ // Turn off errors so we don't get timezone warnings if people
85
+ // don't have their timezone set.
86
+ error_reporting(0);
87
+ echo 'Documentation generated on '.date('r');
88
+ echo ' by [PHP_CodeSniffer '.PHP_CodeSniffer::VERSION.'](https://github.com/squizlabs/PHP_CodeSniffer)';
89
+
90
+ }//end printFooter()
91
+
92
+
93
+ /**
94
+ * Process the documentation for a single sniff.
95
+ *
96
+ * @param DOMNode $doc The DOMNode object for the sniff.
97
+ * It represents the "documentation" tag in the XML
98
+ * standard file.
99
+ *
100
+ * @return void
101
+ */
102
+ protected function processSniff(DOMNode $doc)
103
+ {
104
+ $title = $this->getTitle($doc);
105
+ echo "## $title".PHP_EOL;
106
+
107
+ foreach ($doc->childNodes as $node) {
108
+ if ($node->nodeName === 'standard') {
109
+ $this->printTextBlock($node);
110
+ } else if ($node->nodeName === 'code_comparison') {
111
+ $this->printCodeComparisonBlock($node);
112
+ }
113
+ }
114
+
115
+ }//end processSniff()
116
+
117
+
118
+ /**
119
+ * Print a text block found in a standard.
120
+ *
121
+ * @param DOMNode $node The DOMNode object for the text block.
122
+ *
123
+ * @return void
124
+ */
125
+ protected function printTextBlock(DOMNode $node)
126
+ {
127
+ $content = trim($node->nodeValue);
128
+ $content = htmlspecialchars($content);
129
+
130
+ $content = str_replace('&lt;em&gt;', '*', $content);
131
+ $content = str_replace('&lt;/em&gt;', '*', $content);
132
+
133
+ echo $content.PHP_EOL;
134
+
135
+ }//end printTextBlock()
136
+
137
+
138
+ /**
139
+ * Print a code comparison block found in a standard.
140
+ *
141
+ * @param DOMNode $node The DOMNode object for the code comparison block.
142
+ *
143
+ * @return void
144
+ */
145
+ protected function printCodeComparisonBlock(DOMNode $node)
146
+ {
147
+ $codeBlocks = $node->getElementsByTagName('code');
148
+
149
+ $firstTitle = $codeBlocks->item(0)->getAttribute('title');
150
+ $first = trim($codeBlocks->item(0)->nodeValue);
151
+ $first = str_replace("\n", "\n ", $first);
152
+ $first = str_replace('<em>', '', $first);
153
+ $first = str_replace('</em>', '', $first);
154
+
155
+ $secondTitle = $codeBlocks->item(1)->getAttribute('title');
156
+ $second = trim($codeBlocks->item(1)->nodeValue);
157
+ $second = str_replace("\n", "\n ", $second);
158
+ $second = str_replace('<em>', '', $second);
159
+ $second = str_replace('</em>', '', $second);
160
+
161
+ echo ' <table>'.PHP_EOL;
162
+ echo ' <tr>'.PHP_EOL;
163
+ echo " <th>$firstTitle</th>".PHP_EOL;
164
+ echo " <th>$secondTitle</th>".PHP_EOL;
165
+ echo ' </tr>'.PHP_EOL;
166
+ echo ' <tr>'.PHP_EOL;
167
+ echo '<td>'.PHP_EOL.PHP_EOL;
168
+ echo " $first".PHP_EOL.PHP_EOL;
169
+ echo '</td>'.PHP_EOL;
170
+ echo '<td>'.PHP_EOL.PHP_EOL;
171
+ echo " $second".PHP_EOL.PHP_EOL;
172
+ echo '</td>'.PHP_EOL;
173
+ echo ' </tr>'.PHP_EOL;
174
+ echo ' </table>'.PHP_EOL;
175
+
176
+ }//end printCodeComparisonBlock()
177
+
178
+
179
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/DocGenerators/Text.php ADDED
@@ -0,0 +1,265 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * A doc generator that outputs text-based documentation.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Greg Sherwood <gsherwood@squiz.net>
10
+ * @author Marc McIntyre <mmcintyre@squiz.net>
11
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
12
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
13
+ * @link http://pear.php.net/package/PHP_CodeSniffer
14
+ */
15
+
16
+ if (class_exists('PHP_CodeSniffer_DocGenerators_Generator', true) === false) {
17
+ throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_DocGenerators_Generator not found');
18
+ }
19
+
20
+ /**
21
+ * A doc generator that outputs text-based documentation.
22
+ *
23
+ * Output is designed to be displayed in a terminal and is wrapped to 100 characters.
24
+ *
25
+ * @category PHP
26
+ * @package PHP_CodeSniffer
27
+ * @author Greg Sherwood <gsherwood@squiz.net>
28
+ * @author Marc McIntyre <mmcintyre@squiz.net>
29
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
30
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
31
+ * @version Release: @package_version@
32
+ * @link http://pear.php.net/package/PHP_CodeSniffer
33
+ */
34
+ class PHP_CodeSniffer_DocGenerators_Text extends PHP_CodeSniffer_DocGenerators_Generator
35
+ {
36
+
37
+
38
+ /**
39
+ * Process the documentation for a single sniff.
40
+ *
41
+ * @param DOMNode $doc The DOMNode object for the sniff.
42
+ * It represents the "documentation" tag in the XML
43
+ * standard file.
44
+ *
45
+ * @return void
46
+ */
47
+ public function processSniff(DOMNode $doc)
48
+ {
49
+ $this->printTitle($doc);
50
+
51
+ foreach ($doc->childNodes as $node) {
52
+ if ($node->nodeName === 'standard') {
53
+ $this->printTextBlock($node);
54
+ } else if ($node->nodeName === 'code_comparison') {
55
+ $this->printCodeComparisonBlock($node);
56
+ }
57
+ }
58
+
59
+ }//end processSniff()
60
+
61
+
62
+ /**
63
+ * Prints the title area for a single sniff.
64
+ *
65
+ * @param DOMNode $doc The DOMNode object for the sniff.
66
+ * It represents the "documentation" tag in the XML
67
+ * standard file.
68
+ *
69
+ * @return void
70
+ */
71
+ protected function printTitle(DOMNode $doc)
72
+ {
73
+ $title = $this->getTitle($doc);
74
+ $standard = $this->getStandard();
75
+
76
+ echo PHP_EOL;
77
+ echo str_repeat('-', (strlen("$standard CODING STANDARD: $title") + 4));
78
+ echo strtoupper(PHP_EOL."| $standard CODING STANDARD: $title |".PHP_EOL);
79
+ echo str_repeat('-', (strlen("$standard CODING STANDARD: $title") + 4));
80
+ echo PHP_EOL.PHP_EOL;
81
+
82
+ }//end printTitle()
83
+
84
+
85
+ /**
86
+ * Print a text block found in a standard.
87
+ *
88
+ * @param DOMNode $node The DOMNode object for the text block.
89
+ *
90
+ * @return void
91
+ */
92
+ protected function printTextBlock($node)
93
+ {
94
+ $text = trim($node->nodeValue);
95
+ $text = str_replace('<em>', '*', $text);
96
+ $text = str_replace('</em>', '*', $text);
97
+
98
+ $lines = array();
99
+ $tempLine = '';
100
+ $words = explode(' ', $text);
101
+
102
+ foreach ($words as $word) {
103
+ if (strlen($tempLine.$word) >= 99) {
104
+ if (strlen($tempLine.$word) === 99) {
105
+ // Adding the extra space will push us to the edge
106
+ // so we are done.
107
+ $lines[] = $tempLine.$word;
108
+ $tempLine = '';
109
+ } else if (strlen($tempLine.$word) === 100) {
110
+ // We are already at the edge, so we are done.
111
+ $lines[] = $tempLine.$word;
112
+ $tempLine = '';
113
+ } else {
114
+ $lines[] = rtrim($tempLine);
115
+ $tempLine = $word.' ';
116
+ }
117
+ } else {
118
+ $tempLine .= $word.' ';
119
+ }
120
+ }//end foreach
121
+
122
+ if ($tempLine !== '') {
123
+ $lines[] = rtrim($tempLine);
124
+ }
125
+
126
+ echo implode(PHP_EOL, $lines).PHP_EOL.PHP_EOL;
127
+
128
+ }//end printTextBlock()
129
+
130
+
131
+ /**
132
+ * Print a code comparison block found in a standard.
133
+ *
134
+ * @param DOMNode $node The DOMNode object for the code comparison block.
135
+ *
136
+ * @return void
137
+ */
138
+ protected function printCodeComparisonBlock($node)
139
+ {
140
+ $codeBlocks = $node->getElementsByTagName('code');
141
+ $first = trim($codeBlocks->item(0)->nodeValue);
142
+ $firstTitle = $codeBlocks->item(0)->getAttribute('title');
143
+
144
+ $firstTitleLines = array();
145
+ $tempTitle = '';
146
+ $words = explode(' ', $firstTitle);
147
+
148
+ foreach ($words as $word) {
149
+ if (strlen($tempTitle.$word) >= 45) {
150
+ if (strlen($tempTitle.$word) === 45) {
151
+ // Adding the extra space will push us to the edge
152
+ // so we are done.
153
+ $firstTitleLines[] = $tempTitle.$word;
154
+ $tempTitle = '';
155
+ } else if (strlen($tempTitle.$word) === 46) {
156
+ // We are already at the edge, so we are done.
157
+ $firstTitleLines[] = $tempTitle.$word;
158
+ $tempTitle = '';
159
+ } else {
160
+ $firstTitleLines[] = $tempTitle;
161
+ $tempTitle = $word;
162
+ }
163
+ } else {
164
+ $tempTitle .= $word.' ';
165
+ }
166
+ }//end foreach
167
+
168
+ if ($tempTitle !== '') {
169
+ $firstTitleLines[] = $tempTitle;
170
+ }
171
+
172
+ $first = str_replace('<em>', '', $first);
173
+ $first = str_replace('</em>', '', $first);
174
+ $firstLines = explode("\n", $first);
175
+
176
+ $second = trim($codeBlocks->item(1)->nodeValue);
177
+ $secondTitle = $codeBlocks->item(1)->getAttribute('title');
178
+
179
+ $secondTitleLines = array();
180
+ $tempTitle = '';
181
+ $words = explode(' ', $secondTitle);
182
+
183
+ foreach ($words as $word) {
184
+ if (strlen($tempTitle.$word) >= 45) {
185
+ if (strlen($tempTitle.$word) === 45) {
186
+ // Adding the extra space will push us to the edge
187
+ // so we are done.
188
+ $secondTitleLines[] = $tempTitle.$word;
189
+ $tempTitle = '';
190
+ } else if (strlen($tempTitle.$word) === 46) {
191
+ // We are already at the edge, so we are done.
192
+ $secondTitleLines[] = $tempTitle.$word;
193
+ $tempTitle = '';
194
+ } else {
195
+ $secondTitleLines[] = $tempTitle;
196
+ $tempTitle = $word;
197
+ }
198
+ } else {
199
+ $tempTitle .= $word.' ';
200
+ }
201
+ }//end foreach
202
+
203
+ if ($tempTitle !== '') {
204
+ $secondTitleLines[] = $tempTitle;
205
+ }
206
+
207
+ $second = str_replace('<em>', '', $second);
208
+ $second = str_replace('</em>', '', $second);
209
+ $secondLines = explode("\n", $second);
210
+
211
+ $maxCodeLines = max(count($firstLines), count($secondLines));
212
+ $maxTitleLines = max(count($firstTitleLines), count($secondTitleLines));
213
+
214
+ echo str_repeat('-', 41);
215
+ echo ' CODE COMPARISON ';
216
+ echo str_repeat('-', 42).PHP_EOL;
217
+
218
+ for ($i = 0; $i < $maxTitleLines; $i++) {
219
+ if (isset($firstTitleLines[$i]) === true) {
220
+ $firstLineText = $firstTitleLines[$i];
221
+ } else {
222
+ $firstLineText = '';
223
+ }
224
+
225
+ if (isset($secondTitleLines[$i]) === true) {
226
+ $secondLineText = $secondTitleLines[$i];
227
+ } else {
228
+ $secondLineText = '';
229
+ }
230
+
231
+ echo '| ';
232
+ echo $firstLineText.str_repeat(' ', (46 - strlen($firstLineText)));
233
+ echo ' | ';
234
+ echo $secondLineText.str_repeat(' ', (47 - strlen($secondLineText)));
235
+ echo ' |'.PHP_EOL;
236
+ }//end for
237
+
238
+ echo str_repeat('-', 100).PHP_EOL;
239
+
240
+ for ($i = 0; $i < $maxCodeLines; $i++) {
241
+ if (isset($firstLines[$i]) === true) {
242
+ $firstLineText = $firstLines[$i];
243
+ } else {
244
+ $firstLineText = '';
245
+ }
246
+
247
+ if (isset($secondLines[$i]) === true) {
248
+ $secondLineText = $secondLines[$i];
249
+ } else {
250
+ $secondLineText = '';
251
+ }
252
+
253
+ echo '| ';
254
+ echo $firstLineText.str_repeat(' ', (47 - strlen($firstLineText)));
255
+ echo '| ';
256
+ echo $secondLineText.str_repeat(' ', (48 - strlen($secondLineText)));
257
+ echo '|'.PHP_EOL;
258
+ }//end for
259
+
260
+ echo str_repeat('-', 100).PHP_EOL.PHP_EOL;
261
+
262
+ }//end printCodeComparisonBlock()
263
+
264
+
265
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Exception.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * An exception thrown by PHP_CodeSniffer when it encounters an unrecoverable error.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Greg Sherwood <gsherwood@squiz.net>
10
+ * @author Marc McIntyre <mmcintyre@squiz.net>
11
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
12
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
13
+ * @link http://pear.php.net/package/PHP_CodeSniffer
14
+ */
15
+
16
+ /**
17
+ * An exception thrown by PHP_CodeSniffer when it encounters an unrecoverable error.
18
+ *
19
+ * @category PHP
20
+ * @package PHP_CodeSniffer
21
+ * @author Greg Sherwood <gsherwood@squiz.net>
22
+ * @author Marc McIntyre <mmcintyre@squiz.net>
23
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
24
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
25
+ * @version Release: @package_version@
26
+ * @link http://pear.php.net/package/PHP_CodeSniffer
27
+ */
28
+ class PHP_CodeSniffer_Exception extends Exception
29
+ {
30
+
31
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/File.php ADDED
@@ -0,0 +1,3715 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * A PHP_CodeSniffer_File object represents a PHP source file and the tokens
4
+ * associated with it.
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * @category PHP
9
+ * @package PHP_CodeSniffer
10
+ * @author Greg Sherwood <gsherwood@squiz.net>
11
+ * @author Marc McIntyre <mmcintyre@squiz.net>
12
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
13
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
14
+ * @link http://pear.php.net/package/PHP_CodeSniffer
15
+ */
16
+
17
+ /**
18
+ * A PHP_CodeSniffer_File object represents a PHP source file and the tokens
19
+ * associated with it.
20
+ *
21
+ * It provides a means for traversing the token stack, along with
22
+ * other token related operations. If a PHP_CodeSniffer_Sniff finds and error or
23
+ * warning within a PHP_CodeSniffer_File, you can raise an error using the
24
+ * addError() or addWarning() methods.
25
+ *
26
+ * <b>Token Information</b>
27
+ *
28
+ * Each token within the stack contains information about itself:
29
+ *
30
+ * <code>
31
+ * array(
32
+ * 'code' => 301, // the token type code (see token_get_all())
33
+ * 'content' => 'if', // the token content
34
+ * 'type' => 'T_IF', // the token name
35
+ * 'line' => 56, // the line number when the token is located
36
+ * 'column' => 12, // the column in the line where this token
37
+ * // starts (starts from 1)
38
+ * 'level' => 2 // the depth a token is within the scopes open
39
+ * 'conditions' => array( // a list of scope condition token
40
+ * // positions => codes that
41
+ * 2 => 50, // opened the scopes that this token exists
42
+ * 9 => 353, // in (see conditional tokens section below)
43
+ * ),
44
+ * );
45
+ * </code>
46
+ *
47
+ * <b>Conditional Tokens</b>
48
+ *
49
+ * In addition to the standard token fields, conditions contain information to
50
+ * determine where their scope begins and ends:
51
+ *
52
+ * <code>
53
+ * array(
54
+ * 'scope_condition' => 38, // the token position of the condition
55
+ * 'scope_opener' => 41, // the token position that started the scope
56
+ * 'scope_closer' => 70, // the token position that ended the scope
57
+ * );
58
+ * </code>
59
+ *
60
+ * The condition, the scope opener and the scope closer each contain this
61
+ * information.
62
+ *
63
+ * <b>Parenthesis Tokens</b>
64
+ *
65
+ * Each parenthesis token (T_OPEN_PARENTHESIS and T_CLOSE_PARENTHESIS) has a
66
+ * reference to their opening and closing parenthesis, one being itself, the
67
+ * other being its opposite.
68
+ *
69
+ * <code>
70
+ * array(
71
+ * 'parenthesis_opener' => 34,
72
+ * 'parenthesis_closer' => 40,
73
+ * );
74
+ * </code>
75
+ *
76
+ * Some tokens can "own" a set of parenthesis. For example a T_FUNCTION token
77
+ * has parenthesis around its argument list. These tokens also have the
78
+ * parenthesis_opener and and parenthesis_closer indices. Not all parenthesis
79
+ * have owners, for example parenthesis used for arithmetic operations and
80
+ * function calls. The parenthesis tokens that have an owner have the following
81
+ * auxiliary array indices.
82
+ *
83
+ * <code>
84
+ * array(
85
+ * 'parenthesis_opener' => 34,
86
+ * 'parenthesis_closer' => 40,
87
+ * 'parenthesis_owner' => 33,
88
+ * );
89
+ * </code>
90
+ *
91
+ * Each token within a set of parenthesis also has an array index
92
+ * 'nested_parenthesis' which is an array of the
93
+ * left parenthesis => right parenthesis token positions.
94
+ *
95
+ * <code>
96
+ * 'nested_parenthesis' => array(
97
+ * 12 => 15
98
+ * 11 => 14
99
+ * );
100
+ * </code>
101
+ *
102
+ * <b>Extended Tokens</b>
103
+ *
104
+ * PHP_CodeSniffer extends and augments some of the tokens created by
105
+ * <i>token_get_all()</i>. A full list of these tokens can be seen in the
106
+ * <i>Tokens.php</i> file.
107
+ *
108
+ * @category PHP
109
+ * @package PHP_CodeSniffer
110
+ * @author Greg Sherwood <gsherwood@squiz.net>
111
+ * @author Marc McIntyre <mmcintyre@squiz.net>
112
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
113
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
114
+ * @version Release: @package_version@
115
+ * @link http://pear.php.net/package/PHP_CodeSniffer
116
+ */
117
+ class PHP_CodeSniffer_File
118
+ {
119
+
120
+ /**
121
+ * The absolute path to the file associated with this object.
122
+ *
123
+ * @var string
124
+ */
125
+ private $_file = '';
126
+
127
+ /**
128
+ * The EOL character this file uses.
129
+ *
130
+ * @var string
131
+ */
132
+ public $eolChar = '';
133
+
134
+ /**
135
+ * The PHP_CodeSniffer object controlling this run.
136
+ *
137
+ * @var PHP_CodeSniffer
138
+ */
139
+ public $phpcs = null;
140
+
141
+ /**
142
+ * The Fixer object to control fixing errors.
143
+ *
144
+ * @var PHP_CodeSniffer_Fixer
145
+ */
146
+ public $fixer = null;
147
+
148
+ /**
149
+ * The tokenizer being used for this file.
150
+ *
151
+ * @var object
152
+ */
153
+ public $tokenizer = null;
154
+
155
+ /**
156
+ * The tokenizer being used for this file.
157
+ *
158
+ * @var string
159
+ */
160
+ public $tokenizerType = 'PHP';
161
+
162
+ /**
163
+ * The number of tokens in this file.
164
+ *
165
+ * Stored here to save calling count() everywhere.
166
+ *
167
+ * @var int
168
+ */
169
+ public $numTokens = 0;
170
+
171
+ /**
172
+ * The tokens stack map.
173
+ *
174
+ * Note that the tokens in this array differ in format to the tokens
175
+ * produced by token_get_all(). Tokens are initially produced with
176
+ * token_get_all(), then augmented so that it's easier to process them.
177
+ *
178
+ * @var array()
179
+ * @see Tokens.php
180
+ */
181
+ private $_tokens = array();
182
+
183
+ /**
184
+ * The errors raised from PHP_CodeSniffer_Sniffs.
185
+ *
186
+ * @var array()
187
+ * @see getErrors()
188
+ */
189
+ private $_errors = array();
190
+
191
+ /**
192
+ * The warnings raised from PHP_CodeSniffer_Sniffs.
193
+ *
194
+ * @var array()
195
+ * @see getWarnings()
196
+ */
197
+ private $_warnings = array();
198
+
199
+ /**
200
+ * The metrics recorded from PHP_CodeSniffer_Sniffs.
201
+ *
202
+ * @var array()
203
+ * @see getMetrics()
204
+ */
205
+ private $_metrics = array();
206
+
207
+ /**
208
+ * Record the errors and warnings raised.
209
+ *
210
+ * @var bool
211
+ */
212
+ private $_recordErrors = true;
213
+
214
+ /**
215
+ * An array of lines that are being ignored.
216
+ *
217
+ * @var array()
218
+ */
219
+ private static $_ignoredLines = array();
220
+
221
+ /**
222
+ * An array of sniffs that are being ignored.
223
+ *
224
+ * @var array()
225
+ */
226
+ private $_ignoredListeners = array();
227
+
228
+ /**
229
+ * An array of message codes that are being ignored.
230
+ *
231
+ * @var array()
232
+ */
233
+ private $_ignoredCodes = array();
234
+
235
+ /**
236
+ * The total number of errors raised.
237
+ *
238
+ * @var int
239
+ */
240
+ private $_errorCount = 0;
241
+
242
+ /**
243
+ * The total number of warnings raised.
244
+ *
245
+ * @var int
246
+ */
247
+ private $_warningCount = 0;
248
+
249
+ /**
250
+ * The total number of errors/warnings that can be fixed.
251
+ *
252
+ * @var int
253
+ */
254
+ private $_fixableCount = 0;
255
+
256
+ /**
257
+ * An array of sniffs listening to this file's processing.
258
+ *
259
+ * @var array(PHP_CodeSniffer_Sniff)
260
+ */
261
+ private $_listeners = array();
262
+
263
+ /**
264
+ * The class name of the sniff currently processing the file.
265
+ *
266
+ * @var string
267
+ */
268
+ private $_activeListener = '';
269
+
270
+ /**
271
+ * An array of sniffs being processed and how long they took.
272
+ *
273
+ * @var array()
274
+ */
275
+ private $_listenerTimes = array();
276
+
277
+ /**
278
+ * An array of rules from the ruleset.xml file.
279
+ *
280
+ * This value gets set by PHP_CodeSniffer when the object is created.
281
+ * It may be empty, indicating that the ruleset does not override
282
+ * any of the default sniff settings.
283
+ *
284
+ * @var array
285
+ */
286
+ protected $ruleset = array();
287
+
288
+
289
+ /**
290
+ * Constructs a PHP_CodeSniffer_File.
291
+ *
292
+ * @param string $file The absolute path to the file to process.
293
+ * @param array(string) $listeners The initial listeners listening to processing of this file.
294
+ * to processing of this file.
295
+ * @param array $ruleset An array of rules from the ruleset.xml file.
296
+ * ruleset.xml file.
297
+ * @param PHP_CodeSniffer $phpcs The PHP_CodeSniffer object controlling this run.
298
+ * this run.
299
+ *
300
+ * @throws PHP_CodeSniffer_Exception If the register() method does
301
+ * not return an array.
302
+ */
303
+ public function __construct(
304
+ $file,
305
+ array $listeners,
306
+ array $ruleset,
307
+ PHP_CodeSniffer $phpcs
308
+ ) {
309
+ $this->_file = trim($file);
310
+ $this->_listeners = $listeners;
311
+ $this->ruleset = $ruleset;
312
+ $this->phpcs = $phpcs;
313
+ $this->fixer = new PHP_CodeSniffer_Fixer();
314
+
315
+ if (PHP_CODESNIFFER_INTERACTIVE === false) {
316
+ $cliValues = $phpcs->cli->getCommandLineValues();
317
+ if (isset($cliValues['showSources']) === true
318
+ && $cliValues['showSources'] !== true
319
+ ) {
320
+ $recordErrors = false;
321
+ foreach ($cliValues['reports'] as $report => $output) {
322
+ $reportClass = $phpcs->reporting->factory($report);
323
+ if (property_exists($reportClass, 'recordErrors') === false
324
+ || $reportClass->recordErrors === true
325
+ ) {
326
+ $recordErrors = true;
327
+ break;
328
+ }
329
+ }
330
+
331
+ $this->_recordErrors = $recordErrors;
332
+ }
333
+ }
334
+
335
+ }//end __construct()
336
+
337
+
338
+ /**
339
+ * Sets the name of the currently active sniff.
340
+ *
341
+ * @param string $activeListener The class name of the current sniff.
342
+ *
343
+ * @return void
344
+ */
345
+ public function setActiveListener($activeListener)
346
+ {
347
+ $this->_activeListener = $activeListener;
348
+
349
+ }//end setActiveListener()
350
+
351
+
352
+ /**
353
+ * Adds a listener to the token stack that listens to the specific tokens.
354
+ *
355
+ * When PHP_CodeSniffer encounters on the the tokens specified in $tokens,
356
+ * it invokes the process method of the sniff.
357
+ *
358
+ * @param PHP_CodeSniffer_Sniff $listener The listener to add to the
359
+ * listener stack.
360
+ * @param array(int) $tokens The token types the listener wishes to
361
+ * listen to.
362
+ *
363
+ * @return void
364
+ */
365
+ public function addTokenListener(PHP_CodeSniffer_Sniff $listener, array $tokens)
366
+ {
367
+ $class = get_class($listener);
368
+ foreach ($tokens as $token) {
369
+ if (isset($this->_listeners[$token]) === false) {
370
+ $this->_listeners[$token] = array();
371
+ }
372
+
373
+ if (isset($this->_listeners[$token][$class]) === false) {
374
+ $this->_listeners[$token][$class] = $listener;
375
+ }
376
+ }
377
+
378
+ }//end addTokenListener()
379
+
380
+
381
+ /**
382
+ * Removes a listener from listening from the specified tokens.
383
+ *
384
+ * @param PHP_CodeSniffer_Sniff $listener The listener to remove from the
385
+ * listener stack.
386
+ * @param array(int) $tokens The token types the listener wishes to
387
+ * stop listen to.
388
+ *
389
+ * @return void
390
+ */
391
+ public function removeTokenListener(
392
+ PHP_CodeSniffer_Sniff $listener,
393
+ array $tokens
394
+ ) {
395
+ $class = get_class($listener);
396
+ foreach ($tokens as $token) {
397
+ if (isset($this->_listeners[$token]) === false) {
398
+ continue;
399
+ }
400
+
401
+ unset($this->_listeners[$token][$class]);
402
+ }
403
+
404
+ }//end removeTokenListener()
405
+
406
+
407
+ /**
408
+ * Rebuilds the list of listeners to ensure their state is cleared.
409
+ *
410
+ * @return void
411
+ */
412
+ public function refreshTokenListeners()
413
+ {
414
+ $this->phpcs->populateTokenListeners();
415
+ $this->_listeners = $this->phpcs->getTokenSniffs();
416
+
417
+ }//end refreshTokenListeners()
418
+
419
+
420
+ /**
421
+ * Returns the token stack for this file.
422
+ *
423
+ * @return array
424
+ */
425
+ public function getTokens()
426
+ {
427
+ return $this->_tokens;
428
+
429
+ }//end getTokens()
430
+
431
+
432
+ /**
433
+ * Starts the stack traversal and tells listeners when tokens are found.
434
+ *
435
+ * @param string $contents The contents to parse. If NULL, the content
436
+ * is taken from the file system.
437
+ *
438
+ * @return void
439
+ */
440
+ public function start($contents=null)
441
+ {
442
+ $this->_errors = array();
443
+ $this->_warnings = array();
444
+ $this->_errorCount = 0;
445
+ $this->_warningCount = 0;
446
+ $this->_fixableCount = 0;
447
+
448
+ // Reset the ignored lines because lines numbers may have changed
449
+ // if we are fixing this file.
450
+ self::$_ignoredLines = array();
451
+
452
+ try {
453
+ $this->eolChar = self::detectLineEndings($this->_file, $contents);
454
+ } catch (PHP_CodeSniffer_Exception $e) {
455
+ $this->addWarning($e->getMessage(), null, 'Internal.DetectLineEndings');
456
+ return;
457
+ }
458
+
459
+ // If this is standard input, see if a filename was passed in as well.
460
+ // This is done by including: phpcs_input_file: [file path]
461
+ // as the first line of content.
462
+ if ($this->_file === 'STDIN') {
463
+ $cliValues = $this->phpcs->cli->getCommandLineValues();
464
+ if ($cliValues['stdinPath'] !== '') {
465
+ $this->_file = $cliValues['stdinPath'];
466
+ } else if ($contents !== null && substr($contents, 0, 17) === 'phpcs_input_file:') {
467
+ $eolPos = strpos($contents, $this->eolChar);
468
+ $filename = trim(substr($contents, 17, ($eolPos - 17)));
469
+ $contents = substr($contents, ($eolPos + strlen($this->eolChar)));
470
+ $this->_file = $filename;
471
+ }
472
+ }
473
+
474
+ $this->_parse($contents);
475
+ $this->fixer->startFile($this);
476
+
477
+ if (PHP_CODESNIFFER_VERBOSITY > 2) {
478
+ echo "\t*** START TOKEN PROCESSING ***".PHP_EOL;
479
+ }
480
+
481
+ $foundCode = false;
482
+ $listeners = $this->phpcs->getSniffs();
483
+ $listenerIgnoreTo = array();
484
+ $inTests = defined('PHP_CODESNIFFER_IN_TESTS');
485
+
486
+ // Foreach of the listeners that have registered to listen for this
487
+ // token, get them to process it.
488
+ foreach ($this->_tokens as $stackPtr => $token) {
489
+ // Check for ignored lines.
490
+ if ($token['code'] === T_COMMENT
491
+ || $token['code'] === T_DOC_COMMENT_TAG
492
+ || ($inTests === true && $token['code'] === T_INLINE_HTML)
493
+ ) {
494
+ if (strpos($token['content'], '@codingStandards') !== false) {
495
+ if (strpos($token['content'], '@codingStandardsIgnoreFile') !== false) {
496
+ // Ignoring the whole file, just a little late.
497
+ $this->_errors = array();
498
+ $this->_warnings = array();
499
+ $this->_errorCount = 0;
500
+ $this->_warningCount = 0;
501
+ $this->_fixableCount = 0;
502
+ return;
503
+ } else if (strpos($token['content'], '@codingStandardsChangeSetting') !== false) {
504
+ $start = strpos($token['content'], '@codingStandardsChangeSetting');
505
+ $comment = substr($token['content'], ($start + 30));
506
+ $parts = explode(' ', $comment);
507
+ if (count($parts) >= 3
508
+ && isset($this->phpcs->sniffCodes[$parts[0]]) === true
509
+ ) {
510
+ $listenerClass = $this->phpcs->sniffCodes[$parts[0]];
511
+ $this->phpcs->setSniffProperty($listenerClass, $parts[1], $parts[2]);
512
+ }
513
+ }//end if
514
+ }//end if
515
+ }//end if
516
+
517
+ if (PHP_CODESNIFFER_VERBOSITY > 2) {
518
+ $type = $token['type'];
519
+ $content = PHP_CodeSniffer::prepareForOutput($token['content']);
520
+ echo "\t\tProcess token $stackPtr: $type => $content".PHP_EOL;
521
+ }
522
+
523
+ if ($token['code'] !== T_INLINE_HTML) {
524
+ $foundCode = true;
525
+ }
526
+
527
+ if (isset($this->_listeners[$token['code']]) === false) {
528
+ continue;
529
+ }
530
+
531
+ foreach ($this->_listeners[$token['code']] as $listenerData) {
532
+ if (isset($this->_ignoredListeners[$listenerData['class']]) === true
533
+ || (isset($listenerIgnoreTo[$listenerData['class']]) === true
534
+ && $listenerIgnoreTo[$listenerData['class']] > $stackPtr)
535
+ ) {
536
+ // This sniff is ignoring past this token, or the whole file.
537
+ continue;
538
+ }
539
+
540
+ // Make sure this sniff supports the tokenizer
541
+ // we are currently using.
542
+ $class = $listenerData['class'];
543
+
544
+ if (isset($listenerData['tokenizers'][$this->tokenizerType]) === false) {
545
+ continue;
546
+ }
547
+
548
+ // If the file path matches one of our ignore patterns, skip it.
549
+ // While there is support for a type of each pattern
550
+ // (absolute or relative) we don't actually support it here.
551
+ foreach ($listenerData['ignore'] as $pattern) {
552
+ // We assume a / directory separator, as do the exclude rules
553
+ // most developers write, so we need a special case for any system
554
+ // that is different.
555
+ if (DIRECTORY_SEPARATOR === '\\') {
556
+ $pattern = str_replace('/', '\\\\', $pattern);
557
+ }
558
+
559
+ $pattern = '`'.$pattern.'`i';
560
+ if (preg_match($pattern, $this->_file) === 1) {
561
+ $this->_ignoredListeners[$class] = true;
562
+ continue(2);
563
+ }
564
+ }
565
+
566
+ $this->_activeListener = $class;
567
+
568
+ if (PHP_CODESNIFFER_VERBOSITY > 2) {
569
+ $startTime = microtime(true);
570
+ echo "\t\t\tProcessing ".$this->_activeListener.'... ';
571
+ }
572
+
573
+ $ignoreTo = $listeners[$class]->process($this, $stackPtr);
574
+ if ($ignoreTo !== null) {
575
+ $listenerIgnoreTo[$this->_activeListener] = $ignoreTo;
576
+ }
577
+
578
+ if (PHP_CODESNIFFER_VERBOSITY > 2) {
579
+ $timeTaken = (microtime(true) - $startTime);
580
+ if (isset($this->_listenerTimes[$this->_activeListener]) === false) {
581
+ $this->_listenerTimes[$this->_activeListener] = 0;
582
+ }
583
+
584
+ $this->_listenerTimes[$this->_activeListener] += $timeTaken;
585
+
586
+ $timeTaken = round(($timeTaken), 4);
587
+ echo "DONE in $timeTaken seconds".PHP_EOL;
588
+ }
589
+
590
+ $this->_activeListener = '';
591
+ }//end foreach
592
+ }//end foreach
593
+
594
+ if ($this->_recordErrors === false) {
595
+ $this->_errors = array();
596
+ $this->_warnings = array();
597
+ }
598
+
599
+ // If short open tags are off but the file being checked uses
600
+ // short open tags, the whole content will be inline HTML
601
+ // and nothing will be checked. So try and handle this case.
602
+ if ($foundCode === false && $this->tokenizerType === 'PHP') {
603
+ $shortTags = (bool) ini_get('short_open_tag');
604
+ if ($shortTags === false) {
605
+ $error = 'No PHP code was found in this file and short open tags are not allowed by this install of PHP. This file may be using short open tags but PHP does not allow them.';
606
+ $this->addWarning($error, null, 'Internal.NoCodeFound');
607
+ }
608
+ }
609
+
610
+ if (PHP_CODESNIFFER_VERBOSITY > 2) {
611
+ echo "\t*** END TOKEN PROCESSING ***".PHP_EOL;
612
+ echo "\t*** START SNIFF PROCESSING REPORT ***".PHP_EOL;
613
+
614
+ asort($this->_listenerTimes, SORT_NUMERIC);
615
+ $this->_listenerTimes = array_reverse($this->_listenerTimes, true);
616
+ foreach ($this->_listenerTimes as $listener => $timeTaken) {
617
+ echo "\t$listener: ".round(($timeTaken), 4).' secs'.PHP_EOL;
618
+ }
619
+
620
+ echo "\t*** END SNIFF PROCESSING REPORT ***".PHP_EOL;
621
+ }
622
+
623
+ }//end start()
624
+
625
+
626
+ /**
627
+ * Remove vars stored in this file that are no longer required.
628
+ *
629
+ * @return void
630
+ */
631
+ public function cleanUp()
632
+ {
633
+ $this->_tokens = null;
634
+ $this->_listeners = null;
635
+
636
+ }//end cleanUp()
637
+
638
+
639
+ /**
640
+ * Tokenizes the file and prepares it for the test run.
641
+ *
642
+ * @param string $contents The contents to parse. If NULL, the content
643
+ * is taken from the file system.
644
+ *
645
+ * @return void
646
+ */
647
+ private function _parse($contents=null)
648
+ {
649
+ if ($contents === null && empty($this->_tokens) === false) {
650
+ // File has already been parsed.
651
+ return;
652
+ }
653
+
654
+ $stdin = false;
655
+ $cliValues = $this->phpcs->cli->getCommandLineValues();
656
+ if (empty($cliValues['files']) === true) {
657
+ $stdin = true;
658
+ }
659
+
660
+ // Determine the tokenizer from the file extension.
661
+ $fileParts = explode('.', $this->_file);
662
+ $extension = array_pop($fileParts);
663
+ if (isset($this->phpcs->allowedFileExtensions[$extension]) === true) {
664
+ $tokenizerClass = 'PHP_CodeSniffer_Tokenizers_'.$this->phpcs->allowedFileExtensions[$extension];
665
+ $this->tokenizerType = $this->phpcs->allowedFileExtensions[$extension];
666
+ } else if (isset($this->phpcs->defaultFileExtensions[$extension]) === true) {
667
+ $tokenizerClass = 'PHP_CodeSniffer_Tokenizers_'.$this->phpcs->defaultFileExtensions[$extension];
668
+ $this->tokenizerType = $this->phpcs->defaultFileExtensions[$extension];
669
+ } else {
670
+ // Revert to default.
671
+ $tokenizerClass = 'PHP_CodeSniffer_Tokenizers_'.$this->tokenizerType;
672
+ }
673
+
674
+ $tokenizer = new $tokenizerClass();
675
+ $this->tokenizer = $tokenizer;
676
+
677
+ if ($contents === null) {
678
+ $contents = file_get_contents($this->_file);
679
+ }
680
+
681
+ try {
682
+ $tabWidth = null;
683
+ $encoding = null;
684
+ if (defined('PHP_CODESNIFFER_IN_TESTS') === true) {
685
+ $cliValues = $this->phpcs->cli->getCommandLineValues();
686
+ if (isset($cliValues['tabWidth']) === true) {
687
+ $tabWidth = $cliValues['tabWidth'];
688
+ }
689
+
690
+ if (isset($cliValues['encoding']) === true) {
691
+ $encoding = $cliValues['encoding'];
692
+ }
693
+ }
694
+
695
+ $this->_tokens = self::tokenizeString($contents, $tokenizer, $this->eolChar, $tabWidth, $encoding);
696
+ } catch (PHP_CodeSniffer_Exception $e) {
697
+ $this->addWarning($e->getMessage(), null, 'Internal.Tokenizer.Exception');
698
+ if (PHP_CODESNIFFER_VERBOSITY > 0 || (PHP_CODESNIFFER_CBF === true && $stdin === false)) {
699
+ echo "[$this->tokenizerType => tokenizer error]... ";
700
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
701
+ echo PHP_EOL;
702
+ }
703
+ }
704
+
705
+ return;
706
+ }//end try
707
+
708
+ $this->numTokens = count($this->_tokens);
709
+
710
+ // Check for mixed line endings as these can cause tokenizer errors and we
711
+ // should let the user know that the results they get may be incorrect.
712
+ // This is done by removing all backslashes, removing the newline char we
713
+ // detected, then converting newlines chars into text. If any backslashes
714
+ // are left at the end, we have additional newline chars in use.
715
+ $contents = str_replace('\\', '', $contents);
716
+ $contents = str_replace($this->eolChar, '', $contents);
717
+ $contents = str_replace("\n", '\n', $contents);
718
+ $contents = str_replace("\r", '\r', $contents);
719
+ if (strpos($contents, '\\') !== false) {
720
+ $error = 'File has mixed line endings; this may cause incorrect results';
721
+ $this->addWarning($error, 0, 'Internal.LineEndings.Mixed');
722
+ }
723
+
724
+ if (PHP_CODESNIFFER_VERBOSITY > 0 || (PHP_CODESNIFFER_CBF === true && $stdin === false)) {
725
+ if ($this->numTokens === 0) {
726
+ $numLines = 0;
727
+ } else {
728
+ $numLines = $this->_tokens[($this->numTokens - 1)]['line'];
729
+ }
730
+
731
+ echo "[$this->tokenizerType => $this->numTokens tokens in $numLines lines]... ";
732
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
733
+ echo PHP_EOL;
734
+ }
735
+ }
736
+
737
+ }//end _parse()
738
+
739
+
740
+ /**
741
+ * Opens a file and detects the EOL character being used.
742
+ *
743
+ * @param string $file The full path to the file.
744
+ * @param string $contents The contents to parse. If NULL, the content
745
+ * is taken from the file system.
746
+ *
747
+ * @return string
748
+ * @throws PHP_CodeSniffer_Exception If $file could not be opened.
749
+ */
750
+ public static function detectLineEndings($file, $contents=null)
751
+ {
752
+ if ($contents === null) {
753
+ // Determine the newline character being used in this file.
754
+ // Will be either \r, \r\n or \n.
755
+ if (is_readable($file) === false) {
756
+ $error = 'Error opening file; file no longer exists or you do not have access to read the file';
757
+ throw new PHP_CodeSniffer_Exception($error);
758
+ } else {
759
+ $handle = fopen($file, 'r');
760
+ if ($handle === false) {
761
+ $error = 'Error opening file; could not auto-detect line endings';
762
+ throw new PHP_CodeSniffer_Exception($error);
763
+ }
764
+ }
765
+
766
+ $firstLine = fgets($handle);
767
+ fclose($handle);
768
+
769
+ $eolChar = substr($firstLine, -1);
770
+ if ($eolChar === "\n") {
771
+ $secondLastChar = substr($firstLine, -2, 1);
772
+ if ($secondLastChar === "\r") {
773
+ $eolChar = "\r\n";
774
+ }
775
+ } else if ($eolChar !== "\r") {
776
+ // Must not be an EOL char at the end of the line.
777
+ // Probably a one-line file, so assume \n as it really
778
+ // doesn't matter considering there are no newlines.
779
+ $eolChar = "\n";
780
+ }
781
+ } else {
782
+ if (preg_match("/\r\n?|\n/", $contents, $matches) !== 1) {
783
+ // Assuming there are no newlines.
784
+ $eolChar = "\n";
785
+ } else {
786
+ $eolChar = $matches[0];
787
+ }
788
+ }//end if
789
+
790
+ return $eolChar;
791
+
792
+ }//end detectLineEndings()
793
+
794
+
795
+ /**
796
+ * Records an error against a specific token in the file.
797
+ *
798
+ * @param string $error The error message.
799
+ * @param int $stackPtr The stack position where the error occurred.
800
+ * @param string $code A violation code unique to the sniff message.
801
+ * @param array $data Replacements for the error message.
802
+ * @param int $severity The severity level for this error. A value of 0
803
+ * will be converted into the default severity level.
804
+ * @param boolean $fixable Can the error be fixed by the sniff?
805
+ *
806
+ * @return boolean
807
+ */
808
+ public function addError(
809
+ $error,
810
+ $stackPtr,
811
+ $code='',
812
+ $data=array(),
813
+ $severity=0,
814
+ $fixable=false
815
+ ) {
816
+ if ($stackPtr === null) {
817
+ $line = 1;
818
+ $column = 1;
819
+ } else {
820
+ $line = $this->_tokens[$stackPtr]['line'];
821
+ $column = $this->_tokens[$stackPtr]['column'];
822
+ }
823
+
824
+ return $this->_addError($error, $line, $column, $code, $data, $severity, $fixable);
825
+
826
+ }//end addError()
827
+
828
+
829
+ /**
830
+ * Records a warning against a specific token in the file.
831
+ *
832
+ * @param string $warning The error message.
833
+ * @param int $stackPtr The stack position where the error occurred.
834
+ * @param string $code A violation code unique to the sniff message.
835
+ * @param array $data Replacements for the warning message.
836
+ * @param int $severity The severity level for this warning. A value of 0
837
+ * will be converted into the default severity level.
838
+ * @param boolean $fixable Can the warning be fixed by the sniff?
839
+ *
840
+ * @return boolean
841
+ */
842
+ public function addWarning(
843
+ $warning,
844
+ $stackPtr,
845
+ $code='',
846
+ $data=array(),
847
+ $severity=0,
848
+ $fixable=false
849
+ ) {
850
+ if ($stackPtr === null) {
851
+ $line = 1;
852
+ $column = 1;
853
+ } else {
854
+ $line = $this->_tokens[$stackPtr]['line'];
855
+ $column = $this->_tokens[$stackPtr]['column'];
856
+ }
857
+
858
+ return $this->_addWarning($warning, $line, $column, $code, $data, $severity, $fixable);
859
+
860
+ }//end addWarning()
861
+
862
+
863
+ /**
864
+ * Records an error against a specific line in the file.
865
+ *
866
+ * @param string $error The error message.
867
+ * @param int $line The line on which the error occurred.
868
+ * @param string $code A violation code unique to the sniff message.
869
+ * @param array $data Replacements for the error message.
870
+ * @param int $severity The severity level for this error. A value of 0
871
+ * will be converted into the default severity level.
872
+ *
873
+ * @return boolean
874
+ */
875
+ public function addErrorOnLine(
876
+ $error,
877
+ $line,
878
+ $code='',
879
+ $data=array(),
880
+ $severity=0
881
+ ) {
882
+ return $this->_addError($error, $line, 1, $code, $data, $severity, false);
883
+
884
+ }//end addErrorOnLine()
885
+
886
+
887
+ /**
888
+ * Records a warning against a specific token in the file.
889
+ *
890
+ * @param string $warning The error message.
891
+ * @param int $line The line on which the warning occurred.
892
+ * @param string $code A violation code unique to the sniff message.
893
+ * @param array $data Replacements for the warning message.
894
+ * @param int $severity The severity level for this warning. A value of 0
895
+ * will be converted into the default severity level.
896
+ *
897
+ * @return boolean
898
+ */
899
+ public function addWarningOnLine(
900
+ $warning,
901
+ $line,
902
+ $code='',
903
+ $data=array(),
904
+ $severity=0
905
+ ) {
906
+ return $this->_addWarning($warning, $line, 1, $code, $data, $severity, false);
907
+
908
+ }//end addWarningOnLine()
909
+
910
+
911
+ /**
912
+ * Records a fixable error against a specific token in the file.
913
+ *
914
+ * Returns true if the error was recorded and should be fixed.
915
+ *
916
+ * @param string $error The error message.
917
+ * @param int $stackPtr The stack position where the error occurred.
918
+ * @param string $code A violation code unique to the sniff message.
919
+ * @param array $data Replacements for the error message.
920
+ * @param int $severity The severity level for this error. A value of 0
921
+ * will be converted into the default severity level.
922
+ *
923
+ * @return boolean
924
+ */
925
+ public function addFixableError(
926
+ $error,
927
+ $stackPtr,
928
+ $code='',
929
+ $data=array(),
930
+ $severity=0
931
+ ) {
932
+ $recorded = $this->addError($error, $stackPtr, $code, $data, $severity, true);
933
+ if ($recorded === true && $this->fixer->enabled === true) {
934
+ return true;
935
+ }
936
+
937
+ return false;
938
+
939
+ }//end addFixableError()
940
+
941
+
942
+ /**
943
+ * Records a fixable warning against a specific token in the file.
944
+ *
945
+ * Returns true if the warning was recorded and should be fixed.
946
+ *
947
+ * @param string $warning The error message.
948
+ * @param int $stackPtr The stack position where the error occurred.
949
+ * @param string $code A violation code unique to the sniff message.
950
+ * @param array $data Replacements for the warning message.
951
+ * @param int $severity The severity level for this warning. A value of 0
952
+ * will be converted into the default severity level.
953
+ *
954
+ * @return boolean
955
+ */
956
+ public function addFixableWarning(
957
+ $warning,
958
+ $stackPtr,
959
+ $code='',
960
+ $data=array(),
961
+ $severity=0
962
+ ) {
963
+ $recorded = $this->addWarning($warning, $stackPtr, $code, $data, $severity, true);
964
+ if ($recorded === true && $this->fixer->enabled === true) {
965
+ return true;
966
+ }
967
+
968
+ return false;
969
+
970
+ }//end addFixableWarning()
971
+
972
+
973
+ /**
974
+ * Adds an error to the error stack.
975
+ *
976
+ * @param string $error The error message.
977
+ * @param int $line The line on which the error occurred.
978
+ * @param int $column The column at which the error occurred.
979
+ * @param string $code A violation code unique to the sniff message.
980
+ * @param array $data Replacements for the error message.
981
+ * @param int $severity The severity level for this error. A value of 0
982
+ * will be converted into the default severity level.
983
+ * @param boolean $fixable Can the error be fixed by the sniff?
984
+ *
985
+ * @return boolean
986
+ */
987
+ private function _addError($error, $line, $column, $code, $data, $severity, $fixable)
988
+ {
989
+ if (isset(self::$_ignoredLines[$line]) === true) {
990
+ return false;
991
+ }
992
+
993
+ // Work out which sniff generated the error.
994
+ if (substr($code, 0, 9) === 'Internal.') {
995
+ // Any internal message.
996
+ $sniffCode = $code;
997
+ } else {
998
+ $parts = explode('_', str_replace('\\', '_', $this->_activeListener));
999
+ if (isset($parts[3]) === true) {
1000
+ $sniff = $parts[0].'.'.$parts[2].'.'.$parts[3];
1001
+
1002
+ // Remove "Sniff" from the end.
1003
+ $sniff = substr($sniff, 0, -5);
1004
+ } else {
1005
+ $sniff = 'unknownSniff';
1006
+ }
1007
+
1008
+ $sniffCode = $sniff;
1009
+ if ($code !== '') {
1010
+ $sniffCode .= '.'.$code;
1011
+ }
1012
+ }//end if
1013
+
1014
+ // If we know this sniff code is being ignored for this file, return early.
1015
+ if (isset($this->_ignoredCodes[$sniffCode]) === true) {
1016
+ return false;
1017
+ }
1018
+
1019
+ // Make sure this message type has not been set to "warning".
1020
+ if (isset($this->ruleset[$sniffCode]['type']) === true
1021
+ && $this->ruleset[$sniffCode]['type'] === 'warning'
1022
+ ) {
1023
+ // Pass this off to the warning handler.
1024
+ return $this->_addWarning($error, $line, $column, $code, $data, $severity, $fixable);
1025
+ } else if ($this->phpcs->cli->errorSeverity === 0) {
1026
+ // Don't bother doing any processing as errors are just going to
1027
+ // be hidden in the reports anyway.
1028
+ return false;
1029
+ }
1030
+
1031
+ // Make sure we are interested in this severity level.
1032
+ if (isset($this->ruleset[$sniffCode]['severity']) === true) {
1033
+ $severity = $this->ruleset[$sniffCode]['severity'];
1034
+ } else if ($severity === 0) {
1035
+ $severity = PHPCS_DEFAULT_ERROR_SEV;
1036
+ }
1037
+
1038
+ if ($this->phpcs->cli->errorSeverity > $severity) {
1039
+ return false;
1040
+ }
1041
+
1042
+ // Make sure we are not ignoring this file.
1043
+ $patterns = $this->phpcs->getIgnorePatterns($sniffCode);
1044
+ foreach ($patterns as $pattern => $type) {
1045
+ // While there is support for a type of each pattern
1046
+ // (absolute or relative) we don't actually support it here.
1047
+ $replacements = array(
1048
+ '\\,' => ',',
1049
+ '*' => '.*',
1050
+ );
1051
+
1052
+ // We assume a / directory separator, as do the exclude rules
1053
+ // most developers write, so we need a special case for any system
1054
+ // that is different.
1055
+ if (DIRECTORY_SEPARATOR === '\\') {
1056
+ $replacements['/'] = '\\\\';
1057
+ }
1058
+
1059
+ $pattern = '`'.strtr($pattern, $replacements).'`i';
1060
+ if (preg_match($pattern, $this->_file) === 1) {
1061
+ $this->_ignoredCodes[$sniffCode] = true;
1062
+ return false;
1063
+ }
1064
+ }//end foreach
1065
+
1066
+ $this->_errorCount++;
1067
+ if ($fixable === true) {
1068
+ $this->_fixableCount++;
1069
+ }
1070
+
1071
+ if ($this->_recordErrors === false) {
1072
+ if (isset($this->_errors[$line]) === false) {
1073
+ $this->_errors[$line] = 0;
1074
+ }
1075
+
1076
+ $this->_errors[$line]++;
1077
+ return true;
1078
+ }
1079
+
1080
+ // Work out the error message.
1081
+ if (isset($this->ruleset[$sniffCode]['message']) === true) {
1082
+ $error = $this->ruleset[$sniffCode]['message'];
1083
+ }
1084
+
1085
+ if (empty($data) === true) {
1086
+ $message = $error;
1087
+ } else {
1088
+ $message = vsprintf($error, $data);
1089
+ }
1090
+
1091
+ if (isset($this->_errors[$line]) === false) {
1092
+ $this->_errors[$line] = array();
1093
+ }
1094
+
1095
+ if (isset($this->_errors[$line][$column]) === false) {
1096
+ $this->_errors[$line][$column] = array();
1097
+ }
1098
+
1099
+ $this->_errors[$line][$column][] = array(
1100
+ 'message' => $message,
1101
+ 'source' => $sniffCode,
1102
+ 'severity' => $severity,
1103
+ 'fixable' => $fixable,
1104
+ );
1105
+
1106
+ if (PHP_CODESNIFFER_VERBOSITY > 1
1107
+ && $this->fixer->enabled === true
1108
+ && $fixable === true
1109
+ ) {
1110
+ @ob_end_clean();
1111
+ echo "\tE: [Line $line] $message ($sniffCode)".PHP_EOL;
1112
+ ob_start();
1113
+ }
1114
+
1115
+ return true;
1116
+
1117
+ }//end _addError()
1118
+
1119
+
1120
+ /**
1121
+ * Adds an warning to the warning stack.
1122
+ *
1123
+ * @param string $warning The error message.
1124
+ * @param int $line The line on which the warning occurred.
1125
+ * @param int $column The column at which the warning occurred.
1126
+ * @param string $code A violation code unique to the sniff message.
1127
+ * @param array $data Replacements for the warning message.
1128
+ * @param int $severity The severity level for this warning. A value of 0
1129
+ * will be converted into the default severity level.
1130
+ * @param boolean $fixable Can the warning be fixed by the sniff?
1131
+ *
1132
+ * @return boolean
1133
+ */
1134
+ private function _addWarning($warning, $line, $column, $code, $data, $severity, $fixable)
1135
+ {
1136
+ if (isset(self::$_ignoredLines[$line]) === true) {
1137
+ return false;
1138
+ }
1139
+
1140
+ // Work out which sniff generated the warning.
1141
+ if (substr($code, 0, 9) === 'Internal.') {
1142
+ // Any internal message.
1143
+ $sniffCode = $code;
1144
+ } else {
1145
+ $parts = explode('_', str_replace('\\', '_', $this->_activeListener));
1146
+ if (isset($parts[3]) === true) {
1147
+ $sniff = $parts[0].'.'.$parts[2].'.'.$parts[3];
1148
+
1149
+ // Remove "Sniff" from the end.
1150
+ $sniff = substr($sniff, 0, -5);
1151
+ } else {
1152
+ $sniff = 'unknownSniff';
1153
+ }
1154
+
1155
+ $sniffCode = $sniff;
1156
+ if ($code !== '') {
1157
+ $sniffCode .= '.'.$code;
1158
+ }
1159
+ }//end if
1160
+
1161
+ // If we know this sniff code is being ignored for this file, return early.
1162
+ if (isset($this->_ignoredCodes[$sniffCode]) === true) {
1163
+ return false;
1164
+ }
1165
+
1166
+ // Make sure this message type has not been set to "error".
1167
+ if (isset($this->ruleset[$sniffCode]['type']) === true
1168
+ && $this->ruleset[$sniffCode]['type'] === 'error'
1169
+ ) {
1170
+ // Pass this off to the error handler.
1171
+ return $this->_addError($warning, $line, $column, $code, $data, $severity, $fixable);
1172
+ } else if ($this->phpcs->cli->warningSeverity === 0) {
1173
+ // Don't bother doing any processing as warnings are just going to
1174
+ // be hidden in the reports anyway.
1175
+ return false;
1176
+ }
1177
+
1178
+ // Make sure we are interested in this severity level.
1179
+ if (isset($this->ruleset[$sniffCode]['severity']) === true) {
1180
+ $severity = $this->ruleset[$sniffCode]['severity'];
1181
+ } else if ($severity === 0) {
1182
+ $severity = PHPCS_DEFAULT_WARN_SEV;
1183
+ }
1184
+
1185
+ if ($this->phpcs->cli->warningSeverity > $severity) {
1186
+ return false;
1187
+ }
1188
+
1189
+ // Make sure we are not ignoring this file.
1190
+ $patterns = $this->phpcs->getIgnorePatterns($sniffCode);
1191
+ foreach ($patterns as $pattern => $type) {
1192
+ // While there is support for a type of each pattern
1193
+ // (absolute or relative) we don't actually support it here.
1194
+ $replacements = array(
1195
+ '\\,' => ',',
1196
+ '*' => '.*',
1197
+ );
1198
+
1199
+ // We assume a / directory separator, as do the exclude rules
1200
+ // most developers write, so we need a special case for any system
1201
+ // that is different.
1202
+ if (DIRECTORY_SEPARATOR === '\\') {
1203
+ $replacements['/'] = '\\\\';
1204
+ }
1205
+
1206
+ $pattern = '`'.strtr($pattern, $replacements).'`i';
1207
+ if (preg_match($pattern, $this->_file) === 1) {
1208
+ $this->_ignoredCodes[$sniffCode] = true;
1209
+ return false;
1210
+ }
1211
+ }//end foreach
1212
+
1213
+ $this->_warningCount++;
1214
+ if ($fixable === true) {
1215
+ $this->_fixableCount++;
1216
+ }
1217
+
1218
+ if ($this->_recordErrors === false) {
1219
+ if (isset($this->_warnings[$line]) === false) {
1220
+ $this->_warnings[$line] = 0;
1221
+ }
1222
+
1223
+ $this->_warnings[$line]++;
1224
+ return true;
1225
+ }
1226
+
1227
+ // Work out the warning message.
1228
+ if (isset($this->ruleset[$sniffCode]['message']) === true) {
1229
+ $warning = $this->ruleset[$sniffCode]['message'];
1230
+ }
1231
+
1232
+ if (empty($data) === true) {
1233
+ $message = $warning;
1234
+ } else {
1235
+ $message = vsprintf($warning, $data);
1236
+ }
1237
+
1238
+ if (isset($this->_warnings[$line]) === false) {
1239
+ $this->_warnings[$line] = array();
1240
+ }
1241
+
1242
+ if (isset($this->_warnings[$line][$column]) === false) {
1243
+ $this->_warnings[$line][$column] = array();
1244
+ }
1245
+
1246
+ $this->_warnings[$line][$column][] = array(
1247
+ 'message' => $message,
1248
+ 'source' => $sniffCode,
1249
+ 'severity' => $severity,
1250
+ 'fixable' => $fixable,
1251
+ );
1252
+
1253
+ if (PHP_CODESNIFFER_VERBOSITY > 1
1254
+ && $this->fixer->enabled === true
1255
+ && $fixable === true
1256
+ ) {
1257
+ @ob_end_clean();
1258
+ echo "\tW: $message ($sniffCode)".PHP_EOL;
1259
+ ob_start();
1260
+ }
1261
+
1262
+ return true;
1263
+
1264
+ }//end _addWarning()
1265
+
1266
+
1267
+ /**
1268
+ * Adds an warning to the warning stack.
1269
+ *
1270
+ * @param int $stackPtr The stack position where the metric was recorded.
1271
+ * @param string $metric The name of the metric being recorded.
1272
+ * @param string $value The value of the metric being recorded.
1273
+ *
1274
+ * @return boolean
1275
+ */
1276
+ public function recordMetric($stackPtr, $metric, $value)
1277
+ {
1278
+ if (isset($this->_metrics[$metric]) === false) {
1279
+ $this->_metrics[$metric] = array(
1280
+ 'values' => array(
1281
+ $value => array($stackPtr),
1282
+ ),
1283
+ );
1284
+ } else {
1285
+ if (isset($this->_metrics[$metric]['values'][$value]) === false) {
1286
+ $this->_metrics[$metric]['values'][$value] = array($stackPtr);
1287
+ } else {
1288
+ $this->_metrics[$metric]['values'][$value][] = $stackPtr;
1289
+ }
1290
+ }
1291
+
1292
+ return true;
1293
+
1294
+ }//end recordMetric()
1295
+
1296
+
1297
+ /**
1298
+ * Returns the number of errors raised.
1299
+ *
1300
+ * @return int
1301
+ */
1302
+ public function getErrorCount()
1303
+ {
1304
+ return $this->_errorCount;
1305
+
1306
+ }//end getErrorCount()
1307
+
1308
+
1309
+ /**
1310
+ * Returns the number of warnings raised.
1311
+ *
1312
+ * @return int
1313
+ */
1314
+ public function getWarningCount()
1315
+ {
1316
+ return $this->_warningCount;
1317
+
1318
+ }//end getWarningCount()
1319
+
1320
+
1321
+ /**
1322
+ * Returns the number of successes recorded.
1323
+ *
1324
+ * @return int
1325
+ */
1326
+ public function getSuccessCount()
1327
+ {
1328
+ return $this->_successCount;
1329
+
1330
+ }//end getSuccessCount()
1331
+
1332
+
1333
+ /**
1334
+ * Returns the number of fixable errors/warnings raised.
1335
+ *
1336
+ * @return int
1337
+ */
1338
+ public function getFixableCount()
1339
+ {
1340
+ return $this->_fixableCount;
1341
+
1342
+ }//end getFixableCount()
1343
+
1344
+
1345
+ /**
1346
+ * Returns the list of ignored lines.
1347
+ *
1348
+ * @return array
1349
+ */
1350
+ public function getIgnoredLines()
1351
+ {
1352
+ return self::$_ignoredLines;
1353
+
1354
+ }//end getIgnoredLines()
1355
+
1356
+
1357
+ /**
1358
+ * Returns the errors raised from processing this file.
1359
+ *
1360
+ * @return array
1361
+ */
1362
+ public function getErrors()
1363
+ {
1364
+ return $this->_errors;
1365
+
1366
+ }//end getErrors()
1367
+
1368
+
1369
+ /**
1370
+ * Returns the warnings raised from processing this file.
1371
+ *
1372
+ * @return array
1373
+ */
1374
+ public function getWarnings()
1375
+ {
1376
+ return $this->_warnings;
1377
+
1378
+ }//end getWarnings()
1379
+
1380
+
1381
+ /**
1382
+ * Returns the metrics found while processing this file.
1383
+ *
1384
+ * @return array
1385
+ */
1386
+ public function getMetrics()
1387
+ {
1388
+ return $this->_metrics;
1389
+
1390
+ }//end getMetrics()
1391
+
1392
+
1393
+ /**
1394
+ * Returns the absolute filename of this file.
1395
+ *
1396
+ * @return string
1397
+ */
1398
+ public function getFilename()
1399
+ {
1400
+ return $this->_file;
1401
+
1402
+ }//end getFilename()
1403
+
1404
+
1405
+ /**
1406
+ * Creates an array of tokens when given some PHP code.
1407
+ *
1408
+ * Starts by using token_get_all() but does a lot of extra processing
1409
+ * to insert information about the context of the token.
1410
+ *
1411
+ * @param string $string The string to tokenize.
1412
+ * @param object $tokenizer A tokenizer class to use to tokenize the string.
1413
+ * @param string $eolChar The EOL character to use for splitting strings.
1414
+ * @param int $tabWidth The number of spaces each tab respresents.
1415
+ * @param string $encoding The charset of the sniffed file.
1416
+ *
1417
+ * @throws PHP_CodeSniffer_Exception If the file cannot be processed.
1418
+ * @return array
1419
+ */
1420
+ public static function tokenizeString($string, $tokenizer, $eolChar='\n', $tabWidth=null, $encoding=null)
1421
+ {
1422
+ // Minified files often have a very large number of characters per line
1423
+ // and cause issues when tokenizing.
1424
+ if (property_exists($tokenizer, 'skipMinified') === true
1425
+ && $tokenizer->skipMinified === true
1426
+ ) {
1427
+ $numChars = strlen($string);
1428
+ $numLines = (substr_count($string, $eolChar) + 1);
1429
+ $average = ($numChars / $numLines);
1430
+ if ($average > 100) {
1431
+ throw new PHP_CodeSniffer_Exception('File appears to be minified and cannot be processed');
1432
+ }
1433
+ }
1434
+
1435
+ $tokens = $tokenizer->tokenizeString($string, $eolChar);
1436
+
1437
+ if ($tabWidth === null) {
1438
+ $tabWidth = PHP_CODESNIFFER_TAB_WIDTH;
1439
+ }
1440
+
1441
+ if ($encoding === null) {
1442
+ $encoding = PHP_CODESNIFFER_ENCODING;
1443
+ }
1444
+
1445
+ self::_createPositionMap($tokens, $tokenizer, $eolChar, $encoding, $tabWidth);
1446
+ self::_createTokenMap($tokens, $tokenizer, $eolChar);
1447
+ self::_createParenthesisNestingMap($tokens, $tokenizer, $eolChar);
1448
+ self::_createScopeMap($tokens, $tokenizer, $eolChar);
1449
+
1450
+ self::_createLevelMap($tokens, $tokenizer, $eolChar);
1451
+
1452
+ // Allow the tokenizer to do additional processing if required.
1453
+ $tokenizer->processAdditional($tokens, $eolChar);
1454
+
1455
+ return $tokens;
1456
+
1457
+ }//end tokenizeString()
1458
+
1459
+
1460
+ /**
1461
+ * Sets token position information.
1462
+ *
1463
+ * Can also convert tabs into spaces. Each tab can represent between
1464
+ * 1 and $width spaces, so this cannot be a straight string replace.
1465
+ *
1466
+ * @param array $tokens The array of tokens to process.
1467
+ * @param object $tokenizer The tokenizer being used to process this file.
1468
+ * @param string $eolChar The EOL character to use for splitting strings.
1469
+ * @param string $encoding The charset of the sniffed file.
1470
+ * @param int $tabWidth The number of spaces that each tab represents.
1471
+ * Set to 0 to disable tab replacement.
1472
+ *
1473
+ * @return void
1474
+ */
1475
+ private static function _createPositionMap(&$tokens, $tokenizer, $eolChar, $encoding, $tabWidth)
1476
+ {
1477
+ $currColumn = 1;
1478
+ $lineNumber = 1;
1479
+ $eolLen = (strlen($eolChar) * -1);
1480
+ $tokenizerType = get_class($tokenizer);
1481
+ $ignoring = false;
1482
+ $inTests = defined('PHP_CODESNIFFER_IN_TESTS');
1483
+
1484
+ $checkEncoding = false;
1485
+ if ($encoding !== 'iso-8859-1' && function_exists('iconv_strlen') === true) {
1486
+ $checkEncoding = true;
1487
+ }
1488
+
1489
+ $tokensWithTabs = array(
1490
+ T_WHITESPACE => true,
1491
+ T_COMMENT => true,
1492
+ T_DOC_COMMENT => true,
1493
+ T_DOC_COMMENT_WHITESPACE => true,
1494
+ T_DOC_COMMENT_STRING => true,
1495
+ T_CONSTANT_ENCAPSED_STRING => true,
1496
+ T_DOUBLE_QUOTED_STRING => true,
1497
+ T_HEREDOC => true,
1498
+ T_NOWDOC => true,
1499
+ T_INLINE_HTML => true,
1500
+ );
1501
+
1502
+ $numTokens = count($tokens);
1503
+ for ($i = 0; $i < $numTokens; $i++) {
1504
+ $tokens[$i]['line'] = $lineNumber;
1505
+ $tokens[$i]['column'] = $currColumn;
1506
+
1507
+ if ($tokenizerType === 'PHP_CodeSniffer_Tokenizers_PHP'
1508
+ && isset(PHP_CodeSniffer_Tokens::$knownLengths[$tokens[$i]['code']]) === true
1509
+ ) {
1510
+ // There are no tabs in the tokens we know the length of.
1511
+ $length = PHP_CodeSniffer_Tokens::$knownLengths[$tokens[$i]['code']];
1512
+ $currColumn += $length;
1513
+ } else if ($tabWidth === 0
1514
+ || isset($tokensWithTabs[$tokens[$i]['code']]) === false
1515
+ || strpos($tokens[$i]['content'], "\t") === false
1516
+ ) {
1517
+ // There are no tabs in this content, or we aren't replacing them.
1518
+ if ($checkEncoding === true) {
1519
+ // Not using the default encoding, so take a bit more care.
1520
+ $length = @iconv_strlen($tokens[$i]['content'], $encoding);
1521
+ if ($length === false) {
1522
+ // String contained invalid characters, so revert to default.
1523
+ $length = strlen($tokens[$i]['content']);
1524
+ }
1525
+ } else {
1526
+ $length = strlen($tokens[$i]['content']);
1527
+ }
1528
+
1529
+ $currColumn += $length;
1530
+ } else {
1531
+ if (str_replace("\t", '', $tokens[$i]['content']) === '') {
1532
+ // String only contains tabs, so we can shortcut the process.
1533
+ $numTabs = strlen($tokens[$i]['content']);
1534
+
1535
+ $newContent = '';
1536
+ $firstTabSize = ($tabWidth - ($currColumn % $tabWidth) + 1);
1537
+ $length = ($firstTabSize + ($tabWidth * ($numTabs - 1)));
1538
+ $currColumn += $length;
1539
+ $newContent = str_repeat(' ', $length);
1540
+ } else {
1541
+ // We need to determine the length of each tab.
1542
+ $tabs = explode("\t", $tokens[$i]['content']);
1543
+
1544
+ $numTabs = (count($tabs) - 1);
1545
+ $tabNum = 0;
1546
+ $newContent = '';
1547
+ $length = 0;
1548
+
1549
+ foreach ($tabs as $content) {
1550
+ if ($content !== '') {
1551
+ $newContent .= $content;
1552
+ if ($checkEncoding === true) {
1553
+ // Not using the default encoding, so take a bit more care.
1554
+ $contentLength = @iconv_strlen($content, $encoding);
1555
+ if ($contentLength === false) {
1556
+ // String contained invalid characters, so revert to default.
1557
+ $contentLength = strlen($content);
1558
+ }
1559
+ } else {
1560
+ $contentLength = strlen($content);
1561
+ }
1562
+
1563
+ $currColumn += $contentLength;
1564
+ $length += $contentLength;
1565
+ }
1566
+
1567
+ // The last piece of content does not have a tab after it.
1568
+ if ($tabNum === $numTabs) {
1569
+ break;
1570
+ }
1571
+
1572
+ // Process the tab that comes after the content.
1573
+ $lastCurrColumn = $currColumn;
1574
+ $tabNum++;
1575
+
1576
+ // Move the pointer to the next tab stop.
1577
+ if (($currColumn % $tabWidth) === 0) {
1578
+ // This is the first tab, and we are already at a
1579
+ // tab stop, so this tab counts as a single space.
1580
+ $currColumn++;
1581
+ } else {
1582
+ $currColumn++;
1583
+ while (($currColumn % $tabWidth) !== 0) {
1584
+ $currColumn++;
1585
+ }
1586
+
1587
+ $currColumn++;
1588
+ }
1589
+
1590
+ $length += ($currColumn - $lastCurrColumn);
1591
+ $newContent .= str_repeat(' ', ($currColumn - $lastCurrColumn));
1592
+ }//end foreach
1593
+ }//end if
1594
+
1595
+ $tokens[$i]['orig_content'] = $tokens[$i]['content'];
1596
+ $tokens[$i]['content'] = $newContent;
1597
+ }//end if
1598
+
1599
+ $tokens[$i]['length'] = $length;
1600
+
1601
+ if (isset(PHP_CodeSniffer_Tokens::$knownLengths[$tokens[$i]['code']]) === false
1602
+ && strpos($tokens[$i]['content'], $eolChar) !== false
1603
+ ) {
1604
+ $lineNumber++;
1605
+ $currColumn = 1;
1606
+
1607
+ // Newline chars are not counted in the token length.
1608
+ $tokens[$i]['length'] += $eolLen;
1609
+ }
1610
+
1611
+ if ($tokens[$i]['code'] === T_COMMENT
1612
+ || $tokens[$i]['code'] === T_DOC_COMMENT_TAG
1613
+ || ($inTests === true && $tokens[$i]['code'] === T_INLINE_HTML)
1614
+ ) {
1615
+ if (strpos($tokens[$i]['content'], '@codingStandards') !== false) {
1616
+ if ($ignoring === false
1617
+ && strpos($tokens[$i]['content'], '@codingStandardsIgnoreStart') !== false
1618
+ ) {
1619
+ $ignoring = true;
1620
+ } else if ($ignoring === true
1621
+ && strpos($tokens[$i]['content'], '@codingStandardsIgnoreEnd') !== false
1622
+ ) {
1623
+ $ignoring = false;
1624
+ // Ignore this comment too.
1625
+ self::$_ignoredLines[$tokens[$i]['line']] = true;
1626
+ } else if ($ignoring === false
1627
+ && strpos($tokens[$i]['content'], '@codingStandardsIgnoreLine') !== false
1628
+ ) {
1629
+ self::$_ignoredLines[($tokens[$i]['line'] + 1)] = true;
1630
+ // Ignore this comment too.
1631
+ self::$_ignoredLines[$tokens[$i]['line']] = true;
1632
+ }
1633
+ }
1634
+ }//end if
1635
+
1636
+ if ($ignoring === true) {
1637
+ self::$_ignoredLines[$tokens[$i]['line']] = true;
1638
+ }
1639
+ }//end for
1640
+
1641
+ }//end _createPositionMap()
1642
+
1643
+
1644
+ /**
1645
+ * Creates a map of brackets positions.
1646
+ *
1647
+ * @param array $tokens The array of tokens to process.
1648
+ * @param object $tokenizer The tokenizer being used to process this file.
1649
+ * @param string $eolChar The EOL character to use for splitting strings.
1650
+ *
1651
+ * @return void
1652
+ */
1653
+ private static function _createTokenMap(&$tokens, $tokenizer, $eolChar)
1654
+ {
1655
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1656
+ echo "\t*** START TOKEN MAP ***".PHP_EOL;
1657
+ }
1658
+
1659
+ $squareOpeners = array();
1660
+ $curlyOpeners = array();
1661
+ $numTokens = count($tokens);
1662
+
1663
+ $openers = array();
1664
+ $openOwner = null;
1665
+
1666
+ for ($i = 0; $i < $numTokens; $i++) {
1667
+ /*
1668
+ Parenthesis mapping.
1669
+ */
1670
+
1671
+ if (isset(PHP_CodeSniffer_Tokens::$parenthesisOpeners[$tokens[$i]['code']]) === true) {
1672
+ $tokens[$i]['parenthesis_opener'] = null;
1673
+ $tokens[$i]['parenthesis_closer'] = null;
1674
+ $tokens[$i]['parenthesis_owner'] = $i;
1675
+ $openOwner = $i;
1676
+ } else if ($tokens[$i]['code'] === T_OPEN_PARENTHESIS) {
1677
+ $openers[] = $i;
1678
+ $tokens[$i]['parenthesis_opener'] = $i;
1679
+ if ($openOwner !== null) {
1680
+ $tokens[$openOwner]['parenthesis_opener'] = $i;
1681
+ $tokens[$i]['parenthesis_owner'] = $openOwner;
1682
+ $openOwner = null;
1683
+ }
1684
+ } else if ($tokens[$i]['code'] === T_CLOSE_PARENTHESIS) {
1685
+ // Did we set an owner for this set of parenthesis?
1686
+ $numOpeners = count($openers);
1687
+ if ($numOpeners !== 0) {
1688
+ $opener = array_pop($openers);
1689
+ if (isset($tokens[$opener]['parenthesis_owner']) === true) {
1690
+ $owner = $tokens[$opener]['parenthesis_owner'];
1691
+
1692
+ $tokens[$owner]['parenthesis_closer'] = $i;
1693
+ $tokens[$i]['parenthesis_owner'] = $owner;
1694
+ }
1695
+
1696
+ $tokens[$i]['parenthesis_opener'] = $opener;
1697
+ $tokens[$i]['parenthesis_closer'] = $i;
1698
+ $tokens[$opener]['parenthesis_closer'] = $i;
1699
+ }
1700
+ }//end if
1701
+
1702
+ /*
1703
+ Bracket mapping.
1704
+ */
1705
+
1706
+ switch ($tokens[$i]['code']) {
1707
+ case T_OPEN_SQUARE_BRACKET:
1708
+ $squareOpeners[] = $i;
1709
+
1710
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1711
+ echo str_repeat("\t", count($squareOpeners));
1712
+ echo str_repeat("\t", count($curlyOpeners));
1713
+ echo "=> Found square bracket opener at $i".PHP_EOL;
1714
+ }
1715
+ break;
1716
+ case T_OPEN_CURLY_BRACKET:
1717
+ if (isset($tokens[$i]['scope_closer']) === false) {
1718
+ $curlyOpeners[] = $i;
1719
+
1720
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1721
+ echo str_repeat("\t", count($squareOpeners));
1722
+ echo str_repeat("\t", count($curlyOpeners));
1723
+ echo "=> Found curly bracket opener at $i".PHP_EOL;
1724
+ }
1725
+ }
1726
+ break;
1727
+ case T_CLOSE_SQUARE_BRACKET:
1728
+ if (empty($squareOpeners) === false) {
1729
+ $opener = array_pop($squareOpeners);
1730
+ $tokens[$i]['bracket_opener'] = $opener;
1731
+ $tokens[$i]['bracket_closer'] = $i;
1732
+ $tokens[$opener]['bracket_opener'] = $opener;
1733
+ $tokens[$opener]['bracket_closer'] = $i;
1734
+
1735
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1736
+ echo str_repeat("\t", count($squareOpeners));
1737
+ echo str_repeat("\t", count($curlyOpeners));
1738
+ echo "\t=> Found square bracket closer at $i for $opener".PHP_EOL;
1739
+ }
1740
+ }
1741
+ break;
1742
+ case T_CLOSE_CURLY_BRACKET:
1743
+ if (empty($curlyOpeners) === false
1744
+ && isset($tokens[$i]['scope_opener']) === false
1745
+ ) {
1746
+ $opener = array_pop($curlyOpeners);
1747
+ $tokens[$i]['bracket_opener'] = $opener;
1748
+ $tokens[$i]['bracket_closer'] = $i;
1749
+ $tokens[$opener]['bracket_opener'] = $opener;
1750
+ $tokens[$opener]['bracket_closer'] = $i;
1751
+
1752
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1753
+ echo str_repeat("\t", count($squareOpeners));
1754
+ echo str_repeat("\t", count($curlyOpeners));
1755
+ echo "\t=> Found curly bracket closer at $i for $opener".PHP_EOL;
1756
+ }
1757
+ }
1758
+ break;
1759
+ default:
1760
+ continue;
1761
+ }//end switch
1762
+ }//end for
1763
+
1764
+ // Cleanup for any openers that we didn't find closers for.
1765
+ // This typically means there was a syntax error breaking things.
1766
+ foreach ($openers as $opener) {
1767
+ unset($tokens[$opener]['parenthesis_opener']);
1768
+ unset($tokens[$opener]['parenthesis_owner']);
1769
+ }
1770
+
1771
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1772
+ echo "\t*** END TOKEN MAP ***".PHP_EOL;
1773
+ }
1774
+
1775
+ }//end _createTokenMap()
1776
+
1777
+
1778
+ /**
1779
+ * Creates a map for the parenthesis tokens that surround other tokens.
1780
+ *
1781
+ * @param array $tokens The array of tokens to process.
1782
+ * @param object $tokenizer The tokenizer being used to process this file.
1783
+ * @param string $eolChar The EOL character to use for splitting strings.
1784
+ *
1785
+ * @return void
1786
+ */
1787
+ private static function _createParenthesisNestingMap(
1788
+ &$tokens,
1789
+ $tokenizer,
1790
+ $eolChar
1791
+ ) {
1792
+ $numTokens = count($tokens);
1793
+ $map = array();
1794
+ for ($i = 0; $i < $numTokens; $i++) {
1795
+ if (isset($tokens[$i]['parenthesis_opener']) === true
1796
+ && $i === $tokens[$i]['parenthesis_opener']
1797
+ ) {
1798
+ if (empty($map) === false) {
1799
+ $tokens[$i]['nested_parenthesis'] = $map;
1800
+ }
1801
+
1802
+ if (isset($tokens[$i]['parenthesis_closer']) === true) {
1803
+ $map[$tokens[$i]['parenthesis_opener']]
1804
+ = $tokens[$i]['parenthesis_closer'];
1805
+ }
1806
+ } else if (isset($tokens[$i]['parenthesis_closer']) === true
1807
+ && $i === $tokens[$i]['parenthesis_closer']
1808
+ ) {
1809
+ array_pop($map);
1810
+ if (empty($map) === false) {
1811
+ $tokens[$i]['nested_parenthesis'] = $map;
1812
+ }
1813
+ } else {
1814
+ if (empty($map) === false) {
1815
+ $tokens[$i]['nested_parenthesis'] = $map;
1816
+ }
1817
+ }//end if
1818
+ }//end for
1819
+
1820
+ }//end _createParenthesisNestingMap()
1821
+
1822
+
1823
+ /**
1824
+ * Creates a scope map of tokens that open scopes.
1825
+ *
1826
+ * @param array $tokens The array of tokens to process.
1827
+ * @param object $tokenizer The tokenizer being used to process this file.
1828
+ * @param string $eolChar The EOL character to use for splitting strings.
1829
+ *
1830
+ * @return void
1831
+ * @see _recurseScopeMap()
1832
+ */
1833
+ private static function _createScopeMap(&$tokens, $tokenizer, $eolChar)
1834
+ {
1835
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1836
+ echo "\t*** START SCOPE MAP ***".PHP_EOL;
1837
+ }
1838
+
1839
+ $numTokens = count($tokens);
1840
+ for ($i = 0; $i < $numTokens; $i++) {
1841
+ // Check to see if the current token starts a new scope.
1842
+ if (isset($tokenizer->scopeOpeners[$tokens[$i]['code']]) === true) {
1843
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1844
+ $type = $tokens[$i]['type'];
1845
+ $content = PHP_CodeSniffer::prepareForOutput($tokens[$i]['content']);
1846
+ echo "\tStart scope map at $i:$type => $content".PHP_EOL;
1847
+ }
1848
+
1849
+ if (isset($tokens[$i]['scope_condition']) === true) {
1850
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1851
+ echo "\t* already processed, skipping *".PHP_EOL;
1852
+ }
1853
+
1854
+ continue;
1855
+ }
1856
+
1857
+ $i = self::_recurseScopeMap(
1858
+ $tokens,
1859
+ $numTokens,
1860
+ $tokenizer,
1861
+ $eolChar,
1862
+ $i
1863
+ );
1864
+ }//end if
1865
+ }//end for
1866
+
1867
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1868
+ echo "\t*** END SCOPE MAP ***".PHP_EOL;
1869
+ }
1870
+
1871
+ }//end _createScopeMap()
1872
+
1873
+
1874
+ /**
1875
+ * Recurses though the scope openers to build a scope map.
1876
+ *
1877
+ * @param array $tokens The array of tokens to process.
1878
+ * @param int $numTokens The size of the tokens array.
1879
+ * @param object $tokenizer The tokenizer being used to process this file.
1880
+ * @param string $eolChar The EOL character to use for splitting strings.
1881
+ * @param int $stackPtr The position in the stack of the token that
1882
+ * opened the scope (eg. an IF token or FOR token).
1883
+ * @param int $depth How many scope levels down we are.
1884
+ * @param int $ignore How many curly braces we are ignoring.
1885
+ *
1886
+ * @return int The position in the stack that closed the scope.
1887
+ */
1888
+ private static function _recurseScopeMap(
1889
+ &$tokens,
1890
+ $numTokens,
1891
+ $tokenizer,
1892
+ $eolChar,
1893
+ $stackPtr,
1894
+ $depth=1,
1895
+ &$ignore=0
1896
+ ) {
1897
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1898
+ echo str_repeat("\t", $depth);
1899
+ echo "=> Begin scope map recursion at token $stackPtr with depth $depth".PHP_EOL;
1900
+ }
1901
+
1902
+ $opener = null;
1903
+ $currType = $tokens[$stackPtr]['code'];
1904
+ $startLine = $tokens[$stackPtr]['line'];
1905
+
1906
+ // We will need this to restore the value if we end up
1907
+ // returning a token ID that causes our calling function to go back
1908
+ // over already ignored braces.
1909
+ $originalIgnore = $ignore;
1910
+
1911
+ // If the start token for this scope opener is the same as
1912
+ // the scope token, we have already found our opener.
1913
+ if (isset($tokenizer->scopeOpeners[$currType]['start'][$currType]) === true) {
1914
+ $opener = $stackPtr;
1915
+ }
1916
+
1917
+ for ($i = ($stackPtr + 1); $i < $numTokens; $i++) {
1918
+ $tokenType = $tokens[$i]['code'];
1919
+
1920
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1921
+ $type = $tokens[$i]['type'];
1922
+ $line = $tokens[$i]['line'];
1923
+ $content = PHP_CodeSniffer::prepareForOutput($tokens[$i]['content']);
1924
+
1925
+ echo str_repeat("\t", $depth);
1926
+ echo "Process token $i on line $line [";
1927
+ if ($opener !== null) {
1928
+ echo "opener:$opener;";
1929
+ }
1930
+
1931
+ if ($ignore > 0) {
1932
+ echo "ignore=$ignore;";
1933
+ }
1934
+
1935
+ echo "]: $type => $content".PHP_EOL;
1936
+ }//end if
1937
+
1938
+ // Very special case for IF statements in PHP that can be defined without
1939
+ // scope tokens. E.g., if (1) 1; 1 ? (1 ? 1 : 1) : 1;
1940
+ // If an IF statement below this one has an opener but no
1941
+ // keyword, the opener will be incorrectly assigned to this IF statement.
1942
+ if (($currType === T_IF || $currType === T_ELSE)
1943
+ && $opener === null
1944
+ && $tokens[$i]['code'] === T_SEMICOLON
1945
+ ) {
1946
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1947
+ $type = $tokens[$stackPtr]['type'];
1948
+ echo str_repeat("\t", $depth);
1949
+ echo "=> Found semicolon before scope opener for $stackPtr:$type, bailing".PHP_EOL;
1950
+ }
1951
+
1952
+ return $i;
1953
+ }
1954
+
1955
+ if ($opener === null
1956
+ && $ignore === 0
1957
+ && $tokenType === T_CLOSE_CURLY_BRACKET
1958
+ && isset($tokenizer->scopeOpeners[$currType]['end'][$tokenType]) === true
1959
+ ) {
1960
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1961
+ $type = $tokens[$stackPtr]['type'];
1962
+ echo str_repeat("\t", $depth);
1963
+ echo "=> Found curly brace closer before scope opener for $stackPtr:$type, bailing".PHP_EOL;
1964
+ }
1965
+
1966
+ return ($i - 1);
1967
+ }
1968
+
1969
+ if ($opener !== null
1970
+ && (isset($tokens[$i]['scope_opener']) === false
1971
+ || $tokenizer->scopeOpeners[$tokens[$stackPtr]['code']]['shared'] === true)
1972
+ && isset($tokenizer->scopeOpeners[$currType]['end'][$tokenType]) === true
1973
+ ) {
1974
+ if ($ignore > 0 && $tokenType === T_CLOSE_CURLY_BRACKET) {
1975
+ // The last opening bracket must have been for a string
1976
+ // offset or alike, so let's ignore it.
1977
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1978
+ echo str_repeat("\t", $depth);
1979
+ echo '* finished ignoring curly brace *'.PHP_EOL;
1980
+ }
1981
+
1982
+ $ignore--;
1983
+ continue;
1984
+ } else if ($tokens[$opener]['code'] === T_OPEN_CURLY_BRACKET
1985
+ && $tokenType !== T_CLOSE_CURLY_BRACKET
1986
+ ) {
1987
+ // The opener is a curly bracket so the closer must be a curly bracket as well.
1988
+ // We ignore this closer to handle cases such as T_ELSE or T_ELSEIF being considered
1989
+ // a closer of T_IF when it should not.
1990
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
1991
+ $type = $tokens[$stackPtr]['type'];
1992
+ echo str_repeat("\t", $depth);
1993
+ echo "=> Ignoring non-curly scope closer for $stackPtr:$type".PHP_EOL;
1994
+ }
1995
+ } else {
1996
+ $scopeCloser = $i;
1997
+ $todo = array(
1998
+ $stackPtr,
1999
+ $opener,
2000
+ );
2001
+
2002
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2003
+ $type = $tokens[$stackPtr]['type'];
2004
+ $closerType = $tokens[$scopeCloser]['type'];
2005
+ echo str_repeat("\t", $depth);
2006
+ echo "=> Found scope closer ($scopeCloser:$closerType) for $stackPtr:$type".PHP_EOL;
2007
+ }
2008
+
2009
+ $validCloser = true;
2010
+ if (($tokens[$stackPtr]['code'] === T_IF || $tokens[$stackPtr]['code'] === T_ELSEIF)
2011
+ && ($tokenType === T_ELSE || $tokenType === T_ELSEIF)
2012
+ ) {
2013
+ // To be a closer, this token must have an opener.
2014
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2015
+ echo str_repeat("\t", $depth);
2016
+ echo "* closer needs to be tested *".PHP_EOL;
2017
+ }
2018
+
2019
+ $i = self::_recurseScopeMap(
2020
+ $tokens,
2021
+ $numTokens,
2022
+ $tokenizer,
2023
+ $eolChar,
2024
+ $i,
2025
+ ($depth + 1),
2026
+ $ignore
2027
+ );
2028
+
2029
+ if (isset($tokens[$scopeCloser]['scope_opener']) === false) {
2030
+ $validCloser = false;
2031
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2032
+ echo str_repeat("\t", $depth);
2033
+ echo "* closer is not valid (no opener found) *".PHP_EOL;
2034
+ }
2035
+ } else if ($tokens[$tokens[$scopeCloser]['scope_opener']]['code'] !== $tokens[$opener]['code']) {
2036
+ $validCloser = false;
2037
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2038
+ echo str_repeat("\t", $depth);
2039
+ $type = $tokens[$tokens[$scopeCloser]['scope_opener']]['type'];
2040
+ $openerType = $tokens[$opener]['type'];
2041
+ echo "* closer is not valid (mismatched opener type; $type != $openerType) *".PHP_EOL;
2042
+ }
2043
+ } else if (PHP_CODESNIFFER_VERBOSITY > 1) {
2044
+ echo str_repeat("\t", $depth);
2045
+ echo "* closer was valid *".PHP_EOL;
2046
+ }
2047
+ } else {
2048
+ // The closer was not processed, so we need to
2049
+ // complete that token as well.
2050
+ $todo[] = $scopeCloser;
2051
+ }//end if
2052
+
2053
+ if ($validCloser === true) {
2054
+ foreach ($todo as $token) {
2055
+ $tokens[$token]['scope_condition'] = $stackPtr;
2056
+ $tokens[$token]['scope_opener'] = $opener;
2057
+ $tokens[$token]['scope_closer'] = $scopeCloser;
2058
+ }
2059
+
2060
+ if ($tokenizer->scopeOpeners[$tokens[$stackPtr]['code']]['shared'] === true) {
2061
+ // As we are going back to where we started originally, restore
2062
+ // the ignore value back to its original value.
2063
+ $ignore = $originalIgnore;
2064
+ return $opener;
2065
+ } else if ($scopeCloser === $i
2066
+ && isset($tokenizer->scopeOpeners[$tokenType]) === true
2067
+ ) {
2068
+ // Unset scope_condition here or else the token will appear to have
2069
+ // already been processed, and it will be skipped. Normally we want that,
2070
+ // but in this case, the token is both a closer and an opener, so
2071
+ // it needs to act like an opener. This is also why we return the
2072
+ // token before this one; so the closer has a chance to be processed
2073
+ // a second time, but as an opener.
2074
+ unset($tokens[$scopeCloser]['scope_condition']);
2075
+ return ($i - 1);
2076
+ } else {
2077
+ return $i;
2078
+ }
2079
+ } else {
2080
+ continue;
2081
+ }//end if
2082
+ }//end if
2083
+ }//end if
2084
+
2085
+ // Is this an opening condition ?
2086
+ if (isset($tokenizer->scopeOpeners[$tokenType]) === true) {
2087
+ if ($opener === null) {
2088
+ if ($tokenType === T_USE) {
2089
+ // PHP use keywords are special because they can be
2090
+ // used as blocks but also inline in function definitions.
2091
+ // So if we find them nested inside another opener, just skip them.
2092
+ continue;
2093
+ }
2094
+
2095
+ if ($tokenType === T_FUNCTION
2096
+ && $tokens[$stackPtr]['code'] !== T_FUNCTION
2097
+ ) {
2098
+ // Probably a closure, so process it manually.
2099
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2100
+ $type = $tokens[$stackPtr]['type'];
2101
+ echo str_repeat("\t", $depth);
2102
+ echo "=> Found function before scope opener for $stackPtr:$type, processing manually".PHP_EOL;
2103
+ }
2104
+
2105
+ if (isset($tokens[$i]['scope_closer']) === true) {
2106
+ // We've already processed this closure.
2107
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2108
+ echo str_repeat("\t", $depth);
2109
+ echo '* already processed, skipping *'.PHP_EOL;
2110
+ }
2111
+
2112
+ $i = $tokens[$i]['scope_closer'];
2113
+ continue;
2114
+ }
2115
+
2116
+ $i = self::_recurseScopeMap(
2117
+ $tokens,
2118
+ $numTokens,
2119
+ $tokenizer,
2120
+ $eolChar,
2121
+ $i,
2122
+ ($depth + 1),
2123
+ $ignore
2124
+ );
2125
+
2126
+ continue;
2127
+ }//end if
2128
+
2129
+ // Found another opening condition but still haven't
2130
+ // found our opener, so we are never going to find one.
2131
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2132
+ $type = $tokens[$stackPtr]['type'];
2133
+ echo str_repeat("\t", $depth);
2134
+ echo "=> Found new opening condition before scope opener for $stackPtr:$type, ";
2135
+ }
2136
+
2137
+ if (($tokens[$stackPtr]['code'] === T_IF
2138
+ || $tokens[$stackPtr]['code'] === T_ELSEIF
2139
+ || $tokens[$stackPtr]['code'] === T_ELSE)
2140
+ && ($tokens[$i]['code'] === T_ELSE
2141
+ || $tokens[$i]['code'] === T_ELSEIF)
2142
+ ) {
2143
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2144
+ echo "continuing".PHP_EOL;
2145
+ }
2146
+
2147
+ return ($i - 1);
2148
+ } else {
2149
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2150
+ echo "backtracking".PHP_EOL;
2151
+ }
2152
+
2153
+ return $stackPtr;
2154
+ }
2155
+ }//end if
2156
+
2157
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2158
+ echo str_repeat("\t", $depth);
2159
+ echo '* token is an opening condition *'.PHP_EOL;
2160
+ }
2161
+
2162
+ $isShared = ($tokenizer->scopeOpeners[$tokenType]['shared'] === true);
2163
+
2164
+ if (isset($tokens[$i]['scope_condition']) === true) {
2165
+ // We've been here before.
2166
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2167
+ echo str_repeat("\t", $depth);
2168
+ echo '* already processed, skipping *'.PHP_EOL;
2169
+ }
2170
+
2171
+ if ($isShared === false
2172
+ && isset($tokens[$i]['scope_closer']) === true
2173
+ ) {
2174
+ $i = $tokens[$i]['scope_closer'];
2175
+ }
2176
+
2177
+ continue;
2178
+ } else if ($currType === $tokenType
2179
+ && $isShared === false
2180
+ && $opener === null
2181
+ ) {
2182
+ // We haven't yet found our opener, but we have found another
2183
+ // scope opener which is the same type as us, and we don't
2184
+ // share openers, so we will never find one.
2185
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2186
+ echo str_repeat("\t", $depth);
2187
+ echo '* it was another token\'s opener, bailing *'.PHP_EOL;
2188
+ }
2189
+
2190
+ return $stackPtr;
2191
+ } else {
2192
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2193
+ echo str_repeat("\t", $depth);
2194
+ echo '* searching for opener *'.PHP_EOL;
2195
+ }
2196
+
2197
+ if (isset($tokenizer->scopeOpeners[$tokenType]['end'][T_CLOSE_CURLY_BRACKET]) === true) {
2198
+ $oldIgnore = $ignore;
2199
+ $ignore = 0;
2200
+ }
2201
+
2202
+ // PHP has a max nesting level for functions. Stop before we hit that limit
2203
+ // because too many loops means we've run into trouble anyway.
2204
+ if ($depth > 50) {
2205
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2206
+ echo str_repeat("\t", $depth);
2207
+ echo '* reached maximum nesting level; aborting *'.PHP_EOL;
2208
+ }
2209
+
2210
+ throw new PHP_CodeSniffer_Exception('Maximum nesting level reached; file could not be processed');
2211
+ }
2212
+
2213
+ $oldDepth = $depth;
2214
+ if ($isShared === true
2215
+ && isset($tokenizer->scopeOpeners[$tokenType]['with'][$currType]) === true
2216
+ ) {
2217
+ // Don't allow the depth to increment because this is
2218
+ // possibly not a true nesting if we are sharing our closer.
2219
+ // This can happen, for example, when a SWITCH has a large
2220
+ // number of CASE statements with the same shared BREAK.
2221
+ $depth--;
2222
+ }
2223
+
2224
+ $i = self::_recurseScopeMap(
2225
+ $tokens,
2226
+ $numTokens,
2227
+ $tokenizer,
2228
+ $eolChar,
2229
+ $i,
2230
+ ($depth + 1),
2231
+ $ignore
2232
+ );
2233
+
2234
+ $depth = $oldDepth;
2235
+
2236
+ if (isset($tokenizer->scopeOpeners[$tokenType]['end'][T_CLOSE_CURLY_BRACKET]) === true) {
2237
+ $ignore = $oldIgnore;
2238
+ }
2239
+ }//end if
2240
+ }//end if
2241
+
2242
+ if (isset($tokenizer->scopeOpeners[$currType]['start'][$tokenType]) === true
2243
+ && $opener === null
2244
+ ) {
2245
+ if ($tokenType === T_OPEN_CURLY_BRACKET) {
2246
+ if (isset($tokens[$stackPtr]['parenthesis_closer']) === true
2247
+ && $i < $tokens[$stackPtr]['parenthesis_closer']
2248
+ ) {
2249
+ // We found a curly brace inside the condition of the
2250
+ // current scope opener, so it must be a string offset.
2251
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2252
+ echo str_repeat("\t", $depth);
2253
+ echo '* ignoring curly brace *'.PHP_EOL;
2254
+ }
2255
+
2256
+ $ignore++;
2257
+ } else {
2258
+ // Make sure this is actually an opener and not a
2259
+ // string offset (e.g., $var{0}).
2260
+ for ($x = ($i - 1); $x > 0; $x--) {
2261
+ if (isset(PHP_CodeSniffer_Tokens::$emptyTokens[$tokens[$x]['code']]) === true) {
2262
+ continue;
2263
+ } else {
2264
+ // If the first non-whitespace/comment token is a
2265
+ // variable or object operator then this is an opener
2266
+ // for a string offset and not a scope.
2267
+ if ($tokens[$x]['code'] === T_VARIABLE
2268
+ || $tokens[$x]['code'] === T_OBJECT_OPERATOR
2269
+ ) {
2270
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2271
+ echo str_repeat("\t", $depth);
2272
+ echo '* ignoring curly brace *'.PHP_EOL;
2273
+ }
2274
+
2275
+ $ignore++;
2276
+ }//end if
2277
+
2278
+ break;
2279
+ }//end if
2280
+ }//end for
2281
+ }//end if
2282
+ }//end if
2283
+
2284
+ if ($ignore === 0 || $tokenType !== T_OPEN_CURLY_BRACKET) {
2285
+ // We found the opening scope token for $currType.
2286
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2287
+ $type = $tokens[$stackPtr]['type'];
2288
+ echo str_repeat("\t", $depth);
2289
+ echo "=> Found scope opener for $stackPtr:$type".PHP_EOL;
2290
+ }
2291
+
2292
+ $opener = $i;
2293
+ }
2294
+ } else if ($tokenType === T_OPEN_PARENTHESIS) {
2295
+ if (isset($tokens[$i]['parenthesis_owner']) === true) {
2296
+ $owner = $tokens[$i]['parenthesis_owner'];
2297
+ if (isset(PHP_CodeSniffer_Tokens::$scopeOpeners[$tokens[$owner]['code']]) === true
2298
+ && isset($tokens[$i]['parenthesis_closer']) === true
2299
+ ) {
2300
+ // If we get into here, then we opened a parenthesis for
2301
+ // a scope (eg. an if or else if) so we need to update the
2302
+ // start of the line so that when we check to see
2303
+ // if the closing parenthesis is more than 3 lines away from
2304
+ // the statement, we check from the closing parenthesis.
2305
+ $startLine = $tokens[$tokens[$i]['parenthesis_closer']]['line'];
2306
+ }
2307
+ }
2308
+ } else if ($tokenType === T_OPEN_CURLY_BRACKET && $opener !== null) {
2309
+ // We opened something that we don't have a scope opener for.
2310
+ // Examples of this are curly brackets for string offsets etc.
2311
+ // We want to ignore this so that we don't have an invalid scope
2312
+ // map.
2313
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2314
+ echo str_repeat("\t", $depth);
2315
+ echo '* ignoring curly brace *'.PHP_EOL;
2316
+ }
2317
+
2318
+ $ignore++;
2319
+ } else if ($tokenType === T_CLOSE_CURLY_BRACKET && $ignore > 0) {
2320
+ // We found the end token for the opener we were ignoring.
2321
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2322
+ echo str_repeat("\t", $depth);
2323
+ echo '* finished ignoring curly brace *'.PHP_EOL;
2324
+ }
2325
+
2326
+ $ignore--;
2327
+ } else if ($opener === null
2328
+ && isset($tokenizer->scopeOpeners[$currType]) === true
2329
+ ) {
2330
+ // If we still haven't found the opener after 3 lines,
2331
+ // we're not going to find it, unless we know it requires
2332
+ // an opener (in which case we better keep looking) or the last
2333
+ // token was empty (in which case we'll just confirm there is
2334
+ // more code in this file and not just a big comment).
2335
+ if ($tokens[$i]['line'] >= ($startLine + 3)
2336
+ && isset(PHP_CodeSniffer_Tokens::$emptyTokens[$tokens[($i - 1)]['code']]) === false
2337
+ ) {
2338
+ if ($tokenizer->scopeOpeners[$currType]['strict'] === true) {
2339
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2340
+ $type = $tokens[$stackPtr]['type'];
2341
+ $lines = ($tokens[$i]['line'] - $startLine);
2342
+ echo str_repeat("\t", $depth);
2343
+ echo "=> Still looking for $stackPtr:$type scope opener after $lines lines".PHP_EOL;
2344
+ }
2345
+ } else {
2346
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2347
+ $type = $tokens[$stackPtr]['type'];
2348
+ echo str_repeat("\t", $depth);
2349
+ echo "=> Couldn't find scope opener for $stackPtr:$type, bailing".PHP_EOL;
2350
+ }
2351
+
2352
+ return $stackPtr;
2353
+ }
2354
+ }
2355
+ } else if ($opener !== null
2356
+ && $tokenType !== T_BREAK
2357
+ && isset($tokenizer->endScopeTokens[$tokenType]) === true
2358
+ ) {
2359
+ if (isset($tokens[$i]['scope_condition']) === false) {
2360
+ if ($ignore > 0) {
2361
+ // We found the end token for the opener we were ignoring.
2362
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2363
+ echo str_repeat("\t", $depth);
2364
+ echo '* finished ignoring curly brace *'.PHP_EOL;
2365
+ }
2366
+
2367
+ $ignore--;
2368
+ } else {
2369
+ // We found a token that closes the scope but it doesn't
2370
+ // have a condition, so it belongs to another token and
2371
+ // our token doesn't have a closer, so pretend this is
2372
+ // the closer.
2373
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2374
+ $type = $tokens[$stackPtr]['type'];
2375
+ echo str_repeat("\t", $depth);
2376
+ echo "=> Found (unexpected) scope closer for $stackPtr:$type".PHP_EOL;
2377
+ }
2378
+
2379
+ foreach (array($stackPtr, $opener) as $token) {
2380
+ $tokens[$token]['scope_condition'] = $stackPtr;
2381
+ $tokens[$token]['scope_opener'] = $opener;
2382
+ $tokens[$token]['scope_closer'] = $i;
2383
+ }
2384
+
2385
+ return ($i - 1);
2386
+ }//end if
2387
+ }//end if
2388
+ }//end if
2389
+ }//end for
2390
+
2391
+ return $stackPtr;
2392
+
2393
+ }//end _recurseScopeMap()
2394
+
2395
+
2396
+ /**
2397
+ * Constructs the level map.
2398
+ *
2399
+ * The level map adds a 'level' index to each token which indicates the
2400
+ * depth that a token within a set of scope blocks. It also adds a
2401
+ * 'condition' index which is an array of the scope conditions that opened
2402
+ * each of the scopes - position 0 being the first scope opener.
2403
+ *
2404
+ * @param array $tokens The array of tokens to process.
2405
+ * @param object $tokenizer The tokenizer being used to process this file.
2406
+ * @param string $eolChar The EOL character to use for splitting strings.
2407
+ *
2408
+ * @return void
2409
+ */
2410
+ private static function _createLevelMap(&$tokens, $tokenizer, $eolChar)
2411
+ {
2412
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2413
+ echo "\t*** START LEVEL MAP ***".PHP_EOL;
2414
+ }
2415
+
2416
+ $numTokens = count($tokens);
2417
+ $level = 0;
2418
+ $conditions = array();
2419
+ $lastOpener = null;
2420
+ $openers = array();
2421
+
2422
+ for ($i = 0; $i < $numTokens; $i++) {
2423
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2424
+ $type = $tokens[$i]['type'];
2425
+ $line = $tokens[$i]['line'];
2426
+ $len = $tokens[$i]['length'];
2427
+ $col = $tokens[$i]['column'];
2428
+
2429
+ $content = PHP_CodeSniffer::prepareForOutput($tokens[$i]['content']);
2430
+
2431
+ echo str_repeat("\t", ($level + 1));
2432
+ echo "Process token $i on line $line [col:$col;len:$len;lvl:$level;";
2433
+ if (empty($conditions) !== true) {
2434
+ $condString = 'conds;';
2435
+ foreach ($conditions as $condition) {
2436
+ $condString .= token_name($condition).',';
2437
+ }
2438
+
2439
+ echo rtrim($condString, ',').';';
2440
+ }
2441
+
2442
+ echo "]: $type => $content".PHP_EOL;
2443
+ }//end if
2444
+
2445
+ $tokens[$i]['level'] = $level;
2446
+ $tokens[$i]['conditions'] = $conditions;
2447
+
2448
+ if (isset($tokens[$i]['scope_condition']) === true) {
2449
+ // Check to see if this token opened the scope.
2450
+ if ($tokens[$i]['scope_opener'] === $i) {
2451
+ $stackPtr = $tokens[$i]['scope_condition'];
2452
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2453
+ $type = $tokens[$stackPtr]['type'];
2454
+ echo str_repeat("\t", ($level + 1));
2455
+ echo "=> Found scope opener for $stackPtr:$type".PHP_EOL;
2456
+ }
2457
+
2458
+ $stackPtr = $tokens[$i]['scope_condition'];
2459
+
2460
+ // If we find a scope opener that has a shared closer,
2461
+ // then we need to go back over the condition map that we
2462
+ // just created and fix ourselves as we just added some
2463
+ // conditions where there was none. This happens for T_CASE
2464
+ // statements that are using the same break statement.
2465
+ if ($lastOpener !== null && $tokens[$lastOpener]['scope_closer'] === $tokens[$i]['scope_closer']) {
2466
+ // This opener shares its closer with the previous opener,
2467
+ // but we still need to check if the two openers share their
2468
+ // closer with each other directly (like CASE and DEFAULT)
2469
+ // or if they are just sharing because one doesn't have a
2470
+ // closer (like CASE with no BREAK using a SWITCHes closer).
2471
+ $thisType = $tokens[$tokens[$i]['scope_condition']]['code'];
2472
+ $opener = $tokens[$lastOpener]['scope_condition'];
2473
+
2474
+ $isShared = isset($tokenizer->scopeOpeners[$thisType]['with'][$tokens[$opener]['code']]);
2475
+
2476
+ reset($tokenizer->scopeOpeners[$thisType]['end']);
2477
+ reset($tokenizer->scopeOpeners[$tokens[$opener]['code']]['end']);
2478
+ $sameEnd = (current($tokenizer->scopeOpeners[$thisType]['end']) === current($tokenizer->scopeOpeners[$tokens[$opener]['code']]['end']));
2479
+
2480
+ if ($isShared === true && $sameEnd === true) {
2481
+ $badToken = $opener;
2482
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2483
+ $type = $tokens[$badToken]['type'];
2484
+ echo str_repeat("\t", ($level + 1));
2485
+ echo "* shared closer, cleaning up $badToken:$type *".PHP_EOL;
2486
+ }
2487
+
2488
+ for ($x = $tokens[$i]['scope_condition']; $x <= $i; $x++) {
2489
+ $oldConditions = $tokens[$x]['conditions'];
2490
+ $oldLevel = $tokens[$x]['level'];
2491
+ $tokens[$x]['level']--;
2492
+ unset($tokens[$x]['conditions'][$badToken]);
2493
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2494
+ $type = $tokens[$x]['type'];
2495
+ $oldConds = '';
2496
+ foreach ($oldConditions as $condition) {
2497
+ $oldConds .= token_name($condition).',';
2498
+ }
2499
+
2500
+ $oldConds = rtrim($oldConds, ',');
2501
+
2502
+ $newConds = '';
2503
+ foreach ($tokens[$x]['conditions'] as $condition) {
2504
+ $newConds .= token_name($condition).',';
2505
+ }
2506
+
2507
+ $newConds = rtrim($newConds, ',');
2508
+
2509
+ $newLevel = $tokens[$x]['level'];
2510
+ echo str_repeat("\t", ($level + 1));
2511
+ echo "* cleaned $x:$type *".PHP_EOL;
2512
+ echo str_repeat("\t", ($level + 2));
2513
+ echo "=> level changed from $oldLevel to $newLevel".PHP_EOL;
2514
+ echo str_repeat("\t", ($level + 2));
2515
+ echo "=> conditions changed from $oldConds to $newConds".PHP_EOL;
2516
+ }//end if
2517
+ }//end for
2518
+
2519
+ unset($conditions[$badToken]);
2520
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2521
+ $type = $tokens[$badToken]['type'];
2522
+ echo str_repeat("\t", ($level + 1));
2523
+ echo "* token $badToken:$type removed from conditions array *".PHP_EOL;
2524
+ }
2525
+
2526
+ unset($openers[$lastOpener]);
2527
+
2528
+ $level--;
2529
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2530
+ echo str_repeat("\t", ($level + 2));
2531
+ echo '* level decreased *'.PHP_EOL;
2532
+ }
2533
+ }//end if
2534
+ }//end if
2535
+
2536
+ $level++;
2537
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2538
+ echo str_repeat("\t", ($level + 1));
2539
+ echo '* level increased *'.PHP_EOL;
2540
+ }
2541
+
2542
+ $conditions[$stackPtr] = $tokens[$stackPtr]['code'];
2543
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2544
+ $type = $tokens[$stackPtr]['type'];
2545
+ echo str_repeat("\t", ($level + 1));
2546
+ echo "* token $stackPtr:$type added to conditions array *".PHP_EOL;
2547
+ }
2548
+
2549
+ $lastOpener = $tokens[$i]['scope_opener'];
2550
+ if ($lastOpener !== null) {
2551
+ $openers[$lastOpener] = $lastOpener;
2552
+ }
2553
+ } else if ($lastOpener !== null && $tokens[$lastOpener]['scope_closer'] === $i) {
2554
+ foreach (array_reverse($openers) as $opener) {
2555
+ if ($tokens[$opener]['scope_closer'] === $i) {
2556
+ $oldOpener = array_pop($openers);
2557
+ if (empty($openers) === false) {
2558
+ $lastOpener = array_pop($openers);
2559
+ $openers[$lastOpener] = $lastOpener;
2560
+ } else {
2561
+ $lastOpener = null;
2562
+ }
2563
+
2564
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2565
+ $type = $tokens[$oldOpener]['type'];
2566
+ echo str_repeat("\t", ($level + 1));
2567
+ echo "=> Found scope closer for $oldOpener:$type".PHP_EOL;
2568
+ }
2569
+
2570
+ $oldCondition = array_pop($conditions);
2571
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2572
+ echo str_repeat("\t", ($level + 1));
2573
+ echo '* token '.token_name($oldCondition).' removed from conditions array *'.PHP_EOL;
2574
+ }
2575
+
2576
+ // Make sure this closer actually belongs to us.
2577
+ // Either the condition also has to think this is the
2578
+ // closer, or it has to allow sharing with us.
2579
+ $condition = $tokens[$tokens[$i]['scope_condition']]['code'];
2580
+ if ($condition !== $oldCondition) {
2581
+ if (isset($tokenizer->scopeOpeners[$oldCondition]['with'][$condition]) === false) {
2582
+ $badToken = $tokens[$oldOpener]['scope_condition'];
2583
+
2584
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2585
+ $type = token_name($oldCondition);
2586
+ echo str_repeat("\t", ($level + 1));
2587
+ echo "* scope closer was bad, cleaning up $badToken:$type *".PHP_EOL;
2588
+ }
2589
+
2590
+ for ($x = ($oldOpener + 1); $x <= $i; $x++) {
2591
+ $oldConditions = $tokens[$x]['conditions'];
2592
+ $oldLevel = $tokens[$x]['level'];
2593
+ $tokens[$x]['level']--;
2594
+ unset($tokens[$x]['conditions'][$badToken]);
2595
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2596
+ $type = $tokens[$x]['type'];
2597
+ $oldConds = '';
2598
+ foreach ($oldConditions as $condition) {
2599
+ $oldConds .= token_name($condition).',';
2600
+ }
2601
+
2602
+ $oldConds = rtrim($oldConds, ',');
2603
+
2604
+ $newConds = '';
2605
+ foreach ($tokens[$x]['conditions'] as $condition) {
2606
+ $newConds .= token_name($condition).',';
2607
+ }
2608
+
2609
+ $newConds = rtrim($newConds, ',');
2610
+
2611
+ $newLevel = $tokens[$x]['level'];
2612
+ echo str_repeat("\t", ($level + 1));
2613
+ echo "* cleaned $x:$type *".PHP_EOL;
2614
+ echo str_repeat("\t", ($level + 2));
2615
+ echo "=> level changed from $oldLevel to $newLevel".PHP_EOL;
2616
+ echo str_repeat("\t", ($level + 2));
2617
+ echo "=> conditions changed from $oldConds to $newConds".PHP_EOL;
2618
+ }//end if
2619
+ }//end for
2620
+ }//end if
2621
+ }//end if
2622
+
2623
+ $level--;
2624
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2625
+ echo str_repeat("\t", ($level + 2));
2626
+ echo '* level decreased *'.PHP_EOL;
2627
+ }
2628
+
2629
+ $tokens[$i]['level'] = $level;
2630
+ $tokens[$i]['conditions'] = $conditions;
2631
+ }//end if
2632
+ }//end foreach
2633
+ }//end if
2634
+ }//end if
2635
+ }//end for
2636
+
2637
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
2638
+ echo "\t*** END LEVEL MAP ***".PHP_EOL;
2639
+ }
2640
+
2641
+ }//end _createLevelMap()
2642
+
2643
+
2644
+ /**
2645
+ * Returns the declaration names for T_CLASS, T_INTERFACE and T_FUNCTION tokens.
2646
+ *
2647
+ * @param int $stackPtr The position of the declaration token which
2648
+ * declared the class, interface or function.
2649
+ *
2650
+ * @return string|null The name of the class, interface or function.
2651
+ * or NULL if the function is a closure.
2652
+ * @throws PHP_CodeSniffer_Exception If the specified token is not of type
2653
+ * T_FUNCTION, T_CLASS or T_INTERFACE.
2654
+ */
2655
+ public function getDeclarationName($stackPtr)
2656
+ {
2657
+ $tokenCode = $this->_tokens[$stackPtr]['code'];
2658
+ if ($tokenCode !== T_FUNCTION
2659
+ && $tokenCode !== T_CLASS
2660
+ && $tokenCode !== T_INTERFACE
2661
+ && $tokenCode !== T_TRAIT
2662
+ ) {
2663
+ throw new PHP_CodeSniffer_Exception('Token type "'.$this->_tokens[$stackPtr]['type'].'" is not T_FUNCTION, T_CLASS, T_INTERFACE or T_TRAIT');
2664
+ }
2665
+
2666
+ if ($tokenCode === T_FUNCTION
2667
+ && $this->isAnonymousFunction($stackPtr) === true
2668
+ ) {
2669
+ return null;
2670
+ }
2671
+
2672
+ $content = null;
2673
+ for ($i = $stackPtr; $i < $this->numTokens; $i++) {
2674
+ if ($this->_tokens[$i]['code'] === T_STRING) {
2675
+ $content = $this->_tokens[$i]['content'];
2676
+ break;
2677
+ }
2678
+ }
2679
+
2680
+ return $content;
2681
+
2682
+ }//end getDeclarationName()
2683
+
2684
+
2685
+ /**
2686
+ * Check if the token at the specified position is a anonymous function.
2687
+ *
2688
+ * @param int $stackPtr The position of the declaration token which
2689
+ * declared the class, interface or function.
2690
+ *
2691
+ * @return boolean
2692
+ * @throws PHP_CodeSniffer_Exception If the specified token is not of type
2693
+ * T_FUNCTION
2694
+ */
2695
+ public function isAnonymousFunction($stackPtr)
2696
+ {
2697
+ $tokenCode = $this->_tokens[$stackPtr]['code'];
2698
+ if ($tokenCode !== T_FUNCTION) {
2699
+ throw new PHP_CodeSniffer_Exception('Token type is not T_FUNCTION');
2700
+ }
2701
+
2702
+ if (isset($this->_tokens[$stackPtr]['parenthesis_opener']) === false) {
2703
+ // Something is not right with this function.
2704
+ return false;
2705
+ }
2706
+
2707
+ $name = false;
2708
+ for ($i = ($stackPtr + 1); $i < $this->numTokens; $i++) {
2709
+ if ($this->_tokens[$i]['code'] === T_STRING) {
2710
+ $name = $i;
2711
+ break;
2712
+ }
2713
+ }
2714
+
2715
+ if ($name === false) {
2716
+ // No name found.
2717
+ return true;
2718
+ }
2719
+
2720
+ $open = $this->_tokens[$stackPtr]['parenthesis_opener'];
2721
+ if ($name > $open) {
2722
+ return true;
2723
+ }
2724
+
2725
+ return false;
2726
+
2727
+ }//end isAnonymousFunction()
2728
+
2729
+
2730
+ /**
2731
+ * Returns the method parameters for the specified T_FUNCTION token.
2732
+ *
2733
+ * Each parameter is in the following format:
2734
+ *
2735
+ * <code>
2736
+ * 0 => array(
2737
+ * 'name' => '$var', // The variable name.
2738
+ * 'pass_by_reference' => false, // Passed by reference.
2739
+ * 'type_hint' => string, // Type hint for array or custom type
2740
+ * )
2741
+ * </code>
2742
+ *
2743
+ * Parameters with default values have an additional array index of
2744
+ * 'default' with the value of the default as a string.
2745
+ *
2746
+ * @param int $stackPtr The position in the stack of the T_FUNCTION token
2747
+ * to acquire the parameters for.
2748
+ *
2749
+ * @return array
2750
+ * @throws PHP_CodeSniffer_Exception If the specified $stackPtr is not of
2751
+ * type T_FUNCTION.
2752
+ */
2753
+ public function getMethodParameters($stackPtr)
2754
+ {
2755
+ if ($this->_tokens[$stackPtr]['code'] !== T_FUNCTION) {
2756
+ throw new PHP_CodeSniffer_Exception('$stackPtr must be of type T_FUNCTION');
2757
+ }
2758
+
2759
+ $opener = $this->_tokens[$stackPtr]['parenthesis_opener'];
2760
+ $closer = $this->_tokens[$stackPtr]['parenthesis_closer'];
2761
+
2762
+ $vars = array();
2763
+ $currVar = null;
2764
+ $defaultStart = null;
2765
+ $paramCount = 0;
2766
+ $passByReference = false;
2767
+ $variableLength = false;
2768
+ $typeHint = '';
2769
+
2770
+ for ($i = ($opener + 1); $i <= $closer; $i++) {
2771
+ // Check to see if this token has a parenthesis or bracket opener. If it does
2772
+ // it's likely to be an array which might have arguments in it. This
2773
+ // could cause problems in our parsing below, so lets just skip to the
2774
+ // end of it.
2775
+ if (isset($this->_tokens[$i]['parenthesis_opener']) === true) {
2776
+ // Don't do this if it's the close parenthesis for the method.
2777
+ if ($i !== $this->_tokens[$i]['parenthesis_closer']) {
2778
+ $i = ($this->_tokens[$i]['parenthesis_closer'] + 1);
2779
+ }
2780
+ }
2781
+
2782
+ if (isset($this->_tokens[$i]['bracket_opener']) === true) {
2783
+ // Don't do this if it's the close parenthesis for the method.
2784
+ if ($i !== $this->_tokens[$i]['bracket_closer']) {
2785
+ $i = ($this->_tokens[$i]['bracket_closer'] + 1);
2786
+ }
2787
+ }
2788
+
2789
+ switch ($this->_tokens[$i]['code']) {
2790
+ case T_BITWISE_AND:
2791
+ $passByReference = true;
2792
+ break;
2793
+ case T_VARIABLE:
2794
+ $currVar = $i;
2795
+ break;
2796
+ case T_ELLIPSIS:
2797
+ $variableLength = true;
2798
+ break;
2799
+ case T_ARRAY_HINT:
2800
+ case T_CALLABLE:
2801
+ $typeHint = $this->_tokens[$i]['content'];
2802
+ break;
2803
+ case T_STRING:
2804
+ // This is a string, so it may be a type hint, but it could
2805
+ // also be a constant used as a default value.
2806
+ $prevComma = false;
2807
+ for ($t = $i; $t >= $opener; $t--) {
2808
+ if ($this->_tokens[$t]['code'] === T_COMMA) {
2809
+ $prevComma = $t;
2810
+ break;
2811
+ }
2812
+ }
2813
+
2814
+ if ($prevComma !== false) {
2815
+ $nextEquals = false;
2816
+ for ($t = $prevComma; $t < $i; $t++) {
2817
+ if ($this->_tokens[$t]['code'] === T_EQUAL) {
2818
+ $nextEquals = $t;
2819
+ break;
2820
+ }
2821
+ }
2822
+
2823
+ if ($nextEquals !== false) {
2824
+ break;
2825
+ }
2826
+ }
2827
+
2828
+ if ($defaultStart === null) {
2829
+ $typeHint .= $this->_tokens[$i]['content'];
2830
+ }
2831
+ break;
2832
+ case T_NS_SEPARATOR:
2833
+ // Part of a type hint or default value.
2834
+ if ($defaultStart === null) {
2835
+ $typeHint .= $this->_tokens[$i]['content'];
2836
+ }
2837
+ break;
2838
+ case T_CLOSE_PARENTHESIS:
2839
+ case T_COMMA:
2840
+ // If it's null, then there must be no parameters for this
2841
+ // method.
2842
+ if ($currVar === null) {
2843
+ continue;
2844
+ }
2845
+
2846
+ $vars[$paramCount] = array();
2847
+ $vars[$paramCount]['name'] = $this->_tokens[$currVar]['content'];
2848
+
2849
+ if ($defaultStart !== null) {
2850
+ $vars[$paramCount]['default']
2851
+ = $this->getTokensAsString(
2852
+ $defaultStart,
2853
+ ($i - $defaultStart)
2854
+ );
2855
+ }
2856
+
2857
+ $vars[$paramCount]['pass_by_reference'] = $passByReference;
2858
+ $vars[$paramCount]['variable_length'] = $variableLength;
2859
+ $vars[$paramCount]['type_hint'] = $typeHint;
2860
+
2861
+ // Reset the vars, as we are about to process the next parameter.
2862
+ $defaultStart = null;
2863
+ $passByReference = false;
2864
+ $variableLength = false;
2865
+ $typeHint = '';
2866
+
2867
+ $paramCount++;
2868
+ break;
2869
+ case T_EQUAL:
2870
+ $defaultStart = ($i + 1);
2871
+ break;
2872
+ }//end switch
2873
+ }//end for
2874
+
2875
+ return $vars;
2876
+
2877
+ }//end getMethodParameters()
2878
+
2879
+
2880
+ /**
2881
+ * Returns the visibility and implementation properties of a method.
2882
+ *
2883
+ * The format of the array is:
2884
+ * <code>
2885
+ * array(
2886
+ * 'scope' => 'public', // public private or protected
2887
+ * 'scope_specified' => true, // true is scope keyword was found.
2888
+ * 'is_abstract' => false, // true if the abstract keyword was found.
2889
+ * 'is_final' => false, // true if the final keyword was found.
2890
+ * 'is_static' => false, // true if the static keyword was found.
2891
+ * 'is_closure' => false, // true if no name is found.
2892
+ * );
2893
+ * </code>
2894
+ *
2895
+ * @param int $stackPtr The position in the stack of the T_FUNCTION token to
2896
+ * acquire the properties for.
2897
+ *
2898
+ * @return array
2899
+ * @throws PHP_CodeSniffer_Exception If the specified position is not a
2900
+ * T_FUNCTION token.
2901
+ */
2902
+ public function getMethodProperties($stackPtr)
2903
+ {
2904
+ if ($this->_tokens[$stackPtr]['code'] !== T_FUNCTION) {
2905
+ throw new PHP_CodeSniffer_Exception('$stackPtr must be of type T_FUNCTION');
2906
+ }
2907
+
2908
+ $valid = array(
2909
+ T_PUBLIC => T_PUBLIC,
2910
+ T_PRIVATE => T_PRIVATE,
2911
+ T_PROTECTED => T_PROTECTED,
2912
+ T_STATIC => T_STATIC,
2913
+ T_FINAL => T_FINAL,
2914
+ T_ABSTRACT => T_ABSTRACT,
2915
+ T_WHITESPACE => T_WHITESPACE,
2916
+ T_COMMENT => T_COMMENT,
2917
+ T_DOC_COMMENT => T_DOC_COMMENT,
2918
+ );
2919
+
2920
+ $scope = 'public';
2921
+ $scopeSpecified = false;
2922
+ $isAbstract = false;
2923
+ $isFinal = false;
2924
+ $isStatic = false;
2925
+ $isClosure = $this->isAnonymousFunction($stackPtr);
2926
+
2927
+ for ($i = ($stackPtr - 1); $i > 0; $i--) {
2928
+ if (isset($valid[$this->_tokens[$i]['code']]) === false) {
2929
+ break;
2930
+ }
2931
+
2932
+ switch ($this->_tokens[$i]['code']) {
2933
+ case T_PUBLIC:
2934
+ $scope = 'public';
2935
+ $scopeSpecified = true;
2936
+ break;
2937
+ case T_PRIVATE:
2938
+ $scope = 'private';
2939
+ $scopeSpecified = true;
2940
+ break;
2941
+ case T_PROTECTED:
2942
+ $scope = 'protected';
2943
+ $scopeSpecified = true;
2944
+ break;
2945
+ case T_ABSTRACT:
2946
+ $isAbstract = true;
2947
+ break;
2948
+ case T_FINAL:
2949
+ $isFinal = true;
2950
+ break;
2951
+ case T_STATIC:
2952
+ $isStatic = true;
2953
+ break;
2954
+ }//end switch
2955
+ }//end for
2956
+
2957
+ return array(
2958
+ 'scope' => $scope,
2959
+ 'scope_specified' => $scopeSpecified,
2960
+ 'is_abstract' => $isAbstract,
2961
+ 'is_final' => $isFinal,
2962
+ 'is_static' => $isStatic,
2963
+ 'is_closure' => $isClosure,
2964
+ );
2965
+
2966
+ }//end getMethodProperties()
2967
+
2968
+
2969
+ /**
2970
+ * Returns the visibility and implementation properties of the class member
2971
+ * variable found at the specified position in the stack.
2972
+ *
2973
+ * The format of the array is:
2974
+ *
2975
+ * <code>
2976
+ * array(
2977
+ * 'scope' => 'public', // public private or protected
2978
+ * 'is_static' => false, // true if the static keyword was found.
2979
+ * );
2980
+ * </code>
2981
+ *
2982
+ * @param int $stackPtr The position in the stack of the T_VARIABLE token to
2983
+ * acquire the properties for.
2984
+ *
2985
+ * @return array
2986
+ * @throws PHP_CodeSniffer_Exception If the specified position is not a
2987
+ * T_VARIABLE token, or if the position is not
2988
+ * a class member variable.
2989
+ */
2990
+ public function getMemberProperties($stackPtr)
2991
+ {
2992
+ if ($this->_tokens[$stackPtr]['code'] !== T_VARIABLE) {
2993
+ throw new PHP_CodeSniffer_Exception('$stackPtr must be of type T_VARIABLE');
2994
+ }
2995
+
2996
+ $conditions = array_keys($this->_tokens[$stackPtr]['conditions']);
2997
+ $ptr = array_pop($conditions);
2998
+ if (isset($this->_tokens[$ptr]) === false
2999
+ || ($this->_tokens[$ptr]['code'] !== T_CLASS
3000
+ && $this->_tokens[$ptr]['code'] !== T_TRAIT)
3001
+ ) {
3002
+ if (isset($this->_tokens[$ptr]) === true
3003
+ && $this->_tokens[$ptr]['code'] === T_INTERFACE
3004
+ ) {
3005
+ // T_VARIABLEs in interfaces can actually be method arguments
3006
+ // but they wont be seen as being inside the method because there
3007
+ // are no scope openers and closers for abstract methods. If it is in
3008
+ // parentheses, we can be pretty sure it is a method argument.
3009
+ if (isset($this->_tokens[$stackPtr]['nested_parenthesis']) === false
3010
+ || empty($this->_tokens[$stackPtr]['nested_parenthesis']) === true
3011
+ ) {
3012
+ $error = 'Possible parse error: interfaces may not include member vars';
3013
+ $this->addWarning($error, $stackPtr, 'Internal.ParseError.InterfaceHasMemberVar');
3014
+ return array();
3015
+ }
3016
+ } else {
3017
+ throw new PHP_CodeSniffer_Exception('$stackPtr is not a class member var');
3018
+ }
3019
+ }
3020
+
3021
+ $valid = array(
3022
+ T_PUBLIC => T_PUBLIC,
3023
+ T_PRIVATE => T_PRIVATE,
3024
+ T_PROTECTED => T_PROTECTED,
3025
+ T_STATIC => T_STATIC,
3026
+ T_WHITESPACE => T_WHITESPACE,
3027
+ T_COMMENT => T_COMMENT,
3028
+ T_DOC_COMMENT => T_DOC_COMMENT,
3029
+ T_VARIABLE => T_VARIABLE,
3030
+ T_COMMA => T_COMMA,
3031
+ );
3032
+
3033
+ $scope = 'public';
3034
+ $scopeSpecified = false;
3035
+ $isStatic = false;
3036
+
3037
+ for ($i = ($stackPtr - 1); $i > 0; $i--) {
3038
+ if (isset($valid[$this->_tokens[$i]['code']]) === false) {
3039
+ break;
3040
+ }
3041
+
3042
+ switch ($this->_tokens[$i]['code']) {
3043
+ case T_PUBLIC:
3044
+ $scope = 'public';
3045
+ $scopeSpecified = true;
3046
+ break;
3047
+ case T_PRIVATE:
3048
+ $scope = 'private';
3049
+ $scopeSpecified = true;
3050
+ break;
3051
+ case T_PROTECTED:
3052
+ $scope = 'protected';
3053
+ $scopeSpecified = true;
3054
+ break;
3055
+ case T_STATIC:
3056
+ $isStatic = true;
3057
+ break;
3058
+ }
3059
+ }//end for
3060
+
3061
+ return array(
3062
+ 'scope' => $scope,
3063
+ 'scope_specified' => $scopeSpecified,
3064
+ 'is_static' => $isStatic,
3065
+ );
3066
+
3067
+ }//end getMemberProperties()
3068
+
3069
+
3070
+ /**
3071
+ * Returns the visibility and implementation properties of a class.
3072
+ *
3073
+ * The format of the array is:
3074
+ * <code>
3075
+ * array(
3076
+ * 'is_abstract' => false, // true if the abstract keyword was found.
3077
+ * 'is_final' => false, // true if the final keyword was found.
3078
+ * );
3079
+ * </code>
3080
+ *
3081
+ * @param int $stackPtr The position in the stack of the T_CLASS token to
3082
+ * acquire the properties for.
3083
+ *
3084
+ * @return array
3085
+ * @throws PHP_CodeSniffer_Exception If the specified position is not a
3086
+ * T_CLASS token.
3087
+ */
3088
+ public function getClassProperties($stackPtr)
3089
+ {
3090
+ if ($this->_tokens[$stackPtr]['code'] !== T_CLASS) {
3091
+ throw new PHP_CodeSniffer_Exception('$stackPtr must be of type T_CLASS');
3092
+ }
3093
+
3094
+ $valid = array(
3095
+ T_FINAL => T_FINAL,
3096
+ T_ABSTRACT => T_ABSTRACT,
3097
+ T_WHITESPACE => T_WHITESPACE,
3098
+ T_COMMENT => T_COMMENT,
3099
+ T_DOC_COMMENT => T_DOC_COMMENT,
3100
+ );
3101
+
3102
+ $isAbstract = false;
3103
+ $isFinal = false;
3104
+
3105
+ for ($i = ($stackPtr - 1); $i > 0; $i--) {
3106
+ if (isset($valid[$this->_tokens[$i]['code']]) === false) {
3107
+ break;
3108
+ }
3109
+
3110
+ switch ($this->_tokens[$i]['code']) {
3111
+ case T_ABSTRACT:
3112
+ $isAbstract = true;
3113
+ break;
3114
+
3115
+ case T_FINAL:
3116
+ $isFinal = true;
3117
+ break;
3118
+ }
3119
+ }//end for
3120
+
3121
+ return array(
3122
+ 'is_abstract' => $isAbstract,
3123
+ 'is_final' => $isFinal,
3124
+ );
3125
+
3126
+ }//end getClassProperties()
3127
+
3128
+
3129
+ /**
3130
+ * Determine if the passed token is a reference operator.
3131
+ *
3132
+ * Returns true if the specified token position represents a reference.
3133
+ * Returns false if the token represents a bitwise operator.
3134
+ *
3135
+ * @param int $stackPtr The position of the T_BITWISE_AND token.
3136
+ *
3137
+ * @return boolean
3138
+ */
3139
+ public function isReference($stackPtr)
3140
+ {
3141
+ if ($this->_tokens[$stackPtr]['code'] !== T_BITWISE_AND) {
3142
+ return false;
3143
+ }
3144
+
3145
+ $tokenBefore = $this->findPrevious(
3146
+ PHP_CodeSniffer_Tokens::$emptyTokens,
3147
+ ($stackPtr - 1),
3148
+ null,
3149
+ true
3150
+ );
3151
+
3152
+ if ($this->_tokens[$tokenBefore]['code'] === T_FUNCTION) {
3153
+ // Function returns a reference.
3154
+ return true;
3155
+ }
3156
+
3157
+ if ($this->_tokens[$tokenBefore]['code'] === T_DOUBLE_ARROW) {
3158
+ // Inside a foreach loop, this is a reference.
3159
+ return true;
3160
+ }
3161
+
3162
+ if ($this->_tokens[$tokenBefore]['code'] === T_AS) {
3163
+ // Inside a foreach loop, this is a reference.
3164
+ return true;
3165
+ }
3166
+
3167
+ if ($this->_tokens[$tokenBefore]['code'] === T_OPEN_SHORT_ARRAY) {
3168
+ // Inside an array declaration, this is a reference.
3169
+ return true;
3170
+ }
3171
+
3172
+ if (isset(PHP_CodeSniffer_Tokens::$assignmentTokens[$this->_tokens[$tokenBefore]['code']]) === true) {
3173
+ // This is directly after an assignment. It's a reference. Even if
3174
+ // it is part of an operation, the other tests will handle it.
3175
+ return true;
3176
+ }
3177
+
3178
+ if (isset($this->_tokens[$stackPtr]['nested_parenthesis']) === true) {
3179
+ $brackets = $this->_tokens[$stackPtr]['nested_parenthesis'];
3180
+ $lastBracket = array_pop($brackets);
3181
+ if (isset($this->_tokens[$lastBracket]['parenthesis_owner']) === true) {
3182
+ $owner = $this->_tokens[$this->_tokens[$lastBracket]['parenthesis_owner']];
3183
+ if ($owner['code'] === T_FUNCTION
3184
+ || $owner['code'] === T_CLOSURE
3185
+ || $owner['code'] === T_ARRAY
3186
+ ) {
3187
+ // Inside a function or array declaration, this is a reference.
3188
+ return true;
3189
+ }
3190
+ } else {
3191
+ $prev = false;
3192
+ for ($t = ($this->_tokens[$lastBracket]['parenthesis_opener'] - 1); $t >= 0; $t--) {
3193
+ if ($this->_tokens[$t]['code'] !== T_WHITESPACE) {
3194
+ $prev = $t;
3195
+ break;
3196
+ }
3197
+ }
3198
+
3199
+ if ($prev !== false && $this->_tokens[$prev]['code'] === T_USE) {
3200
+ return true;
3201
+ }
3202
+ }//end if
3203
+ }//end if
3204
+
3205
+ $tokenAfter = $this->findNext(
3206
+ PHP_CodeSniffer_Tokens::$emptyTokens,
3207
+ ($stackPtr + 1),
3208
+ null,
3209
+ true
3210
+ );
3211
+
3212
+ if ($this->_tokens[$tokenAfter]['code'] === T_VARIABLE
3213
+ && ($this->_tokens[$tokenBefore]['code'] === T_OPEN_PARENTHESIS
3214
+ || $this->_tokens[$tokenBefore]['code'] === T_COMMA)
3215
+ ) {
3216
+ return true;
3217
+ }
3218
+
3219
+ return false;
3220
+
3221
+ }//end isReference()
3222
+
3223
+
3224
+ /**
3225
+ * Returns the content of the tokens from the specified start position in
3226
+ * the token stack for the specified length.
3227
+ *
3228
+ * @param int $start The position to start from in the token stack.
3229
+ * @param int $length The length of tokens to traverse from the start pos.
3230
+ *
3231
+ * @return string The token contents.
3232
+ */
3233
+ public function getTokensAsString($start, $length)
3234
+ {
3235
+ $str = '';
3236
+ $end = ($start + $length);
3237
+ if ($end > $this->numTokens) {
3238
+ $end = $this->numTokens;
3239
+ }
3240
+
3241
+ for ($i = $start; $i < $end; $i++) {
3242
+ $str .= $this->_tokens[$i]['content'];
3243
+ }
3244
+
3245
+ return $str;
3246
+
3247
+ }//end getTokensAsString()
3248
+
3249
+
3250
+ /**
3251
+ * Returns the position of the previous specified token(s).
3252
+ *
3253
+ * If a value is specified, the previous token of the specified type(s)
3254
+ * containing the specified value will be returned.
3255
+ *
3256
+ * Returns false if no token can be found.
3257
+ *
3258
+ * @param int|array $types The type(s) of tokens to search for.
3259
+ * @param int $start The position to start searching from in the
3260
+ * token stack.
3261
+ * @param int $end The end position to fail if no token is found.
3262
+ * if not specified or null, end will default to
3263
+ * the start of the token stack.
3264
+ * @param bool $exclude If true, find the previous token that are NOT of
3265
+ * the types specified in $types.
3266
+ * @param string $value The value that the token(s) must be equal to.
3267
+ * If value is omitted, tokens with any value will
3268
+ * be returned.
3269
+ * @param bool $local If true, tokens outside the current statement
3270
+ * will not be checked. IE. checking will stop
3271
+ * at the previous semi-colon found.
3272
+ *
3273
+ * @return int|bool
3274
+ * @see findNext()
3275
+ */
3276
+ public function findPrevious(
3277
+ $types,
3278
+ $start,
3279
+ $end=null,
3280
+ $exclude=false,
3281
+ $value=null,
3282
+ $local=false
3283
+ ) {
3284
+ $types = (array) $types;
3285
+
3286
+ if ($end === null) {
3287
+ $end = 0;
3288
+ }
3289
+
3290
+ for ($i = $start; $i >= $end; $i--) {
3291
+ $found = (bool) $exclude;
3292
+ foreach ($types as $type) {
3293
+ if ($this->_tokens[$i]['code'] === $type) {
3294
+ $found = !$exclude;
3295
+ break;
3296
+ }
3297
+ }
3298
+
3299
+ if ($found === true) {
3300
+ if ($value === null) {
3301
+ return $i;
3302
+ } else if ($this->_tokens[$i]['content'] === $value) {
3303
+ return $i;
3304
+ }
3305
+ }
3306
+
3307
+ if ($local === true) {
3308
+ if (isset($this->_tokens[$i]['scope_opener']) === true
3309
+ && $i === $this->_tokens[$i]['scope_closer']
3310
+ ) {
3311
+ $i = $this->_tokens[$i]['scope_opener'];
3312
+ } else if (isset($this->_tokens[$i]['bracket_opener']) === true
3313
+ && $i === $this->_tokens[$i]['bracket_closer']
3314
+ ) {
3315
+ $i = $this->_tokens[$i]['bracket_opener'];
3316
+ } else if (isset($this->_tokens[$i]['parenthesis_opener']) === true
3317
+ && $i === $this->_tokens[$i]['parenthesis_closer']
3318
+ ) {
3319
+ $i = $this->_tokens[$i]['parenthesis_opener'];
3320
+ } else if ($this->_tokens[$i]['code'] === T_SEMICOLON) {
3321
+ break;
3322
+ }
3323
+ }
3324
+ }//end for
3325
+
3326
+ return false;
3327
+
3328
+ }//end findPrevious()
3329
+
3330
+
3331
+ /**
3332
+ * Returns the position of the next specified token(s).
3333
+ *
3334
+ * If a value is specified, the next token of the specified type(s)
3335
+ * containing the specified value will be returned.
3336
+ *
3337
+ * Returns false if no token can be found.
3338
+ *
3339
+ * @param int|array $types The type(s) of tokens to search for.
3340
+ * @param int $start The position to start searching from in the
3341
+ * token stack.
3342
+ * @param int $end The end position to fail if no token is found.
3343
+ * if not specified or null, end will default to
3344
+ * the end of the token stack.
3345
+ * @param bool $exclude If true, find the next token that is NOT of
3346
+ * a type specified in $types.
3347
+ * @param string $value The value that the token(s) must be equal to.
3348
+ * If value is omitted, tokens with any value will
3349
+ * be returned.
3350
+ * @param bool $local If true, tokens outside the current statement
3351
+ * will not be checked. i.e., checking will stop
3352
+ * at the next semi-colon found.
3353
+ *
3354
+ * @return int|bool
3355
+ * @see findPrevious()
3356
+ */
3357
+ public function findNext(
3358
+ $types,
3359
+ $start,
3360
+ $end=null,
3361
+ $exclude=false,
3362
+ $value=null,
3363
+ $local=false
3364
+ ) {
3365
+ $types = (array) $types;
3366
+
3367
+ if ($end === null || $end > $this->numTokens) {
3368
+ $end = $this->numTokens;
3369
+ }
3370
+
3371
+ for ($i = $start; $i < $end; $i++) {
3372
+ $found = (bool) $exclude;
3373
+ foreach ($types as $type) {
3374
+ if ($this->_tokens[$i]['code'] === $type) {
3375
+ $found = !$exclude;
3376
+ break;
3377
+ }
3378
+ }
3379
+
3380
+ if ($found === true) {
3381
+ if ($value === null) {
3382
+ return $i;
3383
+ } else if ($this->_tokens[$i]['content'] === $value) {
3384
+ return $i;
3385
+ }
3386
+ }
3387
+
3388
+ if ($local === true && $this->_tokens[$i]['code'] === T_SEMICOLON) {
3389
+ break;
3390
+ }
3391
+ }//end for
3392
+
3393
+ return false;
3394
+
3395
+ }//end findNext()
3396
+
3397
+
3398
+ /**
3399
+ * Returns the position of the first non-whitespace token in a statement.
3400
+ *
3401
+ * @param int $start The position to start searching from in the token stack.
3402
+ * @param int|array $ignore Token types that should not be considered stop points.
3403
+ *
3404
+ * @return int
3405
+ */
3406
+ public function findStartOfStatement($start, $ignore=null)
3407
+ {
3408
+ $endTokens = PHP_CodeSniffer_Tokens::$blockOpeners;
3409
+
3410
+ $endTokens[T_COLON] = true;
3411
+ $endTokens[T_COMMA] = true;
3412
+ $endTokens[T_DOUBLE_ARROW] = true;
3413
+ $endTokens[T_SEMICOLON] = true;
3414
+ $endTokens[T_OPEN_TAG] = true;
3415
+ $endTokens[T_CLOSE_TAG] = true;
3416
+ $endTokens[T_OPEN_SHORT_ARRAY] = true;
3417
+
3418
+ if ($ignore !== null) {
3419
+ $ignore = (array) $ignore;
3420
+ foreach ($ignore as $code) {
3421
+ if (isset($endTokens[$code]) === true) {
3422
+ unset($endTokens[$code]);
3423
+ }
3424
+ }
3425
+ }
3426
+
3427
+ $lastNotEmpty = $start;
3428
+
3429
+ for ($i = $start; $i >= 0; $i--) {
3430
+ if (isset($endTokens[$this->_tokens[$i]['code']]) === true) {
3431
+ // Found the end of the previous statement.
3432
+ return $lastNotEmpty;
3433
+ }
3434
+
3435
+ if (isset($this->_tokens[$i]['scope_opener']) === true
3436
+ && $i === $this->_tokens[$i]['scope_closer']
3437
+ ) {
3438
+ // Found the end of the previous scope block.
3439
+ return $lastNotEmpty;
3440
+ }
3441
+
3442
+ // Skip nested statements.
3443
+ if (isset($this->_tokens[$i]['bracket_opener']) === true
3444
+ && $i === $this->_tokens[$i]['bracket_closer']
3445
+ ) {
3446
+ $i = $this->_tokens[$i]['bracket_opener'];
3447
+ } else if (isset($this->_tokens[$i]['parenthesis_opener']) === true
3448
+ && $i === $this->_tokens[$i]['parenthesis_closer']
3449
+ ) {
3450
+ $i = $this->_tokens[$i]['parenthesis_opener'];
3451
+ }
3452
+
3453
+ if (isset(PHP_CodeSniffer_Tokens::$emptyTokens[$this->_tokens[$i]['code']]) === false) {
3454
+ $lastNotEmpty = $i;
3455
+ }
3456
+ }//end for
3457
+
3458
+ return 0;
3459
+
3460
+ }//end findStartOfStatement()
3461
+
3462
+
3463
+ /**
3464
+ * Returns the position of the last non-whitespace token in a statement.
3465
+ *
3466
+ * @param int $start The position to start searching from in the token stack.
3467
+ * @param int|array $ignore Token types that should not be considered stop points.
3468
+ *
3469
+ * @return int
3470
+ */
3471
+ public function findEndOfStatement($start, $ignore=null)
3472
+ {
3473
+ $endTokens = array(
3474
+ T_COLON => true,
3475
+ T_COMMA => true,
3476
+ T_DOUBLE_ARROW => true,
3477
+ T_SEMICOLON => true,
3478
+ T_CLOSE_PARENTHESIS => true,
3479
+ T_CLOSE_SQUARE_BRACKET => true,
3480
+ T_CLOSE_CURLY_BRACKET => true,
3481
+ T_CLOSE_SHORT_ARRAY => true,
3482
+ T_OPEN_TAG => true,
3483
+ T_CLOSE_TAG => true,
3484
+ );
3485
+
3486
+ if ($ignore !== null) {
3487
+ $ignore = (array) $ignore;
3488
+ foreach ($ignore as $code) {
3489
+ if (isset($endTokens[$code]) === true) {
3490
+ unset($endTokens[$code]);
3491
+ }
3492
+ }
3493
+ }
3494
+
3495
+ $lastNotEmpty = $start;
3496
+
3497
+ for ($i = $start; $i < $this->numTokens; $i++) {
3498
+ if ($i !== $start && isset($endTokens[$this->_tokens[$i]['code']]) === true) {
3499
+ // Found the end of the statement.
3500
+ if ($this->_tokens[$i]['code'] === T_CLOSE_PARENTHESIS
3501
+ || $this->_tokens[$i]['code'] === T_CLOSE_SQUARE_BRACKET
3502
+ || $this->_tokens[$i]['code'] === T_CLOSE_CURLY_BRACKET
3503
+ || $this->_tokens[$i]['code'] === T_OPEN_TAG
3504
+ || $this->_tokens[$i]['code'] === T_CLOSE_TAG
3505
+ ) {
3506
+ return $lastNotEmpty;
3507
+ }
3508
+
3509
+ return $i;
3510
+ }
3511
+
3512
+ // Skip nested statements.
3513
+ if (isset($this->_tokens[$i]['scope_closer']) === true
3514
+ && ($i === $this->_tokens[$i]['scope_opener']
3515
+ || $i === $this->_tokens[$i]['scope_condition'])
3516
+ ) {
3517
+ $i = $this->_tokens[$i]['scope_closer'];
3518
+ } else if (isset($this->_tokens[$i]['bracket_closer']) === true
3519
+ && $i === $this->_tokens[$i]['bracket_opener']
3520
+ ) {
3521
+ $i = $this->_tokens[$i]['bracket_closer'];
3522
+ } else if (isset($this->_tokens[$i]['parenthesis_closer']) === true
3523
+ && $i === $this->_tokens[$i]['parenthesis_opener']
3524
+ ) {
3525
+ $i = $this->_tokens[$i]['parenthesis_closer'];
3526
+ }
3527
+
3528
+ if (isset(PHP_CodeSniffer_Tokens::$emptyTokens[$this->_tokens[$i]['code']]) === false) {
3529
+ $lastNotEmpty = $i;
3530
+ }
3531
+ }//end for
3532
+
3533
+ return ($this->numTokens - 1);
3534
+
3535
+ }//end findEndOfStatement()
3536
+
3537
+
3538
+ /**
3539
+ * Returns the position of the first token on a line, matching given type.
3540
+ *
3541
+ * Returns false if no token can be found.
3542
+ *
3543
+ * @param int|array $types The type(s) of tokens to search for.
3544
+ * @param int $start The position to start searching from in the
3545
+ * token stack. The first token matching on
3546
+ * this line before this token will be returned.
3547
+ * @param bool $exclude If true, find the token that is NOT of
3548
+ * the types specified in $types.
3549
+ * @param string $value The value that the token must be equal to.
3550
+ * If value is omitted, tokens with any value will
3551
+ * be returned.
3552
+ *
3553
+ * @return int | bool
3554
+ */
3555
+ public function findFirstOnLine($types, $start, $exclude=false, $value=null)
3556
+ {
3557
+ if (is_array($types) === false) {
3558
+ $types = array($types);
3559
+ }
3560
+
3561
+ $foundToken = false;
3562
+
3563
+ for ($i = $start; $i >= 0; $i--) {
3564
+ if ($this->_tokens[$i]['line'] < $this->_tokens[$start]['line']) {
3565
+ break;
3566
+ }
3567
+
3568
+ $found = $exclude;
3569
+ foreach ($types as $type) {
3570
+ if ($exclude === false) {
3571
+ if ($this->_tokens[$i]['code'] === $type) {
3572
+ $found = true;
3573
+ break;
3574
+ }
3575
+ } else {
3576
+ if ($this->_tokens[$i]['code'] === $type) {
3577
+ $found = false;
3578
+ break;
3579
+ }
3580
+ }
3581
+ }
3582
+
3583
+ if ($found === true) {
3584
+ if ($value === null) {
3585
+ $foundToken = $i;
3586
+ } else if ($this->_tokens[$i]['content'] === $value) {
3587
+ $foundToken = $i;
3588
+ }
3589
+ }
3590
+ }//end for
3591
+
3592
+ return $foundToken;
3593
+
3594
+ }//end findFirstOnLine()
3595
+
3596
+
3597
+ /**
3598
+ * Determine if the passed token has a condition of one of the passed types.
3599
+ *
3600
+ * @param int $stackPtr The position of the token we are checking.
3601
+ * @param int|array $types The type(s) of tokens to search for.
3602
+ *
3603
+ * @return boolean
3604
+ */
3605
+ public function hasCondition($stackPtr, $types)
3606
+ {
3607
+ // Check for the existence of the token.
3608
+ if (isset($this->_tokens[$stackPtr]) === false) {
3609
+ return false;
3610
+ }
3611
+
3612
+ // Make sure the token has conditions.
3613
+ if (isset($this->_tokens[$stackPtr]['conditions']) === false) {
3614
+ return false;
3615
+ }
3616
+
3617
+ $types = (array) $types;
3618
+ $conditions = $this->_tokens[$stackPtr]['conditions'];
3619
+
3620
+ foreach ($types as $type) {
3621
+ if (in_array($type, $conditions) === true) {
3622
+ // We found a token with the required type.
3623
+ return true;
3624
+ }
3625
+ }
3626
+
3627
+ return false;
3628
+
3629
+ }//end hasCondition()
3630
+
3631
+
3632
+ /**
3633
+ * Return the position of the condition for the passed token.
3634
+ *
3635
+ * Returns FALSE if the token does not have the condition.
3636
+ *
3637
+ * @param int $stackPtr The position of the token we are checking.
3638
+ * @param int $type The type of token to search for.
3639
+ *
3640
+ * @return int
3641
+ */
3642
+ public function getCondition($stackPtr, $type)
3643
+ {
3644
+ // Check for the existence of the token.
3645
+ if (isset($this->_tokens[$stackPtr]) === false) {
3646
+ return false;
3647
+ }
3648
+
3649
+ // Make sure the token has conditions.
3650
+ if (isset($this->_tokens[$stackPtr]['conditions']) === false) {
3651
+ return false;
3652
+ }
3653
+
3654
+ $conditions = $this->_tokens[$stackPtr]['conditions'];
3655
+ foreach ($conditions as $token => $condition) {
3656
+ if ($condition === $type) {
3657
+ return $token;
3658
+ }
3659
+ }
3660
+
3661
+ return false;
3662
+
3663
+ }//end getCondition()
3664
+
3665
+
3666
+ /**
3667
+ * Returns the name of the class that the specified class extends.
3668
+ *
3669
+ * Returns FALSE on error or if there is no extended class name.
3670
+ *
3671
+ * @param int $stackPtr The stack position of the class.
3672
+ *
3673
+ * @return string
3674
+ */
3675
+ public function findExtendedClassName($stackPtr)
3676
+ {
3677
+ // Check for the existence of the token.
3678
+ if (isset($this->_tokens[$stackPtr]) === false) {
3679
+ return false;
3680
+ }
3681
+
3682
+ if ($this->_tokens[$stackPtr]['code'] !== T_CLASS) {
3683
+ return false;
3684
+ }
3685
+
3686
+ if (isset($this->_tokens[$stackPtr]['scope_closer']) === false) {
3687
+ return false;
3688
+ }
3689
+
3690
+ $classCloserIndex = $this->_tokens[$stackPtr]['scope_closer'];
3691
+ $extendsIndex = $this->findNext(T_EXTENDS, $stackPtr, $classCloserIndex);
3692
+ if (false === $extendsIndex) {
3693
+ return false;
3694
+ }
3695
+
3696
+ $find = array(
3697
+ T_NS_SEPARATOR,
3698
+ T_STRING,
3699
+ T_WHITESPACE,
3700
+ );
3701
+
3702
+ $end = $this->findNext($find, ($extendsIndex + 1), $classCloserIndex, true);
3703
+ $name = $this->getTokensAsString(($extendsIndex + 1), ($end - $extendsIndex - 1));
3704
+ $name = trim($name);
3705
+
3706
+ if ($name === '') {
3707
+ return false;
3708
+ }
3709
+
3710
+ return $name;
3711
+
3712
+ }//end findExtendedClassName()
3713
+
3714
+
3715
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Fixer.php ADDED
@@ -0,0 +1,734 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * A helper class for fixing errors.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Greg Sherwood <gsherwood@squiz.net>
10
+ * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600)
11
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
12
+ * @link http://pear.php.net/package/PHP_CodeSniffer
13
+ */
14
+
15
+ /**
16
+ * A helper class for fixing errors.
17
+ *
18
+ * Provides helper functions that act upon a token array and modify the file
19
+ * content.
20
+ *
21
+ * @category PHP
22
+ * @package PHP_CodeSniffer
23
+ * @author Greg Sherwood <gsherwood@squiz.net>
24
+ * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600)
25
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
26
+ * @version Release: @package_version@
27
+ * @link http://pear.php.net/package/PHP_CodeSniffer
28
+ */
29
+ class PHP_CodeSniffer_Fixer
30
+ {
31
+
32
+ /**
33
+ * Is the fixer enabled and fixing a file?
34
+ *
35
+ * Sniffs should check this value to ensure they are not
36
+ * doing extra processing to prepare for a fix when fixing is
37
+ * not required.
38
+ *
39
+ * @var boolean
40
+ */
41
+ public $enabled = false;
42
+
43
+ /**
44
+ * The number of times we have looped over a file.
45
+ *
46
+ * @var int
47
+ */
48
+ public $loops = 0;
49
+
50
+ /**
51
+ * The file being fixed.
52
+ *
53
+ * @var PHP_CodeSniffer_File
54
+ */
55
+ private $_currentFile = null;
56
+
57
+ /**
58
+ * The list of tokens that make up the file contents.
59
+ *
60
+ * This is a simplified list which just contains the token content and nothing
61
+ * else. This is the array that is updated as fixes are made, not the file's
62
+ * token array. Imploding this array will give you the file content back.
63
+ *
64
+ * @var array(int => string)
65
+ */
66
+ private $_tokens = array();
67
+
68
+ /**
69
+ * A list of tokens that have already been fixed.
70
+ *
71
+ * We don't allow the same token to be fixed more than once each time
72
+ * through a file as this can easily cause conflicts between sniffs.
73
+ *
74
+ * @var array(int)
75
+ */
76
+ private $_fixedTokens = array();
77
+
78
+ /**
79
+ * The last value of each fixed token.
80
+ *
81
+ * If a token is being "fixed" back to its last value, the fix is
82
+ * probably conflicting with another.
83
+ *
84
+ * @var array(int => string)
85
+ */
86
+ private $_oldTokenValues = array();
87
+
88
+ /**
89
+ * A list of tokens that have been fixed during a changeset.
90
+ *
91
+ * All changes in changeset must be able to be applied, or else
92
+ * the entire changeset is rejected.
93
+ *
94
+ * @var array()
95
+ */
96
+ private $_changeset = array();
97
+
98
+ /**
99
+ * Is there an open changeset.
100
+ *
101
+ * @var boolean
102
+ */
103
+ private $_inChangeset = false;
104
+
105
+ /**
106
+ * Is the current fixing loop in conflict?
107
+ *
108
+ * @var boolean
109
+ */
110
+ private $_inConflict = false;
111
+
112
+ /**
113
+ * The number of fixes that have been performed.
114
+ *
115
+ * @var int
116
+ */
117
+ private $_numFixes = 0;
118
+
119
+
120
+ /**
121
+ * Starts fixing a new file.
122
+ *
123
+ * @param PHP_CodeSniffer_File $phpcsFile The file being fixed.
124
+ *
125
+ * @return void
126
+ */
127
+ public function startFile($phpcsFile)
128
+ {
129
+ $this->_currentFile = $phpcsFile;
130
+ $this->_numFixes = 0;
131
+ $this->_fixedTokens = array();
132
+
133
+ $tokens = $phpcsFile->getTokens();
134
+ $this->_tokens = array();
135
+ foreach ($tokens as $index => $token) {
136
+ if (isset($token['orig_content']) === true) {
137
+ $this->_tokens[$index] = $token['orig_content'];
138
+ } else {
139
+ $this->_tokens[$index] = $token['content'];
140
+ }
141
+ }
142
+
143
+ }//end startFile()
144
+
145
+
146
+ /**
147
+ * Attempt to fix the file by processing it until no fixes are made.
148
+ *
149
+ * @return boolean
150
+ */
151
+ public function fixFile()
152
+ {
153
+ $fixable = $this->_currentFile->getFixableCount();
154
+ if ($fixable === 0) {
155
+ // Nothing to fix.
156
+ return false;
157
+ }
158
+
159
+ $stdin = false;
160
+ $cliValues = $this->_currentFile->phpcs->cli->getCommandLineValues();
161
+ if (empty($cliValues['files']) === true) {
162
+ $stdin = true;
163
+ }
164
+
165
+ $this->enabled = true;
166
+
167
+ $this->loops = 0;
168
+ while ($this->loops < 50) {
169
+ ob_start();
170
+
171
+ // Only needed once file content has changed.
172
+ $contents = $this->getContents();
173
+
174
+ if (PHP_CODESNIFFER_VERBOSITY > 2) {
175
+ @ob_end_clean();
176
+ echo '---START FILE CONTENT---'.PHP_EOL;
177
+ $lines = explode($this->_currentFile->eolChar, $contents);
178
+ $max = strlen(count($lines));
179
+ foreach ($lines as $lineNum => $line) {
180
+ $lineNum++;
181
+ echo str_pad($lineNum, $max, ' ', STR_PAD_LEFT).'|'.$line.PHP_EOL;
182
+ }
183
+
184
+ echo '--- END FILE CONTENT ---'.PHP_EOL;
185
+ ob_start();
186
+ }
187
+
188
+ $this->_inConflict = false;
189
+ $this->_currentFile->refreshTokenListeners();
190
+ $this->_currentFile->start($contents);
191
+ ob_end_clean();
192
+
193
+ $this->loops++;
194
+
195
+ if (PHP_CODESNIFFER_CBF === true && $stdin === false) {
196
+ echo "\r".str_repeat(' ', 80)."\r";
197
+ echo "\t=> Fixing file: $this->_numFixes/$fixable violations remaining [made $this->loops pass";
198
+ if ($this->loops > 1) {
199
+ echo 'es';
200
+ }
201
+
202
+ echo ']... ';
203
+ }
204
+
205
+ if ($this->_numFixes === 0 && $this->_inConflict === false) {
206
+ // Nothing left to do.
207
+ break;
208
+ } else if (PHP_CODESNIFFER_VERBOSITY > 1) {
209
+ echo "\t* fixed $this->_numFixes violations, starting loop ".($this->loops + 1).' *'.PHP_EOL;
210
+ }
211
+ }//end while
212
+
213
+ $this->enabled = false;
214
+
215
+ if ($this->_numFixes > 0) {
216
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
217
+ @ob_end_clean();
218
+ echo "\t*** Reached maximum number of loops with $this->_numFixes violations left unfixed ***".PHP_EOL;
219
+ ob_start();
220
+ }
221
+
222
+ return false;
223
+ }
224
+
225
+ return true;
226
+
227
+ }//end fixFile()
228
+
229
+
230
+ /**
231
+ * Generates a text diff of the original file and the new content.
232
+ *
233
+ * @param string $filePath Optional file path to diff the file against.
234
+ * If not specified, the original version of the
235
+ * file will be used.
236
+ * @param boolean $colors Print colored output or not.
237
+ *
238
+ * @return string
239
+ */
240
+ public function generateDiff($filePath=null, $colors=true)
241
+ {
242
+ if ($filePath === null) {
243
+ $filePath = $this->_currentFile->getFilename();
244
+ }
245
+
246
+ $cwd = getcwd().DIRECTORY_SEPARATOR;
247
+ $filename = str_replace($cwd, '', $filePath);
248
+ $contents = $this->getContents();
249
+
250
+ if (function_exists('sys_get_temp_dir') === true) {
251
+ // This is needed for HHVM support, but only available from 5.2.1.
252
+ $tempName = tempnam(sys_get_temp_dir(), 'phpcs-fixer');
253
+ $fixedFile = fopen($tempName, 'w');
254
+ } else {
255
+ $fixedFile = tmpfile();
256
+ $data = stream_get_meta_data($fixedFile);
257
+ $tempName = $data['uri'];
258
+ }
259
+
260
+ fwrite($fixedFile, $contents);
261
+
262
+ // We must use something like shell_exec() because whitespace at the end
263
+ // of lines is critical to diff files.
264
+ $cmd = "diff -u -L\"$filename\" -LPHP_CodeSniffer \"$filename\" \"$tempName\"";
265
+ $diff = shell_exec($cmd);
266
+
267
+ fclose($fixedFile);
268
+ if (is_file($tempName) === true) {
269
+ unlink($tempName);
270
+ }
271
+
272
+ if ($colors === false) {
273
+ return $diff;
274
+ }
275
+
276
+ $diffLines = explode(PHP_EOL, $diff);
277
+ if (count($diffLines) === 1) {
278
+ // Seems to be required for cygwin.
279
+ $diffLines = explode("\n", $diff);
280
+ }
281
+
282
+ $diff = array();
283
+ foreach ($diffLines as $line) {
284
+ if (isset($line[0]) === true) {
285
+ switch ($line[0]) {
286
+ case '-':
287
+ $diff[] = "\033[31m$line\033[0m";
288
+ break;
289
+ case '+':
290
+ $diff[] = "\033[32m$line\033[0m";
291
+ break;
292
+ default:
293
+ $diff[] = $line;
294
+ }
295
+ }
296
+ }
297
+
298
+ $diff = implode(PHP_EOL, $diff);
299
+
300
+ return $diff;
301
+
302
+ }//end generateDiff()
303
+
304
+
305
+ /**
306
+ * Get a count of fixes that have been performed on the file.
307
+ *
308
+ * This value is reset every time a new file is started, or an existing
309
+ * file is restarted.
310
+ *
311
+ * @return int
312
+ */
313
+ public function getFixCount()
314
+ {
315
+ return $this->_numFixes;
316
+
317
+ }//end getFixCount()
318
+
319
+
320
+ /**
321
+ * Get the current content of the file, as a string.
322
+ *
323
+ * @return string
324
+ */
325
+ public function getContents()
326
+ {
327
+ $contents = implode($this->_tokens);
328
+ return $contents;
329
+
330
+ }//end getContents()
331
+
332
+
333
+ /**
334
+ * Get the current fixed content of a token.
335
+ *
336
+ * This function takes changesets into account so should be used
337
+ * instead of directly accessing the token array.
338
+ *
339
+ * @param int $stackPtr The position of the token in the token stack.
340
+ *
341
+ * @return string
342
+ */
343
+ public function getTokenContent($stackPtr)
344
+ {
345
+ if ($this->_inChangeset === true
346
+ && isset($this->_changeset[$stackPtr]) === true
347
+ ) {
348
+ return $this->_changeset[$stackPtr];
349
+ } else {
350
+ return $this->_tokens[$stackPtr];
351
+ }
352
+
353
+ }//end getTokenContent()
354
+
355
+
356
+ /**
357
+ * Start recording actions for a changeset.
358
+ *
359
+ * @return void
360
+ */
361
+ public function beginChangeset()
362
+ {
363
+ if ($this->_inConflict === true) {
364
+ return false;
365
+ }
366
+
367
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
368
+ $bt = debug_backtrace();
369
+ $sniff = $bt[1]['class'];
370
+ $line = $bt[0]['line'];
371
+
372
+ @ob_end_clean();
373
+ echo "\t=> Changeset started by $sniff (line $line)".PHP_EOL;
374
+ ob_start();
375
+ }
376
+
377
+ $this->_changeset = array();
378
+ $this->_inChangeset = true;
379
+
380
+ }//end beginChangeset()
381
+
382
+
383
+ /**
384
+ * Stop recording actions for a changeset, and apply logged changes.
385
+ *
386
+ * @return boolean
387
+ */
388
+ public function endChangeset()
389
+ {
390
+ if ($this->_inConflict === true) {
391
+ return false;
392
+ }
393
+
394
+ $this->_inChangeset = false;
395
+
396
+ $success = true;
397
+ $applied = array();
398
+ foreach ($this->_changeset as $stackPtr => $content) {
399
+ $success = $this->replaceToken($stackPtr, $content);
400
+ if ($success === false) {
401
+ break;
402
+ } else {
403
+ $applied[] = $stackPtr;
404
+ }
405
+ }
406
+
407
+ if ($success === false) {
408
+ // Rolling back all changes.
409
+ foreach ($applied as $stackPtr) {
410
+ $this->revertToken($stackPtr);
411
+ }
412
+
413
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
414
+ @ob_end_clean();
415
+ echo "\t=> Changeset failed to apply".PHP_EOL;
416
+ ob_start();
417
+ }
418
+ } else if (PHP_CODESNIFFER_VERBOSITY > 1) {
419
+ $fixes = count($this->_changeset);
420
+ @ob_end_clean();
421
+ echo "\t=> Changeset ended: $fixes changes applied".PHP_EOL;
422
+ ob_start();
423
+ }
424
+
425
+ $this->_changeset = array();
426
+
427
+ }//end endChangeset()
428
+
429
+
430
+ /**
431
+ * Stop recording actions for a changeset, and discard logged changes.
432
+ *
433
+ * @return void
434
+ */
435
+ public function rollbackChangeset()
436
+ {
437
+ $this->_inChangeset = false;
438
+ $this->_inConflict = false;
439
+
440
+ if (empty($this->_changeset) === false) {
441
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
442
+ $bt = debug_backtrace();
443
+ if ($bt[1]['class'] === 'PHP_CodeSniffer_Fixer') {
444
+ $sniff = $bt[2]['class'];
445
+ $line = $bt[1]['line'];
446
+ } else {
447
+ $sniff = $bt[1]['class'];
448
+ $line = $bt[0]['line'];
449
+ }
450
+
451
+ $numChanges = count($this->_changeset);
452
+
453
+ @ob_end_clean();
454
+ echo "\t\tR: $sniff (line $line) rolled back the changeset ($numChanges changes)".PHP_EOL;
455
+ echo "\t=> Changeset rolled back".PHP_EOL;
456
+ ob_start();
457
+ }
458
+
459
+ $this->_changeset = array();
460
+ }//end if
461
+
462
+ }//end rollbackChangeset()
463
+
464
+
465
+ /**
466
+ * Replace the entire contents of a token.
467
+ *
468
+ * @param int $stackPtr The position of the token in the token stack.
469
+ * @param string $content The new content of the token.
470
+ *
471
+ * @return bool If the change was accepted.
472
+ */
473
+ public function replaceToken($stackPtr, $content)
474
+ {
475
+ if ($this->_inConflict === true) {
476
+ return false;
477
+ }
478
+
479
+ if ($this->_inChangeset === false
480
+ && isset($this->_fixedTokens[$stackPtr]) === true
481
+ ) {
482
+ $indent = "\t";
483
+ if (empty($this->_changeset) === false) {
484
+ $indent .= "\t";
485
+ }
486
+
487
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
488
+ @ob_end_clean();
489
+ echo "$indent* token $stackPtr has already been modified, skipping *".PHP_EOL;
490
+ ob_start();
491
+ }
492
+
493
+ return false;
494
+ }
495
+
496
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
497
+ $bt = debug_backtrace();
498
+ if ($bt[1]['class'] === 'PHP_CodeSniffer_Fixer') {
499
+ $sniff = $bt[2]['class'];
500
+ $line = $bt[1]['line'];
501
+ } else {
502
+ $sniff = $bt[1]['class'];
503
+ $line = $bt[0]['line'];
504
+ }
505
+
506
+ $tokens = $this->_currentFile->getTokens();
507
+ $type = $tokens[$stackPtr]['type'];
508
+ $oldContent = PHP_CodeSniffer::prepareForOutput($this->_tokens[$stackPtr]);
509
+ $newContent = PHP_CodeSniffer::prepareForOutput($content);
510
+ if (trim($this->_tokens[$stackPtr]) === '' && isset($this->_tokens[($stackPtr + 1)]) === true) {
511
+ // Add some context for whitespace only changes.
512
+ $append = PHP_CodeSniffer::prepareForOutput($this->_tokens[($stackPtr + 1)]);
513
+ $oldContent .= $append;
514
+ $newContent .= $append;
515
+ }
516
+ }//end if
517
+
518
+ if ($this->_inChangeset === true) {
519
+ $this->_changeset[$stackPtr] = $content;
520
+
521
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
522
+ @ob_end_clean();
523
+ echo "\t\tQ: $sniff (line $line) replaced token $stackPtr ($type) \"$oldContent\" => \"$newContent\"".PHP_EOL;
524
+ ob_start();
525
+ }
526
+
527
+ return true;
528
+ }
529
+
530
+ if (isset($this->_oldTokenValues[$stackPtr]) === false) {
531
+ $this->_oldTokenValues[$stackPtr] = array(
532
+ 'curr' => $content,
533
+ 'prev' => $this->_tokens[$stackPtr],
534
+ 'loop' => $this->loops,
535
+ );
536
+ } else {
537
+ if ($this->_oldTokenValues[$stackPtr]['prev'] === $content
538
+ && $this->_oldTokenValues[$stackPtr]['loop'] === ($this->loops - 1)
539
+ ) {
540
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
541
+ $indent = "\t";
542
+ if (empty($this->_changeset) === false) {
543
+ $indent .= "\t";
544
+ }
545
+
546
+ $loop = $this->_oldTokenValues[$stackPtr]['loop'];
547
+
548
+ @ob_end_clean();
549
+ echo "$indent**** $sniff (line $line) has possible conflict with another sniff on loop $loop; caused by the following change ****".PHP_EOL;
550
+ echo "$indent**** replaced token $stackPtr ($type) \"$oldContent\" => \"$newContent\" ****".PHP_EOL;
551
+ }
552
+
553
+ if ($this->_oldTokenValues[$stackPtr]['loop'] >= ($this->loops - 1)) {
554
+ $this->_inConflict = true;
555
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
556
+ echo "$indent**** ignoring all changes until next loop ****".PHP_EOL;
557
+ }
558
+ }
559
+
560
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
561
+ ob_start();
562
+ }
563
+
564
+ return false;
565
+ }//end if
566
+
567
+ $this->_oldTokenValues[$stackPtr]['prev'] = $this->_oldTokenValues[$stackPtr]['curr'];
568
+ $this->_oldTokenValues[$stackPtr]['curr'] = $content;
569
+ $this->_oldTokenValues[$stackPtr]['loop'] = $this->loops;
570
+ }//end if
571
+
572
+ $this->_fixedTokens[$stackPtr] = $this->_tokens[$stackPtr];
573
+ $this->_tokens[$stackPtr] = $content;
574
+ $this->_numFixes++;
575
+
576
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
577
+ $indent = "\t";
578
+ if (empty($this->_changeset) === false) {
579
+ $indent .= "\tA: ";
580
+ }
581
+
582
+ @ob_end_clean();
583
+ echo "$indent$sniff (line $line) replaced token $stackPtr ($type) \"$oldContent\" => \"$newContent\"".PHP_EOL;
584
+ ob_start();
585
+ }
586
+
587
+ return true;
588
+
589
+ }//end replaceToken()
590
+
591
+
592
+ /**
593
+ * Reverts the previous fix made to a token.
594
+ *
595
+ * @param int $stackPtr The position of the token in the token stack.
596
+ *
597
+ * @return bool If a change was reverted.
598
+ */
599
+ public function revertToken($stackPtr)
600
+ {
601
+ if (isset($this->_fixedTokens[$stackPtr]) === false) {
602
+ return false;
603
+ }
604
+
605
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
606
+ $bt = debug_backtrace();
607
+ if ($bt[1]['class'] === 'PHP_CodeSniffer_Fixer') {
608
+ $sniff = $bt[2]['class'];
609
+ $line = $bt[1]['line'];
610
+ } else {
611
+ $sniff = $bt[1]['class'];
612
+ $line = $bt[0]['line'];
613
+ }
614
+
615
+ $tokens = $this->_currentFile->getTokens();
616
+ $type = $tokens[$stackPtr]['type'];
617
+ $oldContent = PHP_CodeSniffer::prepareForOutput($this->_tokens[$stackPtr]);
618
+ $newContent = PHP_CodeSniffer::prepareForOutput($this->_fixedTokens[$stackPtr]);
619
+ if (trim($this->_tokens[$stackPtr]) === '' && isset($tokens[($stackPtr + 1)]) === true) {
620
+ // Add some context for whitespace only changes.
621
+ $append = PHP_CodeSniffer::prepareForOutput($this->_tokens[($stackPtr + 1)]);
622
+ $oldContent .= $append;
623
+ $newContent .= $append;
624
+ }
625
+ }//end if
626
+
627
+ $this->_tokens[$stackPtr] = $this->_fixedTokens[$stackPtr];
628
+ unset($this->_fixedTokens[$stackPtr]);
629
+ $this->_numFixes--;
630
+
631
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
632
+ $indent = "\t";
633
+ if (empty($this->_changeset) === false) {
634
+ $indent .= "\tR: ";
635
+ }
636
+
637
+ @ob_end_clean();
638
+ echo "$indent$sniff (line $line) reverted token $stackPtr ($type) \"$oldContent\" => \"$newContent\"".PHP_EOL;
639
+ ob_start();
640
+ }
641
+
642
+ return true;
643
+
644
+ }//end revertToken()
645
+
646
+
647
+ /**
648
+ * Replace the content of a token with a part of its current content.
649
+ *
650
+ * @param int $stackPtr The position of the token in the token stack.
651
+ * @param int $start The first character to keep.
652
+ * @param int $length The number of chacters to keep. If NULL, the content of
653
+ * the token from $start to the end of the content is kept.
654
+ *
655
+ * @return bool If the change was accepted.
656
+ */
657
+ public function substrToken($stackPtr, $start, $length=null)
658
+ {
659
+ $current = $this->getTokenContent($stackPtr);
660
+
661
+ if ($length === null) {
662
+ $newContent = substr($current, $start);
663
+ } else {
664
+ $newContent = substr($current, $start, $length);
665
+ }
666
+
667
+ return $this->replaceToken($stackPtr, $newContent);
668
+
669
+ }//end substrToken()
670
+
671
+
672
+ /**
673
+ * Adds a newline to end of a token's content.
674
+ *
675
+ * @param int $stackPtr The position of the token in the token stack.
676
+ *
677
+ * @return bool If the change was accepted.
678
+ */
679
+ public function addNewline($stackPtr)
680
+ {
681
+ $current = $this->getTokenContent($stackPtr);
682
+ return $this->replaceToken($stackPtr, $current.$this->_currentFile->eolChar);
683
+
684
+ }//end addNewline()
685
+
686
+
687
+ /**
688
+ * Adds a newline to the start of a token's content.
689
+ *
690
+ * @param int $stackPtr The position of the token in the token stack.
691
+ *
692
+ * @return bool If the change was accepted.
693
+ */
694
+ public function addNewlineBefore($stackPtr)
695
+ {
696
+ $current = $this->getTokenContent($stackPtr);
697
+ return $this->replaceToken($stackPtr, $this->_currentFile->eolChar.$current);
698
+
699
+ }//end addNewlineBefore()
700
+
701
+
702
+ /**
703
+ * Adds content to the end of a token's current content.
704
+ *
705
+ * @param int $stackPtr The position of the token in the token stack.
706
+ * @param string $content The content to add.
707
+ *
708
+ * @return bool If the change was accepted.
709
+ */
710
+ public function addContent($stackPtr, $content)
711
+ {
712
+ $current = $this->getTokenContent($stackPtr);
713
+ return $this->replaceToken($stackPtr, $current.$content);
714
+
715
+ }//end addContent()
716
+
717
+
718
+ /**
719
+ * Adds content to the start of a token's current content.
720
+ *
721
+ * @param int $stackPtr The position of the token in the token stack.
722
+ * @param string $content The content to add.
723
+ *
724
+ * @return bool If the change was accepted.
725
+ */
726
+ public function addContentBefore($stackPtr, $content)
727
+ {
728
+ $current = $this->getTokenContent($stackPtr);
729
+ return $this->replaceToken($stackPtr, $content.$current);
730
+
731
+ }//end addContentBefore()
732
+
733
+
734
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Report.php ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Represents a PHP_CodeSniffer report.
4
+ *
5
+ * PHP version 5.
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Gabriele Santini <gsantini@sqli.com>
10
+ * @author Greg Sherwood <gsherwood@squiz.net>
11
+ * @copyright 2009-2014 SQLI <www.sqli.com>
12
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
13
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
14
+ * @link http://pear.php.net/package/PHP_CodeSniffer
15
+ */
16
+
17
+ /**
18
+ * Represents a PHP_CodeSniffer report.
19
+ *
20
+ * @category PHP
21
+ * @package PHP_CodeSniffer
22
+ * @author Gabriele Santini <gsantini@sqli.com>
23
+ * @author Greg Sherwood <gsherwood@squiz.net>
24
+ * @copyright 2009-2014 SQLI <www.sqli.com>
25
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
26
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
27
+ * @version Release: @package_version@
28
+ * @link http://pear.php.net/package/PHP_CodeSniffer
29
+ */
30
+ interface PHP_CodeSniffer_Report
31
+ {
32
+
33
+
34
+ /**
35
+ * Generate a partial report for a single processed file.
36
+ *
37
+ * Function should return TRUE if it printed or stored data about the file
38
+ * and FALSE if it ignored the file. Returning TRUE indicates that the file and
39
+ * its data should be counted in the grand totals.
40
+ *
41
+ * @param array $report Prepared report data.
42
+ * @param PHP_CodeSniffer_File $phpcsFile The file being reported on.
43
+ * @param boolean $showSources Show sources?
44
+ * @param int $width Maximum allowed line width.
45
+ *
46
+ * @return boolean
47
+ */
48
+ public function generateFileReport(
49
+ $report,
50
+ PHP_CodeSniffer_File $phpcsFile,
51
+ $showSources=false,
52
+ $width=80
53
+ );
54
+
55
+
56
+ /**
57
+ * Generate the actual report.
58
+ *
59
+ * @param string $cachedData Any partial report data that was returned from
60
+ * generateFileReport during the run.
61
+ * @param int $totalFiles Total number of files processed during the run.
62
+ * @param int $totalErrors Total number of errors found during the run.
63
+ * @param int $totalWarnings Total number of warnings found during the run.
64
+ * @param int $totalFixable Total number of problems that can be fixed.
65
+ * @param boolean $showSources Show sources?
66
+ * @param int $width Maximum allowed line width.
67
+ * @param boolean $toScreen Is the report being printed to screen?
68
+ *
69
+ * @return void
70
+ */
71
+ public function generate(
72
+ $cachedData,
73
+ $totalFiles,
74
+ $totalErrors,
75
+ $totalWarnings,
76
+ $totalFixable,
77
+ $showSources=false,
78
+ $width=80,
79
+ $toScreen=true
80
+ );
81
+
82
+
83
+ }//end interface
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reporting.php ADDED
@@ -0,0 +1,425 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * A class to manage reporting.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Gabriele Santini <gsantini@sqli.com>
10
+ * @author Greg Sherwood <gsherwood@squiz.net>
11
+ * @copyright 2009-2014 SQLI <www.sqli.com>
12
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
13
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
14
+ * @link http://pear.php.net/package/PHP_CodeSniffer
15
+ */
16
+
17
+ /**
18
+ * A class to manage reporting.
19
+ *
20
+ * @category PHP
21
+ * @package PHP_CodeSniffer
22
+ * @author Gabriele Santini <gsantini@sqli.com>
23
+ * @author Greg Sherwood <gsherwood@squiz.net>
24
+ * @copyright 2009-2014 SQLI <www.sqli.com>
25
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
26
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
27
+ * @version Release: @package_version@
28
+ * @link http://pear.php.net/package/PHP_CodeSniffer
29
+ */
30
+ class PHP_CodeSniffer_Reporting
31
+ {
32
+
33
+ /**
34
+ * Total number of files that contain errors or warnings.
35
+ *
36
+ * @var int
37
+ */
38
+ public $totalFiles = 0;
39
+
40
+ /**
41
+ * Total number of errors found during the run.
42
+ *
43
+ * @var int
44
+ */
45
+ public $totalErrors = 0;
46
+
47
+ /**
48
+ * Total number of warnings found during the run.
49
+ *
50
+ * @var int
51
+ */
52
+ public $totalWarnings = 0;
53
+
54
+ /**
55
+ * Total number of errors/warnings that can be fixed.
56
+ *
57
+ * @var int
58
+ */
59
+ public $totalFixable = 0;
60
+
61
+ /**
62
+ * When the PHPCS run started.
63
+ *
64
+ * @var float
65
+ */
66
+ public static $startTime = 0;
67
+
68
+ /**
69
+ * A list of reports that have written partial report output.
70
+ *
71
+ * @var array
72
+ */
73
+ private $_cachedReports = array();
74
+
75
+ /**
76
+ * A cache of report objects.
77
+ *
78
+ * @var array
79
+ */
80
+ private $_reports = array();
81
+
82
+ /**
83
+ * A cache of opened tmp files.
84
+ *
85
+ * @var array
86
+ */
87
+ private $_tmpFiles = array();
88
+
89
+
90
+ /**
91
+ * Produce the appropriate report object based on $type parameter.
92
+ *
93
+ * @param string $type The type of the report.
94
+ *
95
+ * @return PHP_CodeSniffer_Report
96
+ * @throws PHP_CodeSniffer_Exception If report is not available.
97
+ */
98
+ public function factory($type)
99
+ {
100
+ $type = ucfirst($type);
101
+ if (isset($this->_reports[$type]) === true) {
102
+ return $this->_reports[$type];
103
+ }
104
+
105
+ if (strpos($type, '.') !== false) {
106
+ // This is a path to a custom report class.
107
+ $filename = realpath($type);
108
+ if ($filename === false) {
109
+ echo 'ERROR: Custom report "'.$type.'" not found'.PHP_EOL;
110
+ exit(2);
111
+ }
112
+
113
+ $reportClassName = 'PHP_CodeSniffer_Reports_'.basename($filename);
114
+ $reportClassName = substr($reportClassName, 0, strpos($reportClassName, '.'));
115
+ include_once $filename;
116
+ } else {
117
+ $filename = $type.'.php';
118
+ $reportClassName = 'PHP_CodeSniffer_Reports_'.$type;
119
+ if (class_exists($reportClassName, true) === false) {
120
+ echo 'ERROR: Report type "'.$type.'" not found'.PHP_EOL;
121
+ exit(2);
122
+ }
123
+ }//end if
124
+
125
+ $reportClass = new $reportClassName();
126
+ if (false === ($reportClass instanceof PHP_CodeSniffer_Report)) {
127
+ throw new PHP_CodeSniffer_Exception('Class "'.$reportClassName.'" must implement the "PHP_CodeSniffer_Report" interface.');
128
+ }
129
+
130
+ $this->_reports[$type] = $reportClass;
131
+ return $this->_reports[$type];
132
+
133
+ }//end factory()
134
+
135
+
136
+ /**
137
+ * Actually generates the report.
138
+ *
139
+ * @param PHP_CodeSniffer_File $phpcsFile The file that has been processed.
140
+ * @param array $cliValues An array of command line arguments.
141
+ *
142
+ * @return void
143
+ */
144
+ public function cacheFileReport(PHP_CodeSniffer_File $phpcsFile, array $cliValues)
145
+ {
146
+ if (isset($cliValues['reports']) === false) {
147
+ // This happens during unit testing, or any time someone just wants
148
+ // the error data and not the printed report.
149
+ return;
150
+ }
151
+
152
+ $reportData = $this->prepareFileReport($phpcsFile);
153
+ $errorsShown = false;
154
+
155
+ foreach ($cliValues['reports'] as $report => $output) {
156
+ $reportClass = $this->factory($report);
157
+ $report = get_class($reportClass);
158
+
159
+ ob_start();
160
+ $result = $reportClass->generateFileReport($reportData, $phpcsFile, $cliValues['showSources'], $cliValues['reportWidth']);
161
+ if ($result === true) {
162
+ $errorsShown = true;
163
+ }
164
+
165
+ $generatedReport = ob_get_contents();
166
+ ob_end_clean();
167
+
168
+ if ($output === null && $cliValues['reportFile'] !== null) {
169
+ $output = $cliValues['reportFile'];
170
+ }
171
+
172
+ if ($output === null) {
173
+ // Using a temp file.
174
+ if (isset($this->_tmpFiles[$report]) === false) {
175
+ if (function_exists('sys_get_temp_dir') === true) {
176
+ // This is needed for HHVM support, but only available from 5.2.1.
177
+ $this->_tmpFiles[$report] = fopen(tempnam(sys_get_temp_dir(), 'phpcs'), 'w');
178
+ } else {
179
+ $this->_tmpFiles[$report] = tmpfile();
180
+ }
181
+ }
182
+
183
+ fwrite($this->_tmpFiles[$report], $generatedReport);
184
+ } else {
185
+ $flags = FILE_APPEND;
186
+ if (isset($this->_cachedReports[$report]) === false) {
187
+ $this->_cachedReports[$report] = true;
188
+ $flags = null;
189
+ }
190
+
191
+ file_put_contents($output, $generatedReport, $flags);
192
+ }//end if
193
+ }//end foreach
194
+
195
+ if ($errorsShown === true) {
196
+ $this->totalFiles++;
197
+ $this->totalErrors += $reportData['errors'];
198
+ $this->totalWarnings += $reportData['warnings'];
199
+ $this->totalFixable += $reportData['fixable'];
200
+ }
201
+
202
+ }//end cacheFileReport()
203
+
204
+
205
+ /**
206
+ * Generates and prints a final report.
207
+ *
208
+ * Returns an array with the number of errors and the number of
209
+ * warnings, in the form ['errors' => int, 'warnings' => int].
210
+ *
211
+ * @param string $report Report type.
212
+ * @param boolean $showSources Show sources?
213
+ * @param array $cliValues An array of command line arguments.
214
+ * @param string $reportFile Report file to generate.
215
+ * @param integer $reportWidth Report max width.
216
+ *
217
+ * @return int[]
218
+ */
219
+ public function printReport(
220
+ $report,
221
+ $showSources,
222
+ array $cliValues,
223
+ $reportFile='',
224
+ $reportWidth=80
225
+ ) {
226
+ $reportClass = $this->factory($report);
227
+ $report = get_class($reportClass);
228
+
229
+ if ($reportFile !== null) {
230
+ $filename = $reportFile;
231
+ $toScreen = false;
232
+
233
+ if (file_exists($filename) === true
234
+ && isset($this->_cachedReports[$report]) === true
235
+ ) {
236
+ $reportCache = file_get_contents($filename);
237
+ } else {
238
+ $reportCache = '';
239
+ }
240
+ } else {
241
+ if (isset($this->_tmpFiles[$report]) === true) {
242
+ $data = stream_get_meta_data($this->_tmpFiles[$report]);
243
+ $filename = $data['uri'];
244
+ $reportCache = file_get_contents($filename);
245
+ fclose($this->_tmpFiles[$report]);
246
+ } else {
247
+ $reportCache = '';
248
+ $filename = null;
249
+ }
250
+
251
+ $toScreen = true;
252
+ }//end if
253
+
254
+ ob_start();
255
+ $reportClass->generate(
256
+ $reportCache,
257
+ $this->totalFiles,
258
+ $this->totalErrors,
259
+ $this->totalWarnings,
260
+ $this->totalFixable,
261
+ $showSources,
262
+ $reportWidth,
263
+ $toScreen
264
+ );
265
+ $generatedReport = ob_get_contents();
266
+ ob_end_clean();
267
+
268
+ if ($cliValues['colors'] !== true || $reportFile !== null) {
269
+ $generatedReport = preg_replace('`\033\[[0-9]+m`', '', $generatedReport);
270
+ }
271
+
272
+ if ($reportFile !== null) {
273
+ if (PHP_CODESNIFFER_VERBOSITY > 0) {
274
+ echo $generatedReport;
275
+ }
276
+
277
+ file_put_contents($reportFile, $generatedReport.PHP_EOL);
278
+ } else {
279
+ echo $generatedReport;
280
+ if ($filename !== null && file_exists($filename) === true) {
281
+ unlink($filename);
282
+ }
283
+ }
284
+
285
+ return array(
286
+ 'errors' => $this->totalErrors,
287
+ 'warnings' => $this->totalWarnings,
288
+ );
289
+
290
+ }//end printReport()
291
+
292
+
293
+ /**
294
+ * Pre-process and package violations for all files.
295
+ *
296
+ * Used by error reports to get a packaged list of all errors in each file.
297
+ *
298
+ * @param PHP_CodeSniffer_File $phpcsFile The file that has been processed.
299
+ *
300
+ * @return array
301
+ */
302
+ public function prepareFileReport(PHP_CodeSniffer_File $phpcsFile)
303
+ {
304
+ $report = array(
305
+ 'filename' => $phpcsFile->getFilename(),
306
+ 'errors' => $phpcsFile->getErrorCount(),
307
+ 'warnings' => $phpcsFile->getWarningCount(),
308
+ 'fixable' => $phpcsFile->getFixableCount(),
309
+ 'messages' => array(),
310
+ );
311
+
312
+ if ($report['errors'] === 0 && $report['warnings'] === 0) {
313
+ // Prefect score!
314
+ return $report;
315
+ }
316
+
317
+ $errors = array();
318
+
319
+ // Merge errors and warnings.
320
+ foreach ($phpcsFile->getErrors() as $line => $lineErrors) {
321
+ if (is_array($lineErrors) === false) {
322
+ continue;
323
+ }
324
+
325
+ foreach ($lineErrors as $column => $colErrors) {
326
+ $newErrors = array();
327
+ foreach ($colErrors as $data) {
328
+ $newErrors[] = array(
329
+ 'message' => $data['message'],
330
+ 'source' => $data['source'],
331
+ 'severity' => $data['severity'],
332
+ 'fixable' => $data['fixable'],
333
+ 'type' => 'ERROR',
334
+ );
335
+ }//end foreach
336
+
337
+ $errors[$line][$column] = $newErrors;
338
+ }//end foreach
339
+
340
+ ksort($errors[$line]);
341
+ }//end foreach
342
+
343
+ foreach ($phpcsFile->getWarnings() as $line => $lineWarnings) {
344
+ if (is_array($lineWarnings) === false) {
345
+ continue;
346
+ }
347
+
348
+ foreach ($lineWarnings as $column => $colWarnings) {
349
+ $newWarnings = array();
350
+ foreach ($colWarnings as $data) {
351
+ $newWarnings[] = array(
352
+ 'message' => $data['message'],
353
+ 'source' => $data['source'],
354
+ 'severity' => $data['severity'],
355
+ 'fixable' => $data['fixable'],
356
+ 'type' => 'WARNING',
357
+ );
358
+ }//end foreach
359
+
360
+ if (isset($errors[$line]) === false) {
361
+ $errors[$line] = array();
362
+ }
363
+
364
+ if (isset($errors[$line][$column]) === true) {
365
+ $errors[$line][$column] = array_merge(
366
+ $newWarnings,
367
+ $errors[$line][$column]
368
+ );
369
+ } else {
370
+ $errors[$line][$column] = $newWarnings;
371
+ }
372
+ }//end foreach
373
+
374
+ ksort($errors[$line]);
375
+ }//end foreach
376
+
377
+ ksort($errors);
378
+ $report['messages'] = $errors;
379
+ return $report;
380
+
381
+ }//end prepareFileReport()
382
+
383
+
384
+ /**
385
+ * Start recording time for the run.
386
+ *
387
+ * @return void
388
+ */
389
+ public static function startTiming()
390
+ {
391
+
392
+ self::$startTime = microtime(true);
393
+
394
+ }//end startTiming()
395
+
396
+
397
+ /**
398
+ * Print information about the run.
399
+ *
400
+ * @return void
401
+ */
402
+ public static function printRunTime()
403
+ {
404
+ $time = ((microtime(true) - self::$startTime) * 1000);
405
+
406
+ if ($time > 60000) {
407
+ $mins = floor($time / 60000);
408
+ $secs = round((($time % 60000) / 1000), 2);
409
+ $time = $mins.' mins';
410
+ if ($secs !== 0) {
411
+ $time .= ", $secs secs";
412
+ }
413
+ } else if ($time > 1000) {
414
+ $time = round(($time / 1000), 2).' secs';
415
+ } else {
416
+ $time = round($time).'ms';
417
+ }
418
+
419
+ $mem = round((memory_get_peak_usage(true) / (1024 * 1024)), 2).'Mb';
420
+ echo "Time: $time; Memory: $mem".PHP_EOL.PHP_EOL;
421
+
422
+ }//end printRunTime()
423
+
424
+
425
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Cbf.php ADDED
@@ -0,0 +1,151 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * CBF report for PHP_CodeSniffer.
4
+ *
5
+ * This report implements the various auto-fixing features of the
6
+ * PHPCBF script and is not intended (or allowed) to be selected as a
7
+ * report from the command line.
8
+ *
9
+ * PHP version 5
10
+ *
11
+ * @category PHP
12
+ * @package PHP_CodeSniffer
13
+ * @author Greg Sherwood <gsherwood@squiz.net>
14
+ * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600)
15
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
16
+ * @link http://pear.php.net/package/PHP_CodeSniffer
17
+ */
18
+
19
+ /**
20
+ * CBF report for PHP_CodeSniffer.
21
+ *
22
+ * This report implements the various auto-fixing features of the
23
+ * PHPCBF script and is not intended (or allowed) to be selected as a
24
+ * report from the command line.
25
+ *
26
+ * PHP version 5
27
+ *
28
+ * @category PHP
29
+ * @package PHP_CodeSniffer
30
+ * @author Greg Sherwood <gsherwood@squiz.net>
31
+ * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600)
32
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
33
+ * @version Release: @package_version@
34
+ * @link http://pear.php.net/package/PHP_CodeSniffer
35
+ */
36
+ class PHP_CodeSniffer_Reports_Cbf implements PHP_CodeSniffer_Report
37
+ {
38
+
39
+
40
+ /**
41
+ * Generate a partial report for a single processed file.
42
+ *
43
+ * Function should return TRUE if it printed or stored data about the file
44
+ * and FALSE if it ignored the file. Returning TRUE indicates that the file and
45
+ * its data should be counted in the grand totals.
46
+ *
47
+ * @param array $report Prepared report data.
48
+ * @param PHP_CodeSniffer_File $phpcsFile The file being reported on.
49
+ * @param boolean $showSources Show sources?
50
+ * @param int $width Maximum allowed line width.
51
+ *
52
+ * @return boolean
53
+ */
54
+ public function generateFileReport(
55
+ $report,
56
+ PHP_CodeSniffer_File $phpcsFile,
57
+ $showSources=false,
58
+ $width=80
59
+ ) {
60
+ $cliValues = $phpcsFile->phpcs->cli->getCommandLineValues();
61
+ $errors = $phpcsFile->getFixableCount();
62
+ if ($errors !== 0) {
63
+ if (empty($cliValues['files']) === false) {
64
+ ob_end_clean();
65
+ $errors = $phpcsFile->getFixableCount();
66
+ $startTime = microtime(true);
67
+ echo "\t=> Fixing file: $errors/$errors violations remaining";
68
+ }
69
+
70
+ $fixed = $phpcsFile->fixer->fixFile();
71
+ }
72
+
73
+ if (empty($cliValues['files']) === true) {
74
+ // Replacing STDIN, so output current file to STDOUT
75
+ // even if nothing was fixed. Exit here because we
76
+ // can't process any more than 1 file in this setup.
77
+ echo $phpcsFile->fixer->getContents();
78
+ ob_end_flush();
79
+ exit(1);
80
+ }
81
+
82
+ if ($errors === 0) {
83
+ return false;
84
+ }
85
+
86
+ if ($fixed === false) {
87
+ echo 'ERROR';
88
+ } else {
89
+ echo 'DONE';
90
+ }
91
+
92
+ $timeTaken = ((microtime(true) - $startTime) * 1000);
93
+ if ($timeTaken < 1000) {
94
+ $timeTaken = round($timeTaken);
95
+ echo " in {$timeTaken}ms".PHP_EOL;
96
+ } else {
97
+ $timeTaken = round(($timeTaken / 1000), 2);
98
+ echo " in $timeTaken secs".PHP_EOL;
99
+ }
100
+
101
+ if ($fixed === true) {
102
+ $newFilename = $report['filename'].$cliValues['phpcbf-suffix'];
103
+ $newContent = $phpcsFile->fixer->getContents();
104
+ file_put_contents($newFilename, $newContent);
105
+
106
+ if ($newFilename === $report['filename']) {
107
+ echo "\t=> File was overwritten".PHP_EOL;
108
+ } else {
109
+ echo "\t=> Fixed file written to ".basename($newFilename).PHP_EOL;
110
+ }
111
+ }
112
+
113
+ ob_start();
114
+
115
+ return $fixed;
116
+
117
+ }//end generateFileReport()
118
+
119
+
120
+ /**
121
+ * Prints all errors and warnings for each file processed.
122
+ *
123
+ * @param string $cachedData Any partial report data that was returned from
124
+ * generateFileReport during the run.
125
+ * @param int $totalFiles Total number of files processed during the run.
126
+ * @param int $totalErrors Total number of errors found during the run.
127
+ * @param int $totalWarnings Total number of warnings found during the run.
128
+ * @param int $totalFixable Total number of problems that can be fixed.
129
+ * @param boolean $showSources Show sources?
130
+ * @param int $width Maximum allowed line width.
131
+ * @param boolean $toScreen Is the report being printed to screen?
132
+ *
133
+ * @return void
134
+ */
135
+ public function generate(
136
+ $cachedData,
137
+ $totalFiles,
138
+ $totalErrors,
139
+ $totalWarnings,
140
+ $totalFixable,
141
+ $showSources=false,
142
+ $width=80,
143
+ $toScreen=true
144
+ ) {
145
+ echo $cachedData;
146
+ echo "Fixed $totalFiles files".PHP_EOL;
147
+
148
+ }//end generate()
149
+
150
+
151
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Checkstyle.php ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Checkstyle report for PHP_CodeSniffer.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Gabriele Santini <gsantini@sqli.com>
10
+ * @author Greg Sherwood <gsherwood@squiz.net>
11
+ * @copyright 2009-2014 SQLI <www.sqli.com>
12
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
13
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
14
+ * @link http://pear.php.net/package/PHP_CodeSniffer
15
+ */
16
+
17
+ /**
18
+ * Checkstyle report for PHP_CodeSniffer.
19
+ *
20
+ * PHP version 5
21
+ *
22
+ * @category PHP
23
+ * @package PHP_CodeSniffer
24
+ * @author Gabriele Santini <gsantini@sqli.com>
25
+ * @author Greg Sherwood <gsherwood@squiz.net>
26
+ * @copyright 2009-2014 SQLI <www.sqli.com>
27
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
28
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
29
+ * @version Release: @package_version@
30
+ * @link http://pear.php.net/package/PHP_CodeSniffer
31
+ */
32
+ class PHP_CodeSniffer_Reports_Checkstyle implements PHP_CodeSniffer_Report
33
+ {
34
+
35
+
36
+ /**
37
+ * Generate a partial report for a single processed file.
38
+ *
39
+ * Function should return TRUE if it printed or stored data about the file
40
+ * and FALSE if it ignored the file. Returning TRUE indicates that the file and
41
+ * its data should be counted in the grand totals.
42
+ *
43
+ * @param array $report Prepared report data.
44
+ * @param PHP_CodeSniffer_File $phpcsFile The file being reported on.
45
+ * @param boolean $showSources Show sources?
46
+ * @param int $width Maximum allowed line width.
47
+ *
48
+ * @return boolean
49
+ */
50
+ public function generateFileReport(
51
+ $report,
52
+ PHP_CodeSniffer_File $phpcsFile,
53
+ $showSources=false,
54
+ $width=80
55
+ ) {
56
+ $out = new XMLWriter;
57
+ $out->openMemory();
58
+ $out->setIndent(true);
59
+
60
+ if ($report['errors'] === 0 && $report['warnings'] === 0) {
61
+ // Nothing to print.
62
+ return false;
63
+ }
64
+
65
+ $out->startElement('file');
66
+ $out->writeAttribute('name', $report['filename']);
67
+
68
+ foreach ($report['messages'] as $line => $lineErrors) {
69
+ foreach ($lineErrors as $column => $colErrors) {
70
+ foreach ($colErrors as $error) {
71
+ $error['type'] = strtolower($error['type']);
72
+ if (PHP_CODESNIFFER_ENCODING !== 'utf-8') {
73
+ $error['message'] = iconv(PHP_CODESNIFFER_ENCODING, 'utf-8', $error['message']);
74
+ }
75
+
76
+ $out->startElement('error');
77
+ $out->writeAttribute('line', $line);
78
+ $out->writeAttribute('column', $column);
79
+ $out->writeAttribute('severity', $error['type']);
80
+ $out->writeAttribute('message', $error['message']);
81
+ $out->writeAttribute('source', $error['source']);
82
+ $out->endElement();
83
+ }
84
+ }
85
+ }//end foreach
86
+
87
+ $out->endElement();
88
+ echo $out->flush();
89
+
90
+ return true;
91
+
92
+ }//end generateFileReport()
93
+
94
+
95
+ /**
96
+ * Prints all violations for processed files, in a Checkstyle format.
97
+ *
98
+ * @param string $cachedData Any partial report data that was returned from
99
+ * generateFileReport during the run.
100
+ * @param int $totalFiles Total number of files processed during the run.
101
+ * @param int $totalErrors Total number of errors found during the run.
102
+ * @param int $totalWarnings Total number of warnings found during the run.
103
+ * @param int $totalFixable Total number of problems that can be fixed.
104
+ * @param boolean $showSources Show sources?
105
+ * @param int $width Maximum allowed line width.
106
+ * @param boolean $toScreen Is the report being printed to screen?
107
+ *
108
+ * @return void
109
+ */
110
+ public function generate(
111
+ $cachedData,
112
+ $totalFiles,
113
+ $totalErrors,
114
+ $totalWarnings,
115
+ $totalFixable,
116
+ $showSources=false,
117
+ $width=80,
118
+ $toScreen=true
119
+ ) {
120
+ echo '<?xml version="1.0" encoding="UTF-8"?>'.PHP_EOL;
121
+ echo '<checkstyle version="'.PHP_CodeSniffer::VERSION.'">'.PHP_EOL;
122
+ echo $cachedData;
123
+ echo '</checkstyle>'.PHP_EOL;
124
+
125
+ }//end generate()
126
+
127
+
128
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Csv.php ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Csv report for PHP_CodeSniffer.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Gabriele Santini <gsantini@sqli.com>
10
+ * @author Greg Sherwood <gsherwood@squiz.net>
11
+ * @copyright 2009-2014 SQLI <www.sqli.com>
12
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
13
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
14
+ * @link http://pear.php.net/package/PHP_CodeSniffer
15
+ */
16
+
17
+ /**
18
+ * Csv report for PHP_CodeSniffer.
19
+ *
20
+ * PHP version 5
21
+ *
22
+ * @category PHP
23
+ * @package PHP_CodeSniffer
24
+ * @author Gabriele Santini <gsantini@sqli.com>
25
+ * @author Greg Sherwood <gsherwood@squiz.net>
26
+ * @copyright 2009-2014 SQLI <www.sqli.com>
27
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
28
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
29
+ * @version Release: @package_version@
30
+ * @link http://pear.php.net/package/PHP_CodeSniffer
31
+ */
32
+ class PHP_CodeSniffer_Reports_Csv implements PHP_CodeSniffer_Report
33
+ {
34
+
35
+
36
+ /**
37
+ * Generate a partial report for a single processed file.
38
+ *
39
+ * Function should return TRUE if it printed or stored data about the file
40
+ * and FALSE if it ignored the file. Returning TRUE indicates that the file and
41
+ * its data should be counted in the grand totals.
42
+ *
43
+ * @param array $report Prepared report data.
44
+ * @param PHP_CodeSniffer_File $phpcsFile The file being reported on.
45
+ * @param boolean $showSources Show sources?
46
+ * @param int $width Maximum allowed line width.
47
+ *
48
+ * @return boolean
49
+ */
50
+ public function generateFileReport(
51
+ $report,
52
+ PHP_CodeSniffer_File $phpcsFile,
53
+ $showSources=false,
54
+ $width=80
55
+ ) {
56
+ if ($report['errors'] === 0 && $report['warnings'] === 0) {
57
+ // Nothing to print.
58
+ return false;
59
+ }
60
+
61
+ foreach ($report['messages'] as $line => $lineErrors) {
62
+ foreach ($lineErrors as $column => $colErrors) {
63
+ foreach ($colErrors as $error) {
64
+ $filename = str_replace('"', '\"', $report['filename']);
65
+ $message = str_replace('"', '\"', $error['message']);
66
+ $type = strtolower($error['type']);
67
+ $source = $error['source'];
68
+ $severity = $error['severity'];
69
+ $fixable = (int) $error['fixable'];
70
+ echo "\"$filename\",$line,$column,$type,\"$message\",$source,$severity,$fixable".PHP_EOL;
71
+ }
72
+ }
73
+ }
74
+
75
+ return true;
76
+
77
+ }//end generateFileReport()
78
+
79
+
80
+ /**
81
+ * Generates a csv report.
82
+ *
83
+ * @param string $cachedData Any partial report data that was returned from
84
+ * generateFileReport during the run.
85
+ * @param int $totalFiles Total number of files processed during the run.
86
+ * @param int $totalErrors Total number of errors found during the run.
87
+ * @param int $totalWarnings Total number of warnings found during the run.
88
+ * @param int $totalFixable Total number of problems that can be fixed.
89
+ * @param boolean $showSources Show sources?
90
+ * @param int $width Maximum allowed line width.
91
+ * @param boolean $toScreen Is the report being printed to screen?
92
+ *
93
+ * @return void
94
+ */
95
+ public function generate(
96
+ $cachedData,
97
+ $totalFiles,
98
+ $totalErrors,
99
+ $totalWarnings,
100
+ $totalFixable,
101
+ $showSources=false,
102
+ $width=80,
103
+ $toScreen=true
104
+ ) {
105
+ echo 'File,Line,Column,Type,Message,Source,Severity,Fixable'.PHP_EOL;
106
+ echo $cachedData;
107
+
108
+ }//end generate()
109
+
110
+
111
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Diff.php ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Diff report for PHP_CodeSniffer.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Greg Sherwood <gsherwood@squiz.net>
10
+ * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600)
11
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
12
+ * @link http://pear.php.net/package/PHP_CodeSniffer
13
+ */
14
+
15
+ /**
16
+ * Diff report for PHP_CodeSniffer.
17
+ *
18
+ * PHP version 5
19
+ *
20
+ * @category PHP
21
+ * @package PHP_CodeSniffer
22
+ * @author Greg Sherwood <gsherwood@squiz.net>
23
+ * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600)
24
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
25
+ * @version Release: @package_version@
26
+ * @link http://pear.php.net/package/PHP_CodeSniffer
27
+ */
28
+ class PHP_CodeSniffer_Reports_Diff implements PHP_CodeSniffer_Report
29
+ {
30
+
31
+
32
+ /**
33
+ * Generate a partial report for a single processed file.
34
+ *
35
+ * Function should return TRUE if it printed or stored data about the file
36
+ * and FALSE if it ignored the file. Returning TRUE indicates that the file and
37
+ * its data should be counted in the grand totals.
38
+ *
39
+ * @param array $report Prepared report data.
40
+ * @param PHP_CodeSniffer_File $phpcsFile The file being reported on.
41
+ * @param boolean $showSources Show sources?
42
+ * @param int $width Maximum allowed line width.
43
+ *
44
+ * @return boolean
45
+ */
46
+ public function generateFileReport(
47
+ $report,
48
+ PHP_CodeSniffer_File $phpcsFile,
49
+ $showSources=false,
50
+ $width=80
51
+ ) {
52
+ $errors = $phpcsFile->getFixableCount();
53
+ if ($errors === 0) {
54
+ return false;
55
+ }
56
+
57
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
58
+ ob_end_clean();
59
+ echo "\t*** START FILE FIXING ***".PHP_EOL;
60
+ }
61
+
62
+ if (PHP_CODESNIFFER_CBF === true) {
63
+ ob_end_clean();
64
+ $startTime = microtime(true);
65
+ echo "\t=> Fixing file: $errors/$errors violations remaining";
66
+ }
67
+
68
+ $fixed = $phpcsFile->fixer->fixFile();
69
+
70
+ if (PHP_CODESNIFFER_CBF === true) {
71
+ if ($fixed === false) {
72
+ echo "\033[31mERROR\033[0m";
73
+ } else {
74
+ echo "\033[32mDONE\033[0m";
75
+ }
76
+
77
+ $timeTaken = ((microtime(true) - $startTime) * 1000);
78
+ if ($timeTaken < 1000) {
79
+ $timeTaken = round($timeTaken);
80
+ echo " in {$timeTaken}ms".PHP_EOL;
81
+ } else {
82
+ $timeTaken = round(($timeTaken / 1000), 2);
83
+ echo " in $timeTaken secs".PHP_EOL;
84
+ }
85
+
86
+ ob_start();
87
+ }
88
+
89
+ if (PHP_CODESNIFFER_VERBOSITY > 1) {
90
+ echo "\t*** END FILE FIXING ***".PHP_EOL;
91
+ ob_start();
92
+ }
93
+
94
+ if ($fixed === false) {
95
+ return false;
96
+ }
97
+
98
+ if (PHP_CODESNIFFER_CBF === true) {
99
+ // Diff without colours.
100
+ $diff = $phpcsFile->fixer->generateDiff(null, false);
101
+ } else {
102
+ $diff = $phpcsFile->fixer->generateDiff();
103
+ }
104
+
105
+ if ($diff === '') {
106
+ // Nothing to print.
107
+ return false;
108
+ }
109
+
110
+ echo $diff.PHP_EOL;
111
+ return true;
112
+
113
+ }//end generateFileReport()
114
+
115
+
116
+ /**
117
+ * Prints all errors and warnings for each file processed.
118
+ *
119
+ * @param string $cachedData Any partial report data that was returned from
120
+ * generateFileReport during the run.
121
+ * @param int $totalFiles Total number of files processed during the run.
122
+ * @param int $totalErrors Total number of errors found during the run.
123
+ * @param int $totalWarnings Total number of warnings found during the run.
124
+ * @param int $totalFixable Total number of problems that can be fixed.
125
+ * @param boolean $showSources Show sources?
126
+ * @param int $width Maximum allowed line width.
127
+ * @param boolean $toScreen Is the report being printed to screen?
128
+ *
129
+ * @return void
130
+ */
131
+ public function generate(
132
+ $cachedData,
133
+ $totalFiles,
134
+ $totalErrors,
135
+ $totalWarnings,
136
+ $totalFixable,
137
+ $showSources=false,
138
+ $width=80,
139
+ $toScreen=true
140
+ ) {
141
+ echo $cachedData;
142
+ if ($toScreen === true) {
143
+ echo PHP_EOL;
144
+ }
145
+
146
+ }//end generate()
147
+
148
+
149
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Emacs.php ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Emacs report for PHP_CodeSniffer.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Gabriele Santini <gsantini@sqli.com>
10
+ * @author Greg Sherwood <gsherwood@squiz.net>
11
+ * @copyright 2009-2014 SQLI <www.sqli.com>
12
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
13
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
14
+ * @link http://pear.php.net/package/PHP_CodeSniffer
15
+ */
16
+
17
+ /**
18
+ * Emacs report for PHP_CodeSniffer.
19
+ *
20
+ * PHP version 5
21
+ *
22
+ * @category PHP
23
+ * @package PHP_CodeSniffer
24
+ * @author Gabriele Santini <gsantini@sqli.com>
25
+ * @author Greg Sherwood <gsherwood@squiz.net>
26
+ * @copyright 2009-2014 SQLI <www.sqli.com>
27
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
28
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
29
+ * @version Release: @package_version@
30
+ * @link http://pear.php.net/package/PHP_CodeSniffer
31
+ */
32
+ class PHP_CodeSniffer_Reports_Emacs implements PHP_CodeSniffer_Report
33
+ {
34
+
35
+
36
+ /**
37
+ * Generate a partial report for a single processed file.
38
+ *
39
+ * Function should return TRUE if it printed or stored data about the file
40
+ * and FALSE if it ignored the file. Returning TRUE indicates that the file and
41
+ * its data should be counted in the grand totals.
42
+ *
43
+ * @param array $report Prepared report data.
44
+ * @param PHP_CodeSniffer_File $phpcsFile The file being reported on.
45
+ * @param boolean $showSources Show sources?
46
+ * @param int $width Maximum allowed line width.
47
+ *
48
+ * @return boolean
49
+ */
50
+ public function generateFileReport(
51
+ $report,
52
+ PHP_CodeSniffer_File $phpcsFile,
53
+ $showSources=false,
54
+ $width=80
55
+ ) {
56
+ if ($report['errors'] === 0 && $report['warnings'] === 0) {
57
+ // Nothing to print.
58
+ return false;
59
+ }
60
+
61
+ foreach ($report['messages'] as $line => $lineErrors) {
62
+ foreach ($lineErrors as $column => $colErrors) {
63
+ foreach ($colErrors as $error) {
64
+ $message = $error['message'];
65
+ if ($showSources === true) {
66
+ $message .= ' ('.$error['source'].')';
67
+ }
68
+
69
+ $type = strtolower($error['type']);
70
+ echo $report['filename'].':'.$line.':'.$column.': '.$type.' - '.$message.PHP_EOL;
71
+ }
72
+ }
73
+ }
74
+
75
+ return true;
76
+
77
+ }//end generateFileReport()
78
+
79
+
80
+ /**
81
+ * Generates an emacs report.
82
+ *
83
+ * @param string $cachedData Any partial report data that was returned from
84
+ * generateFileReport during the run.
85
+ * @param int $totalFiles Total number of files processed during the run.
86
+ * @param int $totalErrors Total number of errors found during the run.
87
+ * @param int $totalWarnings Total number of warnings found during the run.
88
+ * @param int $totalFixable Total number of problems that can be fixed.
89
+ * @param boolean $showSources Show sources?
90
+ * @param int $width Maximum allowed line width.
91
+ * @param boolean $toScreen Is the report being printed to screen?
92
+ *
93
+ * @return void
94
+ */
95
+ public function generate(
96
+ $cachedData,
97
+ $totalFiles,
98
+ $totalErrors,
99
+ $totalWarnings,
100
+ $totalFixable,
101
+ $showSources=false,
102
+ $width=80,
103
+ $toScreen=true
104
+ ) {
105
+ echo $cachedData;
106
+
107
+ }//end generate()
108
+
109
+
110
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Full.php ADDED
@@ -0,0 +1,237 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Full report for PHP_CodeSniffer.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Gabriele Santini <gsantini@sqli.com>
10
+ * @author Greg Sherwood <gsherwood@squiz.net>
11
+ * @copyright 2009-2014 SQLI <www.sqli.com>
12
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
13
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
14
+ * @link http://pear.php.net/package/PHP_CodeSniffer
15
+ */
16
+
17
+ /**
18
+ * Full report for PHP_CodeSniffer.
19
+ *
20
+ * PHP version 5
21
+ *
22
+ * @category PHP
23
+ * @package PHP_CodeSniffer
24
+ * @author Gabriele Santini <gsantini@sqli.com>
25
+ * @author Greg Sherwood <gsherwood@squiz.net>
26
+ * @copyright 2009-2014 SQLI <www.sqli.com>
27
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
28
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
29
+ * @version Release: @package_version@
30
+ * @link http://pear.php.net/package/PHP_CodeSniffer
31
+ */
32
+ class PHP_CodeSniffer_Reports_Full implements PHP_CodeSniffer_Report
33
+ {
34
+
35
+
36
+ /**
37
+ * Generate a partial report for a single processed file.
38
+ *
39
+ * Function should return TRUE if it printed or stored data about the file
40
+ * and FALSE if it ignored the file. Returning TRUE indicates that the file and
41
+ * its data should be counted in the grand totals.
42
+ *
43
+ * @param array $report Prepared report data.
44
+ * @param PHP_CodeSniffer_File $phpcsFile The file being reported on.
45
+ * @param boolean $showSources Show sources?
46
+ * @param int $width Maximum allowed line width.
47
+ *
48
+ * @return boolean
49
+ */
50
+ public function generateFileReport(
51
+ $report,
52
+ PHP_CodeSniffer_File $phpcsFile,
53
+ $showSources=false,
54
+ $width=80
55
+ ) {
56
+ if ($report['errors'] === 0 && $report['warnings'] === 0) {
57
+ // Nothing to print.
58
+ return false;
59
+ }
60
+
61
+ // The length of the word ERROR or WARNING; used for padding.
62
+ if ($report['warnings'] > 0) {
63
+ $typeLength = 7;
64
+ } else {
65
+ $typeLength = 5;
66
+ }
67
+
68
+ // Work out the max line number length for formatting.
69
+ $maxLineNumLength = max(array_map('strlen', array_keys($report['messages'])));
70
+
71
+ // The padding that all lines will require that are
72
+ // printing an error message overflow.
73
+ $paddingLine2 = str_repeat(' ', ($maxLineNumLength + 1));
74
+ $paddingLine2 .= ' | ';
75
+ $paddingLine2 .= str_repeat(' ', $typeLength);
76
+ $paddingLine2 .= ' | ';
77
+ if ($report['fixable'] > 0) {
78
+ $paddingLine2 .= ' ';
79
+ }
80
+
81
+ $paddingLength = strlen($paddingLine2);
82
+
83
+ // Make sure the report width isn't too big.
84
+ $maxErrorLength = 0;
85
+ foreach ($report['messages'] as $line => $lineErrors) {
86
+ foreach ($lineErrors as $column => $colErrors) {
87
+ foreach ($colErrors as $error) {
88
+ $length = strlen($error['message']);
89
+ if ($showSources === true) {
90
+ $length += (strlen($error['source']) + 3);
91
+ }
92
+
93
+ $maxErrorLength = max($maxErrorLength, ($length + 1));
94
+ }
95
+ }
96
+ }
97
+
98
+ $file = $report['filename'];
99
+ $fileLength = strlen($file);
100
+ $maxWidth = max(($fileLength + 6), ($maxErrorLength + $paddingLength));
101
+ $width = min($width, $maxWidth);
102
+ if ($width < 70) {
103
+ $width = 70;
104
+ }
105
+
106
+ echo PHP_EOL."\033[1mFILE: ";
107
+ if ($fileLength <= ($width - 6)) {
108
+ echo $file;
109
+ } else {
110
+ echo '...'.substr($file, ($fileLength - ($width - 6)));
111
+ }
112
+
113
+ echo "\033[0m".PHP_EOL;
114
+ echo str_repeat('-', $width).PHP_EOL;
115
+
116
+ echo "\033[1m".'FOUND '.$report['errors'].' ERROR';
117
+ if ($report['errors'] !== 1) {
118
+ echo 'S';
119
+ }
120
+
121
+ if ($report['warnings'] > 0) {
122
+ echo ' AND '.$report['warnings'].' WARNING';
123
+ if ($report['warnings'] !== 1) {
124
+ echo 'S';
125
+ }
126
+ }
127
+
128
+ echo ' AFFECTING '.count($report['messages']).' LINE';
129
+ if (count($report['messages']) !== 1) {
130
+ echo 'S';
131
+ }
132
+
133
+ echo "\033[0m".PHP_EOL;
134
+ echo str_repeat('-', $width).PHP_EOL;
135
+
136
+ // The maximum amount of space an error message can use.
137
+ $maxErrorSpace = ($width - $paddingLength - 1);
138
+ if ($showSources === true) {
139
+ // Account for the chars used to print colors.
140
+ $maxErrorSpace += 8;
141
+ }
142
+
143
+ foreach ($report['messages'] as $line => $lineErrors) {
144
+ foreach ($lineErrors as $column => $colErrors) {
145
+ foreach ($colErrors as $error) {
146
+ $message = $error['message'];
147
+ $message = str_replace("\n", "\n".$paddingLine2, $message);
148
+ if ($showSources === true) {
149
+ $message = "\033[1m".$message."\033[0m".' ('.$error['source'].')';
150
+ }
151
+
152
+ // The padding that goes on the front of the line.
153
+ $padding = ($maxLineNumLength - strlen($line));
154
+ $errorMsg = wordwrap(
155
+ $message,
156
+ $maxErrorSpace,
157
+ PHP_EOL.$paddingLine2
158
+ );
159
+
160
+ echo ' '.str_repeat(' ', $padding).$line.' | ';
161
+ if ($error['type'] === 'ERROR') {
162
+ echo "\033[31mERROR\033[0m";
163
+ if ($report['warnings'] > 0) {
164
+ echo ' ';
165
+ }
166
+ } else {
167
+ echo "\033[33mWARNING\033[0m";
168
+ }
169
+
170
+ echo ' | ';
171
+ if ($report['fixable'] > 0) {
172
+ echo '[';
173
+ if ($error['fixable'] === true) {
174
+ echo 'x';
175
+ } else {
176
+ echo ' ';
177
+ }
178
+
179
+ echo '] ';
180
+ }
181
+
182
+ echo $errorMsg.PHP_EOL;
183
+ }//end foreach
184
+ }//end foreach
185
+ }//end foreach
186
+
187
+ echo str_repeat('-', $width).PHP_EOL;
188
+ if ($report['fixable'] > 0) {
189
+ echo "\033[1m".'PHPCBF CAN FIX THE '.$report['fixable'].' MARKED SNIFF VIOLATIONS AUTOMATICALLY'."\033[0m".PHP_EOL;
190
+ echo str_repeat('-', $width).PHP_EOL;
191
+ }
192
+
193
+ echo PHP_EOL;
194
+ return true;
195
+
196
+ }//end generateFileReport()
197
+
198
+
199
+ /**
200
+ * Prints all errors and warnings for each file processed.
201
+ *
202
+ * @param string $cachedData Any partial report data that was returned from
203
+ * generateFileReport during the run.
204
+ * @param int $totalFiles Total number of files processed during the run.
205
+ * @param int $totalErrors Total number of errors found during the run.
206
+ * @param int $totalWarnings Total number of warnings found during the run.
207
+ * @param int $totalFixable Total number of problems that can be fixed.
208
+ * @param boolean $showSources Show sources?
209
+ * @param int $width Maximum allowed line width.
210
+ * @param boolean $toScreen Is the report being printed to screen?
211
+ *
212
+ * @return void
213
+ */
214
+ public function generate(
215
+ $cachedData,
216
+ $totalFiles,
217
+ $totalErrors,
218
+ $totalWarnings,
219
+ $totalFixable,
220
+ $showSources=false,
221
+ $width=80,
222
+ $toScreen=true
223
+ ) {
224
+ if ($cachedData === '') {
225
+ return;
226
+ }
227
+
228
+ echo $cachedData;
229
+
230
+ if ($toScreen === true && PHP_CODESNIFFER_INTERACTIVE === false) {
231
+ PHP_CodeSniffer_Reporting::printRunTime();
232
+ }
233
+
234
+ }//end generate()
235
+
236
+
237
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Gitblame.php ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Gitblame report for PHP_CodeSniffer.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Ben Selby <benmatselby@gmail.com>
10
+ * @copyright 2009-2014 SQLI <www.sqli.com>
11
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
12
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
13
+ * @link http://pear.php.net/package/PHP_CodeSniffer
14
+ */
15
+
16
+ /**
17
+ * Gitblame report for PHP_CodeSniffer.
18
+ *
19
+ * PHP version 5
20
+ *
21
+ * @category PHP
22
+ * @package PHP_CodeSniffer
23
+ * @author Ben Selby <benmatselby@gmail.com>
24
+ * @copyright 2009-2014 SQLI <www.sqli.com>
25
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
26
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
27
+ * @version Release: 1.2.2
28
+ * @link http://pear.php.net/package/PHP_CodeSniffer
29
+ */
30
+ class PHP_CodeSniffer_Reports_Gitblame extends PHP_CodeSniffer_Reports_VersionControl
31
+ {
32
+
33
+ /**
34
+ * The name of the report we want in the output
35
+ *
36
+ * @var string
37
+ */
38
+ protected $reportName = 'GIT';
39
+
40
+
41
+ /**
42
+ * Extract the author from a blame line.
43
+ *
44
+ * @param string $line Line to parse.
45
+ *
46
+ * @return mixed string or false if impossible to recover.
47
+ */
48
+ protected function getAuthor($line)
49
+ {
50
+ $blameParts = array();
51
+ $line = preg_replace('|\s+|', ' ', $line);
52
+ preg_match(
53
+ '|\(.+[0-9]{4}-[0-9]{2}-[0-9]{2}\s+[0-9]+\)|',
54
+ $line,
55
+ $blameParts
56
+ );
57
+
58
+ if (isset($blameParts[0]) === false) {
59
+ return false;
60
+ }
61
+
62
+ $parts = explode(' ', $blameParts[0]);
63
+
64
+ if (count($parts) < 2) {
65
+ return false;
66
+ }
67
+
68
+ $parts = array_slice($parts, 0, (count($parts) - 2));
69
+ $author = preg_replace('|\(|', '', implode($parts, ' '));
70
+ return $author;
71
+
72
+ }//end getAuthor()
73
+
74
+
75
+ /**
76
+ * Gets the blame output.
77
+ *
78
+ * @param string $filename File to blame.
79
+ *
80
+ * @return array
81
+ */
82
+ protected function getBlameContent($filename)
83
+ {
84
+ $cwd = getcwd();
85
+
86
+ if (PHP_CODESNIFFER_VERBOSITY > 0) {
87
+ echo 'Getting GIT blame info for '.basename($filename).'... ';
88
+ }
89
+
90
+ $fileParts = explode(DIRECTORY_SEPARATOR, $filename);
91
+ $found = false;
92
+ $location = '';
93
+ while (empty($fileParts) === false) {
94
+ array_pop($fileParts);
95
+ $location = implode($fileParts, DIRECTORY_SEPARATOR);
96
+ if (is_dir($location.DIRECTORY_SEPARATOR.'.git') === true) {
97
+ $found = true;
98
+ break;
99
+ }
100
+ }
101
+
102
+ if ($found === true) {
103
+ chdir($location);
104
+ } else {
105
+ echo 'ERROR: Could not locate .git directory '.PHP_EOL.PHP_EOL;
106
+ exit(2);
107
+ }
108
+
109
+ $command = 'git blame --date=short "'.$filename.'" 2>&1';
110
+ $handle = popen($command, 'r');
111
+ if ($handle === false) {
112
+ echo 'ERROR: Could not execute "'.$command.'"'.PHP_EOL.PHP_EOL;
113
+ exit(2);
114
+ }
115
+
116
+ $rawContent = stream_get_contents($handle);
117
+ fclose($handle);
118
+
119
+ if (PHP_CODESNIFFER_VERBOSITY > 0) {
120
+ echo 'DONE'.PHP_EOL;
121
+ }
122
+
123
+ $blames = explode("\n", $rawContent);
124
+ chdir($cwd);
125
+
126
+ return $blames;
127
+
128
+ }//end getBlameContent()
129
+
130
+
131
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Hgblame.php ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Mercurial report for PHP_CodeSniffer.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Ben Selby <benmatselby@gmail.com>
10
+ * @copyright 2009-2014 SQLI <www.sqli.com>
11
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
12
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
13
+ * @link http://pear.php.net/package/PHP_CodeSniffer
14
+ */
15
+
16
+ /**
17
+ * Mercurial report for PHP_CodeSniffer.
18
+ *
19
+ * PHP version 5
20
+ *
21
+ * @category PHP
22
+ * @package PHP_CodeSniffer
23
+ * @author Ben Selby <benmatselby@gmail.com>
24
+ * @copyright 2009-2014 SQLI <www.sqli.com>
25
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
26
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
27
+ * @version Release: @package_version@
28
+ * @link http://pear.php.net/package/PHP_CodeSniffer
29
+ */
30
+ class PHP_CodeSniffer_Reports_Hgblame extends PHP_CodeSniffer_Reports_VersionControl
31
+ {
32
+
33
+ /**
34
+ * The name of the report we want in the output
35
+ *
36
+ * @var string
37
+ */
38
+ protected $reportName = 'MERCURIAL';
39
+
40
+
41
+ /**
42
+ * Extract the author from a blame line.
43
+ *
44
+ * @param string $line Line to parse.
45
+ *
46
+ * @return mixed string or false if impossible to recover.
47
+ */
48
+ protected function getAuthor($line)
49
+ {
50
+ $blameParts = array();
51
+ $line = preg_replace('|\s+|', ' ', $line);
52
+
53
+ preg_match(
54
+ '|(.+[0-9]{2}:[0-9]{2}:[0-9]{2}\s[0-9]{4}\s.[0-9]{4}:)|',
55
+ $line,
56
+ $blameParts
57
+ );
58
+
59
+ if (isset($blameParts[0]) === false) {
60
+ return false;
61
+ }
62
+
63
+ $parts = explode(' ', $blameParts[0]);
64
+
65
+ if (count($parts) < 6) {
66
+ return false;
67
+ }
68
+
69
+ $parts = array_slice($parts, 0, (count($parts) - 6));
70
+
71
+ return trim(preg_replace('|<.+>|', '', implode($parts, ' ')));
72
+
73
+ }//end getAuthor()
74
+
75
+
76
+ /**
77
+ * Gets the blame output.
78
+ *
79
+ * @param string $filename File to blame.
80
+ *
81
+ * @return array
82
+ */
83
+ protected function getBlameContent($filename)
84
+ {
85
+ $cwd = getcwd();
86
+
87
+ if (PHP_CODESNIFFER_VERBOSITY > 0) {
88
+ echo 'Getting MERCURIAL blame info for '.basename($filename).'... ';
89
+ }
90
+
91
+ $fileParts = explode(DIRECTORY_SEPARATOR, $filename);
92
+ $found = false;
93
+ $location = '';
94
+ while (empty($fileParts) === false) {
95
+ array_pop($fileParts);
96
+ $location = implode($fileParts, DIRECTORY_SEPARATOR);
97
+ if (is_dir($location.DIRECTORY_SEPARATOR.'.hg') === true) {
98
+ $found = true;
99
+ break;
100
+ }
101
+ }
102
+
103
+ if ($found === true) {
104
+ chdir($location);
105
+ } else {
106
+ echo 'ERROR: Could not locate .hg directory '.PHP_EOL.PHP_EOL;
107
+ exit(2);
108
+ }
109
+
110
+ $command = 'hg blame -u -d -v "'.$filename.'" 2>&1';
111
+ $handle = popen($command, 'r');
112
+ if ($handle === false) {
113
+ echo 'ERROR: Could not execute "'.$command.'"'.PHP_EOL.PHP_EOL;
114
+ exit(2);
115
+ }
116
+
117
+ $rawContent = stream_get_contents($handle);
118
+ fclose($handle);
119
+
120
+ if (PHP_CODESNIFFER_VERBOSITY > 0) {
121
+ echo 'DONE'.PHP_EOL;
122
+ }
123
+
124
+ $blames = explode("\n", $rawContent);
125
+ chdir($cwd);
126
+
127
+ return $blames;
128
+
129
+ }//end getBlameContent()
130
+
131
+
132
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Info.php ADDED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Info report for PHP_CodeSniffer.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Greg Sherwood <gsherwood@squiz.net>
10
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
11
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
12
+ * @link http://pear.php.net/package/PHP_CodeSniffer
13
+ */
14
+
15
+ /**
16
+ * Info report for PHP_CodeSniffer.
17
+ *
18
+ * PHP version 5
19
+ *
20
+ * @category PHP
21
+ * @package PHP_CodeSniffer
22
+ * @author Greg Sherwood <gsherwood@squiz.net>
23
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
24
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
25
+ * @version Release: @package_version@
26
+ * @link http://pear.php.net/package/PHP_CodeSniffer
27
+ */
28
+ class PHP_CodeSniffer_Reports_Info implements PHP_CodeSniffer_Report
29
+ {
30
+
31
+ /**
32
+ * TRUE if this report needs error messages instead of just totals.
33
+ *
34
+ * @var boolean
35
+ */
36
+ public $recordErrors = false;
37
+
38
+ /**
39
+ * A cache of metrics collected during the run.
40
+ *
41
+ * @var array
42
+ */
43
+ private $_metricCache = array();
44
+
45
+
46
+ /**
47
+ * Generate a partial report for a single processed file.
48
+ *
49
+ * Function should return TRUE if it printed or stored data about the file
50
+ * and FALSE if it ignored the file. Returning TRUE indicates that the file and
51
+ * its data should be counted in the grand totals.
52
+ *
53
+ * @param array $report Prepared report data.
54
+ * @param PHP_CodeSniffer_File $phpcsFile The file being reported on.
55
+ * @param boolean $showSources Show sources?
56
+ * @param int $width Maximum allowed line width.
57
+ *
58
+ * @return boolean
59
+ */
60
+ public function generateFileReport(
61
+ $report,
62
+ PHP_CodeSniffer_File $phpcsFile,
63
+ $showSources=false,
64
+ $width=80
65
+ ) {
66
+ $metrics = $phpcsFile->getMetrics();
67
+ foreach ($metrics as $metric => $data) {
68
+ if (isset($this->_metricCache[$metric]) === false) {
69
+ $this->_metricCache[$metric] = array();
70
+ }
71
+
72
+ foreach ($data['values'] as $value => $locations) {
73
+ $locations = array_unique($locations);
74
+ $count = count($locations);
75
+
76
+ if (isset($this->_metricCache[$metric][$value]) === false) {
77
+ $this->_metricCache[$metric][$value] = $count;
78
+ } else {
79
+ $this->_metricCache[$metric][$value] += $count;
80
+ }
81
+ }
82
+ }//end foreach
83
+
84
+ return true;
85
+
86
+ }//end generateFileReport()
87
+
88
+
89
+ /**
90
+ * Prints the source of all errors and warnings.
91
+ *
92
+ * @param string $cachedData Any partial report data that was returned from
93
+ * generateFileReport during the run.
94
+ * @param int $totalFiles Total number of files processed during the run.
95
+ * @param int $totalErrors Total number of errors found during the run.
96
+ * @param int $totalWarnings Total number of warnings found during the run.
97
+ * @param int $totalFixable Total number of problems that can be fixed.
98
+ * @param boolean $showSources Show sources?
99
+ * @param int $width Maximum allowed line width.
100
+ * @param boolean $toScreen Is the report being printed to screen?
101
+ *
102
+ * @return void
103
+ */
104
+ public function generate(
105
+ $cachedData,
106
+ $totalFiles,
107
+ $totalErrors,
108
+ $totalWarnings,
109
+ $totalFixable,
110
+ $showSources=false,
111
+ $width=80,
112
+ $toScreen=true
113
+ ) {
114
+ if (empty($this->_metricCache) === true) {
115
+ // Nothing to show.
116
+ return;
117
+ }
118
+
119
+ ksort($this->_metricCache);
120
+
121
+ echo PHP_EOL."\033[1m".'PHP CODE SNIFFER INFORMATION REPORT'."\033[0m".PHP_EOL;
122
+ echo str_repeat('-', 70).PHP_EOL;
123
+
124
+ foreach ($this->_metricCache as $metric => $values) {
125
+ $winner = '';
126
+ $winnerCount = 0;
127
+ $totalCount = 0;
128
+ foreach ($values as $value => $count) {
129
+ $totalCount += $count;
130
+ if ($count > $winnerCount) {
131
+ $winner = $value;
132
+ $winnerCount = $count;
133
+ }
134
+ }
135
+
136
+ $winPercent = round(($winnerCount / $totalCount * 100), 2);
137
+ echo "$metric: \033[4m$winner\033[0m [$winnerCount/$totalCount, $winPercent%]".PHP_EOL;
138
+
139
+ asort($values);
140
+ $values = array_reverse($values, true);
141
+ foreach ($values as $value => $count) {
142
+ if ($value === $winner) {
143
+ continue;
144
+ }
145
+
146
+ $percent = round(($count / $totalCount * 100), 2);
147
+ echo "\t$value => $count ($percent%)".PHP_EOL;
148
+ }
149
+
150
+ echo PHP_EOL;
151
+ }//end foreach
152
+
153
+ echo str_repeat('-', 70).PHP_EOL;
154
+
155
+ if ($toScreen === true && PHP_CODESNIFFER_INTERACTIVE === false) {
156
+ PHP_CodeSniffer_Reporting::printRunTime();
157
+ }
158
+
159
+ }//end generate()
160
+
161
+
162
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Json.php ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Json report for PHP_CodeSniffer.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Jeffrey Fisher <jeffslofish@gmail.com>
10
+ * @author Greg Sherwood <gsherwood@squiz.net>
11
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
12
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
13
+ * @link http://pear.php.net/package/PHP_CodeSniffer
14
+ */
15
+
16
+ /**
17
+ * Json report for PHP_CodeSniffer.
18
+ *
19
+ * PHP version 5
20
+ *
21
+ * @category PHP
22
+ * @package PHP_CodeSniffer
23
+ * @author Jeffrey Fisher <jeffslofish@gmail.com>
24
+ * @author Greg Sherwood <gsherwood@squiz.net>
25
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
26
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
27
+ * @version Release: @package_version@
28
+ * @link http://pear.php.net/package/PHP_CodeSniffer
29
+ */
30
+ class PHP_CodeSniffer_Reports_Json implements PHP_CodeSniffer_Report
31
+ {
32
+
33
+
34
+ /**
35
+ * Generate a partial report for a single processed file.
36
+ *
37
+ * Function should return TRUE if it printed or stored data about the file
38
+ * and FALSE if it ignored the file. Returning TRUE indicates that the file and
39
+ * its data should be counted in the grand totals.
40
+ *
41
+ * @param array $report Prepared report data.
42
+ * @param PHP_CodeSniffer_File $phpcsFile The file being reported on.
43
+ * @param boolean $showSources Show sources?
44
+ * @param int $width Maximum allowed line width.
45
+ *
46
+ * @return boolean
47
+ */
48
+ public function generateFileReport(
49
+ $report,
50
+ PHP_CodeSniffer_File $phpcsFile,
51
+ $showSources=false,
52
+ $width=80
53
+ ) {
54
+ $filename = str_replace('\\', '\\\\', $report['filename']);
55
+ $filename = str_replace('"', '\"', $filename);
56
+ $filename = str_replace('/', '\/', $filename);
57
+ echo '"'.$filename.'":{';
58
+ echo '"errors":'.$report['errors'].',"warnings":'.$report['warnings'].',"messages":[';
59
+
60
+ $messages = '';
61
+ foreach ($report['messages'] as $line => $lineErrors) {
62
+ foreach ($lineErrors as $column => $colErrors) {
63
+ foreach ($colErrors as $error) {
64
+ $error['message'] = str_replace('\\', '\\\\', $error['message']);
65
+ $error['message'] = str_replace('"', '\"', $error['message']);
66
+ $error['message'] = str_replace('/', '\/', $error['message']);
67
+ $error['message'] = str_replace("\n", '\n', $error['message']);
68
+ $error['message'] = str_replace("\r", '\r', $error['message']);
69
+ $error['message'] = str_replace("\t", '\t', $error['message']);
70
+
71
+ $fixable = 'false';
72
+ if ($error['fixable'] === true) {
73
+ $fixable = 'true';
74
+ }
75
+
76
+ $messages .= '{"message":"'.$error['message'].'",';
77
+ $messages .= '"source":"'.$error['source'].'",';
78
+ $messages .= '"severity":'.$error['severity'].',';
79
+ $messages .= '"type":"'.$error['type'].'",';
80
+ $messages .= '"line":'.$line.',';
81
+ $messages .= '"column":'.$column.',';
82
+ $messages .= '"fixable":'.$fixable;
83
+ $messages .= '},';
84
+ }//end foreach
85
+ }//end foreach
86
+ }//end foreach
87
+
88
+ echo rtrim($messages, ',');
89
+ echo ']},';
90
+
91
+ return true;
92
+
93
+ }//end generateFileReport()
94
+
95
+
96
+ /**
97
+ * Generates a JSON report.
98
+ *
99
+ * @param string $cachedData Any partial report data that was returned from
100
+ * generateFileReport during the run.
101
+ * @param int $totalFiles Total number of files processed during the run.
102
+ * @param int $totalErrors Total number of errors found during the run.
103
+ * @param int $totalWarnings Total number of warnings found during the run.
104
+ * @param int $totalFixable Total number of problems that can be fixed.
105
+ * @param boolean $showSources Show sources?
106
+ * @param int $width Maximum allowed line width.
107
+ * @param boolean $toScreen Is the report being printed to screen?
108
+ *
109
+ * @return void
110
+ */
111
+ public function generate(
112
+ $cachedData,
113
+ $totalFiles,
114
+ $totalErrors,
115
+ $totalWarnings,
116
+ $totalFixable,
117
+ $showSources=false,
118
+ $width=80,
119
+ $toScreen=true
120
+ ) {
121
+ echo '{"totals":{"errors":'.$totalErrors.',"warnings":'.$totalWarnings.',"fixable":'.$totalFixable.'},"files":{';
122
+ echo rtrim($cachedData, ',');
123
+ echo "}}";
124
+
125
+ }//end generate()
126
+
127
+
128
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Junit.php ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * JUnit report for PHP_CodeSniffer.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Oleg Lobach <oleg@lobach.info>
10
+ * @author Greg Sherwood <gsherwood@squiz.net>
11
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
12
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
13
+ * @link http://pear.php.net/package/PHP_CodeSniffer
14
+ */
15
+
16
+ /**
17
+ * JUnit report for PHP_CodeSniffer.
18
+ *
19
+ * PHP version 5
20
+ *
21
+ * @category PHP
22
+ * @package PHP_CodeSniffer
23
+ * @author Oleg Lobach <oleg@lobach.info>
24
+ * @author Greg Sherwood <gsherwood@squiz.net>
25
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
26
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
27
+ * @version Release: @package_version@
28
+ * @link http://pear.php.net/package/PHP_CodeSniffer
29
+ */
30
+ class PHP_CodeSniffer_Reports_Junit implements PHP_CodeSniffer_Report
31
+ {
32
+
33
+ /**
34
+ * A count of tests that have been performed.
35
+ *
36
+ * @var int
37
+ */
38
+ private $_tests = 0;
39
+
40
+
41
+ /**
42
+ * Generate a partial report for a single processed file.
43
+ *
44
+ * Function should return TRUE if it printed or stored data about the file
45
+ * and FALSE if it ignored the file. Returning TRUE indicates that the file and
46
+ * its data should be counted in the grand totals.
47
+ *
48
+ * @param array $report Prepared report data.
49
+ * @param PHP_CodeSniffer_File $phpcsFile The file being reported on.
50
+ * @param boolean $showSources Show sources?
51
+ * @param int $width Maximum allowed line width.
52
+ *
53
+ * @return boolean
54
+ */
55
+ public function generateFileReport(
56
+ $report,
57
+ PHP_CodeSniffer_File $phpcsFile,
58
+ $showSources=false,
59
+ $width=80
60
+ ) {
61
+ if (count($report['messages']) === 0) {
62
+ $this->_tests++;
63
+ } else {
64
+ $this->_tests += ($report['errors'] + $report['warnings']);
65
+ }
66
+
67
+ $out = new XMLWriter;
68
+ $out->openMemory();
69
+ $out->setIndent(true);
70
+
71
+ $out->startElement('testsuite');
72
+ $out->writeAttribute('name', $report['filename']);
73
+
74
+ if (count($report['messages']) === 0) {
75
+ $out->writeAttribute('tests', 1);
76
+ $out->writeAttribute('failures', 0);
77
+
78
+ $out->startElement('testcase');
79
+ $out->writeAttribute('name', $report['filename']);
80
+ $out->endElement();
81
+ } else {
82
+ $failures = ($report['errors'] + $report['warnings']);
83
+ $out->writeAttribute('tests', $failures);
84
+ $out->writeAttribute('failures', $failures);
85
+
86
+ foreach ($report['messages'] as $line => $lineErrors) {
87
+ foreach ($lineErrors as $column => $colErrors) {
88
+ foreach ($colErrors as $error) {
89
+ $out->startElement('testcase');
90
+ $out->writeAttribute('name', $error['source'].' at '.$report['filename']." ($line:$column)");
91
+
92
+ $error['type'] = strtolower($error['type']);
93
+ if (PHP_CODESNIFFER_ENCODING !== 'utf-8') {
94
+ $error['message'] = iconv(PHP_CODESNIFFER_ENCODING, 'utf-8', $error['message']);
95
+ }
96
+
97
+ $out->startElement('failure');
98
+ $out->writeAttribute('type', $error['type']);
99
+ $out->writeAttribute('message', $error['message']);
100
+ $out->endElement();
101
+
102
+ $out->endElement();
103
+ }
104
+ }
105
+ }
106
+ }//end if
107
+
108
+ $out->endElement();
109
+ echo $out->flush();
110
+ return true;
111
+
112
+ }//end generateFileReport()
113
+
114
+
115
+ /**
116
+ * Prints all violations for processed files, in a proprietary XML format.
117
+ *
118
+ * @param string $cachedData Any partial report data that was returned from
119
+ * generateFileReport during the run.
120
+ * @param int $totalFiles Total number of files processed during the run.
121
+ * @param int $totalErrors Total number of errors found during the run.
122
+ * @param int $totalWarnings Total number of warnings found during the run.
123
+ * @param int $totalFixable Total number of problems that can be fixed.
124
+ * @param boolean $showSources Show sources?
125
+ * @param int $width Maximum allowed line width.
126
+ * @param boolean $toScreen Is the report being printed to screen?
127
+ *
128
+ * @return void
129
+ */
130
+ public function generate(
131
+ $cachedData,
132
+ $totalFiles,
133
+ $totalErrors,
134
+ $totalWarnings,
135
+ $totalFixable,
136
+ $showSources=false,
137
+ $width=80,
138
+ $toScreen=true
139
+ ) {
140
+ $failures = ($totalErrors + $totalWarnings);
141
+ echo '<?xml version="1.0" encoding="UTF-8"?>'.PHP_EOL;
142
+ echo '<testsuites name="PHP_CodeSniffer '.PHP_CodeSniffer::VERSION.'" tests="'.$this->_tests.'" failures="'.$failures.'">'.PHP_EOL;
143
+ echo $cachedData;
144
+ echo '</testsuites>'.PHP_EOL;
145
+
146
+ }//end generate()
147
+
148
+
149
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Notifysend.php ADDED
@@ -0,0 +1,262 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Notify-send report for PHP_CodeSniffer.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Christian Weiske <christian.weiske@netresearch.de>
10
+ * @author Greg Sherwood <gsherwood@squiz.net>
11
+ * @copyright 2012-2014 Christian Weiske
12
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
13
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
14
+ * @link http://pear.php.net/package/PHP_CodeSniffer
15
+ */
16
+
17
+ /**
18
+ * Notify-send report for PHP_CodeSniffer.
19
+ *
20
+ * Supported configuration parameters:
21
+ * - notifysend_path - Full path to notify-send cli command
22
+ * - notifysend_timeout - Timeout in milliseconds
23
+ * - notifysend_showok - Show "ok, all fine" messages (0/1)
24
+ *
25
+ * @category PHP
26
+ * @package PHP_CodeSniffer
27
+ * @author Christian Weiske <christian.weiske@netresearch.de>
28
+ * @author Greg Sherwood <gsherwood@squiz.net>
29
+ * @copyright 2012-2014 Christian Weiske
30
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
31
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
32
+ * @version Release: @package_version@
33
+ * @link http://pear.php.net/package/PHP_CodeSniffer
34
+ */
35
+ class PHP_CodeSniffer_Reports_Notifysend implements PHP_CodeSniffer_Report
36
+ {
37
+
38
+ /**
39
+ * Notification timeout in milliseconds.
40
+ *
41
+ * @var integer
42
+ */
43
+ protected $timeout = 3000;
44
+
45
+ /**
46
+ * Path to notify-send command.
47
+ *
48
+ * @var string
49
+ */
50
+ protected $path = 'notify-send';
51
+
52
+ /**
53
+ * Show "ok, all fine" messages.
54
+ *
55
+ * @var boolean
56
+ */
57
+ protected $showOk = true;
58
+
59
+ /**
60
+ * Version of installed notify-send executable.
61
+ *
62
+ * @var string
63
+ */
64
+ protected $version = null;
65
+
66
+ /**
67
+ * A record of the last file checked.
68
+ *
69
+ * This is used in case we only checked one file and need to print
70
+ * the name/path of the file. We wont have access to the checked file list
71
+ * after the run has been completed.
72
+ *
73
+ * @var string
74
+ */
75
+ private $_lastCheckedFile = '';
76
+
77
+
78
+ /**
79
+ * Load configuration data.
80
+ */
81
+ public function __construct()
82
+ {
83
+ $path = PHP_CodeSniffer::getConfigData('notifysend_path');
84
+ if ($path !== null) {
85
+ $this->path = $path;
86
+ }
87
+
88
+ $timeout = PHP_CodeSniffer::getConfigData('notifysend_timeout');
89
+ if ($timeout !== null) {
90
+ $this->timeout = (int) $timeout;
91
+ }
92
+
93
+ $showOk = PHP_CodeSniffer::getConfigData('notifysend_showok');
94
+ if ($showOk !== null) {
95
+ $this->showOk = (boolean) $showOk;
96
+ }
97
+
98
+ $this->version = str_replace(
99
+ 'notify-send ',
100
+ '',
101
+ exec($this->path.' --version')
102
+ );
103
+
104
+ }//end __construct()
105
+
106
+
107
+ /**
108
+ * Generate a partial report for a single processed file.
109
+ *
110
+ * Function should return TRUE if it printed or stored data about the file
111
+ * and FALSE if it ignored the file. Returning TRUE indicates that the file and
112
+ * its data should be counted in the grand totals.
113
+ *
114
+ * @param array $report Prepared report data.
115
+ * @param PHP_CodeSniffer_File $phpcsFile The file being reported on.
116
+ * @param boolean $showSources Show sources?
117
+ * @param int $width Maximum allowed line width.
118
+ *
119
+ * @return boolean
120
+ */
121
+ public function generateFileReport(
122
+ $report,
123
+ PHP_CodeSniffer_File $phpcsFile,
124
+ $showSources=false,
125
+ $width=80
126
+ ) {
127
+ // We don't need to print anything, but we want this file counted
128
+ // in the total number of checked files even if it has no errors.
129
+ $this->_lastCheckedFile = $report['filename'];
130
+ return true;
131
+
132
+ }//end generateFileReport()
133
+
134
+
135
+ /**
136
+ * Generates a summary of errors and warnings for each file processed.
137
+ *
138
+ * @param string $cachedData Any partial report data that was returned from
139
+ * generateFileReport during the run.
140
+ * @param int $totalFiles Total number of files processed during the run.
141
+ * @param int $totalErrors Total number of errors found during the run.
142
+ * @param int $totalWarnings Total number of warnings found during the run.
143
+ * @param int $totalFixable Total number of problems that can be fixed.
144
+ * @param boolean $showSources Show sources?
145
+ * @param int $width Maximum allowed line width.
146
+ * @param boolean $toScreen Is the report being printed to screen?
147
+ *
148
+ * @return void
149
+ */
150
+ public function generate(
151
+ $cachedData,
152
+ $totalFiles,
153
+ $totalErrors,
154
+ $totalWarnings,
155
+ $totalFixable,
156
+ $showSources=false,
157
+ $width=80,
158
+ $toScreen=true
159
+ ) {
160
+ $msg = $this->generateMessage($totalFiles, $totalErrors, $totalWarnings);
161
+ if ($msg === null) {
162
+ if ($this->showOk === true) {
163
+ $this->notifyAllFine();
164
+ }
165
+ } else {
166
+ $this->notifyErrors($msg);
167
+ }
168
+
169
+ }//end generate()
170
+
171
+
172
+ /**
173
+ * Generate the error message to show to the user.
174
+ *
175
+ * @param int $totalFiles Total number of files processed during the run.
176
+ * @param int $totalErrors Total number of errors found during the run.
177
+ * @param int $totalWarnings Total number of warnings found during the run.
178
+ *
179
+ * @return string Error message or NULL if no error/warning found.
180
+ */
181
+ protected function generateMessage($totalFiles, $totalErrors, $totalWarnings)
182
+ {
183
+ if ($totalErrors === 0 && $totalWarnings === 0) {
184
+ // Nothing to print.
185
+ return null;
186
+ }
187
+
188
+ $msg = '';
189
+ if ($totalFiles > 1) {
190
+ $msg .= 'Checked '.$totalFiles.' files'.PHP_EOL;
191
+ } else {
192
+ $msg .= $this->_lastCheckedFile.PHP_EOL;
193
+ }
194
+
195
+ if ($totalWarnings > 0) {
196
+ $msg .= $totalWarnings.' warnings'.PHP_EOL;
197
+ }
198
+
199
+ if ($totalErrors > 0) {
200
+ $msg .= $totalErrors.' errors'.PHP_EOL;
201
+ }
202
+
203
+ return $msg;
204
+
205
+ }//end generateMessage()
206
+
207
+
208
+ /**
209
+ * Tell the user that all is fine and no error/warning has been found.
210
+ *
211
+ * @return void
212
+ */
213
+ protected function notifyAllFine()
214
+ {
215
+ $cmd = $this->getBasicCommand();
216
+ $cmd .= ' -i info';
217
+ $cmd .= ' "PHP CodeSniffer: Ok"';
218
+ $cmd .= ' "All fine"';
219
+ exec($cmd);
220
+
221
+ }//end notifyAllFine()
222
+
223
+
224
+ /**
225
+ * Tell the user that errors/warnings have been found.
226
+ *
227
+ * @param string $msg Message to display.
228
+ *
229
+ * @return void
230
+ */
231
+ protected function notifyErrors($msg)
232
+ {
233
+ $cmd = $this->getBasicCommand();
234
+ $cmd .= ' -i error';
235
+ $cmd .= ' "PHP CodeSniffer: Error"';
236
+ $cmd .= ' '.escapeshellarg(trim($msg));
237
+ exec($cmd);
238
+
239
+ }//end notifyErrors()
240
+
241
+
242
+ /**
243
+ * Generate and return the basic notify-send command string to execute.
244
+ *
245
+ * @return string Shell command with common parameters.
246
+ */
247
+ protected function getBasicCommand()
248
+ {
249
+ $cmd = escapeshellcmd($this->path);
250
+ $cmd .= ' --category dev.validate';
251
+ $cmd .= ' -h int:transient:1';
252
+ $cmd .= ' -t '.(int) $this->timeout;
253
+ if (version_compare($this->version, '0.7.3', '>=') === true) {
254
+ $cmd .= ' -a phpcs';
255
+ }
256
+
257
+ return $cmd;
258
+
259
+ }//end getBasicCommand()
260
+
261
+
262
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Source.php ADDED
@@ -0,0 +1,334 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Source report for PHP_CodeSniffer.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Gabriele Santini <gsantini@sqli.com>
10
+ * @author Greg Sherwood <gsherwood@squiz.net>
11
+ * @copyright 2009-2014 SQLI <www.sqli.com>
12
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
13
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
14
+ * @link http://pear.php.net/package/PHP_CodeSniffer
15
+ */
16
+
17
+ /**
18
+ * Source report for PHP_CodeSniffer.
19
+ *
20
+ * PHP version 5
21
+ *
22
+ * @category PHP
23
+ * @package PHP_CodeSniffer
24
+ * @author Gabriele Santini <gsantini@sqli.com>
25
+ * @author Greg Sherwood <gsherwood@squiz.net>
26
+ * @copyright 2009-2014 SQLI <www.sqli.com>
27
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
28
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
29
+ * @version Release: @package_version@
30
+ * @link http://pear.php.net/package/PHP_CodeSniffer
31
+ */
32
+ class PHP_CodeSniffer_Reports_Source implements PHP_CodeSniffer_Report
33
+ {
34
+
35
+ /**
36
+ * A cache of source stats collected during the run.
37
+ *
38
+ * @var array
39
+ */
40
+ private $_sourceCache = array();
41
+
42
+
43
+ /**
44
+ * Generate a partial report for a single processed file.
45
+ *
46
+ * Function should return TRUE if it printed or stored data about the file
47
+ * and FALSE if it ignored the file. Returning TRUE indicates that the file and
48
+ * its data should be counted in the grand totals.
49
+ *
50
+ * @param array $report Prepared report data.
51
+ * @param PHP_CodeSniffer_File $phpcsFile The file being reported on.
52
+ * @param boolean $showSources Show sources?
53
+ * @param int $width Maximum allowed line width.
54
+ *
55
+ * @return boolean
56
+ */
57
+ public function generateFileReport(
58
+ $report,
59
+ PHP_CodeSniffer_File $phpcsFile,
60
+ $showSources=false,
61
+ $width=80
62
+ ) {
63
+ if ($report['errors'] === 0 && $report['warnings'] === 0) {
64
+ // Nothing to print.
65
+ return false;
66
+ }
67
+
68
+ foreach ($report['messages'] as $line => $lineErrors) {
69
+ foreach ($lineErrors as $column => $colErrors) {
70
+ foreach ($colErrors as $error) {
71
+ $source = $error['source'];
72
+ if (isset($this->_sourceCache[$source]) === false) {
73
+ if ($showSources === true) {
74
+ $parts = null;
75
+ $sniff = $source;
76
+ } else {
77
+ $parts = explode('.', $source);
78
+ if ($parts[0] === 'Internal') {
79
+ $parts[2] = $parts[1];
80
+ $parts[1] = '';
81
+ }
82
+
83
+ $parts[1] = $this->makeFriendlyName($parts[1]);
84
+
85
+ $sniff = $this->makeFriendlyName($parts[2]);
86
+ if (isset($parts[3]) === true) {
87
+ $name = $this->makeFriendlyName($parts[3]);
88
+ $name[0] = strtolower($name[0]);
89
+ $sniff .= ' '.$name;
90
+ unset($parts[3]);
91
+ }
92
+
93
+ $parts[2] = $sniff;
94
+ }//end if
95
+
96
+ $this->_sourceCache[$source] = array(
97
+ 'count' => 1,
98
+ 'fixable' => $error['fixable'],
99
+ 'parts' => $parts,
100
+ 'strlen' => strlen($sniff),
101
+ );
102
+ } else {
103
+ $this->_sourceCache[$source]['count']++;
104
+ }//end if
105
+ }//end foreach
106
+ }//end foreach
107
+ }//end foreach
108
+
109
+ return true;
110
+
111
+ }//end generateFileReport()
112
+
113
+
114
+ /**
115
+ * Prints the source of all errors and warnings.
116
+ *
117
+ * @param string $cachedData Any partial report data that was returned from
118
+ * generateFileReport during the run.
119
+ * @param int $totalFiles Total number of files processed during the run.
120
+ * @param int $totalErrors Total number of errors found during the run.
121
+ * @param int $totalWarnings Total number of warnings found during the run.
122
+ * @param int $totalFixable Total number of problems that can be fixed.
123
+ * @param boolean $showSources Show sources?
124
+ * @param int $width Maximum allowed line width.
125
+ * @param boolean $toScreen Is the report being printed to screen?
126
+ *
127
+ * @return void
128
+ */
129
+ public function generate(
130
+ $cachedData,
131
+ $totalFiles,
132
+ $totalErrors,
133
+ $totalWarnings,
134
+ $totalFixable,
135
+ $showSources=false,
136
+ $width=80,
137
+ $toScreen=true
138
+ ) {
139
+ if (empty($this->_sourceCache) === true) {
140
+ // Nothing to show.
141
+ return;
142
+ }
143
+
144
+ // Make sure the report width isn't too big.
145
+ $maxLength = 0;
146
+ foreach ($this->_sourceCache as $source => $data) {
147
+ $maxLength = max($maxLength, $data['strlen']);
148
+ }
149
+
150
+ if ($showSources === true) {
151
+ $width = min($width, ($maxLength + 11));
152
+ } else {
153
+ $width = min($width, ($maxLength + 41));
154
+ }
155
+
156
+ $width = max($width, 70);
157
+
158
+ asort($this->_sourceCache);
159
+ $this->_sourceCache = array_reverse($this->_sourceCache);
160
+
161
+ echo PHP_EOL."\033[1mPHP CODE SNIFFER VIOLATION SOURCE SUMMARY\033[0m".PHP_EOL;
162
+ echo str_repeat('-', $width).PHP_EOL."\033[1m";
163
+ if ($showSources === true) {
164
+ if ($totalFixable > 0) {
165
+ echo ' SOURCE'.str_repeat(' ', ($width - 15)).'COUNT'.PHP_EOL;
166
+ } else {
167
+ echo 'SOURCE'.str_repeat(' ', ($width - 11)).'COUNT'.PHP_EOL;
168
+ }
169
+ } else {
170
+ if ($totalFixable > 0) {
171
+ echo ' STANDARD CATEGORY SNIFF'.str_repeat(' ', ($width - 44)).'COUNT'.PHP_EOL;
172
+ } else {
173
+ echo 'STANDARD CATEGORY SNIFF'.str_repeat(' ', ($width - 40)).'COUNT'.PHP_EOL;
174
+ }
175
+ }
176
+
177
+ echo "\033[0m".str_repeat('-', $width).PHP_EOL;
178
+
179
+ $fixableSources = 0;
180
+
181
+ if ($showSources === true) {
182
+ $maxSniffWidth = ($width - 7);
183
+ } else {
184
+ $maxSniffWidth = ($width - 37);
185
+ }
186
+
187
+ if ($totalFixable > 0) {
188
+ $maxSniffWidth -= 4;
189
+ }
190
+
191
+ foreach ($this->_sourceCache as $source => $sourceData) {
192
+ if ($totalFixable > 0) {
193
+ echo '[';
194
+ if ($sourceData['fixable'] === true) {
195
+ echo 'x';
196
+ $fixableSources++;
197
+ } else {
198
+ echo ' ';
199
+ }
200
+
201
+ echo '] ';
202
+ }
203
+
204
+ if ($showSources === true) {
205
+ if ($sourceData['strlen'] > $maxSniffWidth) {
206
+ $source = substr($source, 0, $maxSniffWidth);
207
+ }
208
+
209
+ echo $source;
210
+ if ($totalFixable > 0) {
211
+ echo str_repeat(' ', ($width - 9 - strlen($source)));
212
+ } else {
213
+ echo str_repeat(' ', ($width - 5 - strlen($source)));
214
+ }
215
+ } else {
216
+ $parts = $sourceData['parts'];
217
+
218
+ if (strlen($parts[0]) > 8) {
219
+ $parts[0] = substr($parts[0], 0, ((strlen($parts[0]) - 8) * -1));
220
+ }
221
+
222
+ echo $parts[0].str_repeat(' ', (10 - strlen($parts[0])));
223
+
224
+ $category = $parts[1];
225
+ if (strlen($category) > 18) {
226
+ $category = substr($category, 0, ((strlen($category) - 18) * -1));
227
+ }
228
+
229
+ echo $category.str_repeat(' ', (20 - strlen($category)));
230
+
231
+ $sniff = $parts[2];
232
+ if (strlen($sniff) > $maxSniffWidth) {
233
+ $sniff = substr($sniff, 0, $maxSniffWidth);
234
+ }
235
+
236
+ if ($totalFixable > 0) {
237
+ echo $sniff.str_repeat(' ', ($width - 39 - strlen($sniff)));
238
+ } else {
239
+ echo $sniff.str_repeat(' ', ($width - 35 - strlen($sniff)));
240
+ }
241
+ }//end if
242
+
243
+ echo $sourceData['count'].PHP_EOL;
244
+ }//end foreach
245
+
246
+ echo str_repeat('-', $width).PHP_EOL;
247
+ echo "\033[1m".'A TOTAL OF '.($totalErrors + $totalWarnings).' SNIFF VIOLATION';
248
+ if (($totalErrors + $totalWarnings) > 1) {
249
+ echo 'S';
250
+ }
251
+
252
+ echo ' WERE FOUND IN '.count($this->_sourceCache).' SOURCE';
253
+ if (count($this->_sourceCache) !== 1) {
254
+ echo 'S';
255
+ }
256
+
257
+ echo "\033[0m";
258
+
259
+ if ($totalFixable > 0) {
260
+ echo PHP_EOL.str_repeat('-', $width).PHP_EOL;
261
+ echo "\033[1mPHPCBF CAN FIX THE $fixableSources MARKED SOURCES AUTOMATICALLY ($totalFixable VIOLATIONS IN TOTAL)\033[0m";
262
+ }
263
+
264
+ echo PHP_EOL.str_repeat('-', $width).PHP_EOL.PHP_EOL;
265
+
266
+ if ($toScreen === true && PHP_CODESNIFFER_INTERACTIVE === false) {
267
+ PHP_CodeSniffer_Reporting::printRunTime();
268
+ }
269
+
270
+ }//end generate()
271
+
272
+
273
+ /**
274
+ * Converts a camel caps name into a readable string.
275
+ *
276
+ * @param string $name The camel caps name to convert.
277
+ *
278
+ * @return string
279
+ */
280
+ public function makeFriendlyName($name)
281
+ {
282
+ if (trim($name) === '') {
283
+ return '';
284
+ }
285
+
286
+ $friendlyName = '';
287
+ $length = strlen($name);
288
+
289
+ $lastWasUpper = false;
290
+ $lastWasNumeric = false;
291
+ for ($i = 0; $i < $length; $i++) {
292
+ if (is_numeric($name[$i]) === true) {
293
+ if ($lastWasNumeric === false) {
294
+ $friendlyName .= ' ';
295
+ }
296
+
297
+ $lastWasUpper = false;
298
+ $lastWasNumeric = true;
299
+ } else {
300
+ $lastWasNumeric = false;
301
+
302
+ $char = strtolower($name[$i]);
303
+ if ($char === $name[$i]) {
304
+ // Lowercase.
305
+ $lastWasUpper = false;
306
+ } else {
307
+ // Uppercase.
308
+ if ($lastWasUpper === false) {
309
+ $friendlyName .= ' ';
310
+ if ($i < ($length - 1)) {
311
+ $next = $name[($i + 1)];
312
+ if (strtolower($next) === $next) {
313
+ // Next char is lowercase so it is a word boundary.
314
+ $name[$i] = strtolower($name[$i]);
315
+ }
316
+ }
317
+ }
318
+
319
+ $lastWasUpper = true;
320
+ }
321
+ }//end if
322
+
323
+ $friendlyName .= $name[$i];
324
+ }//end for
325
+
326
+ $friendlyName = trim($friendlyName);
327
+ $friendlyName[0] = strtoupper($friendlyName[0]);
328
+
329
+ return $friendlyName;
330
+
331
+ }//end makeFriendlyName()
332
+
333
+
334
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Summary.php ADDED
@@ -0,0 +1,189 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Summary report for PHP_CodeSniffer.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Gabriele Santini <gsantini@sqli.com>
10
+ * @author Greg Sherwood <gsherwood@squiz.net>
11
+ * @copyright 2009-2014 SQLI <www.sqli.com>
12
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
13
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
14
+ * @link http://pear.php.net/package/PHP_CodeSniffer
15
+ */
16
+
17
+ /**
18
+ * Summary report for PHP_CodeSniffer.
19
+ *
20
+ * PHP version 5
21
+ *
22
+ * @category PHP
23
+ * @package PHP_CodeSniffer
24
+ * @author Gabriele Santini <gsantini@sqli.com>
25
+ * @author Greg Sherwood <gsherwood@squiz.net>
26
+ * @copyright 2009-2014 SQLI <www.sqli.com>
27
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
28
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
29
+ * @version Release: @package_version@
30
+ * @link http://pear.php.net/package/PHP_CodeSniffer
31
+ */
32
+ class PHP_CodeSniffer_Reports_Summary implements PHP_CodeSniffer_Report
33
+ {
34
+
35
+ /**
36
+ * TRUE if this report needs error messages instead of just totals.
37
+ *
38
+ * @var boolean
39
+ */
40
+ public $recordErrors = false;
41
+
42
+ /**
43
+ * An array of process files and their error data.
44
+ *
45
+ * @var boolean
46
+ */
47
+ private $_reportFiles = array();
48
+
49
+
50
+ /**
51
+ * Generate a partial report for a single processed file.
52
+ *
53
+ * Function should return TRUE if it printed or stored data about the file
54
+ * and FALSE if it ignored the file. Returning TRUE indicates that the file and
55
+ * its data should be counted in the grand totals.
56
+ *
57
+ * @param array $report Prepared report data.
58
+ * @param PHP_CodeSniffer_File $phpcsFile The file being reported on.
59
+ * @param boolean $showSources Show sources?
60
+ * @param int $width Maximum allowed line width.
61
+ *
62
+ * @return boolean
63
+ */
64
+ public function generateFileReport(
65
+ $report,
66
+ PHP_CodeSniffer_File $phpcsFile,
67
+ $showSources=false,
68
+ $width=80
69
+ ) {
70
+ if (PHP_CODESNIFFER_VERBOSITY === 0
71
+ && $report['errors'] === 0
72
+ && $report['warnings'] === 0
73
+ ) {
74
+ // Nothing to print.
75
+ return false;
76
+ }
77
+
78
+ $this->_reportFiles[$report['filename']] = array(
79
+ 'errors' => $report['errors'],
80
+ 'warnings' => $report['warnings'],
81
+ 'strlen' => strlen($report['filename']),
82
+ );
83
+
84
+ return true;
85
+
86
+ }//end generateFileReport()
87
+
88
+
89
+ /**
90
+ * Generates a summary of errors and warnings for each file processed.
91
+ *
92
+ * @param string $cachedData Any partial report data that was returned from
93
+ * generateFileReport during the run.
94
+ * @param int $totalFiles Total number of files processed during the run.
95
+ * @param int $totalErrors Total number of errors found during the run.
96
+ * @param int $totalWarnings Total number of warnings found during the run.
97
+ * @param int $totalFixable Total number of problems that can be fixed.
98
+ * @param boolean $showSources Show sources?
99
+ * @param int $width Maximum allowed line width.
100
+ * @param boolean $toScreen Is the report being printed to screen?
101
+ *
102
+ * @return void
103
+ */
104
+ public function generate(
105
+ $cachedData,
106
+ $totalFiles,
107
+ $totalErrors,
108
+ $totalWarnings,
109
+ $totalFixable,
110
+ $showSources=false,
111
+ $width=80,
112
+ $toScreen=true
113
+ ) {
114
+
115
+ if (empty($this->_reportFiles) === true) {
116
+ return;
117
+ }
118
+
119
+ // Make sure the report width isn't too big.
120
+ $maxLength = 0;
121
+ foreach ($this->_reportFiles as $file => $data) {
122
+ $maxLength = max($maxLength, $data['strlen']);
123
+ }
124
+
125
+ $width = min($width, ($maxLength + 21));
126
+ $width = max($width, 70);
127
+
128
+ echo PHP_EOL."\033[1m".'PHP CODE SNIFFER REPORT SUMMARY'."\033[0m".PHP_EOL;
129
+ echo str_repeat('-', $width).PHP_EOL;
130
+ echo "\033[1m".'FILE'.str_repeat(' ', ($width - 20)).'ERRORS WARNINGS'."\033[0m".PHP_EOL;
131
+ echo str_repeat('-', $width).PHP_EOL;
132
+
133
+ foreach ($this->_reportFiles as $file => $data) {
134
+ $padding = ($width - 18 - $data['strlen']);
135
+ if ($padding < 0) {
136
+ $file = '...'.substr($file, (($padding * -1) + 3));
137
+ $padding = 0;
138
+ }
139
+
140
+ echo $file.str_repeat(' ', $padding).' ';
141
+ if ($data['errors'] !== 0) {
142
+ echo "\033[31m".$data['errors']."\033[0m";
143
+ echo str_repeat(' ', (8 - strlen((string) $data['errors'])));
144
+ } else {
145
+ echo '0 ';
146
+ }
147
+
148
+ if ($data['warnings'] !== 0) {
149
+ echo "\033[33m".$data['warnings']."\033[0m";
150
+ } else {
151
+ echo '0';
152
+ }
153
+
154
+ echo PHP_EOL;
155
+ }//end foreach
156
+
157
+ echo str_repeat('-', $width).PHP_EOL;
158
+ echo "\033[1mA TOTAL OF $totalErrors ERROR";
159
+ if ($totalErrors !== 1) {
160
+ echo 'S';
161
+ }
162
+
163
+ echo ' AND '.$totalWarnings.' WARNING';
164
+ if ($totalWarnings !== 1) {
165
+ echo 'S';
166
+ }
167
+
168
+ echo ' WERE FOUND IN '.$totalFiles.' FILE';
169
+ if ($totalFiles !== 1) {
170
+ echo 'S';
171
+ }
172
+
173
+ echo "\033[0m";
174
+
175
+ if ($totalFixable > 0) {
176
+ echo PHP_EOL.str_repeat('-', $width).PHP_EOL;
177
+ echo "\033[1mPHPCBF CAN FIX $totalFixable OF THESE SNIFF VIOLATIONS AUTOMATICALLY\033[0m";
178
+ }
179
+
180
+ echo PHP_EOL.str_repeat('-', $width).PHP_EOL.PHP_EOL;
181
+
182
+ if ($toScreen === true && PHP_CODESNIFFER_INTERACTIVE === false) {
183
+ PHP_CodeSniffer_Reporting::printRunTime();
184
+ }
185
+
186
+ }//end generate()
187
+
188
+
189
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Svnblame.php ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Svnblame report for PHP_CodeSniffer.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Gabriele Santini <gsantini@sqli.com>
10
+ * @author Greg Sherwood <gsherwood@squiz.net>
11
+ * @copyright 2009-2014 SQLI <www.sqli.com>
12
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
13
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
14
+ * @link http://pear.php.net/package/PHP_CodeSniffer
15
+ */
16
+
17
+ /**
18
+ * Svnblame report for PHP_CodeSniffer.
19
+ *
20
+ * PHP version 5
21
+ *
22
+ * @category PHP
23
+ * @package PHP_CodeSniffer
24
+ * @author Gabriele Santini <gsantini@sqli.com>
25
+ * @author Greg Sherwood <gsherwood@squiz.net>
26
+ * @copyright 2009-2014 SQLI <www.sqli.com>
27
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
28
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
29
+ * @version Release: @package_version@
30
+ * @link http://pear.php.net/package/PHP_CodeSniffer
31
+ */
32
+ class PHP_CodeSniffer_Reports_Svnblame extends PHP_CodeSniffer_Reports_VersionControl
33
+ {
34
+
35
+ /**
36
+ * The name of the report we want in the output
37
+ *
38
+ * @var string
39
+ */
40
+ protected $reportName = 'SVN';
41
+
42
+
43
+ /**
44
+ * Extract the author from a blame line.
45
+ *
46
+ * @param string $line Line to parse.
47
+ *
48
+ * @return mixed string or false if impossible to recover.
49
+ */
50
+ protected function getAuthor($line)
51
+ {
52
+ $blameParts = array();
53
+ preg_match('|\s*([^\s]+)\s+([^\s]+)|', $line, $blameParts);
54
+
55
+ if (isset($blameParts[2]) === false) {
56
+ return false;
57
+ }
58
+
59
+ return $blameParts[2];
60
+
61
+ }//end getAuthor()
62
+
63
+
64
+ /**
65
+ * Gets the blame output.
66
+ *
67
+ * @param string $filename File to blame.
68
+ *
69
+ * @return array
70
+ */
71
+ protected function getBlameContent($filename)
72
+ {
73
+ if (PHP_CODESNIFFER_VERBOSITY > 0) {
74
+ echo 'Getting SVN blame info for '.basename($filename).'... ';
75
+ }
76
+
77
+ $command = 'svn blame "'.$filename.'" 2>&1';
78
+ $handle = popen($command, 'r');
79
+ if ($handle === false) {
80
+ echo 'ERROR: Could not execute "'.$command.'"'.PHP_EOL.PHP_EOL;
81
+ exit(2);
82
+ }
83
+
84
+ $rawContent = stream_get_contents($handle);
85
+ fclose($handle);
86
+
87
+ if (PHP_CODESNIFFER_VERBOSITY > 0) {
88
+ echo 'DONE'.PHP_EOL;
89
+ }
90
+
91
+ $blames = explode("\n", $rawContent);
92
+
93
+ return $blames;
94
+
95
+ }//end getBlameContent()
96
+
97
+
98
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/VersionControl.php ADDED
@@ -0,0 +1,342 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Version control report base class for PHP_CodeSniffer.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Ben Selby <benmatselby@gmail.com>
10
+ * @copyright 2009-2014 SQLI <www.sqli.com>
11
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
12
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
13
+ * @link http://pear.php.net/package/PHP_CodeSniffer
14
+ */
15
+
16
+ /**
17
+ * Version control report base class for PHP_CodeSniffer.
18
+ *
19
+ * PHP version 5
20
+ *
21
+ * @category PHP
22
+ * @package PHP_CodeSniffer
23
+ * @author Ben Selby <benmatselby@gmail.com>
24
+ * @copyright 2009-2014 SQLI <www.sqli.com>
25
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
26
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
27
+ * @version Release: 1.2.2
28
+ * @link http://pear.php.net/package/PHP_CodeSniffer
29
+ */
30
+ abstract class PHP_CodeSniffer_Reports_VersionControl implements PHP_CodeSniffer_Report
31
+ {
32
+
33
+ /**
34
+ * The name of the report we want in the output.
35
+ *
36
+ * @var string
37
+ */
38
+ protected $reportName = 'VERSION CONTROL';
39
+
40
+ /**
41
+ * A cache of author stats collected during the run.
42
+ *
43
+ * @var array
44
+ */
45
+ private $_authorCache = array();
46
+
47
+ /**
48
+ * A cache of blame stats collected during the run.
49
+ *
50
+ * @var array
51
+ */
52
+ private $_praiseCache = array();
53
+
54
+ /**
55
+ * A cache of source stats collected during the run.
56
+ *
57
+ * @var array
58
+ */
59
+ private $_sourceCache = array();
60
+
61
+
62
+ /**
63
+ * Generate a partial report for a single processed file.
64
+ *
65
+ * Function should return TRUE if it printed or stored data about the file
66
+ * and FALSE if it ignored the file. Returning TRUE indicates that the file and
67
+ * its data should be counted in the grand totals.
68
+ *
69
+ * @param array $report Prepared report data.
70
+ * @param PHP_CodeSniffer_File $phpcsFile The file being reported on.
71
+ * @param boolean $showSources Show sources?
72
+ * @param int $width Maximum allowed line width.
73
+ *
74
+ * @return boolean
75
+ */
76
+ public function generateFileReport(
77
+ $report,
78
+ PHP_CodeSniffer_File $phpcsFile,
79
+ $showSources=false,
80
+ $width=80
81
+ ) {
82
+ $blames = $this->getBlameContent($report['filename']);
83
+
84
+ foreach ($report['messages'] as $line => $lineErrors) {
85
+ $author = 'Unknown';
86
+ if (isset($blames[($line - 1)]) === true) {
87
+ $blameAuthor = $this->getAuthor($blames[($line - 1)]);
88
+ if ($blameAuthor !== false) {
89
+ $author = $blameAuthor;
90
+ }
91
+ }
92
+
93
+ if (isset($this->_authorCache[$author]) === false) {
94
+ $this->_authorCache[$author] = 0;
95
+ $this->_praiseCache[$author] = array(
96
+ 'good' => 0,
97
+ 'bad' => 0,
98
+ );
99
+ }
100
+
101
+ $this->_praiseCache[$author]['bad']++;
102
+
103
+ foreach ($lineErrors as $column => $colErrors) {
104
+ foreach ($colErrors as $error) {
105
+ $this->_authorCache[$author]++;
106
+
107
+ if ($showSources === true) {
108
+ $source = $error['source'];
109
+ if (isset($this->_sourceCache[$author][$source]) === false) {
110
+ $this->_sourceCache[$author][$source] = array(
111
+ 'count' => 1,
112
+ 'fixable' => $error['fixable'],
113
+ );
114
+ } else {
115
+ $this->_sourceCache[$author][$source]['count']++;
116
+ }
117
+ }
118
+ }
119
+ }
120
+
121
+ unset($blames[($line - 1)]);
122
+ }//end foreach
123
+
124
+ // No go through and give the authors some credit for
125
+ // all the lines that do not have errors.
126
+ foreach ($blames as $line) {
127
+ $author = $this->getAuthor($line);
128
+ if ($author === false) {
129
+ $author = 'Unknown';
130
+ }
131
+
132
+ if (isset($this->_authorCache[$author]) === false) {
133
+ // This author doesn't have any errors.
134
+ if (PHP_CODESNIFFER_VERBOSITY === 0) {
135
+ continue;
136
+ }
137
+
138
+ $this->_authorCache[$author] = 0;
139
+ $this->_praiseCache[$author] = array(
140
+ 'good' => 0,
141
+ 'bad' => 0,
142
+ );
143
+ }
144
+
145
+ $this->_praiseCache[$author]['good']++;
146
+ }//end foreach
147
+
148
+ return true;
149
+
150
+ }//end generateFileReport()
151
+
152
+
153
+ /**
154
+ * Prints the author of all errors and warnings, as given by "version control blame".
155
+ *
156
+ * @param string $cachedData Any partial report data that was returned from
157
+ * generateFileReport during the run.
158
+ * @param int $totalFiles Total number of files processed during the run.
159
+ * @param int $totalErrors Total number of errors found during the run.
160
+ * @param int $totalWarnings Total number of warnings found during the run.
161
+ * @param int $totalFixable Total number of problems that can be fixed.
162
+ * @param boolean $showSources Show sources?
163
+ * @param int $width Maximum allowed line width.
164
+ * @param boolean $toScreen Is the report being printed to screen?
165
+ *
166
+ * @return void
167
+ */
168
+ public function generate(
169
+ $cachedData,
170
+ $totalFiles,
171
+ $totalErrors,
172
+ $totalWarnings,
173
+ $totalFixable,
174
+ $showSources=false,
175
+ $width=80,
176
+ $toScreen=true
177
+ ) {
178
+ $errorsShown = ($totalErrors + $totalWarnings);
179
+ if ($errorsShown === 0) {
180
+ // Nothing to show.
181
+ return;
182
+ }
183
+
184
+ // Make sure the report width isn't too big.
185
+ $maxLength = 0;
186
+ foreach ($this->_authorCache as $author => $count) {
187
+ $maxLength = max($maxLength, strlen($author));
188
+ if ($showSources === true && isset($this->_sourceCache[$author]) === true) {
189
+ foreach ($this->_sourceCache[$author] as $source => $sourceData) {
190
+ if ($source === 'count') {
191
+ continue;
192
+ }
193
+
194
+ $maxLength = max($maxLength, (strlen($source) + 9));
195
+ }
196
+ }
197
+ }
198
+
199
+ $width = min($width, ($maxLength + 30));
200
+ $width = max($width, 70);
201
+ arsort($this->_authorCache);
202
+
203
+ echo PHP_EOL."\033[1m".'PHP CODE SNIFFER '.$this->reportName.' BLAME SUMMARY'."\033[0m".PHP_EOL;
204
+ echo str_repeat('-', $width).PHP_EOL."\033[1m";
205
+ if ($showSources === true) {
206
+ echo 'AUTHOR SOURCE'.str_repeat(' ', ($width - 43)).'(Author %) (Overall %) COUNT'.PHP_EOL;
207
+ echo str_repeat('-', $width).PHP_EOL;
208
+ } else {
209
+ echo 'AUTHOR'.str_repeat(' ', ($width - 34)).'(Author %) (Overall %) COUNT'.PHP_EOL;
210
+ echo str_repeat('-', $width).PHP_EOL;
211
+ }
212
+
213
+ echo "\033[0m";
214
+
215
+ if ($showSources === true) {
216
+ $maxSniffWidth = ($width - 15);
217
+
218
+ if ($totalFixable > 0) {
219
+ $maxSniffWidth -= 4;
220
+ }
221
+ }
222
+
223
+ $fixableSources = 0;
224
+
225
+ foreach ($this->_authorCache as $author => $count) {
226
+ if ($this->_praiseCache[$author]['good'] === 0) {
227
+ $percent = 0;
228
+ } else {
229
+ $total = ($this->_praiseCache[$author]['bad'] + $this->_praiseCache[$author]['good']);
230
+ $percent = round(($this->_praiseCache[$author]['bad'] / $total * 100), 2);
231
+ }
232
+
233
+ $overallPercent = '('.round((($count / $errorsShown) * 100), 2).')';
234
+ $authorPercent = '('.$percent.')';
235
+ $line = str_repeat(' ', (6 - strlen($count))).$count;
236
+ $line = str_repeat(' ', (12 - strlen($overallPercent))).$overallPercent.$line;
237
+ $line = str_repeat(' ', (11 - strlen($authorPercent))).$authorPercent.$line;
238
+ $line = $author.str_repeat(' ', ($width - strlen($author) - strlen($line))).$line;
239
+
240
+ if ($showSources === true) {
241
+ $line = "\033[1m$line\033[0m";
242
+ }
243
+
244
+ echo $line.PHP_EOL;
245
+
246
+ if ($showSources === true && isset($this->_sourceCache[$author]) === true) {
247
+ $errors = $this->_sourceCache[$author];
248
+ asort($errors);
249
+ $errors = array_reverse($errors);
250
+
251
+ foreach ($errors as $source => $sourceData) {
252
+ if ($source === 'count') {
253
+ continue;
254
+ }
255
+
256
+ $count = $sourceData['count'];
257
+
258
+ $srcLength = strlen($source);
259
+ if ($srcLength > $maxSniffWidth) {
260
+ $source = substr($source, 0, $maxSniffWidth);
261
+ }
262
+
263
+ $line = str_repeat(' ', (5 - strlen($count))).$count;
264
+
265
+ echo ' ';
266
+ if ($totalFixable > 0) {
267
+ echo '[';
268
+ if ($sourceData['fixable'] === true) {
269
+ echo 'x';
270
+ $fixableSources++;
271
+ } else {
272
+ echo ' ';
273
+ }
274
+
275
+ echo '] ';
276
+ }
277
+
278
+ echo $source;
279
+ if ($totalFixable > 0) {
280
+ echo str_repeat(' ', ($width - 18 - strlen($source)));
281
+ } else {
282
+ echo str_repeat(' ', ($width - 14 - strlen($source)));
283
+ }
284
+
285
+ echo $line.PHP_EOL;
286
+ }//end foreach
287
+ }//end if
288
+ }//end foreach
289
+
290
+ echo str_repeat('-', $width).PHP_EOL;
291
+ echo "\033[1m".'A TOTAL OF '.$errorsShown.' SNIFF VIOLATION';
292
+ if ($errorsShown !== 1) {
293
+ echo 'S';
294
+ }
295
+
296
+ echo ' WERE COMMITTED BY '.count($this->_authorCache).' AUTHOR';
297
+ if (count($this->_authorCache) !== 1) {
298
+ echo 'S';
299
+ }
300
+
301
+ echo "\033[0m";
302
+
303
+ if ($totalFixable > 0) {
304
+ if ($showSources === true) {
305
+ echo PHP_EOL.str_repeat('-', $width).PHP_EOL;
306
+ echo "\033[1mPHPCBF CAN FIX THE $fixableSources MARKED SOURCES AUTOMATICALLY ($totalFixable VIOLATIONS IN TOTAL)\033[0m";
307
+ } else {
308
+ echo PHP_EOL.str_repeat('-', $width).PHP_EOL;
309
+ echo "\033[1mPHPCBF CAN FIX $totalFixable OF THESE SNIFF VIOLATIONS AUTOMATICALLY\033[0m";
310
+ }
311
+ }
312
+
313
+ echo PHP_EOL.str_repeat('-', $width).PHP_EOL.PHP_EOL;
314
+
315
+ if ($toScreen === true && PHP_CODESNIFFER_INTERACTIVE === false) {
316
+ PHP_CodeSniffer_Reporting::printRunTime();
317
+ }
318
+
319
+ }//end generate()
320
+
321
+
322
+ /**
323
+ * Extract the author from a blame line.
324
+ *
325
+ * @param string $line Line to parse.
326
+ *
327
+ * @return mixed string or false if impossible to recover.
328
+ */
329
+ abstract protected function getAuthor($line);
330
+
331
+
332
+ /**
333
+ * Gets the blame output.
334
+ *
335
+ * @param string $filename File to blame.
336
+ *
337
+ * @return array
338
+ */
339
+ abstract protected function getBlameContent($filename);
340
+
341
+
342
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Reports/Xml.php ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Xml report for PHP_CodeSniffer.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Gabriele Santini <gsantini@sqli.com>
10
+ * @author Greg Sherwood <gsherwood@squiz.net>
11
+ * @copyright 2009-2014 SQLI <www.sqli.com>
12
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
13
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
14
+ * @link http://pear.php.net/package/PHP_CodeSniffer
15
+ */
16
+
17
+ /**
18
+ * Xml report for PHP_CodeSniffer.
19
+ *
20
+ * PHP version 5
21
+ *
22
+ * @category PHP
23
+ * @package PHP_CodeSniffer
24
+ * @author Gabriele Santini <gsantini@sqli.com>
25
+ * @author Greg Sherwood <gsherwood@squiz.net>
26
+ * @copyright 2009-2014 SQLI <www.sqli.com>
27
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
28
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
29
+ * @version Release: @package_version@
30
+ * @link http://pear.php.net/package/PHP_CodeSniffer
31
+ */
32
+ class PHP_CodeSniffer_Reports_Xml implements PHP_CodeSniffer_Report
33
+ {
34
+
35
+
36
+ /**
37
+ * Generate a partial report for a single processed file.
38
+ *
39
+ * Function should return TRUE if it printed or stored data about the file
40
+ * and FALSE if it ignored the file. Returning TRUE indicates that the file and
41
+ * its data should be counted in the grand totals.
42
+ *
43
+ * @param array $report Prepared report data.
44
+ * @param PHP_CodeSniffer_File $phpcsFile The file being reported on.
45
+ * @param boolean $showSources Show sources?
46
+ * @param int $width Maximum allowed line width.
47
+ *
48
+ * @return boolean
49
+ */
50
+ public function generateFileReport(
51
+ $report,
52
+ PHP_CodeSniffer_File $phpcsFile,
53
+ $showSources=false,
54
+ $width=80
55
+ ) {
56
+ $out = new XMLWriter;
57
+ $out->openMemory();
58
+ $out->setIndent(true);
59
+
60
+ if ($report['errors'] === 0 && $report['warnings'] === 0) {
61
+ // Nothing to print.
62
+ return false;
63
+ }
64
+
65
+ $out->startElement('file');
66
+ $out->writeAttribute('name', $report['filename']);
67
+ $out->writeAttribute('errors', $report['errors']);
68
+ $out->writeAttribute('warnings', $report['warnings']);
69
+ $out->writeAttribute('fixable', $report['fixable']);
70
+
71
+ foreach ($report['messages'] as $line => $lineErrors) {
72
+ foreach ($lineErrors as $column => $colErrors) {
73
+ foreach ($colErrors as $error) {
74
+ $error['type'] = strtolower($error['type']);
75
+ if (PHP_CODESNIFFER_ENCODING !== 'utf-8') {
76
+ $error['message'] = iconv(PHP_CODESNIFFER_ENCODING, 'utf-8', $error['message']);
77
+ }
78
+
79
+ $out->startElement($error['type']);
80
+ $out->writeAttribute('line', $line);
81
+ $out->writeAttribute('column', $column);
82
+ $out->writeAttribute('source', $error['source']);
83
+ $out->writeAttribute('severity', $error['severity']);
84
+ $out->writeAttribute('fixable', (int) $error['fixable']);
85
+ $out->text($error['message']);
86
+ $out->endElement();
87
+ }
88
+ }
89
+ }//end foreach
90
+
91
+ $out->endElement();
92
+ echo $out->flush();
93
+
94
+ return true;
95
+
96
+ }//end generateFileReport()
97
+
98
+
99
+ /**
100
+ * Prints all violations for processed files, in a proprietary XML format.
101
+ *
102
+ * @param string $cachedData Any partial report data that was returned from
103
+ * generateFileReport during the run.
104
+ * @param int $totalFiles Total number of files processed during the run.
105
+ * @param int $totalErrors Total number of errors found during the run.
106
+ * @param int $totalWarnings Total number of warnings found during the run.
107
+ * @param int $totalFixable Total number of problems that can be fixed.
108
+ * @param boolean $showSources Show sources?
109
+ * @param int $width Maximum allowed line width.
110
+ * @param boolean $toScreen Is the report being printed to screen?
111
+ *
112
+ * @return void
113
+ */
114
+ public function generate(
115
+ $cachedData,
116
+ $totalFiles,
117
+ $totalErrors,
118
+ $totalWarnings,
119
+ $totalFixable,
120
+ $showSources=false,
121
+ $width=80,
122
+ $toScreen=true
123
+ ) {
124
+ echo '<?xml version="1.0" encoding="UTF-8"?>'.PHP_EOL;
125
+ echo '<phpcs version="'.PHP_CodeSniffer::VERSION.'">'.PHP_EOL;
126
+ echo $cachedData;
127
+ echo '</phpcs>'.PHP_EOL;
128
+
129
+ }//end generate()
130
+
131
+
132
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Sniff.php ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Represents a PHP_CodeSniffer sniff for sniffing coding standards.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Greg Sherwood <gsherwood@squiz.net>
10
+ * @author Marc McIntyre <mmcintyre@squiz.net>
11
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
12
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
13
+ * @link http://pear.php.net/package/PHP_CodeSniffer
14
+ */
15
+
16
+ /**
17
+ * Represents a PHP_CodeSniffer sniff for sniffing coding standards.
18
+ *
19
+ * A sniff registers what token types it wishes to listen for, then, when
20
+ * PHP_CodeSniffer encounters that token, the sniff is invoked and passed
21
+ * information about where the token was found in the stack, and the
22
+ * PHP_CodeSniffer file in which the token was found.
23
+ *
24
+ * @category PHP
25
+ * @package PHP_CodeSniffer
26
+ * @author Greg Sherwood <gsherwood@squiz.net>
27
+ * @author Marc McIntyre <mmcintyre@squiz.net>
28
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
29
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
30
+ * @version Release: @package_version@
31
+ * @link http://pear.php.net/package/PHP_CodeSniffer
32
+ */
33
+ interface PHP_CodeSniffer_Sniff
34
+ {
35
+
36
+
37
+ /**
38
+ * Registers the tokens that this sniff wants to listen for.
39
+ *
40
+ * An example return value for a sniff that wants to listen for whitespace
41
+ * and any comments would be:
42
+ *
43
+ * <code>
44
+ * return array(
45
+ * T_WHITESPACE,
46
+ * T_DOC_COMMENT,
47
+ * T_COMMENT,
48
+ * );
49
+ * </code>
50
+ *
51
+ * @return int[]
52
+ * @see Tokens.php
53
+ */
54
+ public function register();
55
+
56
+
57
+ /**
58
+ * Called when one of the token types that this sniff is listening for
59
+ * is found.
60
+ *
61
+ * The stackPtr variable indicates where in the stack the token was found.
62
+ * A sniff can acquire information this token, along with all the other
63
+ * tokens within the stack by first acquiring the token stack:
64
+ *
65
+ * <code>
66
+ * $tokens = $phpcsFile->getTokens();
67
+ * echo 'Encountered a '.$tokens[$stackPtr]['type'].' token';
68
+ * echo 'token information: ';
69
+ * print_r($tokens[$stackPtr]);
70
+ * </code>
71
+ *
72
+ * If the sniff discovers an anomaly in the code, they can raise an error
73
+ * by calling addError() on the PHP_CodeSniffer_File object, specifying an error
74
+ * message and the position of the offending token:
75
+ *
76
+ * <code>
77
+ * $phpcsFile->addError('Encountered an error', $stackPtr);
78
+ * </code>
79
+ *
80
+ * @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where the
81
+ * token was found.
82
+ * @param int $stackPtr The position in the PHP_CodeSniffer
83
+ * file's token stack where the token
84
+ * was found.
85
+ *
86
+ * @return void|int Optionally returns a stack pointer. The sniff will not be
87
+ * called again on the current file until the returned stack
88
+ * pointer is reached. Return (count($tokens) + 1) to skip
89
+ * the rest of the file.
90
+ */
91
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr);
92
+
93
+
94
+ }//end interface
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/AbstractPatternSniff.php ADDED
@@ -0,0 +1,962 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Processes pattern strings and checks that the code conforms to the pattern.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Greg Sherwood <gsherwood@squiz.net>
10
+ * @author Marc McIntyre <mmcintyre@squiz.net>
11
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
12
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
13
+ * @link http://pear.php.net/package/PHP_CodeSniffer
14
+ */
15
+
16
+ if (class_exists('PHP_CodeSniffer_Standards_IncorrectPatternException', true) === false) {
17
+ $error = 'Class PHP_CodeSniffer_Standards_IncorrectPatternException not found';
18
+ throw new PHP_CodeSniffer_Exception($error);
19
+ }
20
+
21
+ /**
22
+ * Processes pattern strings and checks that the code conforms to the pattern.
23
+ *
24
+ * This test essentially checks that code is correctly formatted with whitespace.
25
+ *
26
+ * @category PHP
27
+ * @package PHP_CodeSniffer
28
+ * @author Greg Sherwood <gsherwood@squiz.net>
29
+ * @author Marc McIntyre <mmcintyre@squiz.net>
30
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
31
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
32
+ * @version Release: @package_version@
33
+ * @link http://pear.php.net/package/PHP_CodeSniffer
34
+ */
35
+ abstract class PHP_CodeSniffer_Standards_AbstractPatternSniff implements PHP_CodeSniffer_Sniff
36
+ {
37
+
38
+ /**
39
+ * If true, comments will be ignored if they are found in the code.
40
+ *
41
+ * @var boolean
42
+ */
43
+ public $ignoreComments = false;
44
+
45
+ /**
46
+ * The current file being checked.
47
+ *
48
+ * @var string
49
+ */
50
+ protected $currFile = '';
51
+
52
+ /**
53
+ * The parsed patterns array.
54
+ *
55
+ * @var array
56
+ */
57
+ private $_parsedPatterns = array();
58
+
59
+ /**
60
+ * Tokens that this sniff wishes to process outside of the patterns.
61
+ *
62
+ * @var array(int)
63
+ * @see registerSupplementary()
64
+ * @see processSupplementary()
65
+ */
66
+ private $_supplementaryTokens = array();
67
+
68
+ /**
69
+ * Positions in the stack where errors have occurred.
70
+ *
71
+ * @var array()
72
+ */
73
+ private $_errorPos = array();
74
+
75
+
76
+ /**
77
+ * Constructs a PHP_CodeSniffer_Standards_AbstractPatternSniff.
78
+ *
79
+ * @param boolean $ignoreComments If true, comments will be ignored.
80
+ */
81
+ public function __construct($ignoreComments=null)
82
+ {
83
+ // This is here for backwards compatibility.
84
+ if ($ignoreComments !== null) {
85
+ $this->ignoreComments = $ignoreComments;
86
+ }
87
+
88
+ $this->_supplementaryTokens = $this->registerSupplementary();
89
+
90
+ }//end __construct()
91
+
92
+
93
+ /**
94
+ * Registers the tokens to listen to.
95
+ *
96
+ * Classes extending <i>AbstractPatternTest</i> should implement the
97
+ * <i>getPatterns()</i> method to register the patterns they wish to test.
98
+ *
99
+ * @return int[]
100
+ * @see process()
101
+ */
102
+ public final function register()
103
+ {
104
+ $listenTypes = array();
105
+ $patterns = $this->getPatterns();
106
+
107
+ foreach ($patterns as $pattern) {
108
+ $parsedPattern = $this->_parse($pattern);
109
+
110
+ // Find a token position in the pattern that we can use
111
+ // for a listener token.
112
+ $pos = $this->_getListenerTokenPos($parsedPattern);
113
+ $tokenType = $parsedPattern[$pos]['token'];
114
+ $listenTypes[] = $tokenType;
115
+
116
+ $patternArray = array(
117
+ 'listen_pos' => $pos,
118
+ 'pattern' => $parsedPattern,
119
+ 'pattern_code' => $pattern,
120
+ );
121
+
122
+ if (isset($this->_parsedPatterns[$tokenType]) === false) {
123
+ $this->_parsedPatterns[$tokenType] = array();
124
+ }
125
+
126
+ $this->_parsedPatterns[$tokenType][] = $patternArray;
127
+ }//end foreach
128
+
129
+ return array_unique(array_merge($listenTypes, $this->_supplementaryTokens));
130
+
131
+ }//end register()
132
+
133
+
134
+ /**
135
+ * Returns the token types that the specified pattern is checking for.
136
+ *
137
+ * Returned array is in the format:
138
+ * <code>
139
+ * array(
140
+ * T_WHITESPACE => 0, // 0 is the position where the T_WHITESPACE token
141
+ * // should occur in the pattern.
142
+ * );
143
+ * </code>
144
+ *
145
+ * @param array $pattern The parsed pattern to find the acquire the token
146
+ * types from.
147
+ *
148
+ * @return array<int, int>
149
+ */
150
+ private function _getPatternTokenTypes($pattern)
151
+ {
152
+ $tokenTypes = array();
153
+ foreach ($pattern as $pos => $patternInfo) {
154
+ if ($patternInfo['type'] === 'token') {
155
+ if (isset($tokenTypes[$patternInfo['token']]) === false) {
156
+ $tokenTypes[$patternInfo['token']] = $pos;
157
+ }
158
+ }
159
+ }
160
+
161
+ return $tokenTypes;
162
+
163
+ }//end _getPatternTokenTypes()
164
+
165
+
166
+ /**
167
+ * Returns the position in the pattern that this test should register as
168
+ * a listener for the pattern.
169
+ *
170
+ * @param array $pattern The pattern to acquire the listener for.
171
+ *
172
+ * @return int The position in the pattern that this test should register
173
+ * as the listener.
174
+ * @throws PHP_CodeSniffer_Exception If we could not determine a token
175
+ * to listen for.
176
+ */
177
+ private function _getListenerTokenPos($pattern)
178
+ {
179
+ $tokenTypes = $this->_getPatternTokenTypes($pattern);
180
+ $tokenCodes = array_keys($tokenTypes);
181
+ $token = PHP_CodeSniffer_Tokens::getHighestWeightedToken($tokenCodes);
182
+
183
+ // If we could not get a token.
184
+ if ($token === false) {
185
+ $error = 'Could not determine a token to listen for';
186
+ throw new PHP_CodeSniffer_Exception($error);
187
+ }
188
+
189
+ return $tokenTypes[$token];
190
+
191
+ }//end _getListenerTokenPos()
192
+
193
+
194
+ /**
195
+ * Processes the test.
196
+ *
197
+ * @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where the
198
+ * token occurred.
199
+ * @param int $stackPtr The position in the tokens stack
200
+ * where the listening token type was
201
+ * found.
202
+ *
203
+ * @return void
204
+ * @see register()
205
+ */
206
+ public final function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
207
+ {
208
+ $file = $phpcsFile->getFilename();
209
+ if ($this->currFile !== $file) {
210
+ // We have changed files, so clean up.
211
+ $this->_errorPos = array();
212
+ $this->currFile = $file;
213
+ }
214
+
215
+ $tokens = $phpcsFile->getTokens();
216
+
217
+ if (in_array($tokens[$stackPtr]['code'], $this->_supplementaryTokens) === true) {
218
+ $this->processSupplementary($phpcsFile, $stackPtr);
219
+ }
220
+
221
+ $type = $tokens[$stackPtr]['code'];
222
+
223
+ // If the type is not set, then it must have been a token registered
224
+ // with registerSupplementary().
225
+ if (isset($this->_parsedPatterns[$type]) === false) {
226
+ return;
227
+ }
228
+
229
+ $allErrors = array();
230
+
231
+ // Loop over each pattern that is listening to the current token type
232
+ // that we are processing.
233
+ foreach ($this->_parsedPatterns[$type] as $patternInfo) {
234
+ // If processPattern returns false, then the pattern that we are
235
+ // checking the code with must not be designed to check that code.
236
+ $errors = $this->processPattern($patternInfo, $phpcsFile, $stackPtr);
237
+ if ($errors === false) {
238
+ // The pattern didn't match.
239
+ continue;
240
+ } else if (empty($errors) === true) {
241
+ // The pattern matched, but there were no errors.
242
+ break;
243
+ }
244
+
245
+ foreach ($errors as $stackPtr => $error) {
246
+ if (isset($this->_errorPos[$stackPtr]) === false) {
247
+ $this->_errorPos[$stackPtr] = true;
248
+ $allErrors[$stackPtr] = $error;
249
+ }
250
+ }
251
+ }
252
+
253
+ foreach ($allErrors as $stackPtr => $error) {
254
+ $phpcsFile->addError($error, $stackPtr);
255
+ }
256
+
257
+ }//end process()
258
+
259
+
260
+ /**
261
+ * Processes the pattern and verifies the code at $stackPtr.
262
+ *
263
+ * @param array $patternInfo Information about the pattern used
264
+ * for checking, which includes are
265
+ * parsed token representation of the
266
+ * pattern.
267
+ * @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where the
268
+ * token occurred.
269
+ * @param int $stackPtr The position in the tokens stack where
270
+ * the listening token type was found.
271
+ *
272
+ * @return array
273
+ */
274
+ protected function processPattern(
275
+ $patternInfo,
276
+ PHP_CodeSniffer_File $phpcsFile,
277
+ $stackPtr
278
+ ) {
279
+ $tokens = $phpcsFile->getTokens();
280
+ $pattern = $patternInfo['pattern'];
281
+ $patternCode = $patternInfo['pattern_code'];
282
+ $errors = array();
283
+ $found = '';
284
+
285
+ $ignoreTokens = array(T_WHITESPACE);
286
+ if ($this->ignoreComments === true) {
287
+ $ignoreTokens
288
+ = array_merge($ignoreTokens, PHP_CodeSniffer_Tokens::$commentTokens);
289
+ }
290
+
291
+ $origStackPtr = $stackPtr;
292
+ $hasError = false;
293
+
294
+ if ($patternInfo['listen_pos'] > 0) {
295
+ $stackPtr--;
296
+
297
+ for ($i = ($patternInfo['listen_pos'] - 1); $i >= 0; $i--) {
298
+ if ($pattern[$i]['type'] === 'token') {
299
+ if ($pattern[$i]['token'] === T_WHITESPACE) {
300
+ if ($tokens[$stackPtr]['code'] === T_WHITESPACE) {
301
+ $found = $tokens[$stackPtr]['content'].$found;
302
+ }
303
+
304
+ // Only check the size of the whitespace if this is not
305
+ // the first token. We don't care about the size of
306
+ // leading whitespace, just that there is some.
307
+ if ($i !== 0) {
308
+ if ($tokens[$stackPtr]['content'] !== $pattern[$i]['value']) {
309
+ $hasError = true;
310
+ }
311
+ }
312
+ } else {
313
+ // Check to see if this important token is the same as the
314
+ // previous important token in the pattern. If it is not,
315
+ // then the pattern cannot be for this piece of code.
316
+ $prev = $phpcsFile->findPrevious(
317
+ $ignoreTokens,
318
+ $stackPtr,
319
+ null,
320
+ true
321
+ );
322
+
323
+ if ($prev === false
324
+ || $tokens[$prev]['code'] !== $pattern[$i]['token']
325
+ ) {
326
+ return false;
327
+ }
328
+
329
+ // If we skipped past some whitespace tokens, then add them
330
+ // to the found string.
331
+ $tokenContent = $phpcsFile->getTokensAsString(
332
+ ($prev + 1),
333
+ ($stackPtr - $prev - 1)
334
+ );
335
+
336
+ $found = $tokens[$prev]['content'].$tokenContent.$found;
337
+
338
+ if (isset($pattern[($i - 1)]) === true
339
+ && $pattern[($i - 1)]['type'] === 'skip'
340
+ ) {
341
+ $stackPtr = $prev;
342
+ } else {
343
+ $stackPtr = ($prev - 1);
344
+ }
345
+ }//end if
346
+ } else if ($pattern[$i]['type'] === 'skip') {
347
+ // Skip to next piece of relevant code.
348
+ if ($pattern[$i]['to'] === 'parenthesis_closer') {
349
+ $to = 'parenthesis_opener';
350
+ } else {
351
+ $to = 'scope_opener';
352
+ }
353
+
354
+ // Find the previous opener.
355
+ $next = $phpcsFile->findPrevious(
356
+ $ignoreTokens,
357
+ $stackPtr,
358
+ null,
359
+ true
360
+ );
361
+
362
+ if ($next === false || isset($tokens[$next][$to]) === false) {
363
+ // If there was not opener, then we must be
364
+ // using the wrong pattern.
365
+ return false;
366
+ }
367
+
368
+ if ($to === 'parenthesis_opener') {
369
+ $found = '{'.$found;
370
+ } else {
371
+ $found = '('.$found;
372
+ }
373
+
374
+ $found = '...'.$found;
375
+
376
+ // Skip to the opening token.
377
+ $stackPtr = ($tokens[$next][$to] - 1);
378
+ } else if ($pattern[$i]['type'] === 'string') {
379
+ $found = 'abc';
380
+ } else if ($pattern[$i]['type'] === 'newline') {
381
+ if ($this->ignoreComments === true
382
+ && isset(PHP_CodeSniffer_Tokens::$commentTokens[$tokens[$stackPtr]['code']]) === true
383
+ ) {
384
+ $startComment = $phpcsFile->findPrevious(
385
+ PHP_CodeSniffer_Tokens::$commentTokens,
386
+ ($stackPtr - 1),
387
+ null,
388
+ true
389
+ );
390
+
391
+ if ($tokens[$startComment]['line'] !== $tokens[($startComment + 1)]['line']) {
392
+ $startComment++;
393
+ }
394
+
395
+ $tokenContent = $phpcsFile->getTokensAsString(
396
+ $startComment,
397
+ ($stackPtr - $startComment + 1)
398
+ );
399
+
400
+ $found = $tokenContent.$found;
401
+ $stackPtr = ($startComment - 1);
402
+ }
403
+
404
+ if ($tokens[$stackPtr]['code'] === T_WHITESPACE) {
405
+ if ($tokens[$stackPtr]['content'] !== $phpcsFile->eolChar) {
406
+ $found = $tokens[$stackPtr]['content'].$found;
407
+
408
+ // This may just be an indent that comes after a newline
409
+ // so check the token before to make sure. If it is a newline, we
410
+ // can ignore the error here.
411
+ if (($tokens[($stackPtr - 1)]['content'] !== $phpcsFile->eolChar)
412
+ && ($this->ignoreComments === true
413
+ && isset(PHP_CodeSniffer_Tokens::$commentTokens[$tokens[($stackPtr - 1)]['code']]) === false)
414
+ ) {
415
+ $hasError = true;
416
+ } else {
417
+ $stackPtr--;
418
+ }
419
+ } else {
420
+ $found = 'EOL'.$found;
421
+ }
422
+ } else {
423
+ $found = $tokens[$stackPtr]['content'].$found;
424
+ $hasError = true;
425
+ }//end if
426
+
427
+ if ($hasError === false && $pattern[($i - 1)]['type'] !== 'newline') {
428
+ // Make sure they only have 1 newline.
429
+ $prev = $phpcsFile->findPrevious($ignoreTokens, ($stackPtr - 1), null, true);
430
+ if ($prev !== false && $tokens[$prev]['line'] !== $tokens[$stackPtr]['line']) {
431
+ $hasError = true;
432
+ }
433
+ }
434
+ }//end if
435
+ }//end for
436
+ }//end if
437
+
438
+ $stackPtr = $origStackPtr;
439
+ $lastAddedStackPtr = null;
440
+ $patternLen = count($pattern);
441
+
442
+ for ($i = $patternInfo['listen_pos']; $i < $patternLen; $i++) {
443
+ if (isset($tokens[$stackPtr]) === false) {
444
+ break;
445
+ }
446
+
447
+ if ($pattern[$i]['type'] === 'token') {
448
+ if ($pattern[$i]['token'] === T_WHITESPACE) {
449
+ if ($this->ignoreComments === true) {
450
+ // If we are ignoring comments, check to see if this current
451
+ // token is a comment. If so skip it.
452
+ if (isset(PHP_CodeSniffer_Tokens::$commentTokens[$tokens[$stackPtr]['code']]) === true) {
453
+ continue;
454
+ }
455
+
456
+ // If the next token is a comment, the we need to skip the
457
+ // current token as we should allow a space before a
458
+ // comment for readability.
459
+ if (isset($tokens[($stackPtr + 1)]) === true
460
+ && isset(PHP_CodeSniffer_Tokens::$commentTokens[$tokens[($stackPtr + 1)]['code']]) === true
461
+ ) {
462
+ continue;
463
+ }
464
+ }
465
+
466
+ $tokenContent = '';
467
+ if ($tokens[$stackPtr]['code'] === T_WHITESPACE) {
468
+ if (isset($pattern[($i + 1)]) === false) {
469
+ // This is the last token in the pattern, so just compare
470
+ // the next token of content.
471
+ $tokenContent = $tokens[$stackPtr]['content'];
472
+ } else {
473
+ // Get all the whitespace to the next token.
474
+ $next = $phpcsFile->findNext(
475
+ PHP_CodeSniffer_Tokens::$emptyTokens,
476
+ $stackPtr,
477
+ null,
478
+ true
479
+ );
480
+
481
+ $tokenContent = $phpcsFile->getTokensAsString(
482
+ $stackPtr,
483
+ ($next - $stackPtr)
484
+ );
485
+
486
+ $lastAddedStackPtr = $stackPtr;
487
+ $stackPtr = $next;
488
+ }//end if
489
+
490
+ if ($stackPtr !== $lastAddedStackPtr) {
491
+ $found .= $tokenContent;
492
+ }
493
+ } else {
494
+ if ($stackPtr !== $lastAddedStackPtr) {
495
+ $found .= $tokens[$stackPtr]['content'];
496
+ $lastAddedStackPtr = $stackPtr;
497
+ }
498
+ }//end if
499
+
500
+ if (isset($pattern[($i + 1)]) === true
501
+ && $pattern[($i + 1)]['type'] === 'skip'
502
+ ) {
503
+ // The next token is a skip token, so we just need to make
504
+ // sure the whitespace we found has *at least* the
505
+ // whitespace required.
506
+ if (strpos($tokenContent, $pattern[$i]['value']) !== 0) {
507
+ $hasError = true;
508
+ }
509
+ } else {
510
+ if ($tokenContent !== $pattern[$i]['value']) {
511
+ $hasError = true;
512
+ }
513
+ }
514
+ } else {
515
+ // Check to see if this important token is the same as the
516
+ // next important token in the pattern. If it is not, then
517
+ // the pattern cannot be for this piece of code.
518
+ $next = $phpcsFile->findNext(
519
+ $ignoreTokens,
520
+ $stackPtr,
521
+ null,
522
+ true
523
+ );
524
+
525
+ if ($next === false
526
+ || $tokens[$next]['code'] !== $pattern[$i]['token']
527
+ ) {
528
+ // The next important token did not match the pattern.
529
+ return false;
530
+ }
531
+
532
+ if ($lastAddedStackPtr !== null) {
533
+ if (($tokens[$next]['code'] === T_OPEN_CURLY_BRACKET
534
+ || $tokens[$next]['code'] === T_CLOSE_CURLY_BRACKET)
535
+ && isset($tokens[$next]['scope_condition']) === true
536
+ && $tokens[$next]['scope_condition'] > $lastAddedStackPtr
537
+ ) {
538
+ // This is a brace, but the owner of it is after the current
539
+ // token, which means it does not belong to any token in
540
+ // our pattern. This means the pattern is not for us.
541
+ return false;
542
+ }
543
+
544
+ if (($tokens[$next]['code'] === T_OPEN_PARENTHESIS
545
+ || $tokens[$next]['code'] === T_CLOSE_PARENTHESIS)
546
+ && isset($tokens[$next]['parenthesis_owner']) === true
547
+ && $tokens[$next]['parenthesis_owner'] > $lastAddedStackPtr
548
+ ) {
549
+ // This is a bracket, but the owner of it is after the current
550
+ // token, which means it does not belong to any token in
551
+ // our pattern. This means the pattern is not for us.
552
+ return false;
553
+ }
554
+ }//end if
555
+
556
+ // If we skipped past some whitespace tokens, then add them
557
+ // to the found string.
558
+ if (($next - $stackPtr) > 0) {
559
+ $hasComment = false;
560
+ for ($j = $stackPtr; $j < $next; $j++) {
561
+ $found .= $tokens[$j]['content'];
562
+ if (isset(PHP_CodeSniffer_Tokens::$commentTokens[$tokens[$j]['code']]) === true) {
563
+ $hasComment = true;
564
+ }
565
+ }
566
+
567
+ // If we are not ignoring comments, this additional
568
+ // whitespace or comment is not allowed. If we are
569
+ // ignoring comments, there needs to be at least one
570
+ // comment for this to be allowed.
571
+ if ($this->ignoreComments === false
572
+ || ($this->ignoreComments === true
573
+ && $hasComment === false)
574
+ ) {
575
+ $hasError = true;
576
+ }
577
+
578
+ // Even when ignoring comments, we are not allowed to include
579
+ // newlines without the pattern specifying them, so
580
+ // everything should be on the same line.
581
+ if ($tokens[$next]['line'] !== $tokens[$stackPtr]['line']) {
582
+ $hasError = true;
583
+ }
584
+ }//end if
585
+
586
+ if ($next !== $lastAddedStackPtr) {
587
+ $found .= $tokens[$next]['content'];
588
+ $lastAddedStackPtr = $next;
589
+ }
590
+
591
+ if (isset($pattern[($i + 1)]) === true
592
+ && $pattern[($i + 1)]['type'] === 'skip'
593
+ ) {
594
+ $stackPtr = $next;
595
+ } else {
596
+ $stackPtr = ($next + 1);
597
+ }
598
+ }//end if
599
+ } else if ($pattern[$i]['type'] === 'skip') {
600
+ if ($pattern[$i]['to'] === 'unknown') {
601
+ $next = $phpcsFile->findNext(
602
+ $pattern[($i + 1)]['token'],
603
+ $stackPtr
604
+ );
605
+
606
+ if ($next === false) {
607
+ // Couldn't find the next token, so we must
608
+ // be using the wrong pattern.
609
+ return false;
610
+ }
611
+
612
+ $found .= '...';
613
+ $stackPtr = $next;
614
+ } else {
615
+ // Find the previous opener.
616
+ $next = $phpcsFile->findPrevious(
617
+ PHP_CodeSniffer_Tokens::$blockOpeners,
618
+ $stackPtr
619
+ );
620
+
621
+ if ($next === false
622
+ || isset($tokens[$next][$pattern[$i]['to']]) === false
623
+ ) {
624
+ // If there was not opener, then we must
625
+ // be using the wrong pattern.
626
+ return false;
627
+ }
628
+
629
+ $found .= '...';
630
+ if ($pattern[$i]['to'] === 'parenthesis_closer') {
631
+ $found .= ')';
632
+ } else {
633
+ $found .= '}';
634
+ }
635
+
636
+ // Skip to the closing token.
637
+ $stackPtr = ($tokens[$next][$pattern[$i]['to']] + 1);
638
+ }//end if
639
+ } else if ($pattern[$i]['type'] === 'string') {
640
+ if ($tokens[$stackPtr]['code'] !== T_STRING) {
641
+ $hasError = true;
642
+ }
643
+
644
+ if ($stackPtr !== $lastAddedStackPtr) {
645
+ $found .= 'abc';
646
+ $lastAddedStackPtr = $stackPtr;
647
+ }
648
+
649
+ $stackPtr++;
650
+ } else if ($pattern[$i]['type'] === 'newline') {
651
+ // Find the next token that contains a newline character.
652
+ $newline = 0;
653
+ for ($j = $stackPtr; $j < $phpcsFile->numTokens; $j++) {
654
+ if (strpos($tokens[$j]['content'], $phpcsFile->eolChar) !== false) {
655
+ $newline = $j;
656
+ break;
657
+ }
658
+ }
659
+
660
+ if ($newline === 0) {
661
+ // We didn't find a newline character in the rest of the file.
662
+ $next = ($phpcsFile->numTokens - 1);
663
+ $hasError = true;
664
+ } else {
665
+ if ($this->ignoreComments === false) {
666
+ // The newline character cannot be part of a comment.
667
+ if (isset(PHP_CodeSniffer_Tokens::$commentTokens[$tokens[$newline]['code']]) === true) {
668
+ $hasError = true;
669
+ }
670
+ }
671
+
672
+ if ($newline === $stackPtr) {
673
+ $next = ($stackPtr + 1);
674
+ } else {
675
+ // Check that there were no significant tokens that we
676
+ // skipped over to find our newline character.
677
+ $next = $phpcsFile->findNext(
678
+ $ignoreTokens,
679
+ $stackPtr,
680
+ null,
681
+ true
682
+ );
683
+
684
+ if ($next < $newline) {
685
+ // We skipped a non-ignored token.
686
+ $hasError = true;
687
+ } else {
688
+ $next = ($newline + 1);
689
+ }
690
+ }
691
+ }//end if
692
+
693
+ if ($stackPtr !== $lastAddedStackPtr) {
694
+ $found .= $phpcsFile->getTokensAsString(
695
+ $stackPtr,
696
+ ($next - $stackPtr)
697
+ );
698
+
699
+ $diff = ($next - $stackPtr);
700
+ $lastAddedStackPtr = ($next - 1);
701
+ }
702
+
703
+ $stackPtr = $next;
704
+ }//end if
705
+ }//end for
706
+
707
+ if ($hasError === true) {
708
+ $error = $this->prepareError($found, $patternCode);
709
+ $errors[$origStackPtr] = $error;
710
+ }
711
+
712
+ return $errors;
713
+
714
+ }//end processPattern()
715
+
716
+
717
+ /**
718
+ * Prepares an error for the specified patternCode.
719
+ *
720
+ * @param string $found The actual found string in the code.
721
+ * @param string $patternCode The expected pattern code.
722
+ *
723
+ * @return string The error message.
724
+ */
725
+ protected function prepareError($found, $patternCode)
726
+ {
727
+ $found = str_replace("\r\n", '\n', $found);
728
+ $found = str_replace("\n", '\n', $found);
729
+ $found = str_replace("\r", '\n', $found);
730
+ $found = str_replace("\t", '\t', $found);
731
+ $found = str_replace('EOL', '\n', $found);
732
+ $expected = str_replace('EOL', '\n', $patternCode);
733
+
734
+ $error = "Expected \"$expected\"; found \"$found\"";
735
+
736
+ return $error;
737
+
738
+ }//end prepareError()
739
+
740
+
741
+ /**
742
+ * Returns the patterns that should be checked.
743
+ *
744
+ * @return string[]
745
+ */
746
+ protected abstract function getPatterns();
747
+
748
+
749
+ /**
750
+ * Registers any supplementary tokens that this test might wish to process.
751
+ *
752
+ * A sniff may wish to register supplementary tests when it wishes to group
753
+ * an arbitrary validation that cannot be performed using a pattern, with
754
+ * other pattern tests.
755
+ *
756
+ * @return int[]
757
+ * @see processSupplementary()
758
+ */
759
+ protected function registerSupplementary()
760
+ {
761
+ return array();
762
+
763
+ }//end registerSupplementary()
764
+
765
+
766
+ /**
767
+ * Processes any tokens registered with registerSupplementary().
768
+ *
769
+ * @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where to
770
+ * process the skip.
771
+ * @param int $stackPtr The position in the tokens stack to
772
+ * process.
773
+ *
774
+ * @return void
775
+ * @see registerSupplementary()
776
+ */
777
+ protected function processSupplementary(
778
+ PHP_CodeSniffer_File $phpcsFile,
779
+ $stackPtr
780
+ ) {
781
+
782
+ }//end processSupplementary()
783
+
784
+
785
+ /**
786
+ * Parses a pattern string into an array of pattern steps.
787
+ *
788
+ * @param string $pattern The pattern to parse.
789
+ *
790
+ * @return array The parsed pattern array.
791
+ * @see _createSkipPattern()
792
+ * @see _createTokenPattern()
793
+ */
794
+ private function _parse($pattern)
795
+ {
796
+ $patterns = array();
797
+ $length = strlen($pattern);
798
+ $lastToken = 0;
799
+ $firstToken = 0;
800
+
801
+ for ($i = 0; $i < $length; $i++) {
802
+ $specialPattern = false;
803
+ $isLastChar = ($i === ($length - 1));
804
+ $oldFirstToken = $firstToken;
805
+
806
+ if (substr($pattern, $i, 3) === '...') {
807
+ // It's a skip pattern. The skip pattern requires the
808
+ // content of the token in the "from" position and the token
809
+ // to skip to.
810
+ $specialPattern = $this->_createSkipPattern($pattern, ($i - 1));
811
+ $lastToken = ($i - $firstToken);
812
+ $firstToken = ($i + 3);
813
+ $i = ($i + 2);
814
+
815
+ if ($specialPattern['to'] !== 'unknown') {
816
+ $firstToken++;
817
+ }
818
+ } else if (substr($pattern, $i, 3) === 'abc') {
819
+ $specialPattern = array('type' => 'string');
820
+ $lastToken = ($i - $firstToken);
821
+ $firstToken = ($i + 3);
822
+ $i = ($i + 2);
823
+ } else if (substr($pattern, $i, 3) === 'EOL') {
824
+ $specialPattern = array('type' => 'newline');
825
+ $lastToken = ($i - $firstToken);
826
+ $firstToken = ($i + 3);
827
+ $i = ($i + 2);
828
+ }//end if
829
+
830
+ if ($specialPattern !== false || $isLastChar === true) {
831
+ // If we are at the end of the string, don't worry about a limit.
832
+ if ($isLastChar === true) {
833
+ // Get the string from the end of the last skip pattern, if any,
834
+ // to the end of the pattern string.
835
+ $str = substr($pattern, $oldFirstToken);
836
+ } else {
837
+ // Get the string from the end of the last special pattern,
838
+ // if any, to the start of this special pattern.
839
+ if ($lastToken === 0) {
840
+ // Note that if the last special token was zero characters ago,
841
+ // there will be nothing to process so we can skip this bit.
842
+ // This happens if you have something like: EOL... in your pattern.
843
+ $str = '';
844
+ } else {
845
+ $str = substr($pattern, $oldFirstToken, $lastToken);
846
+ }
847
+ }
848
+
849
+ if ($str !== '') {
850
+ $tokenPatterns = $this->_createTokenPattern($str);
851
+ foreach ($tokenPatterns as $tokenPattern) {
852
+ $patterns[] = $tokenPattern;
853
+ }
854
+ }
855
+
856
+ // Make sure we don't skip the last token.
857
+ if ($isLastChar === false && $i === ($length - 1)) {
858
+ $i--;
859
+ }
860
+ }//end if
861
+
862
+ // Add the skip pattern *after* we have processed
863
+ // all the tokens from the end of the last skip pattern
864
+ // to the start of this skip pattern.
865
+ if ($specialPattern !== false) {
866
+ $patterns[] = $specialPattern;
867
+ }
868
+ }//end for
869
+
870
+ return $patterns;
871
+
872
+ }//end _parse()
873
+
874
+
875
+ /**
876
+ * Creates a skip pattern.
877
+ *
878
+ * @param string $pattern The pattern being parsed.
879
+ * @param string $from The token content that the skip pattern starts from.
880
+ *
881
+ * @return array The pattern step.
882
+ * @see _createTokenPattern()
883
+ * @see _parse()
884
+ */
885
+ private function _createSkipPattern($pattern, $from)
886
+ {
887
+ $skip = array('type' => 'skip');
888
+
889
+ $nestedParenthesis = 0;
890
+ $nestedBraces = 0;
891
+ for ($start = $from; $start >= 0; $start--) {
892
+ switch ($pattern[$start]) {
893
+ case '(':
894
+ if ($nestedParenthesis === 0) {
895
+ $skip['to'] = 'parenthesis_closer';
896
+ }
897
+
898
+ $nestedParenthesis--;
899
+ break;
900
+ case '{':
901
+ if ($nestedBraces === 0) {
902
+ $skip['to'] = 'scope_closer';
903
+ }
904
+
905
+ $nestedBraces--;
906
+ break;
907
+ case '}':
908
+ $nestedBraces++;
909
+ break;
910
+ case ')':
911
+ $nestedParenthesis++;
912
+ break;
913
+ }//end switch
914
+
915
+ if (isset($skip['to']) === true) {
916
+ break;
917
+ }
918
+ }//end for
919
+
920
+ if (isset($skip['to']) === false) {
921
+ $skip['to'] = 'unknown';
922
+ }
923
+
924
+ return $skip;
925
+
926
+ }//end _createSkipPattern()
927
+
928
+
929
+ /**
930
+ * Creates a token pattern.
931
+ *
932
+ * @param string $str The tokens string that the pattern should match.
933
+ *
934
+ * @return array The pattern step.
935
+ * @see _createSkipPattern()
936
+ * @see _parse()
937
+ */
938
+ private function _createTokenPattern($str)
939
+ {
940
+ // Don't add a space after the closing php tag as it will add a new
941
+ // whitespace token.
942
+ $tokenizer = new PHP_CodeSniffer_Tokenizers_PHP();
943
+ $tokens = $tokenizer->tokenizeString('<?php '.$str.'?>');
944
+
945
+ // Remove the <?php tag from the front and the end php tag from the back.
946
+ $tokens = array_slice($tokens, 1, (count($tokens) - 2));
947
+
948
+ $patterns = array();
949
+ foreach ($tokens as $patternInfo) {
950
+ $patterns[] = array(
951
+ 'type' => 'token',
952
+ 'token' => $patternInfo['code'],
953
+ 'value' => $patternInfo['content'],
954
+ );
955
+ }
956
+
957
+ return $patterns;
958
+
959
+ }//end _createTokenPattern()
960
+
961
+
962
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/AbstractScopeSniff.php ADDED
@@ -0,0 +1,199 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * An AbstractScopeTest allows for tests that extend from this class to
4
+ * listen for tokens within a particular scope.
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * @category PHP
9
+ * @package PHP_CodeSniffer
10
+ * @author Greg Sherwood <gsherwood@squiz.net>
11
+ * @author Marc McIntyre <mmcintyre@squiz.net>
12
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
13
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
14
+ * @link http://pear.php.net/package/PHP_CodeSniffer
15
+ */
16
+
17
+ /**
18
+ * An AbstractScopeTest allows for tests that extend from this class to
19
+ * listen for tokens within a particular scope.
20
+ *
21
+ * Below is a test that listens to methods that exist only within classes:
22
+ * <code>
23
+ * class ClassScopeTest extends PHP_CodeSniffer_Standards_AbstractScopeSniff
24
+ * {
25
+ * public function __construct()
26
+ * {
27
+ * parent::__construct(array(T_CLASS), array(T_FUNCTION));
28
+ * }
29
+ *
30
+ * protected function processTokenWithinScope(PHP_CodeSniffer_File $phpcsFile, $)
31
+ * {
32
+ * $className = $phpcsFile->getDeclarationName($currScope);
33
+ * echo 'encountered a method within class '.$className;
34
+ * }
35
+ * }
36
+ * </code>
37
+ *
38
+ * @category PHP
39
+ * @package PHP_CodeSniffer
40
+ * @author Greg Sherwood <gsherwood@squiz.net>
41
+ * @author Marc McIntyre <mmcintyre@squiz.net>
42
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
43
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
44
+ * @version Release: @package_version@
45
+ * @link http://pear.php.net/package/PHP_CodeSniffer
46
+ */
47
+ abstract class PHP_CodeSniffer_Standards_AbstractScopeSniff implements PHP_CodeSniffer_Sniff
48
+ {
49
+
50
+ /**
51
+ * The token types that this test wishes to listen to within the scope.
52
+ *
53
+ * @var array
54
+ */
55
+ private $_tokens = array();
56
+
57
+ /**
58
+ * The type of scope opener tokens that this test wishes to listen to.
59
+ *
60
+ * @var string
61
+ */
62
+ private $_scopeTokens = array();
63
+
64
+ /**
65
+ * True if this test should fire on tokens outside of the scope.
66
+ *
67
+ * @var boolean
68
+ */
69
+ private $_listenOutside = false;
70
+
71
+
72
+ /**
73
+ * Constructs a new AbstractScopeTest.
74
+ *
75
+ * @param array $scopeTokens The type of scope the test wishes to listen to.
76
+ * @param array $tokens The tokens that the test wishes to listen to
77
+ * within the scope.
78
+ * @param boolean $listenOutside If true this test will also alert the
79
+ * extending class when a token is found outside
80
+ * the scope, by calling the
81
+ * processTokenOutsideScope method.
82
+ *
83
+ * @see PHP_CodeSniffer.getValidScopeTokeners()
84
+ * @throws PHP_CodeSniffer_Exception If the specified tokens array is empty.
85
+ */
86
+ public function __construct(
87
+ array $scopeTokens,
88
+ array $tokens,
89
+ $listenOutside=false
90
+ ) {
91
+ if (empty($scopeTokens) === true) {
92
+ $error = 'The scope tokens list cannot be empty';
93
+ throw new PHP_CodeSniffer_Exception($error);
94
+ }
95
+
96
+ if (empty($tokens) === true) {
97
+ $error = 'The tokens list cannot be empty';
98
+ throw new PHP_CodeSniffer_Exception($error);
99
+ }
100
+
101
+ $invalidScopeTokens = array_intersect($scopeTokens, $tokens);
102
+ if (empty($invalidScopeTokens) === false) {
103
+ $invalid = implode(', ', $invalidScopeTokens);
104
+ $error = "Scope tokens [$invalid] cant be in the tokens array";
105
+ throw new PHP_CodeSniffer_Exception($error);
106
+ }
107
+
108
+ $this->_listenOutside = $listenOutside;
109
+ $this->_scopeTokens = array_flip($scopeTokens);
110
+ $this->_tokens = $tokens;
111
+
112
+ }//end __construct()
113
+
114
+
115
+ /**
116
+ * The method that is called to register the tokens this test wishes to
117
+ * listen to.
118
+ *
119
+ * DO NOT OVERRIDE THIS METHOD. Use the constructor of this class to register
120
+ * for the desired tokens and scope.
121
+ *
122
+ * @return int[]
123
+ * @see __constructor()
124
+ */
125
+ public final function register()
126
+ {
127
+ return $this->_tokens;
128
+
129
+ }//end register()
130
+
131
+
132
+ /**
133
+ * Processes the tokens that this test is listening for.
134
+ *
135
+ * @param PHP_CodeSniffer_File $phpcsFile The file where this token was found.
136
+ * @param int $stackPtr The position in the stack where this
137
+ * token was found.
138
+ *
139
+ * @return void
140
+ * @see processTokenWithinScope()
141
+ */
142
+ public final function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
143
+ {
144
+ $tokens = $phpcsFile->getTokens();
145
+
146
+ $foundScope = false;
147
+ foreach ($tokens[$stackPtr]['conditions'] as $scope => $code) {
148
+ if (isset($this->_scopeTokens[$code]) === true) {
149
+ $this->processTokenWithinScope($phpcsFile, $stackPtr, $scope);
150
+ $foundScope = true;
151
+ }
152
+ }
153
+
154
+ if ($this->_listenOutside === true && $foundScope === false) {
155
+ $this->processTokenOutsideScope($phpcsFile, $stackPtr);
156
+ }
157
+
158
+ }//end process()
159
+
160
+
161
+ /**
162
+ * Processes a token that is found within the scope that this test is
163
+ * listening to.
164
+ *
165
+ * @param PHP_CodeSniffer_File $phpcsFile The file where this token was found.
166
+ * @param int $stackPtr The position in the stack where this
167
+ * token was found.
168
+ * @param int $currScope The position in the tokens array that
169
+ * opened the scope that this test is
170
+ * listening for.
171
+ *
172
+ * @return void
173
+ */
174
+ protected abstract function processTokenWithinScope(
175
+ PHP_CodeSniffer_File $phpcsFile,
176
+ $stackPtr,
177
+ $currScope
178
+ );
179
+
180
+
181
+ /**
182
+ * Processes a token that is found within the scope that this test is
183
+ * listening to.
184
+ *
185
+ * @param PHP_CodeSniffer_File $phpcsFile The file where this token was found.
186
+ * @param int $stackPtr The position in the stack where this
187
+ * token was found.
188
+ *
189
+ * @return void
190
+ */
191
+ protected function processTokenOutsideScope(
192
+ PHP_CodeSniffer_File $phpcsFile,
193
+ $stackPtr
194
+ ) {
195
+
196
+ }//end processTokenOutsideScope()
197
+
198
+
199
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/AbstractVariableSniff.php ADDED
@@ -0,0 +1,244 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * A class to find T_VARIABLE tokens.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Greg Sherwood <gsherwood@squiz.net>
10
+ * @author Marc McIntyre <mmcintyre@squiz.net>
11
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
12
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
13
+ * @link http://pear.php.net/package/PHP_CodeSniffer
14
+ */
15
+
16
+ if (class_exists('PHP_CodeSniffer_Standards_AbstractScopeSniff', true) === false) {
17
+ $error = 'Class PHP_CodeSniffer_Standards_AbstractScopeSniff not found';
18
+ throw new PHP_CodeSniffer_Exception($error);
19
+ }
20
+
21
+ /**
22
+ * A class to find T_VARIABLE tokens.
23
+ *
24
+ * This class can distinguish between normal T_VARIABLE tokens, and those tokens
25
+ * that represent class members. If a class member is encountered, then then
26
+ * processMemberVar method is called so the extending class can process it. If
27
+ * the token is found to be a normal T_VARIABLE token, then processVariable is
28
+ * called.
29
+ *
30
+ * @category PHP
31
+ * @package PHP_CodeSniffer
32
+ * @author Greg Sherwood <gsherwood@squiz.net>
33
+ * @author Marc McIntyre <mmcintyre@squiz.net>
34
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
35
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
36
+ * @version Release: @package_version@
37
+ * @link http://pear.php.net/package/PHP_CodeSniffer
38
+ */
39
+ abstract class PHP_CodeSniffer_Standards_AbstractVariableSniff extends PHP_CodeSniffer_Standards_AbstractScopeSniff
40
+ {
41
+
42
+ /**
43
+ * The end token of the current function that we are in.
44
+ *
45
+ * @var int
46
+ */
47
+ private $_endFunction = -1;
48
+
49
+ /**
50
+ * TRUE if a function is currently open.
51
+ *
52
+ * @var boolean
53
+ */
54
+ private $_functionOpen = false;
55
+
56
+ /**
57
+ * The current PHP_CodeSniffer file that we are processing.
58
+ *
59
+ * @var PHP_CodeSniffer_File
60
+ */
61
+ protected $currentFile = null;
62
+
63
+
64
+ /**
65
+ * Constructs an AbstractVariableTest.
66
+ */
67
+ public function __construct()
68
+ {
69
+ $scopes = array(
70
+ T_CLASS,
71
+ T_TRAIT,
72
+ T_INTERFACE,
73
+ );
74
+
75
+ $listen = array(
76
+ T_FUNCTION,
77
+ T_VARIABLE,
78
+ T_DOUBLE_QUOTED_STRING,
79
+ T_HEREDOC,
80
+ );
81
+
82
+ parent::__construct($scopes, $listen, true);
83
+
84
+ }//end __construct()
85
+
86
+
87
+ /**
88
+ * Processes the token in the specified PHP_CodeSniffer_File.
89
+ *
90
+ * @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where this
91
+ * token was found.
92
+ * @param int $stackPtr The position where the token was found.
93
+ * @param array $currScope The current scope opener token.
94
+ *
95
+ * @return void
96
+ */
97
+ protected final function processTokenWithinScope(
98
+ PHP_CodeSniffer_File $phpcsFile,
99
+ $stackPtr,
100
+ $currScope
101
+ ) {
102
+ if ($this->currentFile !== $phpcsFile) {
103
+ $this->currentFile = $phpcsFile;
104
+ $this->_functionOpen = false;
105
+ $this->_endFunction = -1;
106
+ }
107
+
108
+ $tokens = $phpcsFile->getTokens();
109
+
110
+ if ($stackPtr > $this->_endFunction) {
111
+ $this->_functionOpen = false;
112
+ }
113
+
114
+ if ($tokens[$stackPtr]['code'] === T_FUNCTION
115
+ && $this->_functionOpen === false
116
+ ) {
117
+ $this->_functionOpen = true;
118
+
119
+ $methodProps = $phpcsFile->getMethodProperties($stackPtr);
120
+
121
+ // If the function is abstract, or is in an interface,
122
+ // then set the end of the function to it's closing semicolon.
123
+ if ($methodProps['is_abstract'] === true
124
+ || $tokens[$currScope]['code'] === T_INTERFACE
125
+ ) {
126
+ $this->_endFunction
127
+ = $phpcsFile->findNext(array(T_SEMICOLON), $stackPtr);
128
+ } else {
129
+ if (isset($tokens[$stackPtr]['scope_closer']) === false) {
130
+ $error = 'Possible parse error: non-abstract method defined as abstract';
131
+ $phpcsFile->addWarning($error, $stackPtr);
132
+ return;
133
+ }
134
+
135
+ $this->_endFunction = $tokens[$stackPtr]['scope_closer'];
136
+ }
137
+ }//end if
138
+
139
+ if ($tokens[$stackPtr]['code'] === T_DOUBLE_QUOTED_STRING
140
+ || $tokens[$stackPtr]['code'] === T_HEREDOC
141
+ ) {
142
+ // Check to see if this string has a variable in it.
143
+ $pattern = '|(?<!\\\\)(?:\\\\{2})*\${?[a-zA-Z0-9_]+}?|';
144
+ if (preg_match($pattern, $tokens[$stackPtr]['content']) !== 0) {
145
+ $this->processVariableInString($phpcsFile, $stackPtr);
146
+ }
147
+
148
+ return;
149
+ }
150
+
151
+ if ($this->_functionOpen === true) {
152
+ if ($tokens[$stackPtr]['code'] === T_VARIABLE) {
153
+ $this->processVariable($phpcsFile, $stackPtr);
154
+ }
155
+ } else {
156
+ // What if we assign a member variable to another?
157
+ // ie. private $_count = $this->_otherCount + 1;.
158
+ $this->processMemberVar($phpcsFile, $stackPtr);
159
+ }
160
+
161
+ }//end processTokenWithinScope()
162
+
163
+
164
+ /**
165
+ * Processes the token outside the scope in the file.
166
+ *
167
+ * @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where this
168
+ * token was found.
169
+ * @param int $stackPtr The position where the token was found.
170
+ *
171
+ * @return void
172
+ */
173
+ protected final function processTokenOutsideScope(
174
+ PHP_CodeSniffer_File $phpcsFile,
175
+ $stackPtr
176
+ ) {
177
+ $tokens = $phpcsFile->getTokens();
178
+ // These variables are not member vars.
179
+ if ($tokens[$stackPtr]['code'] === T_VARIABLE) {
180
+ $this->processVariable($phpcsFile, $stackPtr);
181
+ } else if ($tokens[$stackPtr]['code'] === T_DOUBLE_QUOTED_STRING
182
+ || $tokens[$stackPtr]['code'] === T_HEREDOC
183
+ ) {
184
+ // Check to see if this string has a variable in it.
185
+ $pattern = '|(?<!\\\\)(?:\\\\{2})*\${?[a-zA-Z0-9_]+}?|';
186
+ if (preg_match($pattern, $tokens[$stackPtr]['content']) !== 0) {
187
+ $this->processVariableInString($phpcsFile, $stackPtr);
188
+ }
189
+ }
190
+
191
+ }//end processTokenOutsideScope()
192
+
193
+
194
+ /**
195
+ * Called to process class member vars.
196
+ *
197
+ * @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where this
198
+ * token was found.
199
+ * @param int $stackPtr The position where the token was found.
200
+ *
201
+ * @return void
202
+ */
203
+ abstract protected function processMemberVar(
204
+ PHP_CodeSniffer_File $phpcsFile,
205
+ $stackPtr
206
+ );
207
+
208
+
209
+ /**
210
+ * Called to process normal member vars.
211
+ *
212
+ * @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where this
213
+ * token was found.
214
+ * @param int $stackPtr The position where the token was found.
215
+ *
216
+ * @return void
217
+ */
218
+ abstract protected function processVariable(
219
+ PHP_CodeSniffer_File $phpcsFile,
220
+ $stackPtr
221
+ );
222
+
223
+
224
+ /**
225
+ * Called to process variables found in double quoted strings or heredocs.
226
+ *
227
+ * Note that there may be more than one variable in the string, which will
228
+ * result only in one call for the string or one call per line for heredocs.
229
+ *
230
+ * @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where this
231
+ * token was found.
232
+ * @param int $stackPtr The position where the double quoted
233
+ * string was found.
234
+ *
235
+ * @return void
236
+ */
237
+ abstract protected function processVariableInString(
238
+ PHP_CodeSniffer_File
239
+ $phpcsFile,
240
+ $stackPtr
241
+ );
242
+
243
+
244
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Classes/DuplicateClassNameStandard.xml ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Duplicate Class Names">
2
+ <standard>
3
+ <![CDATA[
4
+ Class and Interface names should be unique in a project. They should never be duplicated.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: A unique class name.">
9
+ <![CDATA[
10
+ class <em>Foo</em>
11
+ {
12
+ }
13
+ ]]>
14
+ </code>
15
+ <code title="Invalid: A class duplicated (including across multiple files).">
16
+ <![CDATA[
17
+ class <em>Foo</em>
18
+ {
19
+ }
20
+
21
+ class <em>Foo</em>
22
+ {
23
+ }
24
+ ]]>
25
+ </code>
26
+ </code_comparison>
27
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/CodeAnalysis/EmptyStatementStandard.xml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Empty Statements">
2
+ <standard>
3
+ <![CDATA[
4
+ Control Structures must have at least one statement inside of the body.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: There is a statement inside the control structure.">
9
+ <![CDATA[
10
+ if ($test) {
11
+ $var = 1;
12
+ }
13
+ ]]>
14
+ </code>
15
+ <code title="Invalid: The control structure has no statements.">
16
+ <![CDATA[
17
+ if ($test) {
18
+ <em>// do nothing</em>
19
+ }
20
+ ]]>
21
+ </code>
22
+ </code_comparison>
23
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/CodeAnalysis/ForLoopShouldBeWhileLoopStandard.xml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Condition-Only For Loops">
2
+ <standard>
3
+ <![CDATA[
4
+ For loops that have only a second expression (the condition) should be converted to while loops.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: A for loop is used with all three expressions.">
9
+ <![CDATA[
10
+ for (<em>$i = 0</em>; $i < 10; <em>$i++</em>) {
11
+ echo "{$i}\n";
12
+ }
13
+ ]]>
14
+ </code>
15
+ <code title="Invalid: A for loop is used without a first or third expression.">
16
+ <![CDATA[
17
+ for (<em></em>;$test;<em></em>) {
18
+ $test = doSomething();
19
+ }
20
+ ]]>
21
+ </code>
22
+ </code_comparison>
23
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/CodeAnalysis/ForLoopWithTestFunctionCallStandard.xml ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="For Loops With Function Calls in the Test">
2
+ <standard>
3
+ <![CDATA[
4
+ For loops should not call functions inside the test for the loop when they can be computed beforehand.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: A for loop that determines its end condition before the loop starts.">
9
+ <![CDATA[
10
+ <em>$end = count($foo);</em>
11
+ for ($i = 0; $i < $end; $i++) {
12
+ echo $foo[$i]."\n";
13
+ }
14
+ ]]>
15
+ </code>
16
+ <code title="Invalid: A for loop that unnecessarily computes the same value on every iteration.">
17
+ <![CDATA[
18
+ for ($i = 0; $i < <em>count($foo)</em>; $i++) {
19
+ echo $foo[$i]."\n";
20
+ }
21
+ ]]>
22
+ </code>
23
+ </code_comparison>
24
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/CodeAnalysis/JumbledIncrementerStandard.xml ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Jumbled Incrementers">
2
+ <standard>
3
+ <![CDATA[
4
+ Incrementers in nested loops should use different variable names.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: Two different variables being used to increment.">
9
+ <![CDATA[
10
+ for ($i = 0; $i < 10; <em>$i++</em>) {
11
+ for ($j = 0; $j < 10; <em>$j++</em>) {
12
+ }
13
+ }
14
+ ]]>
15
+ </code>
16
+ <code title="Invalid: Inner incrementer is the same variable name as the outer one.">
17
+ <![CDATA[
18
+ for ($i = 0; $i < 10; <em>$i++</em>) {
19
+ for ($j = 0; $j < 10; <em>$i++</em>) {
20
+ }
21
+ }
22
+ ]]>
23
+ </code>
24
+ </code_comparison>
25
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/CodeAnalysis/UnconditionalIfStatementStandard.xml ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Unconditional If Statements">
2
+ <standard>
3
+ <![CDATA[
4
+ If statements that are always evaluated should not be used.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: An if statement that only executes conditionally.">
9
+ <![CDATA[
10
+ if (<em>$test</em>) {
11
+ $var = 1;
12
+ }
13
+ ]]>
14
+ </code>
15
+ <code title="Invalid: An if statement that is always performed.">
16
+ <![CDATA[
17
+ if (<em>true</em>) {
18
+ $var = 1;
19
+ }
20
+ ]]>
21
+ </code>
22
+ </code_comparison>
23
+ <code_comparison>
24
+ <code title="Valid: An if statement that only executes conditionally.">
25
+ <![CDATA[
26
+ if (<em>$test</em>) {
27
+ $var = 1;
28
+ }
29
+ ]]>
30
+ </code>
31
+ <code title="Invalid: An if statement that is never performed.">
32
+ <![CDATA[
33
+ if (<em>false</em>) {
34
+ $var = 1;
35
+ }
36
+ ]]>
37
+ </code>
38
+ </code_comparison>
39
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/CodeAnalysis/UnnecessaryFinalModifierStandard.xml ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Unnecessary Final Modifiers">
2
+ <standard>
3
+ <![CDATA[
4
+ Methods should not be declared final inside of classes that are declared final.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: A method in a final class is not marked final.">
9
+ <![CDATA[
10
+ final class Foo
11
+ {
12
+ public function bar()
13
+ {
14
+ }
15
+ }
16
+ ]]>
17
+ </code>
18
+ <code title="Invalid: A method in a final class is also marked final.">
19
+ <![CDATA[
20
+ final class Foo
21
+ {
22
+ public <em>final</em> function bar()
23
+ {
24
+ }
25
+ }
26
+ ]]>
27
+ </code>
28
+ </code_comparison>
29
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/CodeAnalysis/UnusedFunctionParameterStandard.xml ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Unused function parameters">
2
+ <standard>
3
+ <![CDATA[
4
+ All parameters in a functions signature should be used within the function.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: All the parameters are used.">
9
+ <![CDATA[
10
+ function addThree($a, $b, $c)
11
+ {
12
+ return <em>$a + $b + $c</em>;
13
+ }
14
+ ]]>
15
+ </code>
16
+ <code title="Invalid: One of the parameters is not being used.">
17
+ <![CDATA[
18
+ function addThree($a, $b, $c)
19
+ {
20
+ return <em>$a + $b</em>;
21
+ }
22
+ ]]>
23
+ </code>
24
+ </code_comparison>
25
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/CodeAnalysis/UselessOverridingMethodStandard.xml ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Useless Overriding Methods">
2
+ <standard>
3
+ <![CDATA[
4
+ Methods should not be defined that only call the parent method.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: A method that extends functionality on a parent method.">
9
+ <![CDATA[
10
+ final class Foo
11
+ {
12
+ public function bar()
13
+ {
14
+ parent::bar();
15
+ <em>$this->doSomethingElse();</em>
16
+ }
17
+ }
18
+ ]]>
19
+ </code>
20
+ <code title="Invalid: An overriding method that only calls the parent.">
21
+ <![CDATA[
22
+ final class Foo
23
+ {
24
+ public function bar()
25
+ {
26
+ <em>parent::bar();</em>
27
+ }
28
+ }
29
+ ]]>
30
+ </code>
31
+ </code_comparison>
32
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Commenting/FixmeStandard.xml ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Todo Comments">
2
+ <standard>
3
+ <![CDATA[
4
+ FIXME Statements should be taken care of.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: A comment without a fixme.">
9
+ <![CDATA[
10
+ // <em>Handle strange case</em>
11
+ if ($test) {
12
+ $var = 1;
13
+ }
14
+ ]]>
15
+ </code>
16
+ <code title="Invalid: A fixme comment.">
17
+ <![CDATA[
18
+ // <em>FIXME</em>: This needs to be fixed!
19
+ if ($test) {
20
+ $var = 1;
21
+ }
22
+ ]]>
23
+ </code>
24
+ </code_comparison>
25
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Commenting/TodoStandard.xml ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Todo Comments">
2
+ <standard>
3
+ <![CDATA[
4
+ TODO Statements should be taken care of.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: A comment without a todo.">
9
+ <![CDATA[
10
+ // <em>Handle strange case</em>
11
+ if ($test) {
12
+ $var = 1;
13
+ }
14
+ ]]>
15
+ </code>
16
+ <code title="Invalid: A todo comment.">
17
+ <![CDATA[
18
+ // <em>TODO</em>: This needs to be fixed!
19
+ if ($test) {
20
+ $var = 1;
21
+ }
22
+ ]]>
23
+ </code>
24
+ </code_comparison>
25
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/ControlStructures/InlineControlStructureStandard.xml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Inline Control Structures">
2
+ <standard>
3
+ <![CDATA[
4
+ Control Structures should use braces.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: Braces are used around the control structure.">
9
+ <![CDATA[
10
+ if ($test) <em>{</em>
11
+ $var = 1;
12
+ <em>}</em>
13
+ ]]>
14
+ </code>
15
+ <code title="Invalid: No braces are used for the control structure..">
16
+ <![CDATA[
17
+ if ($test)
18
+ $var = 1;
19
+ ]]>
20
+ </code>
21
+ </code_comparison>
22
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Debug/CSSLintStandard.xml ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="CSSLint">
2
+ <standard>
3
+ <![CDATA[
4
+ All css files should pass the basic csslint tests.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: Valid CSS Syntax is used.">
9
+ <![CDATA[
10
+ .foo: { width: 100<em></em>%; }
11
+ ]]>
12
+ </code>
13
+ <code title="Invalid: The CSS has a typo in it.">
14
+ <![CDATA[
15
+ .foo: { width: 100<em> </em>%; }
16
+ ]]>
17
+ </code>
18
+ </code_comparison>
19
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Debug/ClosureLinterStandard.xml ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Closure Linter">
2
+ <standard>
3
+ <![CDATA[
4
+ All javascript files should pass basic Closure Linter tests.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: Valid JS Syntax is used.">
9
+ <![CDATA[
10
+ var foo = [1, 2<em></em>];
11
+ ]]>
12
+ </code>
13
+ <code title="Invalid: Trailing comma in a javascript array.">
14
+ <![CDATA[
15
+ var foo = [1, 2<em>,</em>];
16
+ ]]>
17
+ </code>
18
+ </code_comparison>
19
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Debug/JSHintStandard.xml ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="JSHint">
2
+ <standard>
3
+ <![CDATA[
4
+ All javascript files should pass basic JSHint tests.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: Valid JS Syntax is used.">
9
+ <![CDATA[
10
+ <em>var</em> foo = 5;
11
+ ]]>
12
+ </code>
13
+ <code title="Invalid: The Javascript is using an undefined variable.">
14
+ <![CDATA[
15
+ <em></em>foo = 5;
16
+ ]]>
17
+ </code>
18
+ </code_comparison>
19
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Files/ByteOrderMarkStandard.xml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <documentation title="Byte Order Marks">
2
+ <standard>
3
+ <![CDATA[
4
+ Byte Order Marks that may corrupt your application should not be used. These include 0xefbbbf (UTF-8), 0xfeff (UTF-16 BE) and 0xfffe (UTF-16 LE).
5
+ ]]>
6
+ </standard>
7
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Files/EndFileNewlineStandard.xml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <documentation title="End of File Newline">
2
+ <standard>
3
+ <![CDATA[
4
+ Files should end with a newline character.
5
+ ]]>
6
+ </standard>
7
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Files/EndFileNoNewlineStandard.xml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <documentation title="No End of File Newline">
2
+ <standard>
3
+ <![CDATA[
4
+ Files should not end with a newline character.
5
+ ]]>
6
+ </standard>
7
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Files/InlineHTMLStandard.xml ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Inline HTML">
2
+ <standard>
3
+ <![CDATA[
4
+ Files that contain php code should only have php code and should not have any "inline html".
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: A php file with only php code in it.">
9
+ <![CDATA[
10
+ <?php
11
+ $foo = 'bar';
12
+ echo $foo . 'baz';
13
+ ]]>
14
+ </code>
15
+ <code title="Invalid: A php file with html in it outside of the php tags.">
16
+ <![CDATA[
17
+ <em>some string here</em>
18
+ <?php
19
+ $foo = 'bar';
20
+ echo $foo . 'baz';
21
+ ]]>
22
+ </code>
23
+ </code_comparison>
24
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Files/LineEndingsStandard.xml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <documentation title="Line Endings">
2
+ <standard>
3
+ <![CDATA[
4
+ Unix-style line endings are preferred ("\n" instead of "\r\n").
5
+ ]]>
6
+ </standard>
7
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Files/LineLengthStandard.xml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <documentation title="Line Length">
2
+ <standard>
3
+ <![CDATA[
4
+ It is recommended to keep lines at approximately 80 characters long for better code readability.
5
+ ]]>
6
+ </standard>
7
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Files/LowercasedFilenameStandard.xml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <documentation title="Lowercased Filenames">
2
+ <standard>
3
+ <![CDATA[
4
+ Lowercase filenames are required.
5
+ ]]>
6
+ </standard>
7
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Files/OneClassPerFileStandard.xml ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="One Class Per File">
2
+ <standard>
3
+ <![CDATA[
4
+ There should only be one class defined in a file.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: Only one class in the file.">
9
+ <![CDATA[
10
+ <?php
11
+ <em>class Foo</em>
12
+ {
13
+ }
14
+ ]]>
15
+ </code>
16
+ <code title="Invalid: Multiple classes defined in one file.">
17
+ <![CDATA[
18
+ <?php
19
+ <em>class Foo</em>
20
+ {
21
+ }
22
+
23
+ <em>class Bar</em>
24
+ {
25
+ }
26
+ ]]>
27
+ </code>
28
+ </code_comparison>
29
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Files/OneInterfacePerFileStandard.xml ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="One Interface Per File">
2
+ <standard>
3
+ <![CDATA[
4
+ There should only be one interface defined in a file.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: Only one interface in the file.">
9
+ <![CDATA[
10
+ <?php
11
+ <em>interface Foo</em>
12
+ {
13
+ }
14
+ ]]>
15
+ </code>
16
+ <code title="Invalid: Multiple interfaces defined in one file.">
17
+ <![CDATA[
18
+ <?php
19
+ <em>interface Foo</em>
20
+ {
21
+ }
22
+
23
+ <em>interface Bar</em>
24
+ {
25
+ }
26
+ ]]>
27
+ </code>
28
+ </code_comparison>
29
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Formatting/DisallowMultipleStatementsStandard.xml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Multiple Statements On a Single Line">
2
+ <standard>
3
+ <![CDATA[
4
+ Multiple statements are not allowed on a single line.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: Two statements are spread out on two separate lines.">
9
+ <![CDATA[
10
+ $foo = 1;
11
+ $bar = 2;
12
+ ]]>
13
+ </code>
14
+ <code title="Invalid: Two statements are combined onto one line.">
15
+ <![CDATA[
16
+ $foo = 1; $bar = 2;
17
+ ]]>
18
+ </code>
19
+ </code_comparison>
20
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Formatting/MultipleStatementAlignmentStandard.xml ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Aligning Blocks of Assignments">
2
+ <standard>
3
+ <![CDATA[
4
+ There should be one space on either side of an equals sign used to assign a value to a variable. In the case of a block of related assignments, more space may be inserted to promote readability.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Equals signs aligned">
9
+ <![CDATA[
10
+ $shortVar <em>=</em> (1 + 2);
11
+ $veryLongVarName <em>=</em> 'string';
12
+ $var <em>=</em> foo($bar, $baz, $quux);
13
+ ]]>
14
+ </code>
15
+ <code title="Not aligned; harder to read">
16
+ <![CDATA[
17
+ $shortVar <em>=</em> (1 + 2);
18
+ $veryLongVarName <em>=</em> 'string';
19
+ $var <em>=</em> foo($bar, $baz, $quux);
20
+ ]]>
21
+ </code>
22
+ </code_comparison>
23
+ <standard>
24
+ <![CDATA[
25
+ When using plus-equals, minus-equals etc. still ensure the equals signs are aligned to one space after the longest variable name.
26
+ ]]>
27
+ </standard>
28
+ <code_comparison>
29
+ <code title="Equals signs aligned; only one space after longest var name">
30
+ <![CDATA[
31
+ $shortVar <em>+= </em>1;
32
+ $veryLongVarName<em> = </em>1;
33
+ ]]>
34
+ </code>
35
+ <code title="Two spaces after longest var name">
36
+ <![CDATA[
37
+ $shortVar <em> += </em>1;
38
+ $veryLongVarName<em> = </em>1;
39
+ ]]>
40
+ </code>
41
+ </code_comparison>
42
+ <code_comparison>
43
+ <code title="Equals signs aligned">
44
+ <![CDATA[
45
+ $shortVar <em> = </em>1;
46
+ $veryLongVarName<em> -= </em>1;
47
+ ]]>
48
+ </code>
49
+ <code title="Equals signs not aligned">
50
+ <![CDATA[
51
+ $shortVar <em> = </em>1;
52
+ $veryLongVarName<em> -= </em>1;
53
+ ]]>
54
+ </code>
55
+ </code_comparison>
56
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Formatting/NoSpaceAfterCastStandard.xml ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Space After Casts">
2
+ <standard>
3
+ <![CDATA[
4
+ Spaces are not allowed after casting operators.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: A cast operator is immediately before its value.">
9
+ <![CDATA[
10
+ $foo = (string)1;
11
+ ]]>
12
+ </code>
13
+ <code title="Invalid: A cast operator is followed by whitespace.">
14
+ <![CDATA[
15
+ $foo = (string)<em> </em>1;
16
+ ]]>
17
+ </code>
18
+ </code_comparison>
19
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Formatting/SpaceAfterCastStandard.xml ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Space After Casts">
2
+ <standard>
3
+ <![CDATA[
4
+ Exactly one space is allowed after a cast.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: A cast operator is followed by one space.">
9
+ <![CDATA[
10
+ $foo = (string)<em> </em>1;
11
+ ]]>
12
+ </code>
13
+ <code title="Invalid: A cast operator is not followed by whitespace.">
14
+ <![CDATA[
15
+ $foo = (string)<em></em>1;
16
+ ]]>
17
+ </code>
18
+ </code_comparison>
19
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Functions/CallTimePassByReferenceStandard.xml ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Call-Time Pass-By-Reference">
2
+ <standard>
3
+ <![CDATA[
4
+ Call-time pass-by-reference is not allowed. It should be declared in the function definition.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: Pass-by-reference is specified in the function definition.">
9
+ <![CDATA[
10
+ function foo(<em>&</em>$bar)
11
+ {
12
+ $bar++;
13
+ }
14
+
15
+ $baz = 1;
16
+ foo($baz);
17
+ ]]>
18
+ </code>
19
+ <code title="Invalid: Pass-by-reference is done in the call to a function.">
20
+ <![CDATA[
21
+ function foo($bar)
22
+ {
23
+ $bar++;
24
+ }
25
+
26
+ $baz = 1;
27
+ foo(<em>&</em>$baz);
28
+ ]]>
29
+ </code>
30
+ </code_comparison>
31
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Functions/FunctionCallArgumentSpacingStandard.xml ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Function Argument Spacing">
2
+ <standard>
3
+ <![CDATA[
4
+ Function arguments should have one space after a comma, and single spaces surrounding the equals sign for default values.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: Single spaces after a comma.">
9
+ <![CDATA[
10
+ function foo($bar,<em> </em>$baz)
11
+ {
12
+ }
13
+ ]]>
14
+ </code>
15
+ <code title="Invalid: No spaces after a comma.">
16
+ <![CDATA[
17
+ function foo($bar,<em></em>$baz)
18
+ {
19
+ }
20
+ ]]>
21
+ </code>
22
+ </code_comparison>
23
+ <code_comparison>
24
+ <code title="Valid: Single spaces around an equals sign in function declaration.">
25
+ <![CDATA[
26
+ function foo($bar, $baz<em> </em>=<em> </em>true)
27
+ {
28
+ }
29
+ ]]>
30
+ </code>
31
+ <code title="Invalid: No spaces around an equals sign in function declaration.">
32
+ <![CDATA[
33
+ function foo($bar, $baz<em></em>=<em></em>true)
34
+ {
35
+ }
36
+ ]]>
37
+ </code>
38
+ </code_comparison>
39
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Functions/OpeningFunctionBraceBsdAllmanStandard.xml ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Opening Brace in Function Declarations">
2
+ <standard>
3
+ <![CDATA[
4
+ Function declarations follow the "BSD/Allman style". The function brace is on the line following the function declaration and is indented to the same column as the start of the function declaration.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: brace on next line">
9
+ <![CDATA[
10
+ function fooFunction($arg1, $arg2 = '')
11
+ <em>{</em>
12
+ ...
13
+ }
14
+ ]]>
15
+ </code>
16
+ <code title="Invalid: brace on same line">
17
+ <![CDATA[
18
+ function fooFunction($arg1, $arg2 = '') <em>{</em>
19
+ ...
20
+ }
21
+ ]]>
22
+ </code>
23
+ </code_comparison>
24
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Functions/OpeningFunctionBraceKernighanRitchieStandard.xml ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Opening Brace in Function Declarations">
2
+ <standard>
3
+ <![CDATA[
4
+ Function declarations follow the "Kernighan/Ritchie style". The function brace is on the same line as the function declaration. One space is required between the closing parenthesis and the brace.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: brace on same line">
9
+ <![CDATA[
10
+ function fooFunction($arg1, $arg2 = '')<em> {</em>
11
+ ...
12
+ }
13
+ ]]>
14
+ </code>
15
+ <code title="Invalid: brace on next line">
16
+ <![CDATA[
17
+ function fooFunction($arg1, $arg2 = '')
18
+ <em>{</em>
19
+ ...
20
+ }
21
+ ]]>
22
+ </code>
23
+ </code_comparison>
24
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Metrics/CyclomaticComplexityStandard.xml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <documentation title="Cyclomatic Complexity">
2
+ <standard>
3
+ <![CDATA[
4
+ Functions should not have a cyclomatic complexity greater than 20, and should try to stay below a complexity of 10.
5
+ ]]>
6
+ </standard>
7
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Metrics/NestingLevelStandard.xml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <documentation title="Nesting Level">
2
+ <standard>
3
+ <![CDATA[
4
+ Functions should not have a nesting level greater than 10, and should try to stay below 5.
5
+ ]]>
6
+ </standard>
7
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/NamingConventions/CamelCapsFunctionNameStandard.xml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="camelCaps Function Names">
2
+ <standard>
3
+ <![CDATA[
4
+ Functions should use camelCaps format for their names. Only PHP's magic methods should use a double underscore prefix.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: A function in camelCaps format.">
9
+ <![CDATA[
10
+ function <em>doSomething</em>()
11
+ {
12
+ }
13
+ ]]>
14
+ </code>
15
+ <code title="Invalid: A function in snake_case format.">
16
+ <![CDATA[
17
+ function <em>do_something</em>()
18
+ {
19
+ }
20
+ ]]>
21
+ </code>
22
+ </code_comparison>
23
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/NamingConventions/ConstructorNameStandard.xml ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Constructor name">
2
+ <standard>
3
+ <![CDATA[
4
+ Constructors should be named __construct, not after the class.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: The constructor is named __construct.">
9
+ <![CDATA[
10
+ class Foo
11
+ {
12
+ function <em>__construct</em>()
13
+ {
14
+ }
15
+ }
16
+ ]]>
17
+ </code>
18
+ <code title="Invalid: The old style class name constructor is used.">
19
+ <![CDATA[
20
+ class Foo
21
+ {
22
+ function <em>Foo</em>()
23
+ {
24
+ }
25
+ }
26
+ ]]>
27
+ </code>
28
+ </code_comparison>
29
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/NamingConventions/UpperCaseConstantNameStandard.xml ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Constant Names">
2
+ <standard>
3
+ <![CDATA[
4
+ Constants should always be all-uppercase, with underscores to separate words.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: all uppercase">
9
+ <![CDATA[
10
+ define('<em>FOO_CONSTANT</em>', 'foo');
11
+
12
+ class FooClass
13
+ {
14
+ const <em>FOO_CONSTANT</em> = 'foo';
15
+ }
16
+ ]]>
17
+ </code>
18
+ <code title="Invalid: mixed case">
19
+ <![CDATA[
20
+ define('<em>Foo_Constant</em>', 'foo');
21
+
22
+ class FooClass
23
+ {
24
+ const <em>foo_constant</em> = 'foo';
25
+ }
26
+ ]]>
27
+ </code>
28
+ </code_comparison>
29
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/PHP/CharacterBeforePHPOpeningTagStandard.xml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Opening Tag at Start of File">
2
+ <standard>
3
+ <![CDATA[
4
+ The opening php tag should be the first item in the file.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: A file starting with an opening php tag.">
9
+ <![CDATA[
10
+ <em></em><?php
11
+ echo 'Foo';
12
+ ]]>
13
+ </code>
14
+ <code title="Invalid: A file with content before the opening php tag.">
15
+ <![CDATA[
16
+ <em>Beginning content</em>
17
+ <?php
18
+ echo 'Foo';
19
+ ]]>
20
+ </code>
21
+ </code_comparison>
22
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/PHP/ClosingPHPTagStandard.xml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Closing PHP Tags">
2
+ <standard>
3
+ <![CDATA[
4
+ All opening php tags should have a corresponding closing tag.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: A closing tag paired with it's opening tag.">
9
+ <![CDATA[
10
+ <em><?php</em>
11
+ echo 'Foo';
12
+ <em>?></em>
13
+ ]]>
14
+ </code>
15
+ <code title="Invalid: No closing tag paired with the opening tag.">
16
+ <![CDATA[
17
+ <em><?php</em>
18
+ echo 'Foo';
19
+ ]]>
20
+ </code>
21
+ </code_comparison>
22
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/PHP/DeprecatedFunctionsStandard.xml ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Deprecated Functions">
2
+ <standard>
3
+ <![CDATA[
4
+ Deprecated functions should not be used.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: A non-deprecated function is used.">
9
+ <![CDATA[
10
+ $foo = <em>explode</em>('a', $bar);
11
+ ]]>
12
+ </code>
13
+ <code title="Invalid: A deprecated function is used.">
14
+ <![CDATA[
15
+ $foo = <em>split</em>('a', $bar);
16
+ ]]>
17
+ </code>
18
+ </code_comparison>
19
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/PHP/DisallowShortOpenTagStandard.xml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <documentation title="PHP Code Tags">
2
+ <standard>
3
+ <![CDATA[
4
+ Always use <?php ?> to delimit PHP code, not the <? ?> shorthand. This is the most portable way to include PHP code on differing operating systems and setups.
5
+ ]]>
6
+ </standard>
7
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/PHP/ForbiddenFunctionsStandard.xml ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Forbidden Functions">
2
+ <standard>
3
+ <![CDATA[
4
+ The forbidden functions sizeof() and delete() should not be used.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: count() is used in place of sizeof().">
9
+ <![CDATA[
10
+ $foo = <em>count</em>($bar);
11
+ ]]>
12
+ </code>
13
+ <code title="Invalid: sizeof() is used.">
14
+ <![CDATA[
15
+ $foo = <em>sizeof</em>($bar);
16
+ ]]>
17
+ </code>
18
+ </code_comparison>
19
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/PHP/LowerCaseConstantStandard.xml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="PHP Constants">
2
+ <standard>
3
+ <![CDATA[
4
+ The <em>true</em>, <em>false</em> and <em>null</em> constants must always be lowercase.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: lowercase constants">
9
+ <![CDATA[
10
+ if ($var === <em>false</em> || $var === <em>null</em>) {
11
+ $var = <em>true</em>;
12
+ }
13
+ ]]>
14
+ </code>
15
+ <code title="Invalid: uppercase constants">
16
+ <![CDATA[
17
+ if ($var === <em>FALSE</em> || $var === <em>NULL</em>) {
18
+ $var = <em>TRUE</em>;
19
+ }
20
+ ]]>
21
+ </code>
22
+ </code_comparison>
23
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/PHP/LowerCaseKeywordStandard.xml ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Lowercase Keywords">
2
+ <standard>
3
+ <![CDATA[
4
+ All PHP keywords should be lowercase.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: Lowercase array keyword used.">
9
+ <![CDATA[
10
+ $foo = <em>array</em>();
11
+ ]]>
12
+ </code>
13
+ <code title="Invalid: Non-lowercase array keyword used.">
14
+ <![CDATA[
15
+ $foo = <em>Array</em>();
16
+ ]]>
17
+ </code>
18
+ </code_comparison>
19
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/PHP/NoSilencedErrorsStandard.xml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Silenced Errors">
2
+ <standard>
3
+ <![CDATA[
4
+ Suppressing Errors is not allowed.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: isset() is used to verify that a variable exists before trying to use it.">
9
+ <![CDATA[
10
+ if (<em>isset($foo)</em> && $foo) {
11
+ echo "Hello\n";
12
+ }
13
+ ]]>
14
+ </code>
15
+ <code title="Invalid: Errors are suppressed.">
16
+ <![CDATA[
17
+ if (<em>@</em>$foo) {
18
+ echo "Hello\n";
19
+ }
20
+ ]]>
21
+ </code>
22
+ </code_comparison>
23
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/PHP/SAPIUsageStandard.xml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="SAPI Usage">
2
+ <standard>
3
+ <![CDATA[
4
+ The PHP_SAPI constant should be used instead of php_sapi_name().
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: PHP_SAPI is used.">
9
+ <![CDATA[
10
+ if (<em>PHP_SAPI</em> === 'cli') {
11
+ echo "Hello, CLI user.";
12
+ }
13
+ ]]>
14
+ </code>
15
+ <code title="Invalid: php_sapi_name() is used.">
16
+ <![CDATA[
17
+ if (<em>php_sapi_name()</em> === 'cli') {
18
+ echo "Hello, CLI user.";
19
+ }
20
+ ]]>
21
+ </code>
22
+ </code_comparison>
23
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/PHP/UpperCaseConstantStandard.xml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="PHP Constants">
2
+ <standard>
3
+ <![CDATA[
4
+ The <em>true</em>, <em>false</em> and <em>null</em> constants must always be uppercase.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: uppercase constants">
9
+ <![CDATA[
10
+ if ($var === <em>FALSE</em> || $var === <em>NULL</em>) {
11
+ $var = <em>TRUE</em>;
12
+ }
13
+ ]]>
14
+ </code>
15
+ <code title="Invalid: lowercase constants">
16
+ <![CDATA[
17
+ if ($var === <em>false</em> || $var === <em>null</em>) {
18
+ $var = <em>true</em>;
19
+ }
20
+ ]]>
21
+ </code>
22
+ </code_comparison>
23
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/Strings/UnnecessaryStringConcatStandard.xml ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Unnecessary String Concatenation">
2
+ <standard>
3
+ <![CDATA[
4
+ Strings should not be concatenated together.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: A string can be concatenated with an expression.">
9
+ <![CDATA[
10
+ echo '5 + 2 = ' . (5 + 2);
11
+ ]]>
12
+ </code>
13
+ <code title="Invalid: Strings should not be concatenated together.">
14
+ <![CDATA[
15
+ echo 'Hello' . ' ' . 'World';
16
+ ]]>
17
+ </code>
18
+ </code_comparison>
19
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/VersionControl/SubversionPropertiesStandard.xml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <documentation title="Subversion Properties">
2
+ <standard>
3
+ <![CDATA[
4
+ All php files in a subversion repository should have the svn:keywords property set to 'Author Id Revision' and the svn:eol-style property set to 'native'.
5
+ ]]>
6
+ </standard>
7
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/WhiteSpace/DisallowSpaceIndentStandard.xml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <documentation title="No Space Indentation">
2
+ <standard>
3
+ <![CDATA[
4
+ Tabs should be used for indentation instead of spaces.
5
+ ]]>
6
+ </standard>
7
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/WhiteSpace/DisallowTabIndentStandard.xml ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <documentation title="No Tab Indentation">
2
+ <standard>
3
+ <![CDATA[
4
+ Spaces should be used for indentation instead of tabs.
5
+ ]]>
6
+ </standard>
7
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Docs/WhiteSpace/ScopeIndentStandard.xml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <documentation title="Scope Indentation">
2
+ <standard>
3
+ <![CDATA[
4
+ Indentation for control structures, classes, and functions should be 4 spaces per level.
5
+ ]]>
6
+ </standard>
7
+ <code_comparison>
8
+ <code title="Valid: 4 spaces are used to indent a control structure.">
9
+ <![CDATA[
10
+ if ($test) {
11
+ <em> </em>$var = 1;
12
+ }
13
+ ]]>
14
+ </code>
15
+ <code title="Invalid: 8 spaces are used to indent a control structure.">
16
+ <![CDATA[
17
+ if ($test) {
18
+ <em> </em>$var = 1;
19
+ }
20
+ ]]>
21
+ </code>
22
+ </code_comparison>
23
+ </documentation>
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Arrays/DisallowLongArraySyntaxSniff.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Bans the use of the PHP long array syntax.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Greg Sherwood <gsherwood@squiz.net>
10
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
11
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
12
+ * @link http://pear.php.net/package/PHP_CodeSniffer
13
+ */
14
+
15
+ /**
16
+ * Bans the use of the PHP long array syntax.
17
+ *
18
+ * @category PHP
19
+ * @package PHP_CodeSniffer
20
+ * @author Greg Sherwood <gsherwood@squiz.net>
21
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
22
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
23
+ * @version Release: @package_version@
24
+ * @link http://pear.php.net/package/PHP_CodeSniffer
25
+ */
26
+ class Generic_Sniffs_Arrays_DisallowLongArraySyntaxSniff implements PHP_CodeSniffer_Sniff
27
+ {
28
+
29
+
30
+ /**
31
+ * Registers the tokens that this sniff wants to listen for.
32
+ *
33
+ * @return int[]
34
+ */
35
+ public function register()
36
+ {
37
+ return array(T_ARRAY);
38
+
39
+ }//end register()
40
+
41
+
42
+ /**
43
+ * Processes this test, when one of its tokens is encountered.
44
+ *
45
+ * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
46
+ * @param int $stackPtr The position of the current token
47
+ * in the stack passed in $tokens.
48
+ *
49
+ * @return void
50
+ */
51
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
52
+ {
53
+ $phpcsFile->recordMetric($stackPtr, 'Short array syntax used', 'no');
54
+
55
+ $error = 'Short array syntax must be used to define arrays';
56
+ $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Found');
57
+
58
+ if ($fix === true) {
59
+ $tokens = $phpcsFile->getTokens();
60
+ $opener = $tokens[$stackPtr]['parenthesis_opener'];
61
+ $closer = $tokens[$stackPtr]['parenthesis_closer'];
62
+
63
+ $phpcsFile->fixer->beginChangeset();
64
+
65
+ if ($opener === null) {
66
+ $phpcsFile->fixer->replaceToken($stackPtr, '[]');
67
+ } else {
68
+ $phpcsFile->fixer->replaceToken($stackPtr, '');
69
+ $phpcsFile->fixer->replaceToken($opener, '[');
70
+ $phpcsFile->fixer->replaceToken($closer, ']');
71
+ }
72
+
73
+ $phpcsFile->fixer->endChangeset();
74
+ }
75
+
76
+ }//end process()
77
+
78
+
79
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Arrays/DisallowShortArraySyntaxSniff.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Bans the use of the PHP short array syntax.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Greg Sherwood <gsherwood@squiz.net>
10
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
11
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
12
+ * @link http://pear.php.net/package/PHP_CodeSniffer
13
+ */
14
+
15
+ /**
16
+ * Bans the use of the PHP short array syntax.
17
+ *
18
+ * @category PHP
19
+ * @package PHP_CodeSniffer
20
+ * @author Greg Sherwood <gsherwood@squiz.net>
21
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
22
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
23
+ * @version Release: @package_version@
24
+ * @link http://pear.php.net/package/PHP_CodeSniffer
25
+ */
26
+ class Generic_Sniffs_Arrays_DisallowShortArraySyntaxSniff implements PHP_CodeSniffer_Sniff
27
+ {
28
+
29
+
30
+ /**
31
+ * Registers the tokens that this sniff wants to listen for.
32
+ *
33
+ * @return int[]
34
+ */
35
+ public function register()
36
+ {
37
+ return array(T_OPEN_SHORT_ARRAY);
38
+
39
+ }//end register()
40
+
41
+
42
+ /**
43
+ * Processes this test, when one of its tokens is encountered.
44
+ *
45
+ * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
46
+ * @param int $stackPtr The position of the current token
47
+ * in the stack passed in $tokens.
48
+ *
49
+ * @return void
50
+ */
51
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
52
+ {
53
+ $phpcsFile->recordMetric($stackPtr, 'Short array syntax used', 'yes');
54
+
55
+ $error = 'Short array syntax is not allowed';
56
+ $fix = $phpcsFile->addFixableError($error, $stackPtr, 'Found');
57
+
58
+ if ($fix === true) {
59
+ $tokens = $phpcsFile->getTokens();
60
+ $opener = $tokens[$stackPtr]['bracket_opener'];
61
+ $closer = $tokens[$stackPtr]['bracket_closer'];
62
+
63
+ $phpcsFile->fixer->beginChangeset();
64
+ $phpcsFile->fixer->replaceToken($opener, 'array(');
65
+ $phpcsFile->fixer->replaceToken($closer, ')');
66
+ $phpcsFile->fixer->endChangeset();
67
+ }
68
+
69
+ }//end process()
70
+
71
+
72
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Classes/DuplicateClassNameSniff.php ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Reports errors if the same class or interface name is used in multiple files.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Greg Sherwood <gsherwood@squiz.net>
10
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
11
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
12
+ * @link http://pear.php.net/package/PHP_CodeSniffer
13
+ */
14
+
15
+ /**
16
+ * Reports errors if the same class or interface name is used in multiple files.
17
+ *
18
+ * @category PHP
19
+ * @package PHP_CodeSniffer
20
+ * @author Greg Sherwood <gsherwood@squiz.net>
21
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
22
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
23
+ * @version Release: @package_version@
24
+ * @link http://pear.php.net/package/PHP_CodeSniffer
25
+ */
26
+ class Generic_Sniffs_Classes_DuplicateClassNameSniff implements PHP_CodeSniffer_Sniff
27
+ {
28
+
29
+ /**
30
+ * List of classes that have been found during checking.
31
+ *
32
+ * @var array
33
+ */
34
+ public $foundClasses = array();
35
+
36
+
37
+ /**
38
+ * Registers the tokens that this sniff wants to listen for.
39
+ *
40
+ * @return int[]
41
+ */
42
+ public function register()
43
+ {
44
+ return array(T_OPEN_TAG);
45
+
46
+ }//end register()
47
+
48
+
49
+ /**
50
+ * Processes this test, when one of its tokens is encountered.
51
+ *
52
+ * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
53
+ * @param int $stackPtr The position of the current token
54
+ * in the stack passed in $tokens.
55
+ *
56
+ * @return void
57
+ */
58
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
59
+ {
60
+ $tokens = $phpcsFile->getTokens();
61
+
62
+ $namespace = '';
63
+ $findTokens = array(
64
+ T_CLASS,
65
+ T_INTERFACE,
66
+ T_NAMESPACE,
67
+ T_CLOSE_TAG,
68
+ );
69
+
70
+ $stackPtr = $phpcsFile->findNext($findTokens, ($stackPtr + 1));
71
+ while ($stackPtr !== false) {
72
+ if ($tokens[$stackPtr]['code'] === T_CLOSE_TAG) {
73
+ // We can stop here. The sniff will continue from the next open
74
+ // tag when PHPCS reaches that token, if there is one.
75
+ return;
76
+ }
77
+
78
+ // Keep track of what namespace we are in.
79
+ if ($tokens[$stackPtr]['code'] === T_NAMESPACE) {
80
+ $nsEnd = $phpcsFile->findNext(
81
+ array(
82
+ T_NS_SEPARATOR,
83
+ T_STRING,
84
+ T_WHITESPACE,
85
+ ),
86
+ ($stackPtr + 1),
87
+ null,
88
+ true
89
+ );
90
+
91
+ $namespace = trim($phpcsFile->getTokensAsString(($stackPtr + 1), ($nsEnd - $stackPtr - 1)));
92
+ $stackPtr = $nsEnd;
93
+ } else {
94
+ $nameToken = $phpcsFile->findNext(T_STRING, $stackPtr);
95
+ $name = $tokens[$nameToken]['content'];
96
+ if ($namespace !== '') {
97
+ $name = $namespace.'\\'.$name;
98
+ }
99
+
100
+ $compareName = strtolower($name);
101
+ if (isset($this->foundClasses[$compareName]) === true) {
102
+ $type = strtolower($tokens[$stackPtr]['content']);
103
+ $file = $this->foundClasses[$compareName]['file'];
104
+ $line = $this->foundClasses[$compareName]['line'];
105
+ $error = 'Duplicate %s name "%s" found; first defined in %s on line %s';
106
+ $data = array(
107
+ $type,
108
+ $name,
109
+ $file,
110
+ $line,
111
+ );
112
+ $phpcsFile->addWarning($error, $stackPtr, 'Found', $data);
113
+ } else {
114
+ $this->foundClasses[$compareName] = array(
115
+ 'file' => $phpcsFile->getFilename(),
116
+ 'line' => $tokens[$stackPtr]['line'],
117
+ );
118
+ }
119
+ }//end if
120
+
121
+ $stackPtr = $phpcsFile->findNext($findTokens, ($stackPtr + 1));
122
+ }//end while
123
+
124
+ }//end process()
125
+
126
+
127
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/EmptyStatementSniff.php ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of the CodeAnalysis add-on for PHP_CodeSniffer.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Manuel Pichler <mapi@manuel-pichler.de>
10
+ * @author Greg Sherwood <gsherwood@squiz.net>
11
+ * @copyright 2007-2014 Manuel Pichler. All rights reserved.
12
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
13
+ * @link http://pear.php.net/package/PHP_CodeSniffer
14
+ */
15
+
16
+ /**
17
+ * This sniff class detected empty statement.
18
+ *
19
+ * This sniff implements the common algorithm for empty statement body detection.
20
+ * A body is considered as empty if it is completely empty or it only contains
21
+ * whitespace characters and/or comments.
22
+ *
23
+ * <code>
24
+ * stmt {
25
+ * // foo
26
+ * }
27
+ * stmt (conditions) {
28
+ * // foo
29
+ * }
30
+ * </code>
31
+ *
32
+ * @category PHP
33
+ * @package PHP_CodeSniffer
34
+ * @author Manuel Pichler <mapi@manuel-pichler.de>
35
+ * @author Greg Sherwood <gsherwood@squiz.net>
36
+ * @copyright 2007-2014 Manuel Pichler. All rights reserved.
37
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
38
+ * @version Release: @package_version@
39
+ * @link http://pear.php.net/package/PHP_CodeSniffer
40
+ */
41
+ class Generic_Sniffs_CodeAnalysis_EmptyStatementSniff implements PHP_CodeSniffer_Sniff
42
+ {
43
+
44
+
45
+ /**
46
+ * Registers the tokens that this sniff wants to listen for.
47
+ *
48
+ * @return int[]
49
+ */
50
+ public function register()
51
+ {
52
+ return array(
53
+ T_CATCH,
54
+ T_DO,
55
+ T_ELSE,
56
+ T_ELSEIF,
57
+ T_FOR,
58
+ T_FOREACH,
59
+ T_IF,
60
+ T_SWITCH,
61
+ T_TRY,
62
+ T_WHILE,
63
+ );
64
+
65
+ }//end register()
66
+
67
+
68
+ /**
69
+ * Processes this test, when one of its tokens is encountered.
70
+ *
71
+ * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
72
+ * @param int $stackPtr The position of the current token
73
+ * in the stack passed in $tokens.
74
+ *
75
+ * @return void
76
+ */
77
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
78
+ {
79
+ $tokens = $phpcsFile->getTokens();
80
+ $token = $tokens[$stackPtr];
81
+
82
+ // Skip statements without a body.
83
+ if (isset($token['scope_opener']) === false) {
84
+ return;
85
+ }
86
+
87
+ $next = $phpcsFile->findNext(
88
+ PHP_CodeSniffer_Tokens::$emptyTokens,
89
+ ($token['scope_opener'] + 1),
90
+ ($token['scope_closer'] - 1),
91
+ true
92
+ );
93
+
94
+ if ($next !== false) {
95
+ return;
96
+ }
97
+
98
+ // Get token identifier.
99
+ $name = strtoupper($token['content']);
100
+ $error = 'Empty %s statement detected';
101
+ $phpcsFile->addError($error, $stackPtr, 'Detected'.$name, array($name));
102
+
103
+ }//end process()
104
+
105
+
106
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/ForLoopShouldBeWhileLoopSniff.php ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of the CodeAnalysis add-on for PHP_CodeSniffer.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Greg Sherwood <gsherwood@squiz.net>
10
+ * @author Manuel Pichler <mapi@manuel-pichler.de>
11
+ * @copyright 2007-2014 Manuel Pichler. All rights reserved.
12
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
13
+ * @link http://pear.php.net/package/PHP_CodeSniffer
14
+ */
15
+
16
+ /**
17
+ * Detects for-loops that can be simplified to a while-loop.
18
+ *
19
+ * This rule is based on the PMD rule catalog. Detects for-loops that can be
20
+ * simplified as a while-loop.
21
+ *
22
+ * <code>
23
+ * class Foo
24
+ * {
25
+ * public function bar($x)
26
+ * {
27
+ * for (;true;) true; // No Init or Update part, may as well be: while (true)
28
+ * }
29
+ * }
30
+ * </code>
31
+ *
32
+ * @category PHP
33
+ * @package PHP_CodeSniffer
34
+ * @author Manuel Pichler <mapi@manuel-pichler.de>
35
+ * @copyright 2007-2014 Manuel Pichler. All rights reserved.
36
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
37
+ * @version Release: @package_version@
38
+ * @link http://pear.php.net/package/PHP_CodeSniffer
39
+ */
40
+ class Generic_Sniffs_CodeAnalysis_ForLoopShouldBeWhileLoopSniff implements PHP_CodeSniffer_Sniff
41
+ {
42
+
43
+
44
+ /**
45
+ * Registers the tokens that this sniff wants to listen for.
46
+ *
47
+ * @return int[]
48
+ */
49
+ public function register()
50
+ {
51
+ return array(T_FOR);
52
+
53
+ }//end register()
54
+
55
+
56
+ /**
57
+ * Processes this test, when one of its tokens is encountered.
58
+ *
59
+ * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
60
+ * @param int $stackPtr The position of the current token
61
+ * in the stack passed in $tokens.
62
+ *
63
+ * @return void
64
+ */
65
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
66
+ {
67
+ $tokens = $phpcsFile->getTokens();
68
+ $token = $tokens[$stackPtr];
69
+
70
+ // Skip invalid statement.
71
+ if (isset($token['parenthesis_opener']) === false) {
72
+ return;
73
+ }
74
+
75
+ $next = ++$token['parenthesis_opener'];
76
+ $end = --$token['parenthesis_closer'];
77
+
78
+ $parts = array(
79
+ 0,
80
+ 0,
81
+ 0,
82
+ );
83
+ $index = 0;
84
+
85
+ for (; $next <= $end; ++$next) {
86
+ $code = $tokens[$next]['code'];
87
+ if ($code === T_SEMICOLON) {
88
+ ++$index;
89
+ } else if (isset(PHP_CodeSniffer_Tokens::$emptyTokens[$code]) === false) {
90
+ ++$parts[$index];
91
+ }
92
+ }
93
+
94
+ if ($parts[0] === 0 && $parts[2] === 0 && $parts[1] > 0) {
95
+ $error = 'This FOR loop can be simplified to a WHILE loop';
96
+ $phpcsFile->addWarning($error, $stackPtr, 'CanSimplify');
97
+ }
98
+
99
+ }//end process()
100
+
101
+
102
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/ForLoopWithTestFunctionCallSniff.php ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of the CodeAnalysis add-on for PHP_CodeSniffer.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Greg Sherwood <gsherwood@squiz.net>
10
+ * @author Manuel Pichler <mapi@manuel-pichler.de>
11
+ * @copyright 2007-2014 Manuel Pichler. All rights reserved.
12
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
13
+ * @link http://pear.php.net/package/PHP_CodeSniffer
14
+ */
15
+
16
+ /**
17
+ * Detects for-loops that use a function call in the test expression.
18
+ *
19
+ * This rule is based on the PMD rule catalog. Detects for-loops that use a
20
+ * function call in the test expression.
21
+ *
22
+ * <code>
23
+ * class Foo
24
+ * {
25
+ * public function bar($x)
26
+ * {
27
+ * $a = array(1, 2, 3, 4);
28
+ * for ($i = 0; $i < count($a); $i++) {
29
+ * $a[$i] *= $i;
30
+ * }
31
+ * }
32
+ * }
33
+ * </code>
34
+ *
35
+ * @category PHP
36
+ * @package PHP_CodeSniffer
37
+ * @author Manuel Pichler <mapi@manuel-pichler.de>
38
+ * @copyright 2007-2014 Manuel Pichler. All rights reserved.
39
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
40
+ * @version Release: @package_version@
41
+ * @link http://pear.php.net/package/PHP_CodeSniffer
42
+ */
43
+ class Generic_Sniffs_CodeAnalysis_ForLoopWithTestFunctionCallSniff implements PHP_CodeSniffer_Sniff
44
+ {
45
+
46
+
47
+ /**
48
+ * Registers the tokens that this sniff wants to listen for.
49
+ *
50
+ * @return int[]
51
+ */
52
+ public function register()
53
+ {
54
+ return array(T_FOR);
55
+
56
+ }//end register()
57
+
58
+
59
+ /**
60
+ * Processes this test, when one of its tokens is encountered.
61
+ *
62
+ * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
63
+ * @param int $stackPtr The position of the current token
64
+ * in the stack passed in $tokens.
65
+ *
66
+ * @return void
67
+ */
68
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
69
+ {
70
+ $tokens = $phpcsFile->getTokens();
71
+ $token = $tokens[$stackPtr];
72
+
73
+ // Skip invalid statement.
74
+ if (isset($token['parenthesis_opener']) === false) {
75
+ return;
76
+ }
77
+
78
+ $next = ++$token['parenthesis_opener'];
79
+ $end = --$token['parenthesis_closer'];
80
+
81
+ $position = 0;
82
+
83
+ for (; $next <= $end; ++$next) {
84
+ $code = $tokens[$next]['code'];
85
+ if ($code === T_SEMICOLON) {
86
+ ++$position;
87
+ }
88
+
89
+ if ($position < 1) {
90
+ continue;
91
+ } else if ($position > 1) {
92
+ break;
93
+ } else if ($code !== T_VARIABLE && $code !== T_STRING) {
94
+ continue;
95
+ }
96
+
97
+ // Find next non empty token, if it is a open curly brace we have a
98
+ // function call.
99
+ $index = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, ($next + 1), null, true);
100
+
101
+ if ($tokens[$index]['code'] === T_OPEN_PARENTHESIS) {
102
+ $error = 'Avoid function calls in a FOR loop test part';
103
+ $phpcsFile->addWarning($error, $stackPtr, 'NotAllowed');
104
+ break;
105
+ }
106
+ }//end for
107
+
108
+ }//end process()
109
+
110
+
111
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/JumbledIncrementerSniff.php ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of the CodeAnalysis add-on for PHP_CodeSniffer.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Greg Sherwood <gsherwood@squiz.net>
10
+ * @author Manuel Pichler <mapi@manuel-pichler.de>
11
+ * @copyright 2007-2014 Manuel Pichler. All rights reserved.
12
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
13
+ * @link http://pear.php.net/package/PHP_CodeSniffer
14
+ */
15
+
16
+ /**
17
+ * Detects incrementer jumbling in for loops.
18
+ *
19
+ * This rule is based on the PMD rule catalog. The jumbling incrementer sniff
20
+ * detects the usage of one and the same incrementer into an outer and an inner
21
+ * loop. Even it is intended this is confusing code.
22
+ *
23
+ * <code>
24
+ * class Foo
25
+ * {
26
+ * public function bar($x)
27
+ * {
28
+ * for ($i = 0; $i < 10; $i++)
29
+ * {
30
+ * for ($k = 0; $k < 20; $i++)
31
+ * {
32
+ * echo 'Hello';
33
+ * }
34
+ * }
35
+ * }
36
+ * }
37
+ * </code>
38
+ *
39
+ * @category PHP
40
+ * @package PHP_CodeSniffer
41
+ * @author Manuel Pichler <mapi@manuel-pichler.de>
42
+ * @copyright 2007-2014 Manuel Pichler. All rights reserved.
43
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
44
+ * @version Release: @package_version@
45
+ * @link http://pear.php.net/package/PHP_CodeSniffer
46
+ */
47
+ class Generic_Sniffs_CodeAnalysis_JumbledIncrementerSniff implements PHP_CodeSniffer_Sniff
48
+ {
49
+
50
+
51
+ /**
52
+ * Registers the tokens that this sniff wants to listen for.
53
+ *
54
+ * @return int[]
55
+ */
56
+ public function register()
57
+ {
58
+ return array(T_FOR);
59
+
60
+ }//end register()
61
+
62
+
63
+ /**
64
+ * Processes this test, when one of its tokens is encountered.
65
+ *
66
+ * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
67
+ * @param int $stackPtr The position of the current token
68
+ * in the stack passed in $tokens.
69
+ *
70
+ * @return void
71
+ */
72
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
73
+ {
74
+ $tokens = $phpcsFile->getTokens();
75
+ $token = $tokens[$stackPtr];
76
+
77
+ // Skip for-loop without body.
78
+ if (isset($token['scope_opener']) === false) {
79
+ return;
80
+ }
81
+
82
+ // Find incrementors for outer loop.
83
+ $outer = $this->findIncrementers($tokens, $token);
84
+
85
+ // Skip if empty.
86
+ if (count($outer) === 0) {
87
+ return;
88
+ }
89
+
90
+ // Find nested for loops.
91
+ $start = ++$token['scope_opener'];
92
+ $end = --$token['scope_closer'];
93
+
94
+ for (; $start <= $end; ++$start) {
95
+ if ($tokens[$start]['code'] !== T_FOR) {
96
+ continue;
97
+ }
98
+
99
+ $inner = $this->findIncrementers($tokens, $tokens[$start]);
100
+ $diff = array_intersect($outer, $inner);
101
+
102
+ if (count($diff) !== 0) {
103
+ $error = 'Loop incrementor (%s) jumbling with inner loop';
104
+ $data = array(join(', ', $diff));
105
+ $phpcsFile->addWarning($error, $stackPtr, 'Found', $data);
106
+ }
107
+ }
108
+
109
+ }//end process()
110
+
111
+
112
+ /**
113
+ * Get all used variables in the incrementer part of a for statement.
114
+ *
115
+ * @param array(integer=>array) $tokens Array with all code sniffer tokens.
116
+ * @param array(string=>mixed) $token Current for loop token
117
+ *
118
+ * @return string[] List of all found incrementer variables.
119
+ */
120
+ protected function findIncrementers(array $tokens, array $token)
121
+ {
122
+ // Skip invalid statement.
123
+ if (isset($token['parenthesis_opener']) === false) {
124
+ return array();
125
+ }
126
+
127
+ $start = ++$token['parenthesis_opener'];
128
+ $end = --$token['parenthesis_closer'];
129
+
130
+ $incrementers = array();
131
+ $semicolons = 0;
132
+ for ($next = $start; $next <= $end; ++$next) {
133
+ $code = $tokens[$next]['code'];
134
+ if ($code === T_SEMICOLON) {
135
+ ++$semicolons;
136
+ } else if ($semicolons === 2 && $code === T_VARIABLE) {
137
+ $incrementers[] = $tokens[$next]['content'];
138
+ }
139
+ }
140
+
141
+ return $incrementers;
142
+
143
+ }//end findIncrementers()
144
+
145
+
146
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/UnconditionalIfStatementSniff.php ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of the CodeAnalysis add-on for PHP_CodeSniffer.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Greg Sherwood <gsherwood@squiz.net>
10
+ * @author Manuel Pichler <mapi@manuel-pichler.de>
11
+ * @copyright 2007-2014 Manuel Pichler. All rights reserved.
12
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
13
+ * @link http://pear.php.net/package/PHP_CodeSniffer
14
+ */
15
+
16
+ /**
17
+ * Detects unconditional if- and elseif-statements.
18
+ *
19
+ * This rule is based on the PMD rule catalog. The Unconditional If Statement
20
+ * sniff detects statement conditions that are only set to one of the constant
21
+ * values <b>true</b> or <b>false</b>
22
+ *
23
+ * <code>
24
+ * class Foo
25
+ * {
26
+ * public function close()
27
+ * {
28
+ * if (true)
29
+ * {
30
+ * // ...
31
+ * }
32
+ * }
33
+ * }
34
+ * </code>
35
+ *
36
+ * @category PHP
37
+ * @package PHP_CodeSniffer
38
+ * @author Manuel Pichler <mapi@manuel-pichler.de>
39
+ * @copyright 2007-2014 Manuel Pichler. All rights reserved.
40
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
41
+ * @version Release: @package_version@
42
+ * @link http://pear.php.net/package/PHP_CodeSniffer
43
+ */
44
+ class Generic_Sniffs_CodeAnalysis_UnconditionalIfStatementSniff implements PHP_CodeSniffer_Sniff
45
+ {
46
+
47
+
48
+ /**
49
+ * Registers the tokens that this sniff wants to listen for.
50
+ *
51
+ * @return int[]
52
+ */
53
+ public function register()
54
+ {
55
+ return array(
56
+ T_IF,
57
+ T_ELSEIF,
58
+ );
59
+
60
+ }//end register()
61
+
62
+
63
+ /**
64
+ * Processes this test, when one of its tokens is encountered.
65
+ *
66
+ * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
67
+ * @param int $stackPtr The position of the current token
68
+ * in the stack passed in $tokens.
69
+ *
70
+ * @return void
71
+ */
72
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
73
+ {
74
+ $tokens = $phpcsFile->getTokens();
75
+ $token = $tokens[$stackPtr];
76
+
77
+ // Skip for-loop without body.
78
+ if (isset($token['parenthesis_opener']) === false) {
79
+ return;
80
+ }
81
+
82
+ $next = ++$token['parenthesis_opener'];
83
+ $end = --$token['parenthesis_closer'];
84
+
85
+ $goodCondition = false;
86
+ for (; $next <= $end; ++$next) {
87
+ $code = $tokens[$next]['code'];
88
+
89
+ if (isset(PHP_CodeSniffer_Tokens::$emptyTokens[$code]) === true) {
90
+ continue;
91
+ } else if ($code !== T_TRUE && $code !== T_FALSE) {
92
+ $goodCondition = true;
93
+ }
94
+ }
95
+
96
+ if ($goodCondition === false) {
97
+ $error = 'Avoid IF statements that are always true or false';
98
+ $phpcsFile->addWarning($error, $stackPtr, 'Found');
99
+ }
100
+
101
+ }//end process()
102
+
103
+
104
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/UnnecessaryFinalModifierSniff.php ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of the CodeAnalysis add-on for PHP_CodeSniffer.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Greg Sherwood <gsherwood@squiz.net>
10
+ * @author Manuel Pichler <mapi@manuel-pichler.de>
11
+ * @copyright 2007-2014 Manuel Pichler. All rights reserved.
12
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
13
+ * @link http://pear.php.net/package/PHP_CodeSniffer
14
+ */
15
+
16
+ /**
17
+ * Detects unnecessary final modifiers inside of final classes.
18
+ *
19
+ * This rule is based on the PMD rule catalog. The Unnecessary Final Modifier
20
+ * sniff detects the use of the final modifier inside of a final class which
21
+ * is unnecessary.
22
+ *
23
+ * <code>
24
+ * final class Foo
25
+ * {
26
+ * public final function bar()
27
+ * {
28
+ * }
29
+ * }
30
+ * </code>
31
+ *
32
+ * @category PHP
33
+ * @package PHP_CodeSniffer
34
+ * @author Manuel Pichler <mapi@manuel-pichler.de>
35
+ * @copyright 2007-2014 Manuel Pichler. All rights reserved.
36
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
37
+ * @version Release: @package_version@
38
+ * @link http://pear.php.net/package/PHP_CodeSniffer
39
+ */
40
+ class Generic_Sniffs_CodeAnalysis_UnnecessaryFinalModifierSniff implements PHP_CodeSniffer_Sniff
41
+ {
42
+
43
+
44
+ /**
45
+ * Registers the tokens that this sniff wants to listen for.
46
+ *
47
+ * @return int[]
48
+ */
49
+ public function register()
50
+ {
51
+ return array(T_CLASS);
52
+
53
+ }//end register()
54
+
55
+
56
+ /**
57
+ * Processes this test, when one of its tokens is encountered.
58
+ *
59
+ * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
60
+ * @param int $stackPtr The position of the current token
61
+ * in the stack passed in $tokens.
62
+ *
63
+ * @return void
64
+ */
65
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
66
+ {
67
+ $tokens = $phpcsFile->getTokens();
68
+ $token = $tokens[$stackPtr];
69
+
70
+ // Skip for-statements without body.
71
+ if (isset($token['scope_opener']) === false) {
72
+ return;
73
+ }
74
+
75
+ // Fetch previous token.
76
+ $prev = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, ($stackPtr - 1), null, true);
77
+
78
+ // Skip for non final class.
79
+ if ($prev === false || $tokens[$prev]['code'] !== T_FINAL) {
80
+ return;
81
+ }
82
+
83
+ $next = ++$token['scope_opener'];
84
+ $end = --$token['scope_closer'];
85
+
86
+ for (; $next <= $end; ++$next) {
87
+ if ($tokens[$next]['code'] === T_FINAL) {
88
+ $error = 'Unnecessary FINAL modifier in FINAL class';
89
+ $phpcsFile->addWarning($error, $next, 'Found');
90
+ }
91
+ }
92
+
93
+ }//end process()
94
+
95
+
96
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/UnusedFunctionParameterSniff.php ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of the CodeAnalysis add-on for PHP_CodeSniffer.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Greg Sherwood <gsherwood@squiz.net>
10
+ * @author Manuel Pichler <mapi@manuel-pichler.de>
11
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
12
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
13
+ * @link http://pear.php.net/package/PHP_CodeSniffer
14
+ */
15
+
16
+ /**
17
+ * Checks the for unused function parameters.
18
+ *
19
+ * This sniff checks that all function parameters are used in the function body.
20
+ * One exception is made for empty function bodies or function bodies that only
21
+ * contain comments. This could be useful for the classes that implement an
22
+ * interface that defines multiple methods but the implementation only needs some
23
+ * of them.
24
+ *
25
+ * @category PHP
26
+ * @package PHP_CodeSniffer
27
+ * @author Manuel Pichler <mapi@manuel-pichler.de>
28
+ * @author Greg Sherwood <gsherwood@squiz.net>
29
+ * @copyright 2007-2014 Manuel Pichler. All rights reserved.
30
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
31
+ * @version Release: @package_version@
32
+ * @link http://pear.php.net/package/PHP_CodeSniffer
33
+ */
34
+ class Generic_Sniffs_CodeAnalysis_UnusedFunctionParameterSniff implements PHP_CodeSniffer_Sniff
35
+ {
36
+
37
+
38
+ /**
39
+ * Returns an array of tokens this test wants to listen for.
40
+ *
41
+ * @return array
42
+ */
43
+ public function register()
44
+ {
45
+ return array(T_FUNCTION);
46
+
47
+ }//end register()
48
+
49
+
50
+ /**
51
+ * Processes this test, when one of its tokens is encountered.
52
+ *
53
+ * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
54
+ * @param int $stackPtr The position of the current token
55
+ * in the stack passed in $tokens.
56
+ *
57
+ * @return void
58
+ */
59
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
60
+ {
61
+ $tokens = $phpcsFile->getTokens();
62
+ $token = $tokens[$stackPtr];
63
+
64
+ // Skip broken function declarations.
65
+ if (isset($token['scope_opener']) === false || isset($token['parenthesis_opener']) === false) {
66
+ return;
67
+ }
68
+
69
+ $params = array();
70
+ foreach ($phpcsFile->getMethodParameters($stackPtr) as $param) {
71
+ $params[$param['name']] = $stackPtr;
72
+ }
73
+
74
+ $next = ++$token['scope_opener'];
75
+ $end = --$token['scope_closer'];
76
+
77
+ $foundContent = false;
78
+ $validTokens = array(
79
+ T_HEREDOC => T_HEREDOC,
80
+ T_NOWDOC => T_NOWDOC,
81
+ T_END_HEREDOC => T_END_HEREDOC,
82
+ T_END_NOWDOC => T_END_NOWDOC,
83
+ T_DOUBLE_QUOTED_STRING => T_DOUBLE_QUOTED_STRING,
84
+ );
85
+ $validTokens += PHP_CodeSniffer_Tokens::$emptyTokens;
86
+
87
+ for (; $next <= $end; ++$next) {
88
+ $token = $tokens[$next];
89
+ $code = $token['code'];
90
+
91
+ // Ignorable tokens.
92
+ if (isset(PHP_CodeSniffer_Tokens::$emptyTokens[$code]) === true) {
93
+ continue;
94
+ }
95
+
96
+ if ($foundContent === false) {
97
+ // A throw statement as the first content indicates an interface method.
98
+ if ($code === T_THROW) {
99
+ return;
100
+ }
101
+
102
+ // A return statement as the first content indicates an interface method.
103
+ if ($code === T_RETURN) {
104
+ $tmp = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, ($next + 1), null, true);
105
+ if ($tmp === false) {
106
+ return;
107
+ }
108
+
109
+ // There is a return.
110
+ if ($tokens[$tmp]['code'] === T_SEMICOLON) {
111
+ return;
112
+ }
113
+
114
+ $tmp = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, ($tmp + 1), null, true);
115
+ if ($tmp !== false && $tokens[$tmp]['code'] === T_SEMICOLON) {
116
+ // There is a return <token>.
117
+ return;
118
+ }
119
+ }//end if
120
+ }//end if
121
+
122
+ $foundContent = true;
123
+
124
+ if ($code === T_VARIABLE && isset($params[$token['content']]) === true) {
125
+ unset($params[$token['content']]);
126
+ } else if ($code === T_DOLLAR) {
127
+ $nextToken = $phpcsFile->findNext(T_WHITESPACE, ($next + 1), null, true);
128
+ if ($tokens[$nextToken]['code'] === T_OPEN_CURLY_BRACKET) {
129
+ $nextToken = $phpcsFile->findNext(T_WHITESPACE, ($nextToken + 1), null, true);
130
+ if ($tokens[$nextToken]['code'] === T_STRING) {
131
+ $varContent = '$'.$tokens[$nextToken]['content'];
132
+ if (isset($params[$varContent]) === true) {
133
+ unset($params[$varContent]);
134
+ }
135
+ }
136
+ }
137
+ } else if ($code === T_DOUBLE_QUOTED_STRING
138
+ || $code === T_START_HEREDOC
139
+ || $code === T_START_NOWDOC
140
+ ) {
141
+ // Tokenize strings that can contain variables.
142
+ // Make sure the string is re-joined if it occurs over multiple lines.
143
+ $content = $token['content'];
144
+ for ($i = ($next + 1); $i <= $end; $i++) {
145
+ if (isset($validTokens[$tokens[$i]['code']]) === true) {
146
+ $content .= $tokens[$i]['content'];
147
+ $next++;
148
+ } else {
149
+ break;
150
+ }
151
+ }
152
+
153
+ $stringTokens = token_get_all(sprintf('<?php %s;?>', $content));
154
+ foreach ($stringTokens as $stringPtr => $stringToken) {
155
+ if (is_array($stringToken) === false) {
156
+ continue;
157
+ }
158
+
159
+ $varContent = '';
160
+ if ($stringToken[0] === T_DOLLAR_OPEN_CURLY_BRACES) {
161
+ $varContent = '$'.$stringTokens[($stringPtr + 1)][1];
162
+ } else if ($stringToken[0] === T_VARIABLE) {
163
+ $varContent = $stringToken[1];
164
+ }
165
+
166
+ if ($varContent !== '' && isset($params[$varContent]) === true) {
167
+ unset($params[$varContent]);
168
+ }
169
+ }
170
+ }//end if
171
+ }//end for
172
+
173
+ if ($foundContent === true && count($params) > 0) {
174
+ foreach ($params as $paramName => $position) {
175
+ $error = 'The method parameter %s is never used';
176
+ $data = array($paramName);
177
+ $phpcsFile->addWarning($error, $position, 'Found', $data);
178
+ }
179
+ }
180
+
181
+ }//end process()
182
+
183
+
184
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/UselessOverridingMethodSniff.php ADDED
@@ -0,0 +1,178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This file is part of the CodeAnalysis add-on for PHP_CodeSniffer.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Greg Sherwood <gsherwood@squiz.net>
10
+ * @author Manuel Pichler <mapi@manuel-pichler.de>
11
+ * @copyright 2007-2014 Manuel Pichler. All rights reserved.
12
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
13
+ * @link http://pear.php.net/package/PHP_CodeSniffer
14
+ */
15
+
16
+ /**
17
+ * Detects unnecessary overridden methods that simply call their parent.
18
+ *
19
+ * This rule is based on the PMD rule catalog. The Useless Overriding Method
20
+ * sniff detects the use of methods that only call their parent classes's method
21
+ * with the same name and arguments. These methods are not required.
22
+ *
23
+ * <code>
24
+ * class FooBar {
25
+ * public function __construct($a, $b) {
26
+ * parent::__construct($a, $b);
27
+ * }
28
+ * }
29
+ * </code>
30
+ *
31
+ * @category PHP
32
+ * @package PHP_CodeSniffer
33
+ * @author Manuel Pichler <mapi@manuel-pichler.de>
34
+ * @copyright 2007-2014 Manuel Pichler. All rights reserved.
35
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
36
+ * @version Release: @package_version@
37
+ * @link http://pear.php.net/package/PHP_CodeSniffer
38
+ */
39
+ class Generic_Sniffs_CodeAnalysis_UselessOverridingMethodSniff implements PHP_CodeSniffer_Sniff
40
+ {
41
+
42
+
43
+ /**
44
+ * Registers the tokens that this sniff wants to listen for.
45
+ *
46
+ * @return int[]
47
+ */
48
+ public function register()
49
+ {
50
+ return array(T_FUNCTION);
51
+
52
+ }//end register()
53
+
54
+
55
+ /**
56
+ * Processes this test, when one of its tokens is encountered.
57
+ *
58
+ * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
59
+ * @param int $stackPtr The position of the current token
60
+ * in the stack passed in $tokens.
61
+ *
62
+ * @return void
63
+ */
64
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
65
+ {
66
+ $tokens = $phpcsFile->getTokens();
67
+ $token = $tokens[$stackPtr];
68
+
69
+ // Skip function without body.
70
+ if (isset($token['scope_opener']) === false) {
71
+ return;
72
+ }
73
+
74
+ // Get function name.
75
+ $methodName = $phpcsFile->getDeclarationName($stackPtr);
76
+
77
+ // Get all parameters from method signature.
78
+ $signature = array();
79
+ foreach ($phpcsFile->getMethodParameters($stackPtr) as $param) {
80
+ $signature[] = $param['name'];
81
+ }
82
+
83
+ $next = ++$token['scope_opener'];
84
+ $end = --$token['scope_closer'];
85
+
86
+ for (; $next <= $end; ++$next) {
87
+ $code = $tokens[$next]['code'];
88
+
89
+ if (isset(PHP_CodeSniffer_Tokens::$emptyTokens[$code]) === true) {
90
+ continue;
91
+ } else if ($code === T_RETURN) {
92
+ continue;
93
+ }
94
+
95
+ break;
96
+ }
97
+
98
+ // Any token except 'parent' indicates correct code.
99
+ if ($tokens[$next]['code'] !== T_PARENT) {
100
+ return;
101
+ }
102
+
103
+ // Find next non empty token index, should be double colon.
104
+ $next = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, ($next + 1), null, true);
105
+
106
+ // Skip for invalid code.
107
+ if ($next === false || $tokens[$next]['code'] !== T_DOUBLE_COLON) {
108
+ return;
109
+ }
110
+
111
+ // Find next non empty token index, should be the function name.
112
+ $next = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, ($next + 1), null, true);
113
+
114
+ // Skip for invalid code or other method.
115
+ if ($next === false || $tokens[$next]['content'] !== $methodName) {
116
+ return;
117
+ }
118
+
119
+ // Find next non empty token index, should be the open parenthesis.
120
+ $next = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, ($next + 1), null, true);
121
+
122
+ // Skip for invalid code.
123
+ if ($next === false || $tokens[$next]['code'] !== T_OPEN_PARENTHESIS) {
124
+ return;
125
+ }
126
+
127
+ $validParameterTypes = array(
128
+ T_VARIABLE,
129
+ T_LNUMBER,
130
+ T_CONSTANT_ENCAPSED_STRING,
131
+ );
132
+
133
+ $parameters = array('');
134
+ $parenthesisCount = 1;
135
+ $count = count($tokens);
136
+ for (++$next; $next < $count; ++$next) {
137
+ $code = $tokens[$next]['code'];
138
+
139
+ if ($code === T_OPEN_PARENTHESIS) {
140
+ ++$parenthesisCount;
141
+ } else if ($code === T_CLOSE_PARENTHESIS) {
142
+ --$parenthesisCount;
143
+ } else if ($parenthesisCount === 1 && $code === T_COMMA) {
144
+ $parameters[] = '';
145
+ } else if (isset(PHP_CodeSniffer_Tokens::$emptyTokens[$code]) === false) {
146
+ $parameters[(count($parameters) - 1)] .= $tokens[$next]['content'];
147
+ }
148
+
149
+ if ($parenthesisCount === 0) {
150
+ break;
151
+ }
152
+ }//end for
153
+
154
+ $next = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, ($next + 1), null, true);
155
+ if ($next === false || $tokens[$next]['code'] !== T_SEMICOLON) {
156
+ return;
157
+ }
158
+
159
+ // Check rest of the scope.
160
+ for (++$next; $next <= $end; ++$next) {
161
+ $code = $tokens[$next]['code'];
162
+ // Skip for any other content.
163
+ if (isset(PHP_CodeSniffer_Tokens::$emptyTokens[$code]) === false) {
164
+ return;
165
+ }
166
+ }
167
+
168
+ $parameters = array_map('trim', $parameters);
169
+ $parameters = array_filter($parameters);
170
+
171
+ if (count($parameters) === count($signature) && $parameters === $signature) {
172
+ $phpcsFile->addWarning('Possible useless method overriding detected', $stackPtr, 'Found');
173
+ }
174
+
175
+ }//end process()
176
+
177
+
178
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Commenting/DocCommentSniff.php ADDED
@@ -0,0 +1,350 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Ensures doc blocks follow basic formatting.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Greg Sherwood <gsherwood@squiz.net>
10
+ * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600)
11
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
12
+ * @link http://pear.php.net/package/PHP_CodeSniffer
13
+ */
14
+
15
+ /**
16
+ * Ensures doc blocks follow basic formatting.
17
+ *
18
+ * @category PHP
19
+ * @package PHP_CodeSniffer
20
+ * @author Greg Sherwood <gsherwood@squiz.net>
21
+ * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600)
22
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
23
+ * @version Release: @package_version@
24
+ * @link http://pear.php.net/package/PHP_CodeSniffer
25
+ */
26
+ class Generic_Sniffs_Commenting_DocCommentSniff implements PHP_CodeSniffer_Sniff
27
+ {
28
+
29
+ /**
30
+ * A list of tokenizers this sniff supports.
31
+ *
32
+ * @var array
33
+ */
34
+ public $supportedTokenizers = array(
35
+ 'PHP',
36
+ 'JS',
37
+ );
38
+
39
+
40
+ /**
41
+ * Returns an array of tokens this test wants to listen for.
42
+ *
43
+ * @return array
44
+ */
45
+ public function register()
46
+ {
47
+ return array(T_DOC_COMMENT_OPEN_TAG);
48
+
49
+ }//end register()
50
+
51
+
52
+ /**
53
+ * Processes this test, when one of its tokens is encountered.
54
+ *
55
+ * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
56
+ * @param int $stackPtr The position of the current token
57
+ * in the stack passed in $tokens.
58
+ *
59
+ * @return void
60
+ */
61
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
62
+ {
63
+ $tokens = $phpcsFile->getTokens();
64
+ $commentStart = $stackPtr;
65
+ $commentEnd = $tokens[$stackPtr]['comment_closer'];
66
+
67
+ $empty = array(
68
+ T_DOC_COMMENT_WHITESPACE,
69
+ T_DOC_COMMENT_STAR,
70
+ );
71
+
72
+ $short = $phpcsFile->findNext($empty, ($stackPtr + 1), $commentEnd, true);
73
+ if ($short === false) {
74
+ // No content at all.
75
+ $error = 'Doc comment is empty';
76
+ $phpcsFile->addError($error, $stackPtr, 'Empty');
77
+ return;
78
+ }
79
+
80
+ // The first line of the comment should just be the /** code.
81
+ if ($tokens[$short]['line'] === $tokens[$stackPtr]['line']) {
82
+ $error = 'The open comment tag must be the only content on the line';
83
+ $fix = $phpcsFile->addFixableError($error, $stackPtr, 'ContentAfterOpen');
84
+ if ($fix === true) {
85
+ $phpcsFile->fixer->beginChangeset();
86
+ $phpcsFile->fixer->addNewline($stackPtr);
87
+ $phpcsFile->fixer->addContentBefore($short, '* ');
88
+ $phpcsFile->fixer->endChangeset();
89
+ }
90
+ }
91
+
92
+ // The last line of the comment should just be the */ code.
93
+ $prev = $phpcsFile->findPrevious($empty, ($commentEnd - 1), $stackPtr, true);
94
+ if ($tokens[$prev]['line'] === $tokens[$commentEnd]['line']) {
95
+ $error = 'The close comment tag must be the only content on the line';
96
+ $fix = $phpcsFile->addFixableError($error, $commentEnd, 'ContentBeforeClose');
97
+ if ($fix === true) {
98
+ $phpcsFile->fixer->addNewlineBefore($commentEnd);
99
+ }
100
+ }
101
+
102
+ // Check for additional blank lines at the end of the comment.
103
+ if ($tokens[$prev]['line'] < ($tokens[$commentEnd]['line'] - 1)) {
104
+ $error = 'Additional blank lines found at end of doc comment';
105
+ $fix = $phpcsFile->addFixableError($error, $commentEnd, 'SpacingAfter');
106
+ if ($fix === true) {
107
+ $phpcsFile->fixer->beginChangeset();
108
+ for ($i = ($prev + 1); $i < $commentEnd; $i++) {
109
+ if ($tokens[($i + 1)]['line'] === $tokens[$commentEnd]['line']) {
110
+ break;
111
+ }
112
+
113
+ $phpcsFile->fixer->replaceToken($i, '');
114
+ }
115
+
116
+ $phpcsFile->fixer->endChangeset();
117
+ }
118
+ }
119
+
120
+ // Check for a comment description.
121
+ if ($tokens[$short]['code'] !== T_DOC_COMMENT_STRING) {
122
+ $error = 'Missing short description in doc comment';
123
+ $phpcsFile->addError($error, $stackPtr, 'MissingShort');
124
+ return;
125
+ }
126
+
127
+ // No extra newline before short description.
128
+ if ($tokens[$short]['line'] !== ($tokens[$stackPtr]['line'] + 1)) {
129
+ $error = 'Doc comment short description must be on the first line';
130
+ $fix = $phpcsFile->addFixableError($error, $short, 'SpacingBeforeShort');
131
+ if ($fix === true) {
132
+ $phpcsFile->fixer->beginChangeset();
133
+ for ($i = $stackPtr; $i < $short; $i++) {
134
+ if ($tokens[$i]['line'] === $tokens[$stackPtr]['line']) {
135
+ continue;
136
+ } else if ($tokens[$i]['line'] === $tokens[$short]['line']) {
137
+ break;
138
+ }
139
+
140
+ $phpcsFile->fixer->replaceToken($i, '');
141
+ }
142
+
143
+ $phpcsFile->fixer->endChangeset();
144
+ }
145
+ }
146
+
147
+ // Account for the fact that a short description might cover
148
+ // multiple lines.
149
+ $shortContent = $tokens[$short]['content'];
150
+ $shortEnd = $short;
151
+ for ($i = ($short + 1); $i < $commentEnd; $i++) {
152
+ if ($tokens[$i]['code'] === T_DOC_COMMENT_STRING) {
153
+ if ($tokens[$i]['line'] === ($tokens[$shortEnd]['line'] + 1)) {
154
+ $shortContent .= $tokens[$i]['content'];
155
+ $shortEnd = $i;
156
+ } else {
157
+ break;
158
+ }
159
+ }
160
+ }
161
+
162
+ if (preg_match('/^\p{Ll}/u', $shortContent) === 1) {
163
+ $error = 'Doc comment short description must start with a capital letter';
164
+ $phpcsFile->addError($error, $short, 'ShortNotCapital');
165
+ }
166
+
167
+ $long = $phpcsFile->findNext($empty, ($shortEnd + 1), ($commentEnd - 1), true);
168
+ if ($long !== false && $tokens[$long]['code'] === T_DOC_COMMENT_STRING) {
169
+ if ($tokens[$long]['line'] !== ($tokens[$shortEnd]['line'] + 2)) {
170
+ $error = 'There must be exactly one blank line between descriptions in a doc comment';
171
+ $fix = $phpcsFile->addFixableError($error, $long, 'SpacingBetween');
172
+ if ($fix === true) {
173
+ $phpcsFile->fixer->beginChangeset();
174
+ for ($i = ($shortEnd + 1); $i < $long; $i++) {
175
+ if ($tokens[$i]['line'] === $tokens[$shortEnd]['line']) {
176
+ continue;
177
+ } else if ($tokens[$i]['line'] === ($tokens[$long]['line'] - 1)) {
178
+ break;
179
+ }
180
+
181
+ $phpcsFile->fixer->replaceToken($i, '');
182
+ }
183
+
184
+ $phpcsFile->fixer->endChangeset();
185
+ }
186
+ }
187
+
188
+ if (preg_match('/^\p{Ll}/u', $tokens[$long]['content']) === 1) {
189
+ $error = 'Doc comment long description must start with a capital letter';
190
+ $phpcsFile->addError($error, $long, 'LongNotCapital');
191
+ }
192
+ }//end if
193
+
194
+ if (empty($tokens[$commentStart]['comment_tags']) === true) {
195
+ // No tags in the comment.
196
+ return;
197
+ }
198
+
199
+ $firstTag = $tokens[$commentStart]['comment_tags'][0];
200
+ $prev = $phpcsFile->findPrevious($empty, ($firstTag - 1), $stackPtr, true);
201
+ if ($tokens[$firstTag]['line'] !== ($tokens[$prev]['line'] + 2)) {
202
+ $error = 'There must be exactly one blank line before the tags in a doc comment';
203
+ $fix = $phpcsFile->addFixableError($error, $firstTag, 'SpacingBeforeTags');
204
+ if ($fix === true) {
205
+ $phpcsFile->fixer->beginChangeset();
206
+ for ($i = ($prev + 1); $i < $firstTag; $i++) {
207
+ if ($tokens[$i]['line'] === $tokens[$firstTag]['line']) {
208
+ break;
209
+ }
210
+
211
+ $phpcsFile->fixer->replaceToken($i, '');
212
+ }
213
+
214
+ $indent = str_repeat(' ', $tokens[$stackPtr]['column']);
215
+ $phpcsFile->fixer->addContent($prev, $phpcsFile->eolChar.$indent.'*'.$phpcsFile->eolChar);
216
+ $phpcsFile->fixer->endChangeset();
217
+ }
218
+ }
219
+
220
+ // Break out the tags into groups and check alignment within each.
221
+ // A tag group is one where there are no blank lines between tags.
222
+ // The param tag group is special as it requires all @param tags to be inside.
223
+ $tagGroups = array();
224
+ $groupid = 0;
225
+ $paramGroupid = null;
226
+ foreach ($tokens[$commentStart]['comment_tags'] as $pos => $tag) {
227
+ if ($pos > 0) {
228
+ $prev = $phpcsFile->findPrevious(
229
+ T_DOC_COMMENT_STRING,
230
+ ($tag - 1),
231
+ $tokens[$commentStart]['comment_tags'][($pos - 1)]
232
+ );
233
+
234
+ if ($prev === false) {
235
+ $prev = $tokens[$commentStart]['comment_tags'][($pos - 1)];
236
+ }
237
+
238
+ if ($tokens[$prev]['line'] !== ($tokens[$tag]['line'] - 1)) {
239
+ $groupid++;
240
+ }
241
+ }
242
+
243
+ if ($tokens[$tag]['content'] === '@param') {
244
+ if (($paramGroupid === null
245
+ && empty($tagGroups[$groupid]) === false)
246
+ || ($paramGroupid !== null
247
+ && $paramGroupid !== $groupid)
248
+ ) {
249
+ $error = 'Parameter tags must be grouped together in a doc comment';
250
+ $phpcsFile->addError($error, $tag, 'ParamGroup');
251
+ }
252
+
253
+ if ($paramGroupid === null) {
254
+ $paramGroupid = $groupid;
255
+ }
256
+ } else if ($groupid === $paramGroupid) {
257
+ $error = 'Tag cannot be grouped with parameter tags in a doc comment';
258
+ $phpcsFile->addError($error, $tag, 'NonParamGroup');
259
+ }//end if
260
+
261
+ $tagGroups[$groupid][] = $tag;
262
+ }//end foreach
263
+
264
+ foreach ($tagGroups as $group) {
265
+ $maxLength = 0;
266
+ $paddings = array();
267
+ foreach ($group as $pos => $tag) {
268
+ $tagLength = strlen($tokens[$tag]['content']);
269
+ if ($tagLength > $maxLength) {
270
+ $maxLength = $tagLength;
271
+ }
272
+
273
+ // Check for a value. No value means no padding needed.
274
+ $string = $phpcsFile->findNext(T_DOC_COMMENT_STRING, $tag, $commentEnd);
275
+ if ($string !== false && $tokens[$string]['line'] === $tokens[$tag]['line']) {
276
+ $paddings[$tag] = strlen($tokens[($tag + 1)]['content']);
277
+ }
278
+ }
279
+
280
+ // Check that there was single blank line after the tag block
281
+ // but account for a multi-line tag comments.
282
+ $lastTag = $group[$pos];
283
+ $next = $phpcsFile->findNext(T_DOC_COMMENT_TAG, ($lastTag + 3), $commentEnd);
284
+ if ($next !== false) {
285
+ $prev = $phpcsFile->findPrevious(array(T_DOC_COMMENT_TAG, T_DOC_COMMENT_STRING), ($next - 1), $commentStart);
286
+ if ($tokens[$next]['line'] !== ($tokens[$prev]['line'] + 2)) {
287
+ $error = 'There must be a single blank line after a tag group';
288
+ $fix = $phpcsFile->addFixableError($error, $lastTag, 'SpacingAfterTagGroup');
289
+ if ($fix === true) {
290
+ $phpcsFile->fixer->beginChangeset();
291
+ for ($i = ($prev + 1); $i < $next; $i++) {
292
+ if ($tokens[$i]['line'] === $tokens[$next]['line']) {
293
+ break;
294
+ }
295
+
296
+ $phpcsFile->fixer->replaceToken($i, '');
297
+ }
298
+
299
+ $indent = str_repeat(' ', $tokens[$stackPtr]['column']);
300
+ $phpcsFile->fixer->addContent($prev, $phpcsFile->eolChar.$indent.'*'.$phpcsFile->eolChar);
301
+ $phpcsFile->fixer->endChangeset();
302
+ }
303
+ }
304
+ }//end if
305
+
306
+ // Now check paddings.
307
+ foreach ($paddings as $tag => $padding) {
308
+ $required = ($maxLength - strlen($tokens[$tag]['content']) + 1);
309
+
310
+ if ($padding !== $required) {
311
+ $error = 'Tag value indented incorrectly; expected %s spaces but found %s';
312
+ $data = array(
313
+ $required,
314
+ $padding,
315
+ );
316
+
317
+ $fix = $phpcsFile->addFixableError($error, ($tag + 1), 'TagValueIndent', $data);
318
+ if ($fix === true) {
319
+ $phpcsFile->fixer->replaceToken(($tag + 1), str_repeat(' ', $required));
320
+ }
321
+ }
322
+ }
323
+ }//end foreach
324
+
325
+ // If there is a param group, it needs to be first.
326
+ if ($paramGroupid !== null && $paramGroupid !== 0) {
327
+ $error = 'Parameter tags must be defined first in a doc comment';
328
+ $phpcsFile->addError($error, $tagGroups[$paramGroupid][0], 'ParamNotFirst');
329
+ }
330
+
331
+ $foundTags = array();
332
+ foreach ($tokens[$stackPtr]['comment_tags'] as $pos => $tag) {
333
+ $tagName = $tokens[$tag]['content'];
334
+ if (isset($foundTags[$tagName]) === true) {
335
+ $lastTag = $tokens[$stackPtr]['comment_tags'][($pos - 1)];
336
+ if ($tokens[$lastTag]['content'] !== $tagName) {
337
+ $error = 'Tags must be grouped together in a doc comment';
338
+ $phpcsFile->addError($error, $tag, 'TagsNotGrouped');
339
+ }
340
+
341
+ continue;
342
+ }
343
+
344
+ $foundTags[$tagName] = true;
345
+ }
346
+
347
+ }//end process()
348
+
349
+
350
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Commenting/FixmeSniff.php ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Generic_Sniffs_Commenting_FixmeSniff.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Greg Sherwood <gsherwood@squiz.net>
10
+ * @author Sam Graham <php-codesniffer@illusori.co.uk>
11
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
12
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
13
+ * @link http://pear.php.net/package/PHP_CodeSniffer
14
+ */
15
+
16
+ /**
17
+ * Generic_Sniffs_Commenting_FixmeSniff.
18
+ *
19
+ * Warns about FIXME comments.
20
+ *
21
+ * @category PHP
22
+ * @package PHP_CodeSniffer
23
+ * @author Greg Sherwood <gsherwood@squiz.net>
24
+ * @author Sam Graham <php-codesniffer@illusori.co.uk>
25
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
26
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
27
+ * @version Release: @package_version@
28
+ * @link http://pear.php.net/package/PHP_CodeSniffer
29
+ */
30
+ class Generic_Sniffs_Commenting_FixmeSniff implements PHP_CodeSniffer_Sniff
31
+ {
32
+
33
+ /**
34
+ * A list of tokenizers this sniff supports.
35
+ *
36
+ * @var array
37
+ */
38
+ public $supportedTokenizers = array(
39
+ 'PHP',
40
+ 'JS',
41
+ );
42
+
43
+
44
+ /**
45
+ * Returns an array of tokens this test wants to listen for.
46
+ *
47
+ * @return array
48
+ */
49
+ public function register()
50
+ {
51
+ return PHP_CodeSniffer_Tokens::$commentTokens;
52
+
53
+ }//end register()
54
+
55
+
56
+ /**
57
+ * Processes this sniff, when one of its tokens is encountered.
58
+ *
59
+ * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
60
+ * @param int $stackPtr The position of the current token
61
+ * in the stack passed in $tokens.
62
+ *
63
+ * @return void
64
+ */
65
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
66
+ {
67
+ $tokens = $phpcsFile->getTokens();
68
+
69
+ $content = $tokens[$stackPtr]['content'];
70
+ $matches = array();
71
+ preg_match('/(?:\A|[^\p{L}]+)fixme([^\p{L}]+(.*)|\Z)/ui', $content, $matches);
72
+ if (empty($matches) === false) {
73
+ // Clear whitespace and some common characters not required at
74
+ // the end of a fixme message to make the error more informative.
75
+ $type = 'CommentFound';
76
+ $fixmeMessage = trim($matches[1]);
77
+ $fixmeMessage = trim($fixmeMessage, '-:[](). ');
78
+ $error = 'Comment refers to a FIXME task';
79
+ $data = array($fixmeMessage);
80
+ if ($fixmeMessage !== '') {
81
+ $type = 'TaskFound';
82
+ $error .= ' "%s"';
83
+ }
84
+
85
+ $phpcsFile->addError($error, $stackPtr, $type, $data);
86
+ }
87
+
88
+ }//end process()
89
+
90
+
91
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Commenting/TodoSniff.php ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Generic_Sniffs_Commenting_TodoSniff.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Greg Sherwood <gsherwood@squiz.net>
10
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
11
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
12
+ * @link http://pear.php.net/package/PHP_CodeSniffer
13
+ */
14
+
15
+ /**
16
+ * Generic_Sniffs_Commenting_TodoSniff.
17
+ *
18
+ * Warns about TODO comments.
19
+ *
20
+ * @category PHP
21
+ * @package PHP_CodeSniffer
22
+ * @author Greg Sherwood <gsherwood@squiz.net>
23
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
24
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
25
+ * @version Release: @package_version@
26
+ * @link http://pear.php.net/package/PHP_CodeSniffer
27
+ */
28
+ class Generic_Sniffs_Commenting_TodoSniff implements PHP_CodeSniffer_Sniff
29
+ {
30
+
31
+ /**
32
+ * A list of tokenizers this sniff supports.
33
+ *
34
+ * @var array
35
+ */
36
+ public $supportedTokenizers = array(
37
+ 'PHP',
38
+ 'JS',
39
+ );
40
+
41
+
42
+ /**
43
+ * Returns an array of tokens this test wants to listen for.
44
+ *
45
+ * @return array
46
+ */
47
+ public function register()
48
+ {
49
+ return PHP_CodeSniffer_Tokens::$commentTokens;
50
+
51
+ }//end register()
52
+
53
+
54
+ /**
55
+ * Processes this sniff, when one of its tokens is encountered.
56
+ *
57
+ * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
58
+ * @param int $stackPtr The position of the current token
59
+ * in the stack passed in $tokens.
60
+ *
61
+ * @return void
62
+ */
63
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
64
+ {
65
+ $tokens = $phpcsFile->getTokens();
66
+
67
+ $content = $tokens[$stackPtr]['content'];
68
+ $matches = array();
69
+ preg_match('/(?:\A|[^\p{L}]+)todo([^\p{L}]+(.*)|\Z)/ui', $content, $matches);
70
+ if (empty($matches) === false) {
71
+ // Clear whitespace and some common characters not required at
72
+ // the end of a to-do message to make the warning more informative.
73
+ $type = 'CommentFound';
74
+ $todoMessage = trim($matches[1]);
75
+ $todoMessage = trim($todoMessage, '-:[](). ');
76
+ $error = 'Comment refers to a TODO task';
77
+ $data = array($todoMessage);
78
+ if ($todoMessage !== '') {
79
+ $type = 'TaskFound';
80
+ $error .= ' "%s"';
81
+ }
82
+
83
+ $phpcsFile->addWarning($error, $stackPtr, $type, $data);
84
+ }
85
+
86
+ }//end process()
87
+
88
+
89
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/ControlStructures/InlineControlStructureSniff.php ADDED
@@ -0,0 +1,255 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Generic_Sniffs_ControlStructures_InlineControlStructureSniff.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Greg Sherwood <gsherwood@squiz.net>
10
+ * @author Marc McIntyre <mmcintyre@squiz.net>
11
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
12
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
13
+ * @link http://pear.php.net/package/PHP_CodeSniffer
14
+ */
15
+
16
+ /**
17
+ * Generic_Sniffs_ControlStructures_InlineControlStructureSniff.
18
+ *
19
+ * Verifies that inline control statements are not present.
20
+ *
21
+ * @category PHP
22
+ * @package PHP_CodeSniffer
23
+ * @author Greg Sherwood <gsherwood@squiz.net>
24
+ * @author Marc McIntyre <mmcintyre@squiz.net>
25
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
26
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
27
+ * @version Release: @package_version@
28
+ * @link http://pear.php.net/package/PHP_CodeSniffer
29
+ */
30
+ class Generic_Sniffs_ControlStructures_InlineControlStructureSniff implements PHP_CodeSniffer_Sniff
31
+ {
32
+
33
+ /**
34
+ * A list of tokenizers this sniff supports.
35
+ *
36
+ * @var array
37
+ */
38
+ public $supportedTokenizers = array(
39
+ 'PHP',
40
+ 'JS',
41
+ );
42
+
43
+ /**
44
+ * If true, an error will be thrown; otherwise a warning.
45
+ *
46
+ * @var bool
47
+ */
48
+ public $error = true;
49
+
50
+
51
+ /**
52
+ * Returns an array of tokens this test wants to listen for.
53
+ *
54
+ * @return array
55
+ */
56
+ public function register()
57
+ {
58
+ return array(
59
+ T_IF,
60
+ T_ELSE,
61
+ T_ELSEIF,
62
+ T_FOREACH,
63
+ T_WHILE,
64
+ T_DO,
65
+ T_SWITCH,
66
+ T_FOR,
67
+ );
68
+
69
+ }//end register()
70
+
71
+
72
+ /**
73
+ * Processes this test, when one of its tokens is encountered.
74
+ *
75
+ * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
76
+ * @param int $stackPtr The position of the current token in the
77
+ * stack passed in $tokens.
78
+ *
79
+ * @return void
80
+ */
81
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
82
+ {
83
+ $tokens = $phpcsFile->getTokens();
84
+
85
+ if (isset($tokens[$stackPtr]['scope_opener']) === true) {
86
+ $phpcsFile->recordMetric($stackPtr, 'Control structure defined inline', 'no');
87
+ return;
88
+ }
89
+
90
+ // Ignore the ELSE in ELSE IF. We'll process the IF part later.
91
+ if ($tokens[$stackPtr]['code'] === T_ELSE) {
92
+ $next = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true);
93
+ if ($tokens[$next]['code'] === T_IF) {
94
+ return;
95
+ }
96
+ }
97
+
98
+ if ($tokens[$stackPtr]['code'] === T_WHILE) {
99
+ // This could be from a DO WHILE, which doesn't have an opening brace.
100
+ $lastContent = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
101
+ if ($tokens[$lastContent]['code'] === T_CLOSE_CURLY_BRACKET) {
102
+ $brace = $tokens[$lastContent];
103
+ if (isset($brace['scope_condition']) === true) {
104
+ $condition = $tokens[$brace['scope_condition']];
105
+ if ($condition['code'] === T_DO) {
106
+ return;
107
+ }
108
+ }
109
+ }
110
+
111
+ // In Javascript DO WHILE loops without curly braces are legal. This
112
+ // is only valid if a single statement is present between the DO and
113
+ // the WHILE. We can detect this by checking only a single semicolon
114
+ // is present between them.
115
+ if ($phpcsFile->tokenizerType === 'JS') {
116
+ $lastDo = $phpcsFile->findPrevious(T_DO, ($stackPtr - 1));
117
+ $lastSemicolon = $phpcsFile->findPrevious(T_SEMICOLON, ($stackPtr - 1));
118
+ if ($lastDo !== false && $lastSemicolon !== false && $lastDo < $lastSemicolon) {
119
+ $precedingSemicolon = $phpcsFile->findPrevious(T_SEMICOLON, ($lastSemicolon - 1));
120
+ if ($precedingSemicolon === false || $precedingSemicolon < $lastDo) {
121
+ return;
122
+ }
123
+ }
124
+ }
125
+ }//end if
126
+
127
+ // This is a control structure without an opening brace,
128
+ // so it is an inline statement.
129
+ if ($this->error === true) {
130
+ $fix = $phpcsFile->addFixableError('Inline control structures are not allowed', $stackPtr, 'NotAllowed');
131
+ } else {
132
+ $fix = $phpcsFile->addFixableWarning('Inline control structures are discouraged', $stackPtr, 'Discouraged');
133
+ }
134
+
135
+ $phpcsFile->recordMetric($stackPtr, 'Control structure defined inline', 'yes');
136
+
137
+ // Stop here if we are not fixing the error.
138
+ if ($fix !== true) {
139
+ return;
140
+ }
141
+
142
+ $phpcsFile->fixer->beginChangeset();
143
+ if (isset($tokens[$stackPtr]['parenthesis_closer']) === true) {
144
+ $closer = $tokens[$stackPtr]['parenthesis_closer'];
145
+ } else {
146
+ $closer = $stackPtr;
147
+ }
148
+
149
+ if ($tokens[($closer + 1)]['code'] === T_WHITESPACE
150
+ || $tokens[($closer + 1)]['code'] === T_SEMICOLON
151
+ ) {
152
+ $phpcsFile->fixer->addContent($closer, ' {');
153
+ } else {
154
+ $phpcsFile->fixer->addContent($closer, ' { ');
155
+ }
156
+
157
+ $fixableScopeOpeners = $this->register();
158
+
159
+ $lastNonEmpty = $closer;
160
+ for ($end = ($closer + 1); $end < $phpcsFile->numTokens; $end++) {
161
+ if ($tokens[$end]['code'] === T_SEMICOLON) {
162
+ break;
163
+ }
164
+
165
+ if ($tokens[$end]['code'] === T_CLOSE_TAG) {
166
+ $end = $lastNonEmpty;
167
+ break;
168
+ }
169
+
170
+ if (in_array($tokens[$end]['code'], $fixableScopeOpeners) === true
171
+ && isset($tokens[$end]['scope_opener']) === false
172
+ ) {
173
+ // The best way to fix nested inline scopes is middle-out.
174
+ // So skip this one. It will be detected and fixed on a future loop.
175
+ $phpcsFile->fixer->rollbackChangeset();
176
+ return;
177
+ }
178
+
179
+ if (isset($tokens[$end]['scope_opener']) === true) {
180
+ $type = $tokens[$end]['code'];
181
+ $end = $tokens[$end]['scope_closer'];
182
+ if ($type === T_DO || $type === T_IF || $type === T_ELSEIF) {
183
+ $next = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, ($end + 1), null, true);
184
+ if ($next === false) {
185
+ break;
186
+ }
187
+
188
+ $nextType = $tokens[$next]['code'];
189
+
190
+ // Let additional conditions loop and find their ending.
191
+ if (($type === T_IF
192
+ || $type === T_ELSEIF)
193
+ && ($nextType === T_ELSEIF
194
+ || $nextType === T_ELSE)
195
+ ) {
196
+ continue;
197
+ }
198
+
199
+ // Account for DO... WHILE conditions.
200
+ if ($type === T_DO && $nextType === T_WHILE) {
201
+ $end = $phpcsFile->findNext(T_SEMICOLON, ($next + 1));
202
+ }
203
+ }//end if
204
+
205
+ break;
206
+ }//end if
207
+
208
+ if ($tokens[$end]['code'] !== T_WHITESPACE) {
209
+ $lastNonEmpty = $end;
210
+ }
211
+ }//end for
212
+
213
+ $next = $phpcsFile->findNext(T_WHITESPACE, ($closer + 1), ($end + 1), true);
214
+
215
+ // Account for a comment on the end of the line.
216
+ for ($endLine = $end; $endLine < $phpcsFile->numTokens; $endLine++) {
217
+ if (isset($tokens[($endLine + 1)]) === false
218
+ || $tokens[$endLine]['line'] !== $tokens[($endLine + 1)]['line']
219
+ ) {
220
+ break;
221
+ }
222
+ }
223
+
224
+ if ($tokens[$endLine]['code'] !== T_COMMENT) {
225
+ $endLine = $end;
226
+ }
227
+
228
+ if ($next !== $end) {
229
+ if ($endLine !== $end) {
230
+ $phpcsFile->fixer->addContent($endLine, '}');
231
+ } else {
232
+ if ($tokens[$end]['code'] !== T_SEMICOLON
233
+ && $tokens[$end]['code'] !== T_CLOSE_CURLY_BRACKET
234
+ ) {
235
+ $phpcsFile->fixer->addContent($end, ';');
236
+ }
237
+
238
+ $phpcsFile->fixer->addContent($end, ' }');
239
+ }
240
+ } else {
241
+ if ($endLine !== $end) {
242
+ $phpcsFile->fixer->replaceToken($end, '');
243
+ $phpcsFile->fixer->addNewlineBefore($endLine);
244
+ $phpcsFile->fixer->addContent($endLine, '}');
245
+ } else {
246
+ $phpcsFile->fixer->replaceToken($end, '}');
247
+ }
248
+ }//end if
249
+
250
+ $phpcsFile->fixer->endChangeset();
251
+
252
+ }//end process()
253
+
254
+
255
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Debug/CSSLintSniff.php ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Generic_Sniffs_Debug_CSSLintSniff.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Roman Levishchenko <index.0h@gmail.com>
10
+ * @copyright 2013-2014 Roman Levishchenko
11
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
12
+ * @link http://pear.php.net/package/PHP_CodeSniffer
13
+ */
14
+
15
+ /**
16
+ * Generic_Sniffs_Debug_CSSLintSniff.
17
+ *
18
+ * Runs csslint on the file.
19
+ *
20
+ * @category PHP
21
+ * @package PHP_CodeSniffer
22
+ * @author Roman Levishchenko <index.0h@gmail.com>
23
+ * @copyright 2013-2014 Roman Levishchenko
24
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
25
+ * @version Release: @package_version@
26
+ * @link http://pear.php.net/package/PHP_CodeSniffer
27
+ */
28
+ class Generic_Sniffs_Debug_CSSLintSniff implements PHP_CodeSniffer_Sniff
29
+ {
30
+
31
+ /**
32
+ * A list of tokenizers this sniff supports.
33
+ *
34
+ * @var array
35
+ */
36
+ public $supportedTokenizers = array('CSS');
37
+
38
+
39
+ /**
40
+ * Returns the token types that this sniff is interested in.
41
+ *
42
+ * @return int[]
43
+ */
44
+ public function register()
45
+ {
46
+ return array(T_OPEN_TAG);
47
+
48
+ }//end register()
49
+
50
+
51
+ /**
52
+ * Processes the tokens that this sniff is interested in.
53
+ *
54
+ * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found.
55
+ * @param int $stackPtr The position in the stack where
56
+ * the token was found.
57
+ *
58
+ * @return void
59
+ */
60
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
61
+ {
62
+ $fileName = $phpcsFile->getFilename();
63
+
64
+ $csslintPath = PHP_CodeSniffer::getConfigData('csslint_path');
65
+ if ($csslintPath === null) {
66
+ return;
67
+ }
68
+
69
+ $cmd = $csslintPath.' '.escapeshellarg($fileName);
70
+ exec($cmd, $output, $retval);
71
+
72
+ if (is_array($output) === false) {
73
+ return;
74
+ }
75
+
76
+ $count = count($output);
77
+
78
+ for ($i = 0; $i < $count; $i++) {
79
+ $matches = array();
80
+ $numMatches = preg_match(
81
+ '/(error|warning) at line (\d+)/',
82
+ $output[$i],
83
+ $matches
84
+ );
85
+
86
+ if ($numMatches === 0) {
87
+ continue;
88
+ }
89
+
90
+ $line = (int) $matches[2];
91
+ $message = 'csslint says: '.$output[($i + 1)];
92
+ // First line is message with error line and error code.
93
+ // Second is error message.
94
+ // Third is wrong line in file.
95
+ // Fourth is empty line.
96
+ $i += 4;
97
+
98
+ $phpcsFile->addWarningOnLine($message, $line, 'ExternalTool');
99
+ }//end for
100
+
101
+ // Ignore the rest of the file.
102
+ return ($phpcsFile->numTokens + 1);
103
+
104
+ }//end process()
105
+
106
+
107
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Debug/ClosureLinterSniff.php ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Generic_Sniffs_Debug_ClosureLinterSniff.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Greg Sherwood <gsherwood@squiz.net>
10
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
11
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
12
+ * @link http://pear.php.net/package/PHP_CodeSniffer
13
+ */
14
+
15
+ /**
16
+ * Generic_Sniffs_Debug_ClosureLinterSniff.
17
+ *
18
+ * Runs gjslint on the file.
19
+ *
20
+ * @category PHP
21
+ * @package PHP_CodeSniffer
22
+ * @author Greg Sherwood <gsherwood@squiz.net>
23
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
24
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
25
+ * @version Release: @package_version@
26
+ * @link http://pear.php.net/package/PHP_CodeSniffer
27
+ */
28
+ class Generic_Sniffs_Debug_ClosureLinterSniff implements PHP_CodeSniffer_Sniff
29
+ {
30
+
31
+ /**
32
+ * A list of error codes that should show errors.
33
+ *
34
+ * All other error codes will show warnings.
35
+ *
36
+ * @var int
37
+ */
38
+ public $errorCodes = array();
39
+
40
+ /**
41
+ * A list of error codes to ignore.
42
+ *
43
+ * @var int
44
+ */
45
+ public $ignoreCodes = array();
46
+
47
+ /**
48
+ * A list of tokenizers this sniff supports.
49
+ *
50
+ * @var array
51
+ */
52
+ public $supportedTokenizers = array('JS');
53
+
54
+
55
+ /**
56
+ * Returns the token types that this sniff is interested in.
57
+ *
58
+ * @return int[]
59
+ */
60
+ public function register()
61
+ {
62
+ return array(T_OPEN_TAG);
63
+
64
+ }//end register()
65
+
66
+
67
+ /**
68
+ * Processes the tokens that this sniff is interested in.
69
+ *
70
+ * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found.
71
+ * @param int $stackPtr The position in the stack where
72
+ * the token was found.
73
+ *
74
+ * @return void
75
+ * @throws PHP_CodeSniffer_Exception If jslint.js could not be run
76
+ */
77
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
78
+ {
79
+ $fileName = $phpcsFile->getFilename();
80
+
81
+ $lintPath = PHP_CodeSniffer::getConfigData('gjslint_path');
82
+ if ($lintPath === null) {
83
+ return;
84
+ }
85
+
86
+ $cmd = "$lintPath --nosummary --notime --unix_mode \"$fileName\"";
87
+ $msg = exec($cmd, $output, $retval);
88
+
89
+ if (is_array($output) === false) {
90
+ return;
91
+ }
92
+
93
+ foreach ($output as $finding) {
94
+ $matches = array();
95
+ $numMatches = preg_match('/^(.*):([0-9]+):\(.*?([0-9]+)\)(.*)$/', $finding, $matches);
96
+ if ($numMatches === 0) {
97
+ continue;
98
+ }
99
+
100
+ // Skip error codes we are ignoring.
101
+ $code = $matches[3];
102
+ if (in_array($code, $this->ignoreCodes) === true) {
103
+ continue;
104
+ }
105
+
106
+ $line = (int) $matches[2];
107
+ $error = trim($matches[4]);
108
+
109
+ $message = 'gjslint says: (%s) %s';
110
+ $data = array(
111
+ $code,
112
+ $error,
113
+ );
114
+ if (in_array($code, $this->errorCodes) === true) {
115
+ $phpcsFile->addErrorOnLine($message, $line, 'ExternalToolError', $data);
116
+ } else {
117
+ $phpcsFile->addWarningOnLine($message, $line, 'ExternalTool', $data);
118
+ }
119
+ }//end foreach
120
+
121
+ // Ignore the rest of the file.
122
+ return ($phpcsFile->numTokens + 1);
123
+
124
+ }//end process()
125
+
126
+
127
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Debug/JSHintSniff.php ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Generic_Sniffs_Debug_JSHintSniff.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Greg Sherwood <gsherwood@squiz.net>
10
+ * @author Alexander Wei§ <aweisswa@gmx.de>
11
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
12
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
13
+ * @link http://pear.php.net/package/PHP_CodeSniffer
14
+ */
15
+
16
+ /**
17
+ * Generic_Sniffs_Debug_JSHintSniff.
18
+ *
19
+ * Runs jshint.js on the file.
20
+ *
21
+ * @category PHP
22
+ * @package PHP_CodeSniffer
23
+ * @author Greg Sherwood <gsherwood@squiz.net>
24
+ * @author Alexander Wei§ <aweisswa@gmx.de>
25
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
26
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
27
+ * @version Release: @package_version@
28
+ * @link http://pear.php.net/package/PHP_CodeSniffer
29
+ */
30
+ class Generic_Sniffs_Debug_JSHintSniff implements PHP_CodeSniffer_Sniff
31
+ {
32
+
33
+ /**
34
+ * A list of tokenizers this sniff supports.
35
+ *
36
+ * @var array
37
+ */
38
+ public $supportedTokenizers = array('JS');
39
+
40
+
41
+ /**
42
+ * Returns the token types that this sniff is interested in.
43
+ *
44
+ * @return int[]
45
+ */
46
+ public function register()
47
+ {
48
+ return array(T_OPEN_TAG);
49
+
50
+ }//end register()
51
+
52
+
53
+ /**
54
+ * Processes the tokens that this sniff is interested in.
55
+ *
56
+ * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found.
57
+ * @param int $stackPtr The position in the stack where
58
+ * the token was found.
59
+ *
60
+ * @return void
61
+ * @throws PHP_CodeSniffer_Exception If jshint.js could not be run
62
+ */
63
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
64
+ {
65
+ $fileName = $phpcsFile->getFilename();
66
+
67
+ $rhinoPath = PHP_CodeSniffer::getConfigData('rhino_path');
68
+ $jshintPath = PHP_CodeSniffer::getConfigData('jshint_path');
69
+ if ($rhinoPath === null || $jshintPath === null) {
70
+ return;
71
+ }
72
+
73
+ $cmd = "$rhinoPath \"$jshintPath\" \"$fileName\"";
74
+ $msg = exec($cmd, $output, $retval);
75
+
76
+ if (is_array($output) === true) {
77
+ foreach ($output as $finding) {
78
+ $matches = array();
79
+ $numMatches = preg_match('/^(.+)\(.+:([0-9]+).*:[0-9]+\)$/', $finding, $matches);
80
+ if ($numMatches === 0) {
81
+ continue;
82
+ }
83
+
84
+ $line = (int) $matches[2];
85
+ $message = 'jshint says: '.trim($matches[1]);
86
+ $phpcsFile->addWarningOnLine($message, $line, 'ExternalTool');
87
+ }
88
+ }
89
+
90
+ // Ignore the rest of the file.
91
+ return ($phpcsFile->numTokens + 1);
92
+
93
+ }//end process()
94
+
95
+
96
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/ByteOrderMarkSniff.php ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Generic_Sniffs_Files_ByteOrderMarkSniff.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Greg Sherwood <gsherwood@squiz.net>
10
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
11
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
12
+ * @link http://pear.php.net/package/PHP_CodeSniffer
13
+ */
14
+
15
+ /**
16
+ * Generic_Sniffs_Files_ByteOrderMarkSniff.
17
+ *
18
+ * A simple sniff for detecting BOMs that may corrupt application work.
19
+ *
20
+ * @category PHP
21
+ * @package PHP_CodeSniffer
22
+ * @author Piotr Karas <office@mediaself.pl>
23
+ * @author Greg Sherwood <gsherwood@squiz.net>
24
+ * @copyright 2010-2014 mediaSELF Sp. z o.o.
25
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
26
+ * @version Release: @package_version@
27
+ * @link http://pear.php.net/package/PHP_CodeSniffer
28
+ * @see http://en.wikipedia.org/wiki/Byte_order_mark
29
+ */
30
+ class Generic_Sniffs_Files_ByteOrderMarkSniff implements PHP_CodeSniffer_Sniff
31
+ {
32
+
33
+ /**
34
+ * List of supported BOM definitions.
35
+ *
36
+ * Use encoding names as keys and hex BOM representations as values.
37
+ *
38
+ * @var array
39
+ */
40
+ public $bomDefinitions = array(
41
+ 'UTF-8' => 'efbbbf',
42
+ 'UTF-16 (BE)' => 'feff',
43
+ 'UTF-16 (LE)' => 'fffe',
44
+ );
45
+
46
+
47
+ /**
48
+ * Returns an array of tokens this test wants to listen for.
49
+ *
50
+ * @return array
51
+ */
52
+ public function register()
53
+ {
54
+ return array(T_INLINE_HTML);
55
+
56
+ }//end register()
57
+
58
+
59
+ /**
60
+ * Processes this sniff, when one of its tokens is encountered.
61
+ *
62
+ * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
63
+ * @param int $stackPtr The position of the current token in
64
+ * the stack passed in $tokens.
65
+ *
66
+ * @return void
67
+ */
68
+ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
69
+ {
70
+ // The BOM will be the very first token in the file.
71
+ if ($stackPtr !== 0) {
72
+ return;
73
+ }
74
+
75
+ $tokens = $phpcsFile->getTokens();
76
+
77
+ foreach ($this->bomDefinitions as $bomName => $expectedBomHex) {
78
+ $bomByteLength = (strlen($expectedBomHex) / 2);
79
+ $htmlBomHex = bin2hex(substr($tokens[$stackPtr]['content'], 0, $bomByteLength));
80
+ if ($htmlBomHex === $expectedBomHex) {
81
+ $errorData = array($bomName);
82
+ $error = 'File contains %s byte order mark, which may corrupt your application';
83
+ $phpcsFile->addError($error, $stackPtr, 'Found', $errorData);
84
+ $phpcsFile->recordMetric($stackPtr, 'Using byte order mark', 'yes');
85
+ return;
86
+ }
87
+ }
88
+
89
+ $phpcsFile->recordMetric($stackPtr, 'Using byte order mark', 'no');
90
+
91
+ }//end process()
92
+
93
+
94
+ }//end class
php-compatibility-checker/vendor/squizlabs/php_codesniffer/CodeSniffer/Standards/Generic/Sniffs/Files/EndFileNewlineSniff.php ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Generic_Sniffs_Files_EndFileNewlineSniff.
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * @category PHP
8
+ * @package PHP_CodeSniffer
9
+ * @author Greg Sherwood <gsherwood@squiz.net>
10
+ * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
11
+ * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
12
+ * @link http://pear.php.net/package/PHP_CodeSniffer
13
+ */
14
+
15
+ /**
16
+ * Generic_Sniffs_Files_E