Issues (493)

lib/SP/Util/Util.php (1 issue)

Severity
1
<?php
2
/**
3
 * sysPass
4
 *
5
 * @author    nuxsmin
6
 * @link      https://syspass.org
7
 * @copyright 2012-2019, Rubén Domínguez nuxsmin@$syspass.org
8
 *
9
 * This file is part of sysPass.
10
 *
11
 * sysPass is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU General Public License as published by
13
 * the Free Software Foundation, either version 3 of the License, or
14
 * (at your option) any later version.
15
 *
16
 * sysPass is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU General Public License
22
 *  along with sysPass.  If not, see <http://www.gnu.org/licenses/>.
23
 */
24
25
namespace SP\Util;
26
27
use SP\Storage\File\FileException;
28
use SP\Storage\File\FileHandler;
29
30
defined('APP_ROOT') || die();
31
32
/**
33
 * Clase con utilizades para la aplicación
34
 */
35
final class Util
36
{
37
38
    /**
39
     * Comprueba y devuelve un directorio temporal válido
40
     *
41
     * @return bool|string
42
     */
43
    public static function getTempDir()
44
    {
45
        $sysTmp = sys_get_temp_dir();
46
        $file = 'syspass.test';
47
48
        $checkDir = function ($dir) use ($file) {
49
            if (file_exists($dir . DIRECTORY_SEPARATOR . $file)) {
50
                return $dir;
51
            }
52
53
            if (is_dir($dir) || @mkdir($dir)) {
54
                if (touch($dir . DIRECTORY_SEPARATOR . $file)) {
55
                    return $dir;
56
                }
57
            }
58
59
            return false;
60
        };
61
62
        if ($checkDir(TMP_PATH)) {
63
            return TMP_PATH;
64
        }
65
66
        return $checkDir($sysTmp);
67
    }
68
69
    /**
70
     * Realiza el proceso de logout.
71
     *
72
     * FIXME
73
     */
74
    public static function logout()
75
    {
76
        exit('<script>sysPassApp.actions.main.logout();</script>');
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
77
    }
78
79
    /**
80
     * Obtener el tamaño máximo de subida de PHP.
81
     */
82
    public static function getMaxUpload(): int
83
    {
84
        return min(self::convertShortUnit(ini_get('upload_max_filesize')),
85
            self::convertShortUnit(ini_get('post_max_size')),
86
            self::convertShortUnit(ini_get('memory_limit')));
87
    }
88
89
    /**
90
     * @param $value
91
     *
92
     * @return int
93
     */
94
    public static function convertShortUnit($value): int
95
    {
96
        if (preg_match('/(\d+)(\w+)/', $value, $match)) {
97
            switch (strtoupper($match[2])) {
98
                case 'K':
99
                    return (int)$match[1] * 1024;
100
                case 'M':
101
                    return (int)$match[1] * pow(1024, 2);
102
                case 'G':
103
                    return (int)$match[1] * pow(1024, 3);
104
            }
105
        }
106
107
        return (int)$value;
108
    }
109
110
    /**
111
     * Checks a variable to see if it should be considered a boolean true or false.
112
     * Also takes into account some text-based representations of true of false,
113
     * such as 'false','N','yes','on','off', etc.
114
     *
115
     * @param mixed $in     The variable to check
116
     * @param bool  $strict If set to false, consider everything that is not false to
117
     *                      be true.
118
     *
119
     * @return bool The boolean equivalent or null (if strict, and no exact equivalent)
120
     * @author Samuel Levy <[email protected]>
121
     *
122
     */
123
    public static function boolval($in, $strict = false)
124
    {
125
        $in = is_string($in) ? strtolower($in) : $in;
126
127
        // if not strict, we only have to check if something is false
128
        if (in_array($in, ['false', 'no', 'n', '0', 'off', false, 0], true)
129
            || !$in
130
        ) {
131
            return false;
132
        }
133
134
        if ($strict
135
            && in_array($in, ['true', 'yes', 'y', '1', 'on', true, 1], true)
136
        ) {
137
            return true;
138
        }
139
140
        // not strict? let the regular php bool check figure it out (will
141
        // largely default to true)
142
        return ($in ? true : false);
143
    }
144
145
    /**
146
     * Cast an object to another class, keeping the properties, but changing the methods
147
     *
148
     * @param string        $dstClass Destination class name
149
     * @param string|object $serialized
150
     * @param string        $srcClass Old class name for removing from private methods
151
     *
152
     * @return mixed
153
     */
154
    public static function unserialize($dstClass, $serialized, $srcClass = null)
155
    {
156
        if (!is_object($serialized)) {
157
            $match = preg_match_all('/O:\d+:"(?P<class>[^"]++)"/', $serialized, $matches);
158
159
            $process = false;
160
161
            if ($match) {
162
                foreach ($matches['class'] as $class) {
163
                    if (!class_exists($class)
164
                        || $class !== $dstClass
165
                    ) {
166
                        $process = true;
167
                    }
168
                }
169
170
                if ($process === false) {
171
                    return unserialize($serialized);
172
                }
173
            }
174
175
            // Serialized data needs to be processed to change the class name
176
            if ($process === true) {
177
                // If source class is set, it will try to clean up the class name from private methods
178
                if ($srcClass !== null) {
179
                    $serialized = preg_replace_callback(
180
                        '/:\d+:"\x00' . preg_quote($srcClass, '/') . '\x00(\w+)"/',
181
                        function ($matches) {
182
                            return ':' . strlen($matches[1]) . ':"' . $matches[1] . '"';
183
                        },
184
                        $serialized);
185
                }
186
187
                return self::castToClass($serialized, $dstClass);
188
            }
189
190
            if (preg_match('/a:\d+:{/', $serialized)) {
191
                return unserialize($serialized);
192
            }
193
        }
194
195
        return $serialized;
196
    }
197
198
    /**
199
     * Cast an object to another class
200
     *
201
     * @param $cast
202
     * @param $class
203
     *
204
     * @return mixed
205
     */
206
    public static function castToClass($cast, $class)
207
    {
208
        // TODO: should avoid '__PHP_Incomplete_Class'?
209
210
        $cast = is_object($cast) ? serialize($cast) : $cast;
211
212
        return unserialize(preg_replace('/O:\d+:"[^"]++"/', 'O:' . strlen($class) . ':"' . $class . '"', $cast));
213
    }
214
215
    /**
216
     * Bloquear la aplicación
217
     *
218
     * @param int    $userId
219
     * @param string $subject
220
     *
221
     * @throws FileException
222
     */
223
    public static function lockApp($userId, $subject)
224
    {
225
        $data = ['time' => time(), 'userId' => (int)$userId, 'subject' => $subject];
226
227
        $file = new FileHandler(LOCK_FILE);
228
        $file->save(json_encode($data));
229
230
        logger('Application locked out');
231
    }
232
233
    /**
234
     * Desbloquear la aplicación
235
     *
236
     * @return bool
237
     */
238
    public static function unlockApp()
239
    {
240
        logger('Application unlocked');
241
242
        return @unlink(LOCK_FILE);
243
    }
244
245
    /**
246
     * Comprueba si la aplicación está bloqueada
247
     *
248
     * @return mixed
249
     */
250
    public static function getAppLock()
251
    {
252
        try {
253
            $file = new FileHandler(LOCK_FILE);
254
            return json_decode($file->readToString());
255
        } catch (FileException $e) {
256
            return false;
257
        }
258
    }
259
260
    /**
261
     * Devolver el tiempo aproximado en segundos de una operación
262
     *
263
     * @param $startTime
264
     * @param $numItems
265
     * @param $totalItems
266
     *
267
     * @return array Con el tiempo estimado y los elementos por segundo
268
     */
269
    public static function getETA($startTime, $numItems, $totalItems)
270
    {
271
        if ($numItems > 0 && $totalItems > 0) {
272
            $runtime = time() - $startTime;
273
            $eta = (int)((($totalItems * $runtime) / $numItems) - $runtime);
274
275
            return [$eta, $numItems / $runtime];
276
        }
277
278
        return [0, 0];
279
    }
280
281
    /**
282
     * Adaptador para convertir una cadena de IDs a un array
283
     *
284
     * @param string $itemsId
285
     * @param string $delimiter
286
     *
287
     * @return array
288
     */
289
    public static function itemsIdAdapter(string $itemsId, $delimiter = ','): array
290
    {
291
        return array_map(function ($value) {
292
            return intval($value);
293
        }, explode($delimiter, $itemsId));
294
    }
295
296
    /**
297
     * @return int
298
     */
299
    public static function getMaxDownloadChunk(): int
300
    {
301
        return self::convertShortUnit(ini_get('memory_limit')) / FileHandler::CHUNK_FACTOR;
302
    }
303
}
304