comparison vendor/psy/psysh/src/Psy/ConfigPaths.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4c8ae668cc8c
1 <?php
2
3 /*
4 * This file is part of Psy Shell.
5 *
6 * (c) 2012-2017 Justin Hileman
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12 namespace Psy;
13
14 use XdgBaseDir\Xdg;
15
16 /**
17 * A Psy Shell configuration path helper.
18 */
19 class ConfigPaths
20 {
21 /**
22 * Get potential config directory paths.
23 *
24 * Returns `~/.psysh`, `%APPDATA%/PsySH` (when on Windows), and all
25 * XDG Base Directory config directories:
26 *
27 * http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
28 *
29 * @return string[]
30 */
31 public static function getConfigDirs()
32 {
33 $xdg = new Xdg();
34
35 return self::getDirNames($xdg->getConfigDirs());
36 }
37
38 /**
39 * Get potential home config directory paths.
40 *
41 * Returns `~/.psysh`, `%APPDATA%/PsySH` (when on Windows), and the
42 * XDG Base Directory home config directory:
43 *
44 * http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
45 *
46 * @return string[]
47 */
48 public static function getHomeConfigDirs()
49 {
50 $xdg = new Xdg();
51
52 return self::getDirNames(array($xdg->getHomeConfigDir()));
53 }
54
55 /**
56 * Get the current home config directory.
57 *
58 * Returns the highest precedence home config directory which actually
59 * exists. If none of them exists, returns the highest precedence home
60 * config directory (`%APPDATA%/PsySH` on Windows, `~/.config/psysh`
61 * everywhere else).
62 *
63 * @see self::getHomeConfigDirs
64 *
65 * @return string
66 */
67 public static function getCurrentConfigDir()
68 {
69 $configDirs = self::getHomeConfigDirs();
70 foreach ($configDirs as $configDir) {
71 if (@is_dir($configDir)) {
72 return $configDir;
73 }
74 }
75
76 return $configDirs[0];
77 }
78
79 /**
80 * Find real config files in config directories.
81 *
82 * @param string[] $names Config file names
83 * @param string $configDir Optionally use a specific config directory
84 *
85 * @return string[]
86 */
87 public static function getConfigFiles(array $names, $configDir = null)
88 {
89 $dirs = ($configDir === null) ? self::getConfigDirs() : array($configDir);
90
91 return self::getRealFiles($dirs, $names);
92 }
93
94 /**
95 * Get potential data directory paths.
96 *
97 * If a `dataDir` option was explicitly set, returns an array containing
98 * just that directory.
99 *
100 * Otherwise, it returns `~/.psysh` and all XDG Base Directory data directories:
101 *
102 * http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
103 *
104 * @return string[]
105 */
106 public static function getDataDirs()
107 {
108 $xdg = new Xdg();
109
110 return self::getDirNames($xdg->getDataDirs());
111 }
112
113 /**
114 * Find real data files in config directories.
115 *
116 * @param string[] $names Config file names
117 * @param string $dataDir Optionally use a specific config directory
118 *
119 * @return string[]
120 */
121 public static function getDataFiles(array $names, $dataDir = null)
122 {
123 $dirs = ($dataDir === null) ? self::getDataDirs() : array($dataDir);
124
125 return self::getRealFiles($dirs, $names);
126 }
127
128 /**
129 * Get a runtime directory.
130 *
131 * Defaults to `/psysh` inside the system's temp dir.
132 *
133 * @return string
134 */
135 public static function getRuntimeDir()
136 {
137 $xdg = new Xdg();
138
139 set_error_handler(array('Psy\Exception\ErrorException', 'throwException'));
140
141 try {
142 // XDG doesn't really work on Windows, sometimes complains about
143 // permissions, sometimes tries to remove non-empty directories.
144 // It's a bit flaky. So we'll give this a shot first...
145 $runtimeDir = $xdg->getRuntimeDir(false);
146 } catch (\Exception $e) {
147 // Well. That didn't work. Fall back to a boring old folder in the
148 // system temp dir.
149 $runtimeDir = sys_get_temp_dir();
150 }
151
152 restore_error_handler();
153
154 return strtr($runtimeDir, '\\', '/') . '/psysh';
155 }
156
157 private static function getDirNames(array $baseDirs)
158 {
159 $dirs = array_map(function ($dir) {
160 return strtr($dir, '\\', '/') . '/psysh';
161 }, $baseDirs);
162
163 // Add ~/.psysh
164 if ($home = getenv('HOME')) {
165 $dirs[] = strtr($home, '\\', '/') . '/.psysh';
166 }
167
168 // Add some Windows specific ones :)
169 if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
170 if ($appData = getenv('APPDATA')) {
171 // AppData gets preference
172 array_unshift($dirs, strtr($appData, '\\', '/') . '/PsySH');
173 }
174
175 $dir = strtr(getenv('HOMEDRIVE') . '/' . getenv('HOMEPATH'), '\\', '/') . '/.psysh';
176 if (!in_array($dir, $dirs)) {
177 $dirs[] = $dir;
178 }
179 }
180
181 return $dirs;
182 }
183
184 private static function getRealFiles(array $dirNames, array $fileNames)
185 {
186 $files = array();
187 foreach ($dirNames as $dir) {
188 foreach ($fileNames as $name) {
189 $file = $dir . '/' . $name;
190 if (@is_file($file)) {
191 $files[] = $file;
192 }
193 }
194 }
195
196 return $files;
197 }
198
199 /**
200 * Ensure that $file exists and is writable, make the parent directory if necessary.
201 *
202 * Generates E_USER_NOTICE error if either $file or its directory is not writable.
203 *
204 * @param string $file
205 *
206 * @return string|false Full path to $file, or false if file is not writable
207 */
208 public static function touchFileWithMkdir($file)
209 {
210 if (file_exists($file)) {
211 if (is_writable($file)) {
212 return $file;
213 }
214
215 trigger_error(sprintf('Writing to %s is not allowed.', $file), E_USER_NOTICE);
216
217 return false;
218 }
219
220 $dir = dirname($file);
221
222 if (!is_dir($dir)) {
223 // Just try making it and see if it works
224 @mkdir($dir, 0700, true);
225 }
226
227 if (!is_dir($dir) || !is_writable($dir)) {
228 trigger_error(sprintf('Writing to %s is not allowed.', $dir), E_USER_NOTICE);
229
230 return false;
231 }
232
233 touch($file);
234
235 return $file;
236 }
237 }