Пример #1
0
/**
 * Unzip an uploaded zip file
 *
 * @param array $file           the $_FILES information
 * @param int   $container_guid the container to put the files/folders under
 * @param int   $parent_guid    the parrent folder
 *
 * @return bool
 */
function file_tools_unzip($file, $container_guid, $parent_guid = 0)
{
    $container_guid = (int) $container_guid;
    $parent_guid = (int) $parent_guid;
    if (empty($file) || empty($container_guid)) {
        return false;
    }
    $container_entity = get_entity($container_guid);
    if (empty($container_entity)) {
        return false;
    }
    $extracted = false;
    $allowed_extensions = file_tools_allowed_extensions();
    $zipfile = elgg_extract('tmp_name', $file);
    $access_id = get_input('access_id', false);
    if ($access_id === false) {
        $parent_folder = get_entity($parent_guid);
        if (elgg_instanceof($parent_folder, 'object', FILE_TOOLS_SUBTYPE)) {
            $access_id = $parent_folder->access_id;
        } else {
            if ($container_entity instanceof ElggGroup) {
                $access_id = $container_entity->group_acl;
            } else {
                $access_id = get_default_access($container_entity);
            }
        }
    }
    // open the zip file
    $zip = zip_open($zipfile);
    while ($zip_entry = zip_read($zip)) {
        // open the zip entry
        zip_entry_open($zip, $zip_entry);
        // set some variables
        $zip_entry_name = zip_entry_name($zip_entry);
        $filename = basename($zip_entry_name);
        // check for folder structure
        if (strlen($zip_entry_name) != strlen($filename)) {
            // there is a folder structure, check it and create missing items
            file_tools_create_folders($zip_entry, $container_guid, $parent_guid);
        }
        // extract the folder structure from the zip entry
        $folder_array = explode('/', $zip_entry_name);
        $parent = $parent_guid;
        foreach ($folder_array as $folder) {
            $folder = utf8_encode($folder);
            $entity = file_tools_check_foldertitle_exists($folder, $container_guid, $parent);
            if (!empty($entity)) {
                $parent = $entity->getGUID();
            } else {
                if ($folder !== end($folder_array)) {
                    continue;
                }
                $prefix = 'file/';
                $extension_array = explode('.', $folder);
                $file_extension = end($extension_array);
                if (!in_array(strtolower($file_extension), $allowed_extensions)) {
                    continue;
                }
                $buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
                $filestorename = elgg_strtolower(time() . $folder);
                // create the file
                $filehandler = new ElggFile();
                $filehandler->setFilename($prefix . $filestorename);
                $filehandler->title = $folder;
                $filehandler->originalfilename = $folder;
                $filehandler->owner_guid = elgg_get_logged_in_user_guid();
                $filehandler->container_guid = $container_guid;
                $filehandler->access_id = $access_id;
                if (!$filehandler->save()) {
                    continue;
                }
                $filehandler->open('write');
                $filehandler->write($buf);
                $filehandler->close();
                $mime_type = $filehandler->detectMimeType($filehandler->getFilenameOnFilestore());
                // hack for Microsoft zipped formats
                $info = pathinfo($folder);
                $office_formats = ['docx', 'xlsx', 'pptx'];
                if ($mime_type == 'application/zip' && in_array($info['extension'], $office_formats)) {
                    switch ($info['extension']) {
                        case 'docx':
                            $mime_type = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
                            break;
                        case 'xlsx':
                            $mime_type = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
                            break;
                        case 'pptx':
                            $mime_type = 'application/vnd.openxmlformats-officedocument.presentationml.presentation';
                            break;
                    }
                }
                // check for bad ppt detection
                if ($mime_type == 'application/vnd.ms-office' && $info['extension'] == 'ppt') {
                    $mime_type = 'application/vnd.ms-powerpoint';
                }
                $simple_type = file_get_simple_type($mime_type);
                $filehandler->setMimeType($mime_type);
                $filehandler->simpletype = $simple_type;
                if ($simple_type == 'image') {
                    if ($filehandler->saveIconFromElggFile($filehandler)) {
                        $filehandler->thumbnail = $filehandler->getIcon('small')->getFilename();
                        $filehandler->smallthumb = $filehandler->getIcon('medium')->getFilename();
                        $filehandler->largethumb = $filehandler->getIcon('large')->getFilename();
                    }
                }
                set_input('folder_guid', $parent);
                $filehandler->save();
                $extracted = true;
                if (!empty($parent)) {
                    add_entity_relationship($parent, FILE_TOOLS_RELATIONSHIP, $filehandler->getGUID());
                }
            }
        }
        zip_entry_close($zip_entry);
    }
    zip_close($zip);
    return $extracted;
}