Verzeichnisstruktur phpBB-3.3.15
- Veröffentlicht
- 28.08.2024
So funktioniert es
|
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
php_exporter.php
001 <?php
002 /**
003 *
004 * This file is part of the phpBB Forum Software package.
005 *
006 * @copyright (c) phpBB Limited <https://www.phpbb.com>
007 * @license GNU General Public License, version 2 (GPL-2.0)
008 *
009 * For full copyright and license information, please see
010 * the docs/CREDITS.txt file.
011 *
012 */
013
014 namespace phpbb\event;
015
016 /**
017 * Class php_exporter
018 * Crawls through a list of files and grabs all php-events
019 */
020 class php_exporter
021 {
022 /** @var string Path where we look for files*/
023 protected $path;
024
025 /** @var string phpBB Root Path */
026 protected $root_path;
027
028 /** @var string The minimum version for the events to return */
029 protected $min_version;
030
031 /** @var string The maximum version for the events to return */
032 protected $max_version;
033
034 /** @var string */
035 protected $current_file;
036
037 /** @var string */
038 protected $current_event;
039
040 /** @var int */
041 protected $current_event_line;
042
043 /** @var array */
044 protected $events;
045
046 /** @var array */
047 protected $file_lines;
048
049 /**
050 * @param string $phpbb_root_path
051 * @param mixed $extension String 'vendor/ext' to filter, null for phpBB core
052 * @param string $min_version
053 * @param string $max_version
054 */
055 public function __construct($phpbb_root_path, $extension = null, $min_version = null, $max_version = null)
056 {
057 $this->root_path = $phpbb_root_path;
058 $this->path = $phpbb_root_path;
059 $this->events = $this->file_lines = array();
060 $this->current_file = $this->current_event = '';
061 $this->current_event_line = 0;
062 $this->min_version = $min_version;
063 $this->max_version = $max_version;
064
065 $this->path = $this->root_path;
066 if ($extension)
067 {
068 $this->path .= 'ext/' . $extension . '/';
069 }
070 }
071
072 /**
073 * Get the list of all events
074 *
075 * @return array Array with events: name => details
076 */
077 public function get_events()
078 {
079 return $this->events;
080 }
081
082 /**
083 * Set current event data
084 *
085 * @param string $name Name of the current event (used for error messages)
086 * @param int $line Line where the current event is placed in
087 * @return null
088 */
089 public function set_current_event($name, $line)
090 {
091 $this->current_event = $name;
092 $this->current_event_line = $line;
093 }
094
095 /**
096 * Set the content of this file
097 *
098 * @param array $content Array with the lines of the file
099 * @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 }
804