xref: /dokuwiki/bin/wantedpages.php (revision e8bb93a50f98b9389d6bdca6124744208cde7728)
1#!/usr/bin/php
2<?php
3if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__) . '/../') . '/');
4define('NOSESSION', 1);
5require_once(DOKU_INC . 'inc/init.php');
6
7class WantedPagesCLI extends DokuCLI {
8
9    const DIR_CONTINUE = 1;
10    const DIR_NS       = 2;
11    const DIR_PAGE     = 3;
12
13    /**
14     * Register options and arguments on the given $options object
15     *
16     * @param DokuCLI_Options $options
17     * @return void
18     */
19    protected function setup(DokuCLI_Options $options) {
20        $options->setHelp(
21                'Outputs a list of wanted pages (pages which have internal links but do not yet exist).'
22        );
23        $options->registerArgument(
24                'namespace',
25                'The namespace to lookup. Defaults to root namespace',
26                false
27        );
28    }
29
30    /**
31     * Your main program
32     *
33     * Arguments and options have been parsed when this is run
34     *
35     * @param DokuCLI_Options $options
36     * @return void
37     */
38    protected function main(DokuCLI_Options $options) {
39
40        if($options->args) {
41            $startdir = dirname(wikiFN($options->args[0] . ':xxx'));
42        } else {
43            $startdir = dirname(wikiFN('xxx'));
44        }
45
46        $this->info("searching $startdir");
47
48        $wanted_pages = array();
49
50        foreach($this->get_pages($startdir) as $page) {
51            $wanted_pages = array_merge($wanted_pages, $this->internal_links($page));
52        }
53        $wanted_pages = array_unique($wanted_pages);
54        sort($wanted_pages);
55
56        foreach($wanted_pages as $page) {
57            print $page . "\n";
58        }
59    }
60
61    protected function dir_filter($entry, $basepath) {
62        if($entry == '.' || $entry == '..') {
63            return WantedPagesCLI::DIR_CONTINUE;
64        }
65        if(is_dir($basepath . '/' . $entry)) {
66            if(strpos($entry, '_') === 0) {
67                return WantedPagesCLI::DIR_CONTINUE;
68            }
69            return WantedPagesCLI::DIR_NS;
70        }
71        if(preg_match('/\.txt$/', $entry)) {
72            return WantedPagesCLI::DIR_PAGE;
73        }
74        return WantedPagesCLI::DIR_CONTINUE;
75    }
76
77    protected function get_pages($dir) {
78        static $trunclen = null;
79        if(!$trunclen) {
80            global $conf;
81            $trunclen = strlen($conf['datadir'] . ':');
82        }
83
84        if(!is_dir($dir)) {
85            throw new DokuCLI_Exception("Unable to read directory $dir");
86        }
87
88        $pages = array();
89        $dh    = opendir($dir);
90        while(false !== ($entry = readdir($dh))) {
91            $status = $this->dir_filter($entry, $dir);
92            if($status == WantedPagesCLI::DIR_CONTINUE) {
93                continue;
94            } else if($status == WantedPagesCLI::DIR_NS) {
95                $pages = array_merge($pages, $this->get_pages($dir . '/' . $entry));
96            } else {
97                $page    = array(
98                    'id'   => pathID(substr($dir . '/' . $entry, $trunclen)),
99                    'file' => $dir . '/' . $entry,
100                );
101                $pages[] = $page;
102            }
103        }
104        closedir($dh);
105        return $pages;
106    }
107
108    function internal_links($page) {
109        global $conf;
110        $instructions = p_get_instructions(file_get_contents($page['file']));
111        $links        = array();
112        $cns          = getNS($page['id']);
113        $exists       = false;
114        foreach($instructions as $ins) {
115            if($ins[0] == 'internallink' || ($conf['camelcase'] && $ins[0] == 'camelcaselink')) {
116                $mid = $ins[1][0];
117                resolve_pageid($cns, $mid, $exists);
118                if(!$exists) {
119                    list($mid) = explode('#', $mid); //record pages without hashs
120                    $links[] = $mid;
121                }
122            }
123        }
124        return $links;
125    }
126}
127
128// Main
129$cli = new WantedPagesCLI();
130$cli->run();