1 <?php
2 3 4 5 6 7 8
9
10 defined('JPATH_PLATFORM') or die;
11
12 13 14 15 16
17 class JFile
18 {
19 20 21 22 23 24 25 26 27
28 public static function getExt($file)
29 {
30 $dot = strrpos($file, '.');
31
32 if ($dot === false)
33 {
34 return '';
35 }
36
37 return (string) substr($file, $dot + 1);
38 }
39
40 41 42 43 44 45 46 47 48
49 public static function stripExt($file)
50 {
51 return preg_replace('#\.[^.]*$#', '', $file);
52 }
53
54 55 56 57 58 59 60 61 62
63 public static function makeSafe($file)
64 {
65
66 $file = rtrim($file, '.');
67
68 $regex = array('#(\.){2,}#', '#[^A-Za-z0-9\.\_\- ]#', '#^\.#');
69
70 return trim(preg_replace($regex, '', $file));
71 }
72
73 74 75 76 77 78 79 80 81 82 83 84
85 public static function copy($src, $dest, $path = null, $use_streams = false)
86 {
87 $pathObject = new JFilesystemWrapperPath;
88
89
90 if ($path)
91 {
92 $src = $pathObject->clean($path . '/' . $src);
93 $dest = $pathObject->clean($path . '/' . $dest);
94 }
95
96
97 if (!is_readable($src))
98 {
99 JLog::add(JText::sprintf('JLIB_FILESYSTEM_ERROR_JFILE_FIND_COPY', $src), JLog::WARNING, 'jerror');
100
101 return false;
102 }
103
104 if ($use_streams)
105 {
106 $stream = JFactory::getStream();
107
108 if (!$stream->copy($src, $dest))
109 {
110 JLog::add(JText::sprintf('JLIB_FILESYSTEM_ERROR_JFILE_STREAMS', $src, $dest, $stream->getError()), JLog::WARNING, 'jerror');
111
112 return false;
113 }
114
115 return true;
116 }
117 else
118 {
119 $FTPOptions = JClientHelper::getCredentials('ftp');
120
121 if ($FTPOptions['enabled'] == 1)
122 {
123
124 $ftp = JClientFtp::getInstance($FTPOptions['host'], $FTPOptions['port'], array(), $FTPOptions['user'], $FTPOptions['pass']);
125
126
127 if (!file_exists(dirname($dest)))
128 {
129 $folderObject = new JFilesystemWrapperFolder;
130 $folderObject->create(dirname($dest));
131 }
132
133
134 $dest = $pathObject->clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $dest), '/');
135
136 if (!$ftp->store($src, $dest))
137 {
138
139 return false;
140 }
141
142 $ret = true;
143 }
144 else
145 {
146 if (!@ copy($src, $dest))
147 {
148 JLog::add(JText::sprintf('JLIB_FILESYSTEM_ERROR_COPY_FAILED_ERR01', $src, $dest), JLog::WARNING, 'jerror');
149
150 return false;
151 }
152
153 $ret = true;
154 }
155
156 return $ret;
157 }
158 }
159
160 161 162 163 164 165 166 167 168
169 public static function delete($file)
170 {
171 $FTPOptions = JClientHelper::getCredentials('ftp');
172 $pathObject = new JFilesystemWrapperPath;
173
174 if (is_array($file))
175 {
176 $files = $file;
177 }
178 else
179 {
180 $files[] = $file;
181 }
182
183
184 if ($FTPOptions['enabled'] == 1)
185 {
186
187 $ftp = JClientFtp::getInstance($FTPOptions['host'], $FTPOptions['port'], array(), $FTPOptions['user'], $FTPOptions['pass']);
188 }
189
190 foreach ($files as $file)
191 {
192 $file = $pathObject->clean($file);
193
194 if (!is_file($file))
195 {
196 continue;
197 }
198
199
200
201 @chmod($file, 0777);
202
203
204
205 if (@unlink($file))
206 {
207
208 }
209 elseif ($FTPOptions['enabled'] == 1)
210 {
211 $file = $pathObject->clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $file), '/');
212
213 if (!$ftp->delete($file))
214 {
215
216
217 return false;
218 }
219 }
220 else
221 {
222 $filename = basename($file);
223 JLog::add(JText::sprintf('JLIB_FILESYSTEM_DELETE_FAILED', $filename), JLog::WARNING, 'jerror');
224
225 return false;
226 }
227 }
228
229 return true;
230 }
231
232 233 234 235 236 237 238 239 240 241 242 243
244 public static function move($src, $dest, $path = '', $use_streams = false)
245 {
246 $pathObject = new JFilesystemWrapperPath;
247
248 if ($path)
249 {
250 $src = $pathObject->clean($path . '/' . $src);
251 $dest = $pathObject->clean($path . '/' . $dest);
252 }
253
254
255 if (!is_readable($src))
256 {
257 JLog::add(JText::_('JLIB_FILESYSTEM_CANNOT_FIND_SOURCE_FILE'), JLog::WARNING, 'jerror');
258
259 return false;
260 }
261
262 if ($use_streams)
263 {
264 $stream = JFactory::getStream();
265
266 if (!$stream->move($src, $dest))
267 {
268 JLog::add(JText::sprintf('JLIB_FILESYSTEM_ERROR_JFILE_MOVE_STREAMS', $stream->getError()), JLog::WARNING, 'jerror');
269
270 return false;
271 }
272
273 return true;
274 }
275 else
276 {
277 $FTPOptions = JClientHelper::getCredentials('ftp');
278
279 if ($FTPOptions['enabled'] == 1)
280 {
281
282 $ftp = JClientFtp::getInstance($FTPOptions['host'], $FTPOptions['port'], array(), $FTPOptions['user'], $FTPOptions['pass']);
283
284
285 $src = $pathObject->clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $src), '/');
286 $dest = $pathObject->clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $dest), '/');
287
288
289 if (!$ftp->rename($src, $dest))
290 {
291 JLog::add(JText::_('JLIB_FILESYSTEM_ERROR_RENAME_FILE'), JLog::WARNING, 'jerror');
292
293 return false;
294 }
295 }
296 else
297 {
298 if (!@ rename($src, $dest))
299 {
300 JLog::add(JText::_('JLIB_FILESYSTEM_ERROR_RENAME_FILE'), JLog::WARNING, 'jerror');
301
302 return false;
303 }
304 }
305
306 return true;
307 }
308 }
309
310 311 312 313 314 315 316 317 318 319 320 321 322 323
324 public static function read($filename, $incpath = false, $amount = 0, $chunksize = 8192, $offset = 0)
325 {
326 JLog::add(__METHOD__ . ' is deprecated. Use native file_get_contents() syntax.', JLog::WARNING, 'deprecated');
327
328 $data = null;
329
330 if ($amount && $chunksize > $amount)
331 {
332 $chunksize = $amount;
333 }
334
335 if (false === $fh = fopen($filename, 'rb', $incpath))
336 {
337 JLog::add(JText::sprintf('JLIB_FILESYSTEM_ERROR_READ_UNABLE_TO_OPEN_FILE', $filename), JLog::WARNING, 'jerror');
338
339 return false;
340 }
341
342 clearstatcache();
343
344 if ($offset)
345 {
346 fseek($fh, $offset);
347 }
348
349 if ($fsize = @ filesize($filename))
350 {
351 if ($amount && $fsize > $amount)
352 {
353 $data = fread($fh, $amount);
354 }
355 else
356 {
357 $data = fread($fh, $fsize);
358 }
359 }
360 else
361 {
362 $data = '';
363
364 365 366 367 368 369
370 while (!feof($fh) && (!$amount || strlen($data) < $amount))
371 {
372 $data .= fread($fh, $chunksize);
373 }
374 }
375
376 fclose($fh);
377
378 return $data;
379 }
380
381 382 383 384 385 386 387 388 389 390 391
392 public static function write($file, $buffer, $use_streams = false)
393 {
394 @set_time_limit(ini_get('max_execution_time'));
395
396
397 if (!file_exists(dirname($file)))
398 {
399 $folderObject = new JFilesystemWrapperFolder;
400
401 if ($folderObject->create(dirname($file)) == false)
402 {
403 return false;
404 }
405 }
406
407 if ($use_streams)
408 {
409 $stream = JFactory::getStream();
410
411
412 $stream->set('chunksize', (1024 * 1024));
413
414 if (!$stream->writeFile($file, $buffer))
415 {
416 JLog::add(JText::sprintf('JLIB_FILESYSTEM_ERROR_WRITE_STREAMS', $file, $stream->getError()), JLog::WARNING, 'jerror');
417
418 return false;
419 }
420
421 return true;
422 }
423 else
424 {
425 $FTPOptions = JClientHelper::getCredentials('ftp');
426 $pathObject = new JFilesystemWrapperPath;
427
428 if ($FTPOptions['enabled'] == 1)
429 {
430
431 $ftp = JClientFtp::getInstance($FTPOptions['host'], $FTPOptions['port'], array(), $FTPOptions['user'], $FTPOptions['pass']);
432
433
434 $file = $pathObject->clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $file), '/');
435 $ret = $ftp->write($file, $buffer);
436 }
437 else
438 {
439 $file = $pathObject->clean($file);
440 $ret = is_int(file_put_contents($file, $buffer)) ? true : false;
441 }
442
443 return $ret;
444 }
445 }
446
447 448 449 450 451 452 453 454 455 456 457
458 public static function append($file, $buffer, $use_streams = false)
459 {
460 @set_time_limit(ini_get('max_execution_time'));
461
462
463 if (!file_exists($file))
464 {
465 return self::write($file, $buffer, $use_streams);
466 }
467
468 if ($use_streams)
469 {
470 $stream = JFactory::getStream();
471
472
473 $stream->set('chunksize', (1024 * 1024));
474
475 if ($stream->open($file, 'ab') && $stream->write($buffer) && $stream->close())
476 {
477 return true;
478 }
479
480 JLog::add(JText::sprintf('JLIB_FILESYSTEM_ERROR_WRITE_STREAMS', $file, $stream->getError()), JLog::WARNING, 'jerror');
481
482 return false;
483 }
484 else
485 {
486
487 $FTPOptions = JClientHelper::getCredentials('ftp');
488
489 if ($FTPOptions['enabled'] == 1)
490 {
491
492 $ftp = JClientFtp::getInstance($FTPOptions['host'], $FTPOptions['port'], array(), $FTPOptions['user'], $FTPOptions['pass']);
493
494
495 $file = JPath::clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $file), '/');
496 $ret = $ftp->append($file, $buffer);
497 }
498 else
499 {
500 $file = JPath::clean($file);
501 $ret = is_int(file_put_contents($file, $buffer, FILE_APPEND));
502 }
503
504 return $ret;
505 }
506 }
507
508 509 510 511 512 513 514 515 516 517 518 519 520
521 public static function upload($src, $dest, $use_streams = false, $allow_unsafe = false, $safeFileOptions = array())
522 {
523 if (!$allow_unsafe)
524 {
525 $descriptor = array(
526 'tmp_name' => $src,
527 'name' => basename($dest),
528 'type' => '',
529 'error' => '',
530 'size' => '',
531 );
532
533 $isSafe = JFilterInput::isSafeFile($descriptor, $safeFileOptions);
534
535 if (!$isSafe)
536 {
537 JLog::add(JText::sprintf('JLIB_FILESYSTEM_ERROR_WARNFS_ERR03', $dest), JLog::WARNING, 'jerror');
538
539 return false;
540 }
541 }
542
543
544 $pathObject = new JFilesystemWrapperPath;
545 $dest = $pathObject->clean($dest);
546
547
548 $baseDir = dirname($dest);
549
550 if (!file_exists($baseDir))
551 {
552 $folderObject = new JFilesystemWrapperFolder;
553 $folderObject->create($baseDir);
554 }
555
556 if ($use_streams)
557 {
558 $stream = JFactory::getStream();
559
560 if (!$stream->upload($src, $dest))
561 {
562 JLog::add(JText::sprintf('JLIB_FILESYSTEM_ERROR_UPLOAD', $stream->getError()), JLog::WARNING, 'jerror');
563
564 return false;
565 }
566
567 return true;
568 }
569 else
570 {
571 $FTPOptions = JClientHelper::getCredentials('ftp');
572 $ret = false;
573
574 if ($FTPOptions['enabled'] == 1)
575 {
576
577 $ftp = JClientFtp::getInstance($FTPOptions['host'], $FTPOptions['port'], array(), $FTPOptions['user'], $FTPOptions['pass']);
578
579
580 $dest = $pathObject->clean(str_replace(JPATH_ROOT, $FTPOptions['root'], $dest), '/');
581
582
583 if (is_uploaded_file($src) && $ftp->store($src, $dest))
584 {
585 unlink($src);
586 $ret = true;
587 }
588 else
589 {
590 JLog::add(JText::sprintf('JLIB_FILESYSTEM_ERROR_WARNFS_ERR04', $src, $dest), JLog::WARNING, 'jerror');
591 }
592 }
593 else
594 {
595 if (is_writeable($baseDir) && move_uploaded_file($src, $dest))
596 {
597
598 if ($pathObject->setPermissions($dest))
599 {
600 $ret = true;
601 }
602 else
603 {
604 JLog::add(JText::_('JLIB_FILESYSTEM_ERROR_WARNFS_ERR01'), JLog::WARNING, 'jerror');
605 }
606 }
607 else
608 {
609 JLog::add(JText::sprintf('JLIB_FILESYSTEM_ERROR_WARNFS_ERR04', $src, $dest), JLog::WARNING, 'jerror');
610 }
611 }
612
613 return $ret;
614 }
615 }
616
617 618 619 620 621 622 623 624 625
626 public static function exists($file)
627 {
628 $pathObject = new JFilesystemWrapperPath;
629
630 return is_file($pathObject->clean($file));
631 }
632
633 634 635 636 637 638 639 640 641 642
643 public static function getName($file)
644 {
645 JLog::add(__METHOD__ . ' is deprecated. Use native basename() syntax.', JLog::WARNING, 'deprecated');
646
647
648 $file = str_replace('\\', '/', $file);
649 $slash = strrpos($file, '/');
650
651 if ($slash !== false)
652 {
653 return substr($file, $slash + 1);
654 }
655 else
656 {
657 return $file;
658 }
659 }
660 }
661