functions.php

<?php

/**
 * Get an array of routes that are easier to work with in scrawl template
 * @param $routes from `$router->routeMap`
 * @param $scrawl scarwl instance for parsing relative paths
 *
 * @return array<string, string> where @key=pattern & @value=printable target
 */
function get_clean_routes(array $routes, $scrawl){
    $clean_routes = [];
    foreach ($routes as $search_pattern=>$route_list){
        $route = $route_list[0];
        // $lia->dump($route);
        $pattern = $route['pattern'];

        $pattern = preg_replace('/(^|(\/))(@POST\.@GET\.|@GET\.@POST\.|@GET|@POST)/', '$2', $pattern);
        $pattern = str_replace(['////','///','//'], '/', $pattern);

        $target = $route['target'];
        if (is_string($target)&&is_file($target)){
            $clean_target = get_friendly_path($target, $scrawl);
        } else if (is_callable($target)){
            $closure = new Lia\Utility\FancyClosure($target, []);
            if ($closure->class != null){
                $class = $closure->class;
                $funcName = $closure->funcName;
                $clean_target = "$class::$funcName()";
            } else if ($closure->isAnonymous){
                $refMethod = new ReflectionFunction($closure->function);
                $full = $refMethod->getFileName();
                $file = get_friendly_path($full, $this);
                $clean_target = "Anonymous function defined in $file";
            }
        }

        $clean_routes[$pattern] = $clean_target;
    }
    return $clean_routes;
}

/**
 * Get a file path you can print in your markdown documentation
 *
 * @param $full_path full file path
 * @param $scrawl because that's required for parsing relative paths
 * @return a relative file path as a markdown link, or `...` followed by the last 15 characters of the file path
 */
function get_friendly_path(string $full_path, \Tlf\Scrawl $scrawl){

    $rel = $scrawl->parse_rel_path($scrawl->dir_root, $full_path, true);
    $file = '';
    if ($rel == null){
        $rel = $scrawl->parse_rel_path($scrawl->dir_root, $full_path, false);
    } 

    if ($rel==null){
        $file = '...'.substr($full_path,-15);
    } else {
        if (substr($rel,0,1)!='/')$rel = '/'.$rel;
        $file = "[$rel]($rel)";
    }

    return $file;
}
/**
 * @return arglist definition, like `string $arg1, array $arg2`
 */
function get_arg_list($scrawl, string $class_name, string $method_name): string {
    $php_ext = new \Tlf\Scrawl\FileExt\Php($scrawl);
    $refClass = new ReflectionClass($class_name);
    $abs_path = $refClass->getFileName();


    $ast = $php_ext->parse_file($abs_path);
    $methods = $ast['namespace']['class'][0]['methods'];
    $method = null;
    foreach ($methods as $m){
        if ($m['name']==$method_name){
            $method = $m;
            break;
        }
    }
    $declarations = [];
    foreach ($method['args'] as $arg){
        $declarations[] = $arg['declaration'];
    }
    $arg_list = implode(', ',$declarations);
    
    return $arg_list;
}

/**
 * @return method description
 */
function get_description($scrawl, string $class_name, string $method_name): string {
    $php_ext = new \Tlf\Scrawl\FileExt\Php($scrawl);
    $refClass = new ReflectionClass($class_name);
    $abs_path = $refClass->getFileName();


    $ast = $php_ext->parse_file($abs_path);
    $methods = $ast['namespace']['class'][0]['methods'];
    $method = null;
    foreach ($methods as $m){
        if ($m['name']==$method_name){
            $method = $m;
            break;
        }
    }
    $description = trim($method['docblock']['description'] ?? 'no description');
    $parts = explode("\n",$description);
    $description = implode("...", $parts);

    return $description;
}

/**
 * @return class description
 */
function get_class_description($scrawl, string $class_name): string {
    $php_ext = new \Tlf\Scrawl\FileExt\Php($scrawl);
    $refClass = new ReflectionClass($class_name);
    $abs_path = $refClass->getFileName();


    $ast = $php_ext->parse_file($abs_path);
    $class = $ast['namespace']['class'][0];
    $description = trim($class['docblock']['description'] ?? 'no description');

    if (strlen(trim($description))=='')$description = 'no description';

    return $description;
}