Refactor the tree system
Each element of the tree now only has one parent, not a parent array. - Creating an elements doesn't necessarily rely on an existing file - Moving elements unregisters elements from the previous parent - Moved some helpers to the builder instead of Entry
This commit is contained in:
parent
3235c49acd
commit
aa5602a0fb
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
use Symfony\Component\Console\Output\NullOutput;
|
use Symfony\Component\Console\Output\NullOutput;
|
||||||
use Todaymade\Daux\Tree\Builder;
|
use Todaymade\Daux\Tree\Builder;
|
||||||
|
use Todaymade\Daux\Tree\Root;
|
||||||
|
|
||||||
class Daux
|
class Daux
|
||||||
{
|
{
|
||||||
@ -124,7 +125,9 @@ class Daux
|
|||||||
|
|
||||||
private function generateTree()
|
private function generateTree()
|
||||||
{
|
{
|
||||||
$this->tree = Builder::build($this->docs_path, $this->options['ignore'], $this->getParams());
|
$this->tree = new Root($this->docs_path);
|
||||||
|
Builder::build($this->tree, $this->options['ignore'], $this->getParams());
|
||||||
|
|
||||||
if (!empty($this->options['languages'])) {
|
if (!empty($this->options['languages'])) {
|
||||||
foreach ($this->options['languages'] as $key => $node) {
|
foreach ($this->options['languages'] as $key => $node) {
|
||||||
$this->tree->getEntries()[$key]->title = $node;
|
$this->tree->getEntries()[$key]->title = $node;
|
||||||
|
@ -11,8 +11,7 @@ class MarkdownPage extends \Todaymade\Daux\Format\Base\MarkdownPage
|
|||||||
if ($this->title === 'index') {
|
if ($this->title === 'index') {
|
||||||
$minimum_parent_dir_size = ($this->params['multilanguage']) ? 2 : 1;
|
$minimum_parent_dir_size = ($this->params['multilanguage']) ? 2 : 1;
|
||||||
if (count($this->file->getParents()) >= $minimum_parent_dir_size) {
|
if (count($this->file->getParents()) >= $minimum_parent_dir_size) {
|
||||||
$parents = $this->file->getParents();
|
$this->title = $this->file->getParent()->getTitle();
|
||||||
$this->title = end($parents)->getTitle();
|
|
||||||
} else {
|
} else {
|
||||||
$this->homepage = ($this->file->getName() === '_index');
|
$this->homepage = ($this->file->getName() === '_index');
|
||||||
$this->title = $this->params['title'];
|
$this->title = $this->params['title'];
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<?php namespace Todaymade\Daux\Tree;
|
<?php namespace Todaymade\Daux\Tree;
|
||||||
|
|
||||||
|
use Todaymade\Daux\Config;
|
||||||
use Todaymade\Daux\Daux;
|
use Todaymade\Daux\Daux;
|
||||||
use Todaymade\Daux\DauxHelper;
|
use Todaymade\Daux\DauxHelper;
|
||||||
|
|
||||||
@ -8,25 +9,19 @@ class Builder
|
|||||||
/**
|
/**
|
||||||
* Build the initial tree
|
* Build the initial tree
|
||||||
*
|
*
|
||||||
* @param string $dir
|
* @param Directory $node
|
||||||
* @param array $ignore
|
* @param array $ignore
|
||||||
* @param \Todaymade\Daux\Config $params
|
* @param Config $params
|
||||||
* @param array $parents
|
|
||||||
* @return Directory|void
|
|
||||||
*/
|
*/
|
||||||
public static function build($dir, $ignore, $params, $parents = null)
|
public static function build($node, $ignore, Config $params)
|
||||||
{
|
{
|
||||||
if (!$dh = opendir($dir)) {
|
if (!$dh = opendir($node->getPath())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$node = new Directory($dir, $parents);
|
if ($node instanceof Root) {
|
||||||
|
// Ignore config.json in the root directory
|
||||||
$new_parents = $parents;
|
$ignore['files'][] = 'config.json';
|
||||||
if (is_null($new_parents)) {
|
|
||||||
$new_parents = array();
|
|
||||||
} else {
|
|
||||||
$new_parents[] = $node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (($file = readdir($dh)) !== false) {
|
while (($file = readdir($dh)) !== false) {
|
||||||
@ -34,7 +29,7 @@ class Builder
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$path = $dir . DS . $file;
|
$path = $node->getPath() . DS . $file;
|
||||||
|
|
||||||
if (is_dir($path) && in_array($file, $ignore['folders'])) {
|
if (is_dir($path) && in_array($file, $ignore['folders'])) {
|
||||||
continue;
|
continue;
|
||||||
@ -45,19 +40,12 @@ class Builder
|
|||||||
|
|
||||||
$entry = null;
|
$entry = null;
|
||||||
if (is_dir($path)) {
|
if (is_dir($path)) {
|
||||||
$entry = static::build($path, $ignore, $params, $new_parents);
|
$new = new Directory($node, static::getUriFromFilename(static::getFilename($path)), $path);
|
||||||
} elseif (in_array(pathinfo($path, PATHINFO_EXTENSION), Daux::$VALID_MARKDOWN_EXTENSIONS)) {
|
$new->setName(DauxHelper::pathinfo($path)['filename']);
|
||||||
$entry = new Content($path, $new_parents);
|
$new->setTitle(static::getTitleFromFilename($new->getName()));
|
||||||
|
static::build($new, $ignore, $params);
|
||||||
if ($params['mode'] === Daux::STATIC_MODE) {
|
|
||||||
$entry->setUri($entry->getUri() . '.html');
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
$entry = new Raw($path, $new_parents);
|
static::createContent($node, $path, $params);
|
||||||
}
|
|
||||||
|
|
||||||
if ($entry instanceof Entry) {
|
|
||||||
$node->addChild($entry);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +56,91 @@ class Builder
|
|||||||
} else {
|
} else {
|
||||||
$node->setIndexPage(false);
|
$node->setIndexPage(false);
|
||||||
}
|
}
|
||||||
return $node;
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Directory $parent
|
||||||
|
* @param string $path
|
||||||
|
* @param Config $params
|
||||||
|
* @return Content|Raw
|
||||||
|
*/
|
||||||
|
public static function createContent(Directory $parent, $path, Config $params)
|
||||||
|
{
|
||||||
|
$name = DauxHelper::pathinfo($path)['filename'];
|
||||||
|
|
||||||
|
if (in_array(pathinfo($path, PATHINFO_EXTENSION), Daux::$VALID_MARKDOWN_EXTENSIONS)) {
|
||||||
|
$uri = static::getUriFromFilename($name);
|
||||||
|
if ($params['mode'] === Daux::STATIC_MODE) {
|
||||||
|
$uri .= '.html';
|
||||||
|
}
|
||||||
|
|
||||||
|
$entry = new Content($parent, $uri, $path, filemtime($path));
|
||||||
|
} else {
|
||||||
|
$entry = new Raw($parent, static::getUriFromFilename(static::getFilename($path)), $path, filemtime($path));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($entry->getUri() == $params['index_key']) {
|
||||||
|
if ($parent instanceof Root) {
|
||||||
|
$entry->setTitle($params['title']);
|
||||||
|
} else {
|
||||||
|
$entry->setTitle($parent->getTitle());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$entry->setTitle(static::getTitleFromFilename($name));
|
||||||
|
}
|
||||||
|
|
||||||
|
$entry->setIndexPage(false);
|
||||||
|
$entry->setName($name);
|
||||||
|
|
||||||
|
return $entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $file
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected static function getFilename($file)
|
||||||
|
{
|
||||||
|
$parts = explode('/', $file);
|
||||||
|
return end($parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $filename
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected static function getTitleFromFilename($filename)
|
||||||
|
{
|
||||||
|
$filename = explode('_', $filename);
|
||||||
|
if ($filename[0] == '' || is_numeric($filename[0])) {
|
||||||
|
unset($filename[0]);
|
||||||
|
} else {
|
||||||
|
$t = $filename[0];
|
||||||
|
if ($t[0] == '-') {
|
||||||
|
$filename[0] = substr($t, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$filename = implode(' ', $filename);
|
||||||
|
return $filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $filename
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected static function getUriFromFilename($filename)
|
||||||
|
{
|
||||||
|
$filename = explode('_', $filename);
|
||||||
|
if ($filename[0] == '' || is_numeric($filename[0])) {
|
||||||
|
unset($filename[0]);
|
||||||
|
} else {
|
||||||
|
$t = $filename[0];
|
||||||
|
if ($t[0] == '-') {
|
||||||
|
$filename[0] = substr($t, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$filename = implode('_', $filename);
|
||||||
|
return $filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -84,48 +156,38 @@ class Builder
|
|||||||
return $parent->getEntries()[$slug];
|
return $parent->getEntries()[$slug];
|
||||||
}
|
}
|
||||||
|
|
||||||
$dir = new Directory();
|
$dir = new Directory($parent, $slug);
|
||||||
$dir->setTitle($title);
|
$dir->setTitle($title);
|
||||||
$dir->setUri($slug);
|
|
||||||
$parent->addChild($dir);
|
|
||||||
|
|
||||||
return $dir;
|
return $dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $parents
|
* @param Directory $parent
|
||||||
* @param string $title
|
* @param string $title
|
||||||
* @return Content
|
* @return Content
|
||||||
*/
|
*/
|
||||||
public static function getOrCreatePage($parents, $title)
|
public static function getOrCreatePage(Directory $parent, $title)
|
||||||
{
|
{
|
||||||
$slug = DauxHelper::slug($title);
|
$slug = DauxHelper::slug($title);
|
||||||
$uri = $slug . ".html";
|
$uri = $slug . ".html";
|
||||||
|
|
||||||
/**
|
if (array_key_exists($uri, $parent->getEntries())) {
|
||||||
* @var Directory $nearestParent
|
return $parent->getEntries()[$uri];
|
||||||
*/
|
|
||||||
$nearestParent = end($parents);
|
|
||||||
|
|
||||||
if (array_key_exists($uri, $nearestParent->getEntries())) {
|
|
||||||
return $nearestParent->getEntries()[$uri];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$page = new Content('', $parents);
|
$page = new Content($parent, $uri);
|
||||||
$page->setUri($uri);
|
|
||||||
$page->setContent("-"); //set an almost empty content to avoid problems
|
$page->setContent("-"); //set an almost empty content to avoid problems
|
||||||
|
|
||||||
if ($title == 'index') {
|
if ($title == 'index') {
|
||||||
$page->setName('_index');
|
$page->setName('_index');
|
||||||
$page->setTitle($nearestParent->getTitle());
|
$page->setTitle($parent->getTitle());
|
||||||
$nearestParent->setIndexPage($page);
|
$parent->setIndexPage($page);
|
||||||
} else {
|
} else {
|
||||||
$page->setName($slug);
|
$page->setName($slug);
|
||||||
$page->setTitle($title);
|
$page->setTitle($title);
|
||||||
}
|
}
|
||||||
|
|
||||||
$nearestParent->addChild($page);
|
|
||||||
|
|
||||||
return $page;
|
return $page;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,6 @@ class Directory extends Entry
|
|||||||
|
|
||||||
public function addChild(Entry $entry)
|
public function addChild(Entry $entry)
|
||||||
{
|
{
|
||||||
//TODO :: set parent in the entry
|
|
||||||
//TODO :: remove child from previous parent
|
|
||||||
|
|
||||||
$this->children[$entry->getUri()] = $entry;
|
$this->children[$entry->getUri()] = $entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,4 +68,15 @@ class Directory extends Entry
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function dump()
|
||||||
|
{
|
||||||
|
$dump = parent::dump();
|
||||||
|
|
||||||
|
foreach ($this->getEntries() as $entry) {
|
||||||
|
$dump['children'][] = $entry->dump();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $dump;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
<?php namespace Todaymade\Daux\Tree;
|
<?php namespace Todaymade\Daux\Tree;
|
||||||
|
|
||||||
use Todaymade\Daux\DauxHelper;
|
|
||||||
|
|
||||||
abstract class Entry
|
abstract class Entry
|
||||||
{
|
{
|
||||||
/** @var string */
|
/** @var string */
|
||||||
@ -19,23 +17,33 @@ abstract class Entry
|
|||||||
/** @var string */
|
/** @var string */
|
||||||
protected $uri;
|
protected $uri;
|
||||||
|
|
||||||
|
/** @var Directory */
|
||||||
|
protected $parent;
|
||||||
|
|
||||||
/** @var string */
|
/** @var string */
|
||||||
protected $local_path;
|
protected $path;
|
||||||
|
|
||||||
/** @var integer */
|
/** @var integer */
|
||||||
protected $last_modified;
|
protected $last_modified;
|
||||||
|
|
||||||
/** @var array */
|
|
||||||
protected $parents;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param Directory $parent
|
||||||
|
* @param string $uri
|
||||||
* @param string $path
|
* @param string $path
|
||||||
* @param array $parents
|
* @param integer $last_modified
|
||||||
*/
|
*/
|
||||||
public function __construct($path = '', $parents = array())
|
public function __construct(Directory $parent, $uri, $path = null, $last_modified = null)
|
||||||
{
|
{
|
||||||
$this->setPath($path);
|
$this->setUri($uri);
|
||||||
$this->setParents($parents);
|
$this->setParent($parent);
|
||||||
|
|
||||||
|
if ($path) {
|
||||||
|
$this->path = $path;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($last_modified) {
|
||||||
|
$this->last_modified = $last_modified;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -67,7 +75,15 @@ abstract class Entry
|
|||||||
*/
|
*/
|
||||||
public function setUri($uri)
|
public function setUri($uri)
|
||||||
{
|
{
|
||||||
|
if ($this->parent) {
|
||||||
|
$this->parent->removeChild($this);
|
||||||
|
}
|
||||||
|
|
||||||
$this->uri = $uri;
|
$this->uri = $uri;
|
||||||
|
|
||||||
|
if ($this->parent) {
|
||||||
|
$this->parent->addChild($this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -102,7 +118,7 @@ abstract class Entry
|
|||||||
// First we try to find a real page
|
// First we try to find a real page
|
||||||
foreach ($this->getEntries() as $node) {
|
foreach ($this->getEntries() as $node) {
|
||||||
if ($node instanceof Content) {
|
if ($node instanceof Content) {
|
||||||
if (!count($node->getParents()) && $node->title == 'index') {
|
if (!$node->getParent() && $node->title == 'index') {
|
||||||
//the homepage should not count as first page
|
//the homepage should not count as first page
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -148,19 +164,40 @@ abstract class Entry
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array
|
* @return Directory
|
||||||
*/
|
*/
|
||||||
public function getParents()
|
public function getParent()
|
||||||
{
|
{
|
||||||
return $this->parents;
|
return $this->parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $parents
|
* Return all parents starting with the root
|
||||||
|
*
|
||||||
|
* @return array<Directory>
|
||||||
*/
|
*/
|
||||||
public function setParents($parents)
|
public function getParents()
|
||||||
{
|
{
|
||||||
$this->parents = $parents;
|
$parents = [];
|
||||||
|
if ($this->parent && !$this->parent instanceof Root) {
|
||||||
|
$parents = $this->parent->getParents();
|
||||||
|
$parents[] = $this->parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $parents;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Directory $parent
|
||||||
|
*/
|
||||||
|
protected function setParent(Directory $parent)
|
||||||
|
{
|
||||||
|
if ($this->parent) {
|
||||||
|
$this->parent->removeChild($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
$parent->addChild($this);
|
||||||
|
$this->parent = $parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -168,23 +205,7 @@ abstract class Entry
|
|||||||
*/
|
*/
|
||||||
public function getPath()
|
public function getPath()
|
||||||
{
|
{
|
||||||
return $this->local_path;
|
return $this->path;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $path
|
|
||||||
*/
|
|
||||||
public function setPath($path)
|
|
||||||
{
|
|
||||||
if (!isset($path) || $path == '' || !file_exists($path)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$this->local_path = $path;
|
|
||||||
$this->last_modified = filemtime($path);
|
|
||||||
$this->name = DauxHelper::pathinfo($path)['filename'];
|
|
||||||
$this->title = $this->getTitleInternal($this->name);
|
|
||||||
$this->uri = $this->getUrlInternal($this->getFilename($path));
|
|
||||||
$this->index_page = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -193,58 +214,26 @@ abstract class Entry
|
|||||||
public function getUrl()
|
public function getUrl()
|
||||||
{
|
{
|
||||||
$url = '';
|
$url = '';
|
||||||
foreach ($this->parents as $node) {
|
|
||||||
$url .= $node->uri . '/';
|
if ($this->getParent() && !$this->getParent() instanceof Root) {
|
||||||
|
$url = $this->getParent()->getUrl() . '/' . $url;
|
||||||
}
|
}
|
||||||
$url .= $this->uri;
|
|
||||||
|
$url .= $this->getUri();
|
||||||
return $url;
|
return $url;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function dump()
|
||||||
* @param string $file
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected function getFilename($file)
|
|
||||||
{
|
{
|
||||||
$parts = explode('/', $file);
|
return [
|
||||||
return end($parts);
|
'title' => $this->getTitle(),
|
||||||
}
|
'type' => get_class($this),
|
||||||
|
'name' => $this->getName(),
|
||||||
/**
|
'uri' => $this->getUri(),
|
||||||
* @param string $filename
|
'url' => $this->getUrl(),
|
||||||
* @return string
|
'index' => $this->getIndexPage()? $this->getIndexPage()->getUrl() : '',
|
||||||
*/
|
'first' => $this->getFirstPage() ? $this->getFirstPage()->getUrl() : '',
|
||||||
protected function getTitleInternal($filename)
|
'path' => $this->path
|
||||||
{
|
];
|
||||||
$filename = explode('_', $filename);
|
|
||||||
if ($filename[0] == '' || is_numeric($filename[0])) {
|
|
||||||
unset($filename[0]);
|
|
||||||
} else {
|
|
||||||
$t = $filename[0];
|
|
||||||
if ($t[0] == '-') {
|
|
||||||
$filename[0] = substr($t, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$filename = implode(' ', $filename);
|
|
||||||
return $filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $filename
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected function getUrlInternal($filename)
|
|
||||||
{
|
|
||||||
$filename = explode('_', $filename);
|
|
||||||
if ($filename[0] == '' || is_numeric($filename[0])) {
|
|
||||||
unset($filename[0]);
|
|
||||||
} else {
|
|
||||||
$t = $filename[0];
|
|
||||||
if ($t[0] == '-') {
|
|
||||||
$filename[0] = substr($t, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$filename = implode('_', $filename);
|
|
||||||
return $filename;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
15
libs/Tree/Root.php
Normal file
15
libs/Tree/Root.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php namespace Todaymade\Daux\Tree;
|
||||||
|
|
||||||
|
class Root extends Directory
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The root doesn't have a parent
|
||||||
|
*
|
||||||
|
* @param Directory $uri
|
||||||
|
*/
|
||||||
|
public function __construct($uri)
|
||||||
|
{
|
||||||
|
$this->setUri($uri);
|
||||||
|
$this->path = $uri;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user