Skip to content

Instantly share code, notes, and snippets.

@emanuele45
Created September 19, 2016 17:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save emanuele45/4924876bb2b4d32f1ed6f9d38989a27f to your computer and use it in GitHub Desktop.
Save emanuele45/4924876bb2b4d32f1ed6f9d38989a27f to your computer and use it in GitHub Desktop.
<?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