4 use splitbrain\phpcli\CLI
;
5 use splitbrain\phpcli\Options
;
7 if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__
) . '/../') . '/');
8 define('NOSESSION', 1);
9 require_once(DOKU_INC
. 'inc/init.php');
14 class WantedPagesCLI
extends CLI
{
16 const DIR_CONTINUE
= 1;
20 private $skip = false;
21 private $sort = 'wanted';
23 private $result = array();
26 * Register options and arguments on the given $options object
28 * @param Options $options
31 protected function setup(Options
$options) {
33 'Outputs a list of wanted pages (pages that do not exist yet) and their origin pages ' .
34 ' (the pages that are linkin to these missing pages).'
36 $options->registerArgument(
38 'The namespace to lookup. Defaults to root namespace',
42 $options->registerOption(
44 'Sort by wanted or origin page',
49 $options->registerOption(
51 'Do not show the second dimension',
59 * Arguments and options have been parsed when this is run
61 * @param Options $options
64 protected function main(Options
$options) {
65 $args = $options->getArgs();
67 $startdir = dirname(wikiFN($args[0] . ':xxx'));
69 $startdir = dirname(wikiFN('xxx'));
72 $this->skip
= $options->getOpt('skip');
73 $this->sort
= $options->getOpt('sort');
75 $this->info("searching $startdir");
77 foreach($this->getPages($startdir) as $page) {
78 $this->internalLinks($page);
81 foreach($this->result
as $main => $subs) {
85 $subs = array_unique($subs);
87 foreach($subs as $sub) {
88 printf("%-40s %s\n", $main, $sub);
95 * Determine directions of the search loop
97 * @param string $entry
98 * @param string $basepath
101 protected function dirFilter($entry, $basepath) {
102 if($entry == '.' ||
$entry == '..') {
103 return WantedPagesCLI
::DIR_CONTINUE
;
105 if(is_dir($basepath . '/' . $entry)) {
106 if(strpos($entry, '_') === 0) {
107 return WantedPagesCLI
::DIR_CONTINUE
;
109 return WantedPagesCLI
::DIR_NS
;
111 if(preg_match('/\.txt$/', $entry)) {
112 return WantedPagesCLI
::DIR_PAGE
;
114 return WantedPagesCLI
::DIR_CONTINUE
;
118 * Collects recursively the pages in a namespace
122 * @throws DokuCLI_Exception
124 protected function getPages($dir) {
125 static $trunclen = null;
128 $trunclen = strlen($conf['datadir'] . ':');
132 throw new DokuCLI_Exception("Unable to read directory $dir");
137 while(false !== ($entry = readdir($dh))) {
138 $status = $this->dirFilter($entry, $dir);
139 if($status == WantedPagesCLI
::DIR_CONTINUE
) {
141 } else if($status == WantedPagesCLI
::DIR_NS
) {
142 $pages = array_merge($pages, $this->getPages($dir . '/' . $entry));
145 'id' => pathID(substr($dir . '/' . $entry, $trunclen)),
146 'file' => $dir . '/' . $entry,
156 * Parse instructions and add the non-existing links to the result array
158 * @param array $page array with page id and file path
160 protected function internalLinks($page) {
162 $instructions = p_get_instructions(file_get_contents($page['file']));
163 $cns = getNS($page['id']);
166 foreach($instructions as $ins) {
167 if($ins[0] == 'internallink' ||
($conf['camelcase'] && $ins[0] == 'camelcaselink')) {
169 resolve_pageid($cns, $mid, $exists);
171 list($mid) = explode('#', $mid); //record pages without hashes
173 if($this->sort
== 'origin') {
174 $this->result
[$pid][] = $mid;
176 $this->result
[$mid][] = $pid;
185 $cli = new WantedPagesCLI();