A super easy PHP Framework for web development! https://github.com/exacti/phacil-framework
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

246 lines
5.5 KiB

<?php
/**
* @copyright © 2022 ExacTI Technology Solutions. All rights reserved.
* GPLv3 General License.
* https://exacti.com.br
* Phacil PHP Framework - https://github.com/exacti/phacil-framework
* @author Bruno O. Notario <bruno@exacti.com.br>
*/
namespace Phacil\Framework;
/**
* PHPDoc Parser
*
* Simple example usage:
* @example $a = new Parser($string); $a->parse();
*
* @package Phacil\Framework
* @since 2.0.0
*/
class PHPDocParser {
/**
* The PHPDoc string that we want to parse
* @var string
*/
private $string;
/**
* Storge for the short description
* @var string
*/
private $shortDesc;
/**
* Storge for the long description
*
* @var string
*/
private $longDesc;
/**
* Storge for all the PHPDoc parameters
*
* @var array
*/
private $params = [];
/**
* Parse each line
*
* Takes an array containing all the lines in the string and stores
* the parsed information in the object properties
*
* @param array $lines An array of strings to be parsed
*/
private function parseLines($lines) {
foreach($lines as $line) {
$parsedLine = $this->parseLine($line); //Parse the line
if($parsedLine === false && empty($this->shortDesc)) {
if(isset($desc) && is_array($desc))
$this->shortDesc = implode(PHP_EOL, $desc); //Store the first line in the short description
$desc = array();
} elseif($parsedLine !== false) {
$desc[] = $parsedLine; //Store the line in the long description
}
}
$this->longDesc = implode(PHP_EOL, $desc);
}
/**
* Parse the line
*
* Takes a string and parses it as a PHPDoc comment
*
* @param string $line The line to be parsed
* @return string|bool|array False if the line contains no parameters or paramaters that aren't valid otherwise, the line that was passed in.
*/
private function parseLine($line) {
//Trim the whitespace from the line
$line = trim($line);
if(empty($line)) return false; //Empty line
if(strpos($line, '@') === 0) {
$param = substr($line, 1, strpos($line, ' ') - 1); //Get the parameter name
$value = substr($line, strlen($param) + 2); //Get the value
if($this->setParam($param, $value)) return false; //Parse the line and return false if the parameter is valid
}
return $line;
}
/**
* Setup the valid parameters
*
* @param string $type NOT USED
*/
private function setupParams($type = "") {
$params = array(
"access" => '',
"author" => '',
"copyright" => '',
"deprecated"=> '',
"example" => '',
"ignore" => '',
"internal" => '',
"link" => '',
"param" => '',
"return" => '',
"see" => '',
"since" => '',
"tutorial" => '',
"version" => '',
'throws' => '',
'todo' => ''
);
$this->params = $params;
}
/**
* Parse a parameter or string to display in simple typecast display
*
* @param string $string The string to parse
* @return string Formatted string wiht typecast
*/
private function formatParamOrReturn($string) {
//$pos = strpos($string, ' ');
$parts = preg_split('/\s+/', $string, 3, PREG_SPLIT_NO_EMPTY);
//$type = substr($string, 0, $pos);
if(count($parts) == 3) {
$return = [
$parts[1] => [
'type' => (strpos($parts[0], '|')) ? explode('|',$parts[0]) : $parts[0],
'desc' => $parts[2]
]
];
} elseif (count($parts) == 2) {
$return = [
$parts[1] => [
'type' => (strpos($parts[0], '|')) ? explode('|', $parts[0]) : $parts[0]
]
];
} elseif (count($parts) == 1) {
$return = (strpos($parts[0], '|')) ? explode('|', $parts[0]) : $parts[0];
} else { $return = '';}
//return '(' . $type . ')' . substr($string, $pos+1);
return $return;
}
/**
* Set a parameter
*
* @param string $param The parameter name to store
* @param string $value The value to set
* @return bool True = the parameter has been set, false = the parameter was invalid
*/
private function setParam($param, $value)
{
if (!array_key_exists($param, $this->params)) $this->params[$param] = '';
if ($param == 'param' || $param == 'return') $value = $this->formatParamOrReturn($value);
if (empty($this->params[$param])) {
$this->params[$param] = $value;
} elseif (is_array($this->params[$param])) {
$this->params[$param] = array_merge($this->params[$param], (is_array($value) ? $value : array($value)));
} elseif (is_string($this->params[$param])) {
$this->params[$param] = array($this->params[$param], $value);
}
return true;
}
/**
* Setup the initial object
*
* @param string $string The string we want to parse
*/
public function __construct($string) {
$this->string = $string;
//$this->setupParams();
}
/**
* Parse the string
* @return void
*/
public function parse() {
//Get the comment
if(preg_match('#^/\*\*(.*)\*/#s', $this->string, $comment) === false)
die("Error");
$comment = trim($comment[1]);
//Get all the lines and strip the * from the first character
if(preg_match_all('#^\s*\*(.*)#m', $comment, $lines) === false)
die('Error');
$this->parseLines($lines[1]);
}
/**
* Get the short description
*
* @return string The short description
*/
public function getShortDesc() {
return $this->shortDesc;
}
/**
* Get the long description
*
* @return string The long description
*/
public function getDesc() {
return $this->longDesc;
}
/**
* Get the parameters
*
* @return array The parameters
*/
public function getParams() {
return $this->params;
}
/**
* @param string $key
* @return mixed
*/
public function get($key){
return ($this->$key) ?: null;
}
}