Failed Conditions
Push — refactorResolving ( 1356e5 )
by Andreas
05:46 queued 03:05
created

bin/wantedpages.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
#!/usr/bin/env php
2
<?php
3
4
use splitbrain\phpcli\CLI;
5
use splitbrain\phpcli\Options;
6
use dokuwiki\Utf8\Sort;
7
8
if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__) . '/../') . '/');
9
define('NOSESSION', 1);
10
require_once(DOKU_INC . 'inc/init.php');
11
12
/**
13
 * Find wanted pages
14
 */
15
class WantedPagesCLI extends CLI {
16
17
    const DIR_CONTINUE = 1;
18
    const DIR_NS = 2;
19
    const DIR_PAGE = 3;
20
21
    private $skip = false;
22
    private $sort = 'wanted';
23
24
    private $result = array();
25
26
    /**
27
     * Register options and arguments on the given $options object
28
     *
29
     * @param Options $options
30
     * @return void
31
     */
32
    protected function setup(Options $options) {
33
        $options->setHelp(
34
            'Outputs a list of wanted pages (pages that do not exist yet) and their origin pages ' .
35
            ' (the pages that are linkin to these missing pages).'
36
        );
37
        $options->registerArgument(
38
            'namespace',
39
            'The namespace to lookup. Defaults to root namespace',
40
            false
41
        );
42
43
        $options->registerOption(
44
            'sort',
45
            'Sort by wanted or origin page',
46
            's',
47
            '(wanted|origin)'
48
        );
49
50
        $options->registerOption(
51
            'skip',
52
            'Do not show the second dimension',
53
            'k'
54
        );
55
    }
56
57
    /**
58
     * Your main program
59
     *
60
     * Arguments and options have been parsed when this is run
61
     *
62
     * @param Options $options
63
     * @return void
64
     */
65
    protected function main(Options $options) {
66
        $args = $options->getArgs();
67
        if($args) {
68
            $startdir = dirname(wikiFN($args[0] . ':xxx'));
69
        } else {
70
            $startdir = dirname(wikiFN('xxx'));
71
        }
72
73
        $this->skip = $options->getOpt('skip');
74
        $this->sort = $options->getOpt('sort');
75
76
        $this->info("searching $startdir");
77
78
        foreach($this->getPages($startdir) as $page) {
79
            $this->internalLinks($page);
80
        }
81
        Sort::ksort($this->result);
82
        foreach($this->result as $main => $subs) {
83
            if($this->skip) {
84
                print "$main\n";
85
            } else {
86
                $subs = array_unique($subs);
87
                Sort::sort($subs);
88
                foreach($subs as $sub) {
89
                    printf("%-40s %s\n", $main, $sub);
90
                }
91
            }
92
        }
93
    }
94
95
    /**
96
     * Determine directions of the search loop
97
     *
98
     * @param string $entry
99
     * @param string $basepath
100
     * @return int
101
     */
102
    protected function dirFilter($entry, $basepath) {
103
        if($entry == '.' || $entry == '..') {
104
            return WantedPagesCLI::DIR_CONTINUE;
105
        }
106
        if(is_dir($basepath . '/' . $entry)) {
107
            if(strpos($entry, '_') === 0) {
108
                return WantedPagesCLI::DIR_CONTINUE;
109
            }
110
            return WantedPagesCLI::DIR_NS;
111
        }
112
        if(preg_match('/\.txt$/', $entry)) {
113
            return WantedPagesCLI::DIR_PAGE;
114
        }
115
        return WantedPagesCLI::DIR_CONTINUE;
116
    }
117
118
    /**
119
     * Collects recursively the pages in a namespace
120
     *
121
     * @param string $dir
122
     * @return array
123
     * @throws DokuCLI_Exception
124
     */
125
    protected function getPages($dir) {
126
        static $trunclen = null;
127
        if(!$trunclen) {
128
            global $conf;
129
            $trunclen = strlen($conf['datadir'] . ':');
130
        }
131
132
        if(!is_dir($dir)) {
133
            throw new DokuCLI_Exception("Unable to read directory $dir");
134
        }
135
136
        $pages = array();
137
        $dh = opendir($dir);
138
        while(false !== ($entry = readdir($dh))) {
139
            $status = $this->dirFilter($entry, $dir);
140
            if($status == WantedPagesCLI::DIR_CONTINUE) {
141
                continue;
142
            } else if($status == WantedPagesCLI::DIR_NS) {
143
                $pages = array_merge($pages, $this->getPages($dir . '/' . $entry));
144
            } else {
145
                $page = array(
146
                    'id' => pathID(substr($dir . '/' . $entry, $trunclen)),
147
                    'file' => $dir . '/' . $entry,
148
                );
149
                $pages[] = $page;
150
            }
151
        }
152
        closedir($dh);
153
        return $pages;
154
    }
155
156
    /**
157
     * Parse instructions and add the non-existing links to the result array
158
     *
159
     * @param array $page array with page id and file path
160
     */
161
    protected function internalLinks($page) {
162
        global $conf;
163
        $instructions = p_get_instructions(file_get_contents($page['file']));
164
        $cns = getNS($page['id']);
165
        $exists = false;
166
        $pid = $page['id'];
167
        foreach($instructions as $ins) {
168
            if($ins[0] == 'internallink' || ($conf['camelcase'] && $ins[0] == 'camelcaselink')) {
169
                $mid = $ins[1][0];
170
                resolve_pageid($cns, $mid, $exists);
0 ignored issues
show
Deprecated Code introduced by
The function resolve_pageid() has been deprecated with message: 2020-09-30

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
171
                if(!$exists) {
172
                    list($mid) = explode('#', $mid); //record pages without hashes
173
174
                    if($this->sort == 'origin') {
175
                        $this->result[$pid][] = $mid;
176
                    } else {
177
                        $this->result[$mid][] = $pid;
178
                    }
179
                }
180
            }
181
        }
182
    }
183
}
184
185
// Main
186
$cli = new WantedPagesCLI();
187
$cli->run();
188