' . "\n" . 'Total: ' . count($pages) .
' page(s) on this site.' . "\n" . '
' . "\n";
}
// Generate a tree
$nodes = array();
foreach ($pages as $page)
$nodes[$page] = new MapNode($page, $reverse);
// Node not found: Because of filtererd by $non_list
if (! isset($nodes[$refer])) $vars['refer'] = $refer = $defaultpage;
if ($reverse) {
$keys = array_keys($nodes);
sort($keys, SORT_STRING);
$alone = array();
$retval['body'] .= '' . "\n";
foreach ($keys as $page) {
if (! empty($nodes[$page]->rels)) {
$retval['body'] .= $nodes[$page]->toString($nodes, 1, $nodes[$page]->parent_id);
} else {
$alone[] = $page;
}
}
$retval['body'] .= '
' . "\n";
if (! empty($alone)) {
$retval['body'] .= '
' . "\n" .
'No link from anywhere in this site.
' . "\n";
$retval['body'] .= '' . "\n";
foreach ($alone as $page)
$retval['body'] .= $nodes[$page]->toString($nodes, 1, $nodes[$page]->parent_id);
$retval['body'] .= '
' . "\n";
}
} else {
$nodes[$refer]->chain($nodes);
$retval['body'] .= '' . "\n" . $nodes[$refer]->toString($nodes) . '
' . "\n";
$retval['body'] .= '
' . "\n" .
'Not related from ' . htmlsc($refer) . '
' . "\n";
$keys = array_keys($nodes);
sort($keys, SORT_STRING);
$retval['body'] .= '' . "\n";
foreach ($keys as $page) {
if (! $nodes[$page]->done) {
$nodes[$page]->chain($nodes);
$retval['body'] .= $nodes[$page]->toString($nodes, 1, $nodes[$page]->parent_id);
}
}
$retval['body'] .= '
' . "\n";
}
// 終了
return $retval;
}
class MapNode
{
var $page;
var $is_page;
var $link;
var $id;
var $rels;
var $parent_id = 0;
var $done;
var $hide_pattern;
function MapNode($page, $reverse = FALSE)
{
$this->__construct($page, $reverse);
}
function __construct($page, $reverse = FALSE)
{
global $non_list;
static $id = 0;
$this->page = $page;
$this->is_page = is_page($page);
$this->cache = CACHE_DIR . encode($page);
$this->done = ! $this->is_page;
$this->link = make_pagelink($page);
$this->id = ++$id;
$this->hide_pattern = '/' . $non_list . '/';
$this->rels = $reverse ? $this->ref() : $this->rel();
$mark = $reverse ? '' : '+';
$this->mark = '' .
$mark . '';
}
function hide(& $pages)
{
if (! PLUGIN_MAP_SHOW_HIDDEN)
$pages = array_diff($pages, preg_grep($this->hide_pattern, $pages));
return $pages;
}
function ref()
{
$refs = array();
$file = $this->cache . '.ref';
if (file_exists($file)) {
foreach (file($file) as $line) {
$ref = explode("\t", $line);
$refs[] = $ref[0];
}
$this->hide($refs);
sort($refs, SORT_STRING);
}
return $refs;
}
function rel()
{
$rels = array();
$file = $this->cache . '.rel';
if (file_exists($file)) {
$data = file($file);
$rels = explode("\t", trim($data[0]));
$this->hide($rels);
sort($rels, SORT_STRING);
}
return $rels;
}
function chain(& $nodes)
{
if ($this->done) return;
$this->done = TRUE;
if ($this->parent_id == 0) $this->parent_id = -1;
foreach ($this->rels as $page) {
if (! isset($nodes[$page])) $nodes[$page] = new MapNode($page);
if ($nodes[$page]->parent_id == 0)
$nodes[$page]->parent_id = $this->id;
}
foreach ($this->rels as $page)
$nodes[$page]->chain($nodes);
}
function toString(& $nodes, $level = 1, $parent_id = -1)
{
$indent = str_repeat(' ', $level);
if (! $this->is_page) {
return $indent . '' . $this->link . '' . "\n";
} else if ($this->parent_id != $parent_id) {
return $indent . '' . $this->link .
'...' . "\n";
}
$retval = $indent . '' . $this->mark . $this->link . "\n";
if (! empty($this->rels)) {
$childs = array();
$level += 2;
foreach ($this->rels as $page)
if (isset($nodes[$page]) && $this->parent_id != $nodes[$page]->id)
$childs[] = $nodes[$page]->toString($nodes, $level, $this->id);
if (! empty($childs))
$retval .= $indent . ' ' . "\n" .
join('', $childs) . $indent . '
' . "\n";
}
$retval .= $indent . '' . "\n";
return $retval;
}
}