1<?php
2/**
3 * Copyright (c) 2020. ComboStrap, Inc. and its affiliates. All Rights Reserved.
4 *
5 * This source code is licensed under the GPL license found in the
6 * COPYING  file in the root directory of this source tree.
7 *
8 * @license  GPL 3 (https://www.gnu.org/licenses/gpl-3.0.en.html)
9 * @author   ComboStrap <support@combostrap.com>
10 *
11 */
12
13namespace ComboStrap;
14
15/**
16 * Class PageUtility
17 * @package ComboStrap
18 * See also {@link pageutils.php}
19 */
20class FsWikiUtility
21{
22
23
24    /**
25     * Determine if the current page is a sidebar (a bar)
26     * @return bool
27     * TODO: Duplicate of {@link MarkupPath::isSlot()} ?
28     */
29    public static function isSideBar(): bool
30    {
31        global $INFO;
32        global $ID;
33        $isSidebar = false;
34        if ($INFO != null) {
35            $id = $INFO['id'];
36            if ($ID != $id) {
37                $isSidebar = TRUE;
38            }
39        }
40        return $isSidebar;
41    }
42
43
44    /**
45     * Return all pages and/of sub-namespaces (subdirectory) of a namespace (ie directory)
46     * Adapted from feed.php
47     *
48     * @param string $path The container of the pages
49     * @return array An array of the pages for the namespace
50     * @throws ExceptionBadSyntax if the string is not a namespace path
51     */
52    static function getChildren(string $path): array
53    {
54        require_once(DOKU_INC . '/inc/search.php');
55        global $conf;
56
57        WikiPath::checkNamespacePath($path);
58
59        /**
60         * To the wiki id form
61         */
62        $dokuPath = WikiPath::createMarkupPathFromPath($path);
63        // delete the last separator
64        $dokuwikiId = substr( $dokuPath->getWikiId(),0,-1);
65        $relativeFileSystemPath = str_replace(":", "/", $dokuwikiId);
66
67
68        $data = array();
69
70        // Options of the callback function search_universal
71        // in the search.php file
72        $search_opts = array(
73            'depth' => 1,
74            'pagesonly' => true,
75            'listfiles' => true,
76            'listdirs' => true,
77            'skipacl' => true
78            //'firsthead' => true
79        );
80        // search_universal is a function in inc/search.php that accepts the $search_opts parameters
81        search($data, // The returned data
82            $conf['datadir'], // The root
83            'search_universal', // The recursive function (callback)
84            $search_opts, // The options given to the recursive function
85            $relativeFileSystemPath, // The id
86            1 // Only one level in the tree
87        );
88
89        return $data;
90    }
91
92    /**
93     * Return the page index of a namespace or null if it does not exist
94     * ie the index.html
95     * @param $namespacePath - in dokuwiki format
96     * @return string - the dokuwiki path
97     * @deprecated use {@link MarkupPath::getIndexPageFromNamespace()} instead
98     */
99    public static function getHomePagePath($namespacePath): ?string
100    {
101        $homePage = MarkupPath::getIndexPageFromNamespace($namespacePath);
102        if ($homePage->exists()) {
103            return $homePage->getAbsolutePath();
104        } else {
105            return null;
106        }
107    }
108
109    public static function getChildrenNamespace($nameSpacePath)
110    {
111        require_once(__DIR__ . '/../../../../inc/search.php');
112        global $conf;
113
114        $data = array();
115
116        // Options of the callback function search_universal
117        // in the search.php file
118        $search_opts = array();
119        // search_universal is a function in inc/search.php that accepts the $search_opts parameters
120        search_namespaces($data, // The returned data
121            $conf['datadir'], // The root
122            $nameSpacePath, // The directory to search
123            'd',
124            1, // Only one level in the tree
125            $search_opts
126        );
127
128        return $data;
129    }
130
131    /**
132     * @param $namespacePath
133     * @return MarkupPath|null the page path of the parent or null if it does not exist
134     */
135    public static function getParentPagePath($namespacePath): ?MarkupPath
136    {
137
138        /**
139         * Root case
140         */
141        if ($namespacePath === ":") {
142            return null;
143        }
144
145        /**
146         * A namespace path does not have a `:` at the end
147         * only for the root
148         */
149        $pos = strrpos($namespacePath, ':');
150        if ($pos !== false) {
151            if ($pos == 0) {
152                $parentNamespacePath = ":";
153            } else {
154                $parentNamespacePath = substr($namespacePath, 0, $pos);
155            }
156            return MarkupPath::getIndexPageFromNamespace($parentNamespacePath);
157
158        } else {
159            return null;
160        }
161
162
163    }
164
165
166    /**
167     * Find the pages in the tree
168     * @param $startPath
169     * @param int $depth
170     * @return array
171     */
172    public static function getPages($startPath, int $depth = 0): array
173    {
174
175        if ($startPath === null || $startPath === "") {
176            throw new \RuntimeException("A start path is mandatory");
177        }
178
179
180        // Run as admin to overcome the fact that
181        // anonymous user cannot set all links and backlinks
182        global $conf;
183        $dataDir = $conf['datadir'];
184
185        $pages = array();
186
187        // This is a page
188        if (page_exists($startPath)) {
189            $pages[] = array(
190                'id' => $startPath,
191                'ns' => getNS($startPath),
192                'title' => p_get_first_heading($startPath, false),
193                'size' => filesize(wikiFN($startPath)),
194                'mtime' => filemtime(wikiFN($startPath)),
195                'perm' => 16,
196                'type' => 'f',
197                'level' => 0,
198                'open' => 1,
199            );
200        } else {
201
202            $startPath = str_replace(':', '/', $startPath);
203
204            /**
205             * Directory
206             */
207            search(
208                $pages,
209                $dataDir,
210                'search_universal',
211                array(
212                    'depth' => $depth,
213                    'listfiles' => true,
214                    'listdirs' => false,
215                    'pagesonly' => true,
216                    'skipacl' => true,
217                    'firsthead' => false,
218                    'meta' => false,
219                ),
220                $startPath
221            );
222        }
223        return $pages;
224    }
225
226}
227