[ Index ]

PHP Cross Reference of phpBB-3.3.7-deutsch

title

Body

[close]

/phpbb/event/ -> php_exporter.php (source)

   1  <?php
   2  /**
   3  *
   4  * This file is part of the phpBB Forum Software package.
   5  *
   6  * @copyright (c) phpBB Limited <https://www.phpbb.com>
   7  * @license GNU General Public License, version 2 (GPL-2.0)
   8  *
   9  * For full copyright and license information, please see
  10  * the docs/CREDITS.txt file.
  11  *
  12  */
  13  
  14  namespace phpbb\event;
  15  
  16  /**
  17  * Class php_exporter
  18  * Crawls through a list of files and grabs all php-events
  19  */
  20  class php_exporter
  21  {
  22      /** @var string Path where we look for files*/
  23      protected $path;
  24  
  25      /** @var string phpBB Root Path */
  26      protected $root_path;
  27  
  28      /** @var string The minimum version for the events to return */
  29      protected $min_version;
  30  
  31      /** @var string The maximum version for the events to return */
  32      protected $max_version;
  33  
  34      /** @var string */
  35      protected $current_file;
  36  
  37      /** @var string */
  38      protected $current_event;
  39  
  40      /** @var int */
  41      protected $current_event_line;
  42  
  43      /** @var array */
  44      protected $events;
  45  
  46      /** @var array */
  47      protected $file_lines;
  48  
  49      /**
  50      * @param string $phpbb_root_path
  51      * @param mixed $extension    String 'vendor/ext' to filter, null for phpBB core
  52      * @param string $min_version
  53      * @param string $max_version
  54      */
  55  	public function __construct($phpbb_root_path, $extension = null, $min_version = null, $max_version = null)
  56      {
  57          $this->root_path = $phpbb_root_path;
  58          $this->path = $phpbb_root_path;
  59          $this->events = $this->file_lines = array();
  60          $this->current_file = $this->current_event = '';
  61          $this->current_event_line = 0;
  62          $this->min_version = $min_version;
  63          $this->max_version = $max_version;
  64  
  65          $this->path = $this->root_path;
  66          if ($extension)
  67          {
  68              $this->path .= 'ext/' . $extension . '/';
  69          }
  70      }
  71  
  72      /**
  73      * Get the list of all events
  74      *
  75      * @return array        Array with events: name => details
  76      */
  77  	public function get_events()
  78      {
  79          return $this->events;
  80      }
  81  
  82      /**
  83      * Set current event data
  84      *
  85      * @param string    $name    Name of the current event (used for error messages)
  86      * @param int    $line    Line where the current event is placed in
  87      * @return null
  88      */
  89  	public function set_current_event($name, $line)
  90      {
  91          $this->current_event = $name;
  92          $this->current_event_line = $line;
  93      }
  94  
  95      /**
  96      * Set the content of this file
  97      *
  98      * @param array $content        Array with the lines of the file
  99      * @return null
 100      */
 101  	public function set_content($content)
 102      {
 103          $this->file_lines = $content;
 104      }
 105  
 106      /**
 107      * Crawl the phpBB/ directory for php events
 108      * @return int    The number of events found
 109      */
 110  	public function crawl_phpbb_directory_php()
 111      {
 112          $files = $this->get_recursive_file_list();
 113          $this->events = array();
 114          foreach ($files as $file)
 115          {
 116              $this->crawl_php_file($file);
 117          }
 118          ksort($this->events);
 119  
 120          return count($this->events);
 121      }
 122  
 123      /**
 124      * Returns a list of files in $dir
 125      *
 126      * @return    array    List of files (including the path)
 127      */
 128  	public function get_recursive_file_list()
 129      {
 130          try
 131          {
 132              $iterator = new \RecursiveIteratorIterator(
 133                  new \phpbb\event\recursive_event_filter_iterator(
 134                      new \RecursiveDirectoryIterator(
 135                          $this->path,
 136                          \FilesystemIterator::SKIP_DOTS
 137                      ),
 138                      $this->path
 139                  ),
 140                  \RecursiveIteratorIterator::LEAVES_ONLY
 141              );
 142          }
 143          catch (\Exception $e)
 144          {
 145              return array();
 146          }
 147  
 148          $files = array();
 149          foreach ($iterator as $file_info)
 150          {
 151              /** @var \RecursiveDirectoryIterator $file_info */
 152              $relative_path = $iterator->getInnerIterator()->getSubPathname();
 153              $files[] = str_replace(DIRECTORY_SEPARATOR, '/', $relative_path);
 154          }
 155  
 156          return $files;
 157      }
 158  
 159      /**
 160      * Format the php events as a wiki table
 161      *
 162      * @param string $action
 163      * @return string
 164      * @deprecated 3.3.5-RC1 (To be removed: 4.0.0-a1)
 165      */
 166  	public function export_events_for_wiki($action = '')
 167      {
 168          if ($action === 'diff')
 169          {
 170              $wiki_page = '=== PHP Events (Hook Locations) ===' . "\n";
 171          }
 172          else
 173          {
 174              $wiki_page = '= PHP Events (Hook Locations) =' . "\n";
 175          }
 176          $wiki_page .= '{| class="sortable zebra" cellspacing="0" cellpadding="5"' . "\n";
 177          $wiki_page .= '! Identifier !! Placement !! Arguments !! Added in Release !! Explanation' . "\n";
 178          foreach ($this->events as $event)
 179          {
 180              $wiki_page .= '|- id="' . $event['event'] . '"' . "\n";
 181              $wiki_page .= '| [[#' . $event['event'] . '|' . $event['event'] . ']] || ' . $event['file'] . ' || ' . implode(', ', $event['arguments']) . ' || ' . $event['since'] . ' || ' . $event['description'] . "\n";
 182          }
 183          $wiki_page .= '|}' . "\n";
 184  
 185          return $wiki_page;
 186      }
 187  
 188      /**
 189       * Format the PHP events as a rst table
 190       *
 191       * @param string $action
 192       * @return string
 193       */
 194  	public function export_events_for_rst(string $action = ''): string
 195      {
 196          $rst_exporter = new rst_exporter();
 197          $rst_exporter->add_section_header($action === 'diff' ? 'h3' : 'h2', 'PHP Events');
 198          $rst_exporter->set_columns([
 199              'event'            => 'Identifier',
 200              'file'            => 'Placement',
 201              'arguments'        => 'Arguments',
 202              'since'            => 'Added in Release',
 203              'description'    => 'Explanation',
 204          ]);
 205          $rst_exporter->generate_events_table($this->events);
 206  
 207          return $rst_exporter->get_rst_output();
 208      }
 209  
 210      /**
 211       * Format the PHP events as a BBCode list
 212       *
 213       * @param string $action
 214       * @return string
 215       */
 216  	public function export_events_for_bbcode(string $action = ''): string
 217      {
 218          if ($action === 'diff')
 219          {
 220              $bbcode_text = '[size=150]PHP Events[/size]' . "\n";
 221          }
 222          else
 223          {
 224              $bbcode_text = '[size=200]PHP Events[/size]' . "\n";
 225          }
 226  
 227          foreach ($this->events as $event)
 228          {
 229              $bbcode_text .= "[list]\n";
 230              $bbcode_text .= "[*][b]{$event['event']}[/b]\n";
 231              $bbcode_text .= "Placement: {$event['file']}\n";
 232              $bbcode_text .= 'Arguments: ' . implode(', ', $event['arguments']) . "\n";
 233              $bbcode_text .= "Added in Release: {$event['since']}\n";
 234              $bbcode_text .= "Explanation: {$event['description']}\n";
 235              $bbcode_text .= "[/list]\n";
 236          }
 237  
 238          return $bbcode_text;
 239      }
 240  
 241      /**
 242      * @param string $file
 243      * @return int Number of events found in this file
 244      * @throws \LogicException
 245      */
 246  	public function crawl_php_file($file)
 247      {
 248          $this->current_file = $file;
 249          $this->file_lines = array();
 250          $content = file_get_contents($this->path . $this->current_file);
 251          $num_events_found = 0;
 252  
 253          if (strpos($content, 'dispatcher->trigger_event(') || strpos($content, 'dispatcher->dispatch('))
 254          {
 255              $this->set_content(explode("\n", $content));
 256              for ($i = 0, $num_lines = count($this->file_lines); $i < $num_lines; $i++)
 257              {
 258                  $event_line = false;
 259                  $found_trigger_event = strpos($this->file_lines[$i], 'dispatcher->trigger_event(');
 260                  $arguments = array();
 261                  if ($found_trigger_event !== false)
 262                  {
 263                      $event_line = $i;
 264                      $this->set_current_event($this->get_event_name($event_line, false), $event_line);
 265  
 266                      // Find variables of the event
 267                      $arguments = $this->get_vars_from_array();
 268                      $doc_vars = $this->get_vars_from_docblock();
 269                      $this->validate_vars_docblock_array($arguments, $doc_vars);
 270                  }
 271                  else
 272                  {
 273                      $found_dispatch = strpos($this->file_lines[$i], 'dispatcher->dispatch(');
 274                      if ($found_dispatch !== false)
 275                      {
 276                          $event_line = $i;
 277                          $this->set_current_event($this->get_event_name($event_line, true), $event_line);
 278                      }
 279                  }
 280  
 281                  if ($event_line)
 282                  {
 283                      // Validate @event
 284                      $event_line_num = $this->find_event();
 285                      $this->validate_event($this->current_event, $this->file_lines[$event_line_num]);
 286  
 287                      // Validate @since
 288                      $since_line_num = $this->find_since();
 289                      $since = $this->validate_since($this->file_lines[$since_line_num]);
 290  
 291                      $changed_line_nums = $this->find_changed('changed');
 292                      if (empty($changed_line_nums))
 293                      {
 294                          $changed_line_nums = $this->find_changed('change');
 295                      }
 296                      $changed_versions = array();
 297                      if (!empty($changed_line_nums))
 298                      {
 299                          foreach ($changed_line_nums as $changed_line_num)
 300                          {
 301                              $changed_versions[] = $this->validate_changed($this->file_lines[$changed_line_num]);
 302                          }
 303                      }
 304  
 305                      if (!$this->version_is_filtered($since))
 306                      {
 307                          $valid_version = false;
 308                          foreach ($changed_versions as $changed)
 309                          {
 310                              $valid_version = $valid_version || $this->version_is_filtered($changed);
 311                          }
 312  
 313                          if (!$valid_version)
 314                          {
 315                              continue;
 316                          }
 317                      }
 318  
 319                      // Find event description line
 320                      $description_line_num = $this->find_description();
 321                      $description_lines = array();
 322  
 323                      while (true)
 324                      {
 325                          $description_line = substr(trim($this->file_lines[$description_line_num]), strlen('*'));
 326                          $description_line = trim(str_replace("\t", " ", $description_line));
 327  
 328                          // Reached end of description if line is a tag
 329                          if (strlen($description_line) && $description_line[0] == '@')
 330                          {
 331                              break;
 332                          }
 333  
 334                          $description_lines[] = $description_line;
 335                          $description_line_num++;
 336                      }
 337  
 338                      // If there is an empty line between description and first tag, remove it
 339                      if (!strlen(end($description_lines)))
 340                      {
 341                          array_pop($description_lines);
 342                      }
 343  
 344                      $description = trim(implode('<br>', $description_lines));
 345                      sort($arguments);
 346  
 347                      if (isset($this->events[$this->current_event]))
 348                      {
 349                          if ($this->events[$this->current_event]['arguments'] != $arguments ||
 350                              $this->events[$this->current_event]['since'] != $since)
 351                          {
 352                              throw new \LogicException("The event '{$this->current_event}' from file "
 353                                  . "'{$this->current_file}:{$event_line_num}' already exists in file "
 354                                  . "'{$this->events[$this->current_event]['file']}'", 10);
 355                          }
 356  
 357                          $this->events[$this->current_event]['file'] .= '<br>' . $this->current_file;
 358                      }
 359                      else
 360                      {
 361                          $this->events[$this->current_event] = array(
 362                              'event' => $this->current_event,
 363                              'file' => $this->current_file,
 364                              'arguments' => $arguments,
 365                              'since' => $since,
 366                              'description' => $description,
 367                          );
 368                          $num_events_found++;
 369                      }
 370                  }
 371              }
 372          }
 373  
 374          return $num_events_found;
 375      }
 376  
 377      /**
 378       * The version to check
 379       *
 380       * @param string $version
 381       * @return bool
 382       */
 383  	protected function version_is_filtered($version)
 384      {
 385          return (!$this->min_version || phpbb_version_compare($this->min_version, $version, '<='))
 386              && (!$this->max_version || phpbb_version_compare($this->max_version, $version, '>='));
 387      }
 388  
 389      /**
 390      * Find the name of the event inside the dispatch() line
 391      *
 392      * @param int $event_line
 393      * @param bool $is_dispatch Do we look for dispatch() or trigger_event() ?
 394      * @return string    Name of the event
 395      * @throws \LogicException
 396      */
 397  	public function get_event_name($event_line, $is_dispatch)
 398      {
 399          $event_text_line = $this->file_lines[$event_line];
 400          $event_text_line = ltrim($event_text_line, "\t ");
 401  
 402          if ($is_dispatch)
 403          {
 404              $regex = '#\$[a-z](?:[a-z0-9_]|->)*';
 405              $regex .= '->dispatch\((\[)?';
 406              $regex .= '\'' . $this->preg_match_event_name() . '(?(1)\', \'(?2))+\'';
 407              $regex .= '(?(1)\])\);#';
 408          }
 409          else
 410          {
 411              $regex = '#extract\(\$[a-z](?:[a-z0-9_]|->)*';
 412              $regex .= '->trigger_event\((\[)?';
 413              $regex .= '\'' . $this->preg_match_event_name() . '(?(1)\', \'(?2))+\'';
 414              $regex .= '(?(1)\]), compact\(\$vars\)\)\);#';
 415          }
 416  
 417          $match = array();
 418          preg_match($regex, $event_text_line, $match);
 419          if (!isset($match[2]))
 420          {
 421              throw new \LogicException("Can not find event name in line '{$event_text_line}' "
 422                  . "in file '{$this->current_file}:{$event_line}'", 1);
 423          }
 424  
 425          return $match[2];
 426      }
 427  
 428      /**
 429      * Returns a regex match for the event name
 430      *
 431      * @return string
 432      */
 433  	protected function preg_match_event_name()
 434      {
 435          return '([a-z][a-z0-9_]*(?:\.[a-z][a-z0-9_]*)+)';
 436      }
 437  
 438      /**
 439      * Find the $vars array
 440      *
 441      * @return array        List of variables
 442      * @throws \LogicException
 443      */
 444  	public function get_vars_from_array()
 445      {
 446          $line = ltrim($this->file_lines[$this->current_event_line - 1], "\t");
 447          if ($line === ');' || $line === '];')
 448          {
 449              $vars_array = $this->get_vars_from_multi_line_array();
 450          }
 451          else
 452          {
 453              $vars_array = $this->get_vars_from_single_line_array($line);
 454          }
 455  
 456          foreach ($vars_array as $var)
 457          {
 458              if (!preg_match('#^[a-z_][a-z0-9_]*$#i', $var))
 459              {
 460                  throw new \LogicException("Found invalid var '{$var}' in array for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 3);
 461              }
 462          }
 463  
 464          sort($vars_array);
 465          return $vars_array;
 466      }
 467  
 468      /**
 469      * Find the variables in single line array
 470      *
 471      * @param    string    $line
 472      * @param    bool    $throw_multiline    Throw an exception when there are too
 473      *                                        many arguments in one line.
 474      * @return array        List of variables
 475      * @throws \LogicException
 476      */
 477  	public function get_vars_from_single_line_array($line, $throw_multiline = true)
 478      {
 479          $match = array();
 480          preg_match('#^\$vars = (?:(\[)|array\()\'([a-z0-9_\' ,]+)\'(?(1)\]|\));$#i', $line, $match);
 481  
 482          if (isset($match[2]))
 483          {
 484              $vars_array = explode("', '", $match[2]);
 485              if ($throw_multiline && count($vars_array) > 6)
 486              {
 487                  throw new \LogicException('Should use multiple lines for $vars definition '
 488                      . "for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 2);
 489              }
 490              return $vars_array;
 491          }
 492          else
 493          {
 494              throw new \LogicException("Can not find '\$vars = array();'-line for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 1);
 495          }
 496      }
 497  
 498      /**
 499      * Find the variables in single line array
 500      *
 501      * @return array        List of variables
 502      * @throws \LogicException
 503      */
 504  	public function get_vars_from_multi_line_array()
 505      {
 506          $current_vars_line = 2;
 507          $var_lines = array();
 508          while (!in_array(ltrim($this->file_lines[$this->current_event_line - $current_vars_line], "\t"), ['$vars = array(', '$vars = [']))
 509          {
 510              $var_lines[] = substr(trim($this->file_lines[$this->current_event_line - $current_vars_line]), 0, -1);
 511  
 512              $current_vars_line++;
 513              if ($current_vars_line > $this->current_event_line)
 514              {
 515                  // Reached the start of the file
 516                  throw new \LogicException("Can not find end of \$vars array for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 2);
 517              }
 518          }
 519  
 520          return $this->get_vars_from_single_line_array('$vars = array(' . implode(", ", $var_lines) . ');', false);
 521      }
 522  
 523      /**
 524      * Find the $vars array
 525      *
 526      * @return array        List of variables
 527      * @throws \LogicException
 528      */
 529  	public function get_vars_from_docblock()
 530      {
 531          $doc_vars = array();
 532          $current_doc_line = 1;
 533          $found_comment_end = false;
 534          while (ltrim($this->file_lines[$this->current_event_line - $current_doc_line], "\t") !== '/**')
 535          {
 536              if (ltrim($this->file_lines[$this->current_event_line - $current_doc_line], "\t ") === '*/')
 537              {
 538                  $found_comment_end = true;
 539              }
 540  
 541              if ($found_comment_end)
 542              {
 543                  $var_line = trim($this->file_lines[$this->current_event_line - $current_doc_line]);
 544                  $var_line = preg_replace('!\s+!', ' ', $var_line);
 545                  if (strpos($var_line, '* @var ') === 0)
 546                  {
 547                      $doc_line = explode(' ', $var_line, 5);
 548                      if (count($doc_line) !== 5)
 549                      {
 550                          throw new \LogicException("Found invalid line '{$this->file_lines[$this->current_event_line - $current_doc_line]}' "
 551                          . "for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 1);
 552                      }
 553                      $doc_vars[] = $doc_line[3];
 554                  }
 555              }
 556  
 557              $current_doc_line++;
 558              if ($current_doc_line > $this->current_event_line)
 559              {
 560                  // Reached the start of the file
 561                  throw new \LogicException("Can not find end of docblock for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 2);
 562              }
 563          }
 564  
 565          if (empty($doc_vars))
 566          {
 567              // Reached the start of the file
 568              throw new \LogicException("Can not find @var lines for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 3);
 569          }
 570  
 571          foreach ($doc_vars as $var)
 572          {
 573              if (!preg_match('#^[a-z_][a-z0-9_]*$#i', $var))
 574              {
 575                  throw new \LogicException("Found invalid @var '{$var}' in docblock for event "
 576                      . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 4);
 577              }
 578          }
 579  
 580          sort($doc_vars);
 581          return $doc_vars;
 582      }
 583  
 584      /**
 585      * Find the "@since" Information line
 586      *
 587      * @return int Absolute line number
 588      * @throws \LogicException
 589      */
 590  	public function find_since()
 591      {
 592          return $this->find_tag('since', array('event', 'var'));
 593      }
 594  
 595      /**
 596      * Find the "@changed" Information lines
 597      *
 598      * @param string $tag_name Should be 'change', not 'changed'
 599      * @return array Absolute line numbers
 600      * @throws \LogicException
 601      */
 602  	public function find_changed($tag_name)
 603      {
 604          $lines = array();
 605          $last_line = 0;
 606          try
 607          {
 608              while ($line = $this->find_tag($tag_name, array('since'), $last_line))
 609              {
 610                  $lines[] = $line;
 611                  $last_line = $line;
 612              }
 613          }
 614          catch (\LogicException $e)
 615          {
 616              // Not changed? No problem!
 617          }
 618  
 619          return $lines;
 620      }
 621  
 622      /**
 623      * Find the "@event" Information line
 624      *
 625      * @return int Absolute line number
 626      */
 627  	public function find_event()
 628      {
 629          return $this->find_tag('event', array());
 630      }
 631  
 632      /**
 633      * Find a "@*" Information line
 634      *
 635      * @param string $find_tag        Name of the tag we are trying to find
 636      * @param array $disallowed_tags        List of tags that must not appear between
 637      *                                    the tag and the actual event
 638      * @param int $skip_to_line        Skip lines until this one
 639      * @return int Absolute line number
 640      * @throws \LogicException
 641      */
 642  	public function find_tag($find_tag, $disallowed_tags, $skip_to_line = 0)
 643      {
 644          $find_tag_line = $skip_to_line ? $this->current_event_line - $skip_to_line + 1 : 0;
 645          $found_comment_end = ($skip_to_line) ? true : false;
 646          while (strpos(ltrim($this->file_lines[$this->current_event_line - $find_tag_line], "\t "), '* @' . $find_tag . ' ') !== 0)
 647          {
 648              if ($found_comment_end && ltrim($this->file_lines[$this->current_event_line - $find_tag_line], "\t") === '/**')
 649              {
 650                  // Reached the start of this doc block
 651                  throw new \LogicException("Can not find '@{$find_tag}' information for event "
 652                      . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 1);
 653              }
 654  
 655              foreach ($disallowed_tags as $disallowed_tag)
 656              {
 657                  if ($found_comment_end && strpos(ltrim($this->file_lines[$this->current_event_line - $find_tag_line], "\t "), '* @' . $disallowed_tag) === 0)
 658                  {
 659                      // Found @var after the @since
 660                      throw new \LogicException("Found '@{$disallowed_tag}' information after '@{$find_tag}' for event "
 661                          . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 3);
 662                  }
 663              }
 664  
 665              if (ltrim($this->file_lines[$this->current_event_line - $find_tag_line], "\t ") === '*/')
 666              {
 667                  $found_comment_end = true;
 668              }
 669  
 670              $find_tag_line++;
 671              if ($find_tag_line >= $this->current_event_line)
 672              {
 673                  // Reached the start of the file
 674                  throw new \LogicException("Can not find '@{$find_tag}' information for event "
 675                      . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 2);
 676              }
 677          }
 678  
 679          return $this->current_event_line - $find_tag_line;
 680      }
 681  
 682      /**
 683      * Find a "@*" Information line
 684      *
 685      * @return int Absolute line number
 686      * @throws \LogicException
 687      */
 688  	public function find_description()
 689      {
 690          $find_desc_line = 0;
 691          while (ltrim($this->file_lines[$this->current_event_line - $find_desc_line], "\t") !== '/**')
 692          {
 693              $find_desc_line++;
 694              if ($find_desc_line > $this->current_event_line)
 695              {
 696                  // Reached the start of the file
 697                  throw new \LogicException("Can not find a description for event "
 698                      . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 1);
 699              }
 700          }
 701  
 702          $find_desc_line = $this->current_event_line - $find_desc_line + 1;
 703  
 704          $desc = trim($this->file_lines[$find_desc_line]);
 705          if (strpos($desc, '* @') === 0 || $desc[0] !== '*' || substr($desc, 1) == '')
 706          {
 707              // First line of the doc block is a @-line, empty or only contains "*"
 708              throw new \LogicException("Can not find a description for event "
 709                  . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 2);
 710          }
 711  
 712          return $find_desc_line;
 713      }
 714  
 715      /**
 716      * Validate "@since" Information
 717      *
 718      * @param string $line
 719      * @return string
 720      * @throws \LogicException
 721      */
 722  	public function validate_since($line)
 723      {
 724          $match = array();
 725          preg_match('#^\* @since (\d+\.\d+\.\d+(?:-(?:a|b|RC|pl)\d+)?)$#', ltrim($line, "\t "), $match);
 726          if (!isset($match[1]))
 727          {
 728              throw new \LogicException("Invalid '@since' information for event "
 729                  . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'");
 730          }
 731  
 732          return $match[1];
 733      }
 734  
 735      /**
 736      * Validate "@changed" Information
 737      *
 738      * @param string $line
 739      * @return string
 740      * @throws \LogicException
 741      */
 742  	public function validate_changed($line)
 743      {
 744          $match = array();
 745          $line = str_replace("\t", ' ', ltrim($line, "\t "));
 746          preg_match('#^\* @changed (\d+\.\d+\.\d+(?:-(?:a|b|RC|pl)\d+)?)( (?:.*))?$#', $line, $match);
 747          if (!isset($match[2]))
 748          {
 749              throw new \LogicException("Invalid '@changed' information for event "
 750                  . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'");
 751          }
 752  
 753          return $match[2];
 754      }
 755  
 756      /**
 757      * Validate "@event" Information
 758      *
 759      * @param string $event_name
 760      * @param string $line
 761      * @return string
 762      * @throws \LogicException
 763      */
 764  	public function validate_event($event_name, $line)
 765      {
 766          $event = substr(ltrim($line, "\t "), strlen('* @event '));
 767  
 768          if ($event !== trim($event))
 769          {
 770              throw new \LogicException("Invalid '@event' information for event "
 771                  . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 1);
 772          }
 773  
 774          if ($event !== $event_name)
 775          {
 776              throw new \LogicException("Event name does not match '@event' tag for event "
 777                  . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 2);
 778          }
 779  
 780          return $event;
 781      }
 782  
 783      /**
 784      * Validates that two arrays contain the same strings
 785      *
 786      * @param array $vars_array        Variables found in the array line
 787      * @param array $vars_docblock    Variables found in the doc block
 788      * @return null
 789      * @throws \LogicException
 790      */
 791  	public function validate_vars_docblock_array($vars_array, $vars_docblock)
 792      {
 793          $vars_array = array_unique($vars_array);
 794          $vars_docblock = array_unique($vars_docblock);
 795          $sizeof_vars_array = count($vars_array);
 796  
 797          if ($sizeof_vars_array !== count($vars_docblock) || $sizeof_vars_array !== count(array_intersect($vars_array, $vars_docblock)))
 798          {
 799              throw new \LogicException("\$vars array does not match the list of '@var' tags for event "
 800                  . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'");
 801          }
 802      }
 803  }


Generated: Thu Mar 24 21:31:15 2022 Cross-referenced by PHPXref 0.7.1