Passed
Push — devel-3.0 ( 67d9a6...e0263f )
by Rubén
04:37
created

Util::getETA()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 2
nop 3
dl 0
loc 10
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * sysPass
4
 *
5
 * @author    nuxsmin
6
 * @link      https://syspass.org
7
 * @copyright 2012-2018, 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\FileHandler;
28
29
defined('APP_ROOT') || die();
30
31
/**
32
 * Clase con utilizades para la aplicación
33
 */
34
final class Util
35
{
36
37
    /**
38
     * Comprueba y devuelve un directorio temporal válido
39
     *
40
     * @return bool|string
41
     */
42
    public static function getTempDir()
43
    {
44
        $sysTmp = sys_get_temp_dir();
45
        $appTmp = APP_PATH . DIRECTORY_SEPARATOR . 'temp';
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($appTmp)) {
63
            return $appTmp;
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
Best Practice introduced by
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
     * @author Samuel Levy <[email protected]>
116
     *
117
     * @param mixed $in     The variable to check
118
     * @param bool  $strict If set to false, consider everything that is not false to
119
     *                      be true.
120
     *
121
     * @return bool The boolean equivalent or null (if strict, and no exact equivalent)
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
     * @return bool
222
     */
223
    public static function lockApp($userId, $subject)
224
    {
225
        $data = ['time' => time(), 'userId' => (int)$userId, 'subject' => $subject];
226
227
        return file_put_contents(LOCK_FILE, json_encode($data));
0 ignored issues
show
Bug Best Practice introduced by
The expression return file_put_contents...LE, json_encode($data)) returns the type integer which is incompatible with the documented return type boolean.
Loading history...
228
    }
229
230
    /**
231
     * Desbloquear la aplicación
232
     *
233
     * @return bool
234
     */
235
    public static function unlockApp()
236
    {
237
        return @unlink(LOCK_FILE);
238
    }
239
240
    /**
241
     * Comprueba si la aplicación está bloqueada
242
     *
243
     * @return int
244
     */
245
    public static function getAppLock()
246
    {
247
        if (file_exists(LOCK_FILE)
248
            && ($data = file_get_contents(LOCK_FILE)) !== false
249
        ) {
250
            return json_decode($data) ?: false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return json_decode($data) ?: false could also return false which is incompatible with the documented return type integer. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
251
        }
252
253
        return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type integer.
Loading history...
254
    }
255
256
    /**
257
     * Devolver el tiempo aproximado en segundos de una operación
258
     *
259
     * @param $startTime
260
     * @param $numItems
261
     * @param $totalItems
262
     *
263
     * @return array Con el tiempo estimado y los elementos por segundo
264
     */
265
    public static function getETA($startTime, $numItems, $totalItems)
266
    {
267
        if ($numItems > 0 && $totalItems > 0) {
268
            $runtime = time() - $startTime;
269
            $eta = (int)((($totalItems * $runtime) / $numItems) - $runtime);
270
271
            return [$eta, $numItems / $runtime];
272
        }
273
274
        return [0, 0];
275
    }
276
277
    /**
278
     * Adaptador para convertir una cadena de IDs a un array
279
     *
280
     * @param string $itemsId
281
     * @param string $delimiter
282
     *
283
     * @return array
284
     */
285
    public static function itemsIdAdapter(string $itemsId, $delimiter = ','): array
286
    {
287
        return array_map(function ($value) {
288
            return intval($value);
289
        }, explode($delimiter, $itemsId));
290
    }
291
292
    /**
293
     * @return int
294
     */
295
    public static function getMaxDownloadChunk(): int
296
    {
297
        return self::convertShortUnit(ini_get('memory_limit')) / FileHandler::CHUNK_FACTOR;
298
    }
299
}
300