Passed
Push — 1.11.x ( 31fff3...86e7ae )
by Yannick
15:37 queued 10s
created

src/Chamilo/CoreBundle/Component/Editor/Finder.php (1 issue)

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
namespace Chamilo\CoreBundle\Component\Editor;
5
6
use elFinder;
7
use elFinderSession;
8
use elFinderSessionInterface;
9
use Exception;
10
11
/**
12
 * Based in \elFinder this class only has a small change that allows use
13
 * drivers with out adding elFinderVolume as class name.
14
 *
15
 * Class Finder
16
 *
17
 * This class just modifies this line:
18
 * $class = 'elFinderVolume'.(isset($o['driver']) ? $o['driver'] : '');
19
 * in order to use normal classes and not a custom 'elFinderVolume' class.
20
 *
21
 * @package Chamilo\CoreBundle\Component\Editor
22
 */
23
class Finder extends \elFinder
24
{
25
    /**
26
     * Constructor.
27
     *
28
     * @param array $opts elFinder and roots configurations
29
     *
30
     * @author Dmitry (dio) Levashov
31
     */
32
    public function __construct($opts)
33
    {
34
        // set default_charset
35
        if (version_compare(PHP_VERSION, '5.6', '>=')) {
36
            if (($_val = ini_get('iconv.internal_encoding')) && strtoupper($_val) !== 'UTF-8') {
37
                ini_set('iconv.internal_encoding', '');
38
            }
39
            if (($_val = ini_get('mbstring.internal_encoding')) && strtoupper($_val) !== 'UTF-8') {
40
                ini_set('mbstring.internal_encoding', '');
41
            }
42
            if (($_val = ini_get('internal_encoding')) && strtoupper($_val) !== 'UTF-8') {
43
                ini_set('internal_encoding', '');
44
            }
45
        } else {
46
            if (function_exists('iconv_set_encoding') && strtoupper(iconv_get_encoding('internal_encoding')) !== 'UTF-8') {
47
                iconv_set_encoding('internal_encoding', 'UTF-8');
48
            }
49
            if (function_exists('mb_internal_encoding') && strtoupper(mb_internal_encoding()) !== 'UTF-8') {
50
                mb_internal_encoding('UTF-8');
51
            }
52
        }
53
        ini_set('default_charset', 'UTF-8');
54
        // define accept constant of server commands path
55
        !defined('ELFINDER_TAR_PATH') && define('ELFINDER_TAR_PATH', 'tar');
56
        !defined('ELFINDER_GZIP_PATH') && define('ELFINDER_GZIP_PATH', 'gzip');
57
        !defined('ELFINDER_BZIP2_PATH') && define('ELFINDER_BZIP2_PATH', 'bzip2');
58
        !defined('ELFINDER_XZ_PATH') && define('ELFINDER_XZ_PATH', 'xz');
59
        !defined('ELFINDER_ZIP_PATH') && define('ELFINDER_ZIP_PATH', 'zip');
60
        !defined('ELFINDER_UNZIP_PATH') && define('ELFINDER_UNZIP_PATH', 'unzip');
61
        !defined('ELFINDER_RAR_PATH') && define('ELFINDER_RAR_PATH', 'rar');
62
        !defined('ELFINDER_UNRAR_PATH') && define('ELFINDER_UNRAR_PATH', 'unrar');
63
        !defined('ELFINDER_7Z_PATH') && define('ELFINDER_7Z_PATH', (substr(PHP_OS, 0, 3) === 'WIN') ? '7z' : '7za');
64
        !defined('ELFINDER_CONVERT_PATH') && define('ELFINDER_CONVERT_PATH', 'convert');
65
        !defined('ELFINDER_IDENTIFY_PATH') && define('ELFINDER_IDENTIFY_PATH', 'identify');
66
        !defined('ELFINDER_EXIFTRAN_PATH') && define('ELFINDER_EXIFTRAN_PATH', 'exiftran');
67
        !defined('ELFINDER_JPEGTRAN_PATH') && define('ELFINDER_JPEGTRAN_PATH', 'jpegtran');
68
        !defined('ELFINDER_FFMPEG_PATH') && define('ELFINDER_FFMPEG_PATH', 'ffmpeg');
69
70
        !defined('ELFINDER_DISABLE_ZIPEDITOR') && define('ELFINDER_DISABLE_ZIPEDITOR', false);
71
72
        // enable(true)/disable(false) handling postscript on ImageMagick
73
        // Should be `false` as long as there is a Ghostscript vulnerability
74
        // see https://artifex.com/news/ghostscript-security-resolved/
75
        !defined('ELFINDER_IMAGEMAGICK_PS') && define('ELFINDER_IMAGEMAGICK_PS', false);
76
77
        // for backward compat
78
        $this->version = (string) self::$ApiVersion;
79
80
        // set error handler of WARNING, NOTICE
81
        $errLevel = E_WARNING | E_NOTICE | E_USER_WARNING | E_USER_NOTICE | E_STRICT | E_RECOVERABLE_ERROR;
82
        if (defined('E_DEPRECATED')) {
83
            $errLevel |= E_DEPRECATED | E_USER_DEPRECATED;
84
        }
85
        set_error_handler('elFinder::phpErrorHandler', $errLevel);
86
87
        // convert PATH_INFO to GET query
88
        if (!empty($_SERVER['PATH_INFO'])) {
89
            $_ps = explode('/', trim($_SERVER['PATH_INFO'], '/'));
90
            if (!isset($_GET['cmd'])) {
91
                $_cmd = $_ps[0];
92
                if (isset($this->commands[$_cmd])) {
93
                    $_GET['cmd'] = $_cmd;
94
                    $_i = 1;
95
                    foreach (array_keys($this->commands[$_cmd]) as $_k) {
96
                        if (isset($_ps[$_i])) {
97
                            if (!isset($_GET[$_k])) {
98
                                $_GET[$_k] = $_ps[$_i];
99
                            }
100
                        } else {
101
                            break;
102
                        }
103
                    }
104
                }
105
            }
106
        }
107
108
        // set elFinder instance
109
        elFinder::$instance = $this;
110
111
        // setup debug mode
112
        $this->debug = (isset($opts['debug']) && $opts['debug'] ? true : false);
113
        if ($this->debug) {
114
            error_reporting(defined('ELFINDER_DEBUG_ERRORLEVEL') ? ELFINDER_DEBUG_ERRORLEVEL : -1);
0 ignored issues
show
The constant Chamilo\CoreBundle\Compo...FINDER_DEBUG_ERRORLEVEL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
115
            ini_set('diaplay_errors', '1');
116
        }
117
118
        if (!interface_exists('elFinderSessionInterface')) {
119
            include_once __DIR__.'/elFinderSessionInterface.php';
120
        }
121
122
        // session handler
123
        if (!empty($opts['session']) && $opts['session'] instanceof elFinderSessionInterface) {
124
            $this->session = $opts['session'];
125
        } else {
126
            $sessionOpts = [
127
                'base64encode' => !empty($opts['base64encodeSessionData']),
128
                'keys' => [
129
                    'default' => !empty($opts['sessionCacheKey']) ? $opts['sessionCacheKey'] : 'elFinderCaches',
130
                    'netvolume' => !empty($opts['netVolumesSessionKey']) ? $opts['netVolumesSessionKey'] : 'elFinderNetVolumes',
131
                ],
132
            ];
133
            if (!class_exists('elFinderSession')) {
134
                include_once __DIR__.'/elFinderSession.php';
135
            }
136
            $this->session = new elFinderSession($sessionOpts);
137
        }
138
        // try session start | restart
139
        $this->session->start();
140
141
        $sessionUseCmds = [];
142
        if (isset($opts['sessionUseCmds']) && is_array($opts['sessionUseCmds'])) {
143
            $sessionUseCmds = $opts['sessionUseCmds'];
144
        }
145
146
        // set self::$volumesCnt by HTTP header "X-elFinder-VolumesCntStart"
147
        if (isset($_SERVER['HTTP_X_ELFINDER_VOLUMESCNTSTART']) && ($volumesCntStart = intval($_SERVER['HTTP_X_ELFINDER_VOLUMESCNTSTART']))) {
148
            self::$volumesCnt = $volumesCntStart;
149
        }
150
151
        $this->time = $this->utime();
152
        $this->sessionCloseEarlier = isset($opts['sessionCloseEarlier']) ? (bool) $opts['sessionCloseEarlier'] : true;
153
        $this->sessionUseCmds = array_flip($sessionUseCmds);
154
        $this->timeout = (isset($opts['timeout']) ? $opts['timeout'] : 0);
155
        $this->uploadTempPath = (isset($opts['uploadTempPath']) ? $opts['uploadTempPath'] : '');
156
        $this->callbackWindowURL = (isset($opts['callbackWindowURL']) ? $opts['callbackWindowURL'] : '');
157
        $this->maxTargets = (isset($opts['maxTargets']) ? intval($opts['maxTargets']) : $this->maxTargets);
158
        elFinder::$commonTempPath = (isset($opts['commonTempPath']) ? $opts['commonTempPath'] : './.tmp');
159
        if (!is_writable(elFinder::$commonTempPath)) {
160
            elFinder::$commonTempPath = sys_get_temp_dir();
161
            if (!is_writable(elFinder::$commonTempPath)) {
162
                elFinder::$commonTempPath = '';
163
            }
164
        }
165
        $this->maxArcFilesSize = isset($opts['maxArcFilesSize']) ? intval($opts['maxArcFilesSize']) : 0;
166
        $this->optionsNetVolumes = (isset($opts['optionsNetVolumes']) && is_array($opts['optionsNetVolumes'])) ? $opts['optionsNetVolumes'] : [];
167
        if (isset($opts['itemLockExpire'])) {
168
            $this->itemLockExpire = intval($opts['itemLockExpire']);
169
        }
170
171
        // deprecated settings
172
        $this->netVolumesSessionKey = !empty($opts['netVolumesSessionKey']) ? $opts['netVolumesSessionKey'] : 'elFinderNetVolumes';
173
        self::$sessionCacheKey = !empty($opts['sessionCacheKey']) ? $opts['sessionCacheKey'] : 'elFinderCaches';
174
175
        // check session cache
176
        $_optsMD5 = md5(json_encode($opts['roots']));
177
        if ($this->session->get('_optsMD5') !== $_optsMD5) {
178
            $this->session->set('_optsMD5', $_optsMD5);
179
        }
180
181
        // setlocale and global locale regists to elFinder::locale
182
        self::$locale = !empty($opts['locale']) ? $opts['locale'] : 'en_US.UTF-8';
183
        if (false === setlocale(LC_ALL, self::$locale)) {
184
            self::$locale = setlocale(LC_ALL, '');
185
        }
186
187
        // set defaultMimefile
188
        elFinder::$defaultMimefile = (isset($opts['defaultMimefile']) ? $opts['defaultMimefile'] : '');
189
190
        // bind events listeners
191
        if (!empty($opts['bind']) && is_array($opts['bind'])) {
192
            $_req = $_SERVER["REQUEST_METHOD"] == 'POST' ? $_POST : $_GET;
193
            $_reqCmd = isset($_req['cmd']) ? $_req['cmd'] : '';
194
            foreach ($opts['bind'] as $cmd => $handlers) {
195
                $doRegist = (strpos($cmd, '*') !== false);
196
                if (!$doRegist) {
197
                    $doRegist = ($_reqCmd && in_array($_reqCmd, array_map('self::getCmdOfBind', explode(' ', $cmd))));
198
                }
199
                if ($doRegist) {
200
                    // for backward compatibility
201
                    if (!is_array($handlers)) {
202
                        $handlers = [$handlers];
203
                    } else {
204
                        if (count($handlers) === 2 && is_object($handlers[0])) {
205
                            $handlers = [$handlers];
206
                        }
207
                    }
208
                    foreach ($handlers as $handler) {
209
                        if ($handler) {
210
                            if (is_string($handler) && strpos($handler, '.')) {
211
                                list($_domain, $_name, $_method) = array_pad(explode('.', $handler), 3, '');
212
                                if (strcasecmp($_domain, 'plugin') === 0) {
213
                                    if ($plugin = $this->getPluginInstance($_name, isset($opts['plugin'][$_name]) ? $opts['plugin'][$_name] : [])
214
                                            and method_exists($plugin, $_method)) {
215
                                        $this->bind($cmd, [$plugin, $_method]);
216
                                    }
217
                                }
218
                            } else {
219
                                $this->bind($cmd, $handler);
220
                            }
221
                        }
222
                    }
223
                }
224
            }
225
        }
226
227
        if (!isset($opts['roots']) || !is_array($opts['roots'])) {
228
            $opts['roots'] = [];
229
        }
230
231
        // check for net volumes stored in session
232
        $netVolumes = $this->getNetVolumes();
233
        foreach ($netVolumes as $key => $root) {
234
            if (!isset($root['id'])) {
235
                // given fixed unique id
236
                if (!$root['id'] = $this->getNetVolumeUniqueId($netVolumes)) {
237
                    $this->mountErrors[] = 'Netmount Driver "'.$root['driver'].'" : Could\'t given volume id.';
238
                    continue;
239
                }
240
            }
241
            $opts['roots'][$key] = $root;
242
        }
243
244
        // "mount" volumes
245
        foreach ($opts['roots'] as $i => $o) {
246
            //$class = 'elFinderVolume'.(isset($o['driver']) ? $o['driver'] : '');
247
            // Chamilo change
248
            $class = (isset($o['driver']) ? $o['driver'] : '');
249
250
            if (class_exists($class)) {
251
                $volume = new $class();
252
253
                try {
254
                    if ($this->maxArcFilesSize && (empty($o['maxArcFilesSize']) || $this->maxArcFilesSize < $o['maxArcFilesSize'])) {
255
                        $o['maxArcFilesSize'] = $this->maxArcFilesSize;
256
                    }
257
                    // pass session handler
258
                    $volume->setSession($this->session);
259
                    if ($volume->mount($o)) {
260
                        // unique volume id (ends on "_") - used as prefix to files hash
261
                        $id = $volume->id();
262
263
                        $this->volumes[$id] = $volume;
264
                        if ((!$this->default || $volume->root() !== $volume->defaultPath()) && $volume->isReadable()) {
265
                            $this->default = $this->volumes[$id];
266
                        }
267
                    } else {
268
                        $this->removeNetVolume($i, $volume);
269
                        $this->mountErrors[] = 'Driver "'.$class.'" : '.implode(' ', $volume->error());
270
                    }
271
                } catch (Exception $e) {
272
                    $this->removeNetVolume($i, $volume);
273
                    $this->mountErrors[] = 'Driver "'.$class.'" : '.$e->getMessage();
274
                }
275
            } else {
276
                $this->mountErrors[] = 'Driver "'.$class.'" does not exist';
277
            }
278
        }
279
280
        // if at least one readable volume - ii desu >_<
281
        $this->loaded = !empty($this->default);
282
283
        // restore error handler for now
284
        restore_error_handler();
285
    }
286
}
287