<?php
namespace Tlf;
class ProviOld {
/**
* the state of the current request
*/
public $state = [];
/**
* the directory containing all your git repos
*/
public string $dir;
/**
* all urls for documentation will begin with this url. This url will show a list of projects
*/
public string $base_url;
/**
* the directory where all the views are found
*/
public string $view_dir;
/**
* @param $project_dir the directory containing all your git repos
* @param $base_url all urls for documentation will begin with this url. This url will show a list of projects
* @param $vendor_name the name of the vendor these projects belong to
*/
public function __construct(string $project_dir, string $base_url, string $vendor_name){
$this->dir = $project_dir;
$this->base_url = $base_url;
$this->view_dir = dirname(__DIR__).'/view/';
$this->name = $vendor_name;
}
/**
* Get a response to a request
* @return false on failure or on success an array containing keys `css`, `js`, and `content`, where `content` is a string, and the other two are arrays of `key=>value` where `key` is url & `value` is file path
*/
public function route(){
$url = $_SERVER['REQUEST_URI'];
$pos = strpos($url, '?');
if ($pos!==false)$url = substr($url,0, $pos);
if (substr($url,0,$len=strlen($this->base_url))!==$this->base_url)return false;
$url = substr($url,$len);
if ($url[0]!='/')$url = '/'.$url;
$resources = $this->view('Resources')->resources();
$response_view = $this->get_response($url);
if ($response_view===false)return false;
$response_resources = $response_view->resources();
$all_resources = array_merge($resources, $response_resources);
$all_resources = $this->cleanup_resources($all_resources);
$response = $all_resources;
$response['content'] = $response_view.'';
return $response;
}
/**
* Get a url-specific response ... @see(route()) wraps this to make it easier to send all resource files
*
* @param $url the relative url (base url is removed)
* @return a view on success or `false` on failure
*/
public function get_response($url){
if ($url=='/'){
$view = $this->view('ProjectSelector');
return $view;
}
$state = $this->get_state($url);
$this->state = $state;
// print_r($project);
if ($state->rel_file_path=='/'){
$view = $this->view('ProjectLayout',
[ 'project'=>$state->project,
],
);
return $view;
}
return false;
}
/**
* does nothing ... just here so `\Lia\View` doesn't crash
*/
public function addResourceFile(){}
public function all_projects(){
$projects = [];
foreach (scandir($this->dir) as $file){
if ($file=='.'||$file=='..')continue;
if (!is_dir($path = $this->dir.'/'.$file))continue;
$projects[$file] = $this->get_project($file);
}
return $projects;
}
/**
* @param $project_dir the relative path name inside `$this->dir`
*/
public function get_project($project_dir){
$path = $this->dir.'/'.$project_dir;
$url = $this->base_url.'/'.$project_dir;
$url = str_replace('//','/',$url);
$project = (object)[
'name'=>basename($project_dir),
'dir'=>$project_dir,
// @todo make docs dir configurable
'url'=>$url,
// @todo add project descriptions
'description'=>'project descriptions not yet implemented.',
'src_url'=>$url.'-src',
'docs_url'=>$url,
// 'file'=>
];
return $project;
}
/**
* take the file paths as given by `Lia\Obj\View` and convert them into an array like `['css'=>['/url.css'=>'/path/to/css/file.css'], 'js'=>[...]]`
*/
public function cleanup_resources(array $resources){
$clean = [];
foreach ($resources as $file_path){
$url = substr($file_path,strlen($this->view_dir));
$ext = pathinfo($file_path,PATHINFO_EXTENSION);
$url = $this->base_url.'/files/'.$url;
$url = str_replace('//', '/', $url);
$clean[$ext][$url] = $file_path;
}
return $clean;
}
public function view($rel_name, $args=[]){
$args['lia'] = $this;
$args['provi'] = $this;
$args['state'] = $this->state;
$view = new \Lia\Obj\View('Docu/'.$rel_name, $this->view_dir, $args);
return $view;
}
/**
* @param $url the relative url path
*/
public function get_state($url){
$parsed_url = $this->parse_url($url);
$project = $this->get_project($parsed_url['project_name']);
$branch = $parsed_url['branch'];
if (empty($branch))$branch = $this->get_default_branch($project);
// $state['project'] = $project;
$branch_dir = $this->dir.'/'.$project->name.'/'.$branch.'/';
$file_path = $branch_dir.$parsed_url['path'];
$dir_path = is_dir($file_path) ? $file_path : dirname($file_path);
$state = [
'type'=>$parsed_url['type'],
'branch'=> $branch,
'file_path'=>$file_path,
'rel_file_path'=>$parsed_url['path'],
'dir_path'=>$dir_path,
'project'=>$project,
'parsed_url'=> $parsed_url,
];
return (object)$state;
// print_r($state);
}
/**
* Parse a url into its project-parts. ONLY looks at the url ... does not load any configs or defaults or anything.
*/
public function parse_url(string $url){
$parts = explode('/',$url);
array_shift($parts); // remove the empty element
$project_name = array_shift($parts);
$project_name_parts = explode(':',$project_name);
$project_name = $project_name_parts[0];
if (substr($project_name,-4)=='-src'){
$project_name = substr($project_name,0,-4);
$type = 'src';
} else $type = 'docs';
$branch = $project_name_parts[1] ?? null;
$parsed = [
'project_name' => $project_name,
'type' => $type,
'branch' => $branch, // state will have to fill this in if it's null
'path' => '/'.implode('/', $parts),
];
return $parsed;
}
/**
* @return false if not a request for provi. return array containing parsed info if is a request for provi
*/
public function parse_url2(string $url){
$parsed = [];
$base_url = $this->base_url;
// check if it's a request to provi
if (substr($url,0,strlen($base_url))==$base_url){
$parsed['prefix'] = $base_url;
} else {
return false;
}
// check if request to project listing
$rel_url = substr($url,strlen($base_url));
if ($rel_url==''){
$project = new \Tlf\Provi\Project();
$project->type = 'project_listing';
$project->prefix = $base_url;
return $project;
}
// parse out the project name & branch
$parts = explode('/', $rel_url);
// array_shift($parts); // might need this if the prefix does not end with a `/`
$project_name_and_branch = array_shift($parts);
$parsed['project_url'] = $base_url.'/'.$project_name_and_branch.'/';
$pnab_parts = explode(':', $project_name_and_branch);
if (count($pnab_parts)>1){
$parsed['branch'] = $pnab_parts[1];
} else {
// what info do i need to get the default branch?
// project name
$parsed['branch'] = 'v0.9';//$this->get_default_branch();
}
// parse out the type (src or docs)
$project_name_and_type = $pnab_parts[0];
if (substr($project_name_and_type,-4)=='-src'){
$parsed['project_name'] = substr($project_name_and_type,0,-4);
$parsed['type']='src';
} else {
$parsed['project_name'] = $project_name_and_type;
$parsed['type'] = 'docs';
}
// determine the branch dir
$project_branch_dir = $this->dir.'/'.$parsed['project_name'].'/'.$parsed['branch'].'/';
$parsed['branch_dir'] = $project_branch_dir;
if ($parsed['type']=='docs'){
$docs_dir = $this->get_docs_dir($parsed['branch_dir']);
$file_base_dir = $project_branch_dir.'/'.$docs_dir.'/';//$this->get_docs_dir();
} else {
$file_base_dir = $project_branch_dir;
}
// build the absolute paths
$parsed['docs_dir'] = $project_branch_dir.'/'.$this->get_docs_dir($parsed['branch_dir']).'/';
$parsed['rel_file_path'] = implode('/', $parts);
$parsed['abs_file_path'] = str_replace('//','/',
$file_base_dir.'/'.$parsed['rel_file_path']
);
if (is_dir($parsed['abs_file_path'])){
$parsed['rel_dir_path'] = $parsed['rel_file_path'].'/';
$parsed['abs_dir_path'] = $parsed['abs_file_path'].'/';
// check for a README
if (file_exists($readme_path=$parsed['abs_file_path'].'README.md')){
$parsed['abs_file_path'] = $readme_path;
$parsed['rel_file_path'] .= 'README.md';
}
} else {
$parsed['rel_dir_path'] = dirname($parsed['rel_file_path']).'/';
if ($parsed['rel_dir_path']=='./')$parsed['rel_dir_path'] = '/';
$parsed['abs_dir_path'] = dirname($parsed['abs_file_path']).'/';
}
// remove duplicate forward slashes
$parsed = array_map(
function($v){
return str_replace('//', '/',$v);
},
$parsed
);
// convert array to object
$project = new \Tlf\Provi\Project();
foreach ($parsed as $k=>$v){
$project->$k = $v;
}
return $project;
}
/**
* @return false on failure or the relative path inside the branch dir in which docs are contained
*/
public function get_docs_dir(string $branch_dir){
$try = [
'doc','docs'
];
foreach ($try as $d){
if (is_dir($branch_dir.'/'.$d)){
return $d;
}
}
return false;
}
/**
* @param $project the project as from get_project()
*/
public function get_default_branch(object $project){
//@todo actually figure out default branch
return 'v0.9';
}
/**
* get an array of files & directories in the given dir.
*
* @return array ['files'=>['file1','file2'], 'dirs'=>['dir1','dir2']]
*/
public function files_in_dir(string $dir){
$files = [];
foreach (scandir($dir) as $f){
if ($f=='..'||$f=='.')continue;
if (is_file($dir.'/'.$f))$files['files'][] = $f;
else $files['dirs'][] = $f;
}
rsort($files['dirs']);
rsort($files['files']);
return $files;
}
}