You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

317 lines
13 KiB

<?php
// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
//
// All Rights Reserved. See copyright.txt for details and a complete list of authors.
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
// $Id$
/**
* Class FilegalBatchLib
*
* Container for functions involved in tiki-batch_upload_files.php and files:batchupload console command
*
*/
class FilegalBatchLib extends FileGalLib
{
// list of filetypes you DO NOT want to show
private $disallowed_types = [
'php',
'php3',
'php4',
'phtml',
'phps',
'py',
'pl',
'sh',
'php~'
];
/**
* Processes a list of file to be "uploaded" as a batch
*
* @param array $files
* @param int $galleryId
* @param array $options [bool subToDesc, bool subdirToSubgal, bool createSubgals, string fileUser, string fileGroup, string fileMode]
* @return array feedback messages
*/
public function processBatchUpload($files, $galleryId = null, $options = [])
{
include_once('lib/mime/mimetypes.php');
global $mimetypes, $user, $prefs;
$userlib = TikiLib::lib('user');
$feedback = [];
$options = array_merge(
[
'subToDesc' => false,
'subdirToSubgal' => false,
'subdirIntegerToSubgalId' => false,
'createSubgals' => false,
'deleteAfter' => null,
'fileUser' => '',
'fileGroup' => '',
'fileMode' => '',
'filesPath' => '',
],
$options
);
if ($galleryId === null) {
$galleryId = $prefs['fgal_root_id'];
}
$filesPath = $options['filesPath'] ? $options['filesPath'] : $prefs['fgal_batch_dir'];
$filesPath = rtrim($filesPath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
// for subdirToSubgal we need all existing dir galleries for the current gallery
$subgals = [];
if ($options['subdirToSubgal']) {
$subgals = $this->getSubGalleries($galleryId, true, 'batch_upload_file_dir');
}
// cycle through all files to upload
foreach ($files as $file) {
//add meadata
$metadata = $this->extractMetadataJson($file);
$path_parts = pathinfo($file);
$type = 'application/octet-stream';
if (! empty($path_parts['extension'])) {
$ext = strtolower($path_parts['extension']);
if (isset($mimetypes["$ext"])) {
$type = $mimetypes["$ext"];
}
}
$filesize = @filesize($file);
$creator = $user;
// if the same file creator user matches a tiki user then set the creator to that
if (function_exists('posix_getpwuid')) {
$info = posix_getpwuid(fileowner($file));
if ($userlib->user_exists($info['name'])) {
$creator = $info['name'];
}
}
$destinationGalleryId = $galleryId;
if ($options['fileUser']) {
if (! chown($file, $options['fileUser'])) {
$feedback[] = '<span class="text-danger">' . tr('Problem setting user for "%0"', $path_parts['basename']);
}
}
if ($options['fileGroup']) {
if (! chgrp($file, $options['fileGroup'])) {
$feedback[] = '<span class="text-danger">' . tr('Problem setting group for "%0"', $path_parts['basename']);
}
}
if ($options['fileMode']) {
if (! chmod($file, octdec($options['fileMode']))) {
$feedback[] = '<span class="text-danger">' . tr('Problem setting mode for "%0"', $path_parts['basename']);
}
}
if ($options['subdirToSubgal']) {
$foundDir = true;
$dirs = array_filter(
explode(
DIRECTORY_SEPARATOR,
substr($path_parts['dirname'], strlen($filesPath))
)
);
if ($options['subdirIntegerToSubgalId']) {
$foundDir = false;
// if there is only one subdir and it's a number, check if there's a gallery with that id to use
if (count($dirs) > 1) {
$feedback[] = '<span class="text-danger">' .
tr('Upload was not successful for "%0"', $path_parts['basename']) .
'<br>' . tr('Subgallery number to galleryId error: Too many subdirs (%0)</span>', count($dirs));
} elseif (count($dirs) === 1 && ! ctype_digit($dirs[0])) {
$feedback[] = '<span class="text-danger">' .
tr('Upload was not successful for "%0"', $path_parts['basename']) .
'<br>' . tr('Subgallery number to galleryId error: Not an integer (%0)</span>', $dirs[0]);
} else {
foreach ($subgals['data'] as $subgal) {
if ($subgal['id'] == $dirs[0] || $galleryId == $dirs[0]) {
$foundDir = true;
break;
}
}
if ($foundDir) {
$destinationGalleryId = (int)$dirs[0];
} elseif (count($dirs) === 0) { // in root
$destinationGalleryId = $galleryId;
$foundDir = true;
} else {
$feedback[] = '<span class="text-danger">' .
tr('Upload was not successful for "%0"', $path_parts['basename']) .
'<br>' . tr('Subgallery number to galleryId error: Gallery with ID %0 not found</span>', $dirs[0]);
}
}
} else { // not subdirIntegerToSubgalId
foreach ($dirs as $dir) {
$foundDir = false;
$subgals = $this->getSubGalleries($destinationGalleryId, false, 'batch_upload_file_dir');
foreach ($subgals['data'] as $subgal) {
if ($subgal['parentId'] == $destinationGalleryId && $subgal['name'] == $dir) {
$destinationGalleryId = (int) $subgal['id'];
$foundDir = true;
break;
}
}
if (! $foundDir) {
if ($options['createSubgals']) {
$perms = $this->get_perm_object($destinationGalleryId, 'file gallery', $this->get_file_gallery_info($destinationGalleryId), false);
if ($perms['tiki_p_create_file_galleries'] === 'y') {
$new_info = $this->default_file_gallery();
$new_info['name'] = $dir;
$new_info['description'] = tr('Created by batch upload by user "%0" on %1', $user, $this->get_short_datetime($this->now, $user));
$new_info['parentId'] = $destinationGalleryId;
$new_info['user'] = $user;
$newGalleryId = $this->replace_file_gallery($new_info);
if ($newGalleryId) {
$destinationGalleryId = $newGalleryId;
$subgals = $this->getSubGalleries($galleryId, true, 'batch_upload_file_dir');
$foundDir = true;
} else {
$feedback[] = '<span class="text-danger">' .
tr('Upload was not successful for "%0"', $path_parts['basename']) .
'<br>' . tr('Create gallery "%0" failed</span>', $dir);
break;
}
} else {
$feedback[] = '<span class="text-danger">' .
tr('Upload was not successful for "%0"', $path_parts['basename']) .
'<br>' . tr('No permsission to create gallery "%0"</span>', $dir);
break;
}
} else {
$feedback[] = '<span class="text-danger">' .
tr('Upload was not successful for "%0"', $path_parts['basename']) .
'<br>' . tr('Gallery "%0" not found</span>', $dir);
break;
}
}
}
}
if (! $foundDir) {
continue;
}
}
// if subToDesc is set, set description:
if ($options['subToDesc']) {
// get last subdir 'last' from 'some/path/last'
$tmpDesc = preg_replace('/.*([^\/]*)\/([^\/]+)$/U', '$1', substr($file, strlen($filesPath)));
} else {
$tmpDesc = '';
}
// get filename
$name = $path_parts['basename'];
$tikiFile = new Tiki\FileGallery\File([
'galleryId' => $destinationGalleryId,
'description' => $tmpDesc,
'user' => $creator,
'deleteAfter' => $options['deleteAfter'],
'metadata' => $metadata,
]);
$fileId = $tikiFile->replace(file_get_contents($file), $type, $name, $name);
if ($fileId) {
$feedback[] = tra('Upload was successful') . ': ' . $name;
@unlink($file); // seems to return false sometimes even if the file was deleted
if (! file_exists($file)) {
$feedback[] = sprintf(tra('File %s removed from Batch directory.'), $file);
} else {
$feedback[] = '<span class="text-danger">' . sprintf(tra('Impossible to remove file %s from Batch directory.'), $file) . '</span>';
}
}
}
return $feedback;
}
/**
* build a complete list of all files in $prefs['fgal_batch_dir'] or elsewhere, including all necessary file info
*
* @param string $filedir Path to find files to import, uses fgal_batch_dir pref if empty
* @return array Files [file, size, ext, writable]
* @throws Exception
*/
public function batchUploadFileList($filedir = '')
{
global $prefs;
// get root dir
if (empty($filedir)) {
$filedir = $prefs['fgal_batch_dir'];
}
$filedir = rtrim($filedir, '/');
$filelist = [];
$files = $this->batchUploadDirContent($filedir);
sort($files, SORT_NATURAL);
// build file data array
foreach ($files as $file) {
// get file information
$filesize = @filesize($file);
$filelist[] = [
'file' => $file,
'size' => $filesize,
'ext' => strtolower(substr($file, -(strlen($file) - 1 - strrpos($file, ".")))),
'writable' => is_writable($file) && is_writable(dirname($file)), // it's the parent dir perms needed to move the file
];
}
return $filelist;
}
/**
* recursively get all files from all subdirectories
*
* @param $dir
* @return array
* @throws Exception
*/
private function batchUploadDirContent($dir)
{
$files = [];
if (false === $allfile = scandir($dir)) {
throw new Exception(tra("Invalid directory name"));
}
foreach ($allfile as $filefile) {
if ('.' === $filefile[0]) {
continue;
}
if (is_dir($dir . "/" . $filefile)) {
$files = array_merge($this->batchUploadDirContent($dir . DIRECTORY_SEPARATOR . $filefile), $files);
} elseif (! in_array(strtolower(substr($filefile, -(strlen($filefile) - strrpos($filefile, ".") - 1))), $this->disallowed_types)) {
$files[] = $dir . DIRECTORY_SEPARATOR . $filefile;
}
}
return $files;
}
}