1<?php
2
3declare(strict_types=1);
4
5namespace PhpMyAdmin;
6
7use function asort;
8use function closedir;
9use function file_exists;
10use function function_exists;
11use function is_file;
12use function is_link;
13use function opendir;
14use function preg_match;
15use function readdir;
16use function substr;
17
18/**
19 * Functions for listing directories
20 */
21class FileListing
22{
23    /**
24     * Returns array of filtered file names
25     *
26     * @param string $dir        directory to list
27     * @param string $expression regular expression to match files
28     *
29     * @return array|bool sorted file list on success, false on failure
30     */
31    public function getDirContent(string $dir, string $expression = '')
32    {
33        if (! @file_exists($dir)) {
34            return false;
35        }
36
37        $handle = @opendir($dir);
38
39        if ($handle === false) {
40            return false;
41        }
42
43        $result = [];
44        if (substr($dir, -1) !== '/') {
45            $dir .= '/';
46        }
47        while ($file = @readdir($handle)) {
48            if (! @is_file($dir . $file)
49                || @is_link($dir . $file)
50                || ($expression != '' && ! preg_match($expression, $file))
51            ) {
52                continue;
53            }
54
55            $result[] = $file;
56        }
57        closedir($handle);
58        asort($result);
59
60        return $result;
61    }
62
63    /**
64     * Returns options of filtered file names
65     *
66     * @param string $dir        directory to list
67     * @param string $extensions regular expression to match files
68     * @param string $active     currently active choice
69     *
70     * @return string|false Html <option> field, false if not files in dir
71     */
72    public function getFileSelectOptions(
73        string $dir,
74        string $extensions = '',
75        string $active = ''
76    ) {
77        $list = $this->getDirContent($dir, $extensions);
78        if ($list === false) {
79            return false;
80        }
81
82        $template = new Template();
83
84        return $template->render('file_select_options', [
85            'filesList' => $list,
86            'active' => $active,
87        ]);
88    }
89
90    /**
91     * Get currently supported decompressions.
92     *
93     * @return string separated list of extensions usable in getDirContent
94     */
95    public function supportedDecompressions(): string
96    {
97        global $cfg;
98
99        $compressions = '';
100
101        if ($cfg['GZipDump'] && function_exists('gzopen')) {
102            $compressions = 'gz';
103        }
104        if ($cfg['BZipDump'] && function_exists('bzopen')) {
105            if (! empty($compressions)) {
106                $compressions .= '|';
107            }
108            $compressions .= 'bz2';
109        }
110        if ($cfg['ZipDump'] && function_exists('gzinflate')) {
111            if (! empty($compressions)) {
112                $compressions .= '|';
113            }
114            $compressions .= 'zip';
115        }
116
117        return $compressions;
118    }
119}
120