Created
September 19, 2016 17:24
-
-
Save emanuele45/4924876bb2b4d32f1ed6f9d38989a27f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* @name ElkArte hooks/triggers documentor | |
* @copyright ElkArte Forum contributors | |
* @license BSD http://opensource.org/licenses/BSD-3-Clause | |
* | |
* @version 0.0.1 | |
* | |
*/ | |
$output_path = './'; | |
$dir = realpath(dirname(__FILE__) . '/..'); | |
$files = getFilesRecursive($dir); | |
$hooks = array(); | |
foreach ($files as $file) | |
{ | |
$content = new HooksParsing($file); | |
if ($content->hasHooks()) | |
{ | |
$hooks[] = $content; | |
} | |
} | |
print_r($hooks); | |
function getFilesRecursive($dir, $ext = '.php') | |
{ | |
$full_paths = array(); | |
$iterator = new RecursiveIteratorIterator( | |
new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS), | |
RecursiveIteratorIterator::SELF_FIRST, | |
RecursiveIteratorIterator::CATCH_GET_CHILD | |
); | |
$filter = new RegexIterator($iterator, '/' . preg_quote($ext) . '$/'); | |
foreach ($filter as $path => $file) | |
{ | |
if ($file->isDir() === false) | |
{ | |
$full_paths[] = $path; | |
} | |
} | |
return $full_paths; | |
} | |
class HooksParsing | |
{ | |
protected $file_to_parse = ''; | |
protected $file_text = array(); | |
protected $hooks = array(); | |
public function __construct($file_path) | |
{ | |
$this->file_to_parse = $file_path; | |
$this->parseFile(); | |
} | |
public function hasHooks() | |
{ | |
return !empty($this->hooks); | |
} | |
protected function parseFile() | |
{ | |
$this->file_text = @file($this->file_to_parse); | |
if (empty($this->file_text)) | |
{ | |
return; | |
} | |
foreach ($this->file_text as $id => $line) | |
{ | |
if ($this->looksLikeHook($line)) | |
{ | |
$block = $this->searchDocBlock($id); | |
$block[] = $line; | |
$hook = new Hook($block, $this->file_to_parse, $id + 1); | |
if ($hook->isHook()) | |
{ | |
$this->hooks[] = $hook; | |
} | |
} | |
} | |
} | |
protected function searchDocBlock($id) | |
{ | |
$block = array(); | |
if (trim($this->file_text[$id - 1]) == '*/') | |
{ | |
$i = $id - 1; | |
do | |
{ | |
$block[] = $this->file_text[$i]; | |
$i--; | |
} while(trim($this->file_text[$i + 1]) !== '/**'); | |
} | |
return array_reverse($block); | |
} | |
protected function looksLikeHook($line) | |
{ | |
return strpos($line, 'call_integration_hook') !== false; | |
} | |
} | |
class Hook | |
{ | |
protected $block = array(); | |
protected $string = ''; | |
protected $file = ''; | |
protected $line = ''; | |
protected $name = ''; | |
protected $args = array(); | |
protected $docs = array(); | |
public function __construct($block, $file, $line) | |
{ | |
$this->block = $block; | |
$this->string = $block[count($block) - 1]; | |
$this->file = $file; | |
$this->line = $line; | |
$this->parse_name(); | |
if (empty($this->name)) | |
{ | |
return; | |
} | |
$this->parse_args(); | |
$this->parse_doc($block); | |
} | |
public function getName() | |
{ | |
return $this->name; | |
} | |
public function getArgs() | |
{ | |
return $this->args; | |
} | |
public function getDocs() | |
{ | |
return $this->docs; | |
} | |
public function isHook() | |
{ | |
return !empty($this->name); | |
} | |
protected function parse_name() | |
{ | |
preg_match('/call_integration_hook\(\'(.*?)(?:\'?, array\(|\'\))/', $this->string, $hook_name); | |
$this->name = empty($hook_name[1]) ? '' : $hook_name[1]; | |
} | |
protected function parse_args() | |
{ | |
preg_match('/call_integration_hook\(\'' . preg_quote($this->name) . '\'?, array\((.*)\)\)/', $this->string, $hook_args); | |
if (empty($hook_args[1])) | |
{ | |
$this->args = array(); | |
} | |
else | |
{ | |
$this->args = $this->extractArgs($hook_args[1]); | |
} | |
} | |
protected function parse_doc($array) | |
{ | |
$maintext = array(); | |
$params = array(); | |
$is_param = false; | |
$substrposition = 0; | |
unset($array[count($array) - 1]); | |
foreach ($array as $line) | |
{ | |
if (trim($line) === '/**') | |
{ | |
continue; | |
} | |
$tline = ltrim($line); | |
if (substr($tline, 0, 3) == '* @') | |
{ | |
$is_param = true; | |
} | |
if ($is_param === true) | |
{ | |
// Defining a param | |
if (substr($tline, 0, 3) == '* @') | |
{ | |
if (!empty($param)) | |
{ | |
$params[] = $param; | |
} | |
$string = explode(' ', $tline); | |
$param = new DocParam( | |
$string[2], | |
$string[3], | |
implode(' ', array_slice($string, 4)) | |
); | |
$substrposition = strpos($tline, $string[4]); | |
} | |
else | |
{ | |
$param->appendDesc(substr($tline, $substrposition)); | |
} | |
} | |
else | |
{ | |
$maintext[] = substr($tline, 2); | |
} | |
} | |
if (!empty($param)) | |
{ | |
$params[] = $param; | |
print_r($params);die(); | |
} | |
$this->docs = new DocBlock( | |
implode('', $maintext), | |
$params | |
); | |
} | |
protected function extractArgs($string) | |
{ | |
$len = strlen($string); | |
$in = false; | |
$byref = false; | |
$var_name = ''; | |
$vars = array(); | |
for ($i = 0; $i < $len; $i++) | |
{ | |
if ($string[$i] === '&' && isset($string[$i + 1]) && $string[$i + 1] === '$') | |
{ | |
$byref = true; | |
$in = true; | |
} | |
elseif ($string[$i] === '$' && (!isset($string[$i - 1]) || $string[$i - 1] !== '&')) | |
{ | |
$byref = false; | |
$in = true; | |
} | |
if ($string[$i] === ',' || $string[$i] === ')') | |
{ | |
$in = false; | |
$vars[] = new HookArgument($var_name, $byref); | |
$byref = false; | |
$var_name = ''; | |
} | |
if ($in === true) | |
{ | |
$var_name .= $string[$i]; | |
} | |
} | |
return $vars; | |
} | |
} | |
class DocBlock | |
{ | |
protected $text = ''; | |
protected $params = array(); | |
public function __construct($text, $params = array()) | |
{ | |
$this->text = $text; | |
$this->params = $params; | |
} | |
public function getText() | |
{ | |
return rtrim($this->text, "\n"); | |
} | |
public function getParams() | |
{ | |
return $this->params; | |
} | |
} | |
class DocParam | |
{ | |
protected $type = ''; | |
protected $name = ''; | |
protected $description = ''; | |
public function __construct($type, $name, $desc) | |
{ | |
$this->type = $type; | |
$this->name = $name; | |
$this->description = $desc; | |
} | |
public function appendDesc($text) | |
{ | |
$this->description .= $text; | |
} | |
public function getType() | |
{ | |
return $this->type; | |
} | |
public function getName() | |
{ | |
return $this->name; | |
} | |
public function getDesc() | |
{ | |
return rtrim($this->description, "\n"); | |
} | |
} | |
class HookArgument | |
{ | |
protected $name = ''; | |
protected $byref = false; | |
public function __construct($name, $byref = false) | |
{ | |
$this->byref = (bool) $byref; | |
$this->name = $this->cleanName($name); | |
} | |
protected function cleanName($name) | |
{ | |
if (empty($name)) | |
{ | |
return; | |
} | |
if ($name[0] === '&') | |
{ | |
$this->byref = true; | |
$name = substr($name, 1); | |
} | |
return $name; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment