/** * Handles the extraction of files in a ZIP archive * * @param string $filename * @return bool */ protected function handleZip($filename) { $za = new ZipArchive(); $za->open($this->tmpName); $i = 0; $extractDir = $this->_zula->getDir('tmp') . '/uploader/' . uniqid(); while ($file = $za->statIndex($i)) { $this->fileDetails[$i + 1] = array('name' => $file['name'], 'size' => $file['size'], 'mime' => null, 'category' => null); if ($this->checkFileSize($file['size']) && $this->checkExtension($file['name'])) { // Extract file to get the mime type, will be removed if it is not valid $za->extractTo($extractDir, $file['name']); $mime = zula_get_file_mime($extractDir . '/' . $file['name']); $this->fileDetails[$i + 1]['mime'] = $mime; $this->fileDetails[$i + 1]['category'] = substr($mime, 0, strpos($mime, '/')); if ($mime !== false && $this->checkMime($mime)) { // Move the file to a uniquely named file $category = $this->fileDetails[$i + 1]['category']; if (($uploadDir = $this->makeDirectory($category)) === false) { throw new Uploader_Exception('unable to create upload directory, or not writable'); } $this->uploader->subDirectoryName(null); # Stop the same sub directory being used! $path = $uploadDir . '/' . zula_make_unique_file($uploadDir, pathinfo($file['name'], PATHINFO_EXTENSION), false); rename($extractDir . '/' . $file['name'], $path); $this->fileDetails[$i + 1]['path'] = $path; $this->fileDetails[$i + 1] = array_merge($this->fileDetails[$i + 1], pathinfo($path)); } else { unlink($uploadDir . '/' . $file['name']); } } $this->fileDetails[$i + 1]['fromArchive'] = true; ++$i; } zula_full_rmdir($extractDir); return true; }
/** * Handles the uploading and image post-processing if needed. * * @param array $fd * @return array */ protected function handleUpload(array $fd) { try { $uploader = new Uploader('media_file', $this->_zula->getDir('uploads') . '/media/' . $fd['cid'] . '/{CATEGORY}'); $uploader->subDirectories()->allowedMime($this->allowedMime)->maxFileSize($this->_config->get('media/max_fs'))->extractArchives(); $file = $uploader->getFile(); if ($file->upload() === false) { throw new Media_Exception(t('Please select a file to upload')); } // Upload the thumbail image if one has been provided and resize it $thumbnailWH = $this->_config->get('media/thumb_dimension'); $thumbUploader = new Uploader('media_thumb', $file->dirname); $thumbUploader->subDirectories(false)->allowImages(); $thumbnail = $thumbUploader->getFile(); if ($thumbnail->upload() !== false) { $thumbImage = new Image($thumbnail->path); $thumbImage->mime = 'image/png'; $thumbImage->thumbnail($thumbnailWH, $thumbnailWH); // Remove the original uploaded file unlink($thumbnail->path); } /** * Get details of all the images (could have been an archive containing * multiple media files */ $uploadedItems = array(); while ($details = $file->getDetails()) { if (isset($details['path'])) { // Get the directory name where the files are stored (just the name, not path) $dirname = substr($details['dirname'], strrpos($details['dirname'], DIRECTORY_SEPARATOR) + 1); /** * Use uploaded thumbnail, or attempt to create one from the uploaded image */ $thumbname = $details['filename'] . '_thumb.png'; if (isset($thumbImage)) { $thumbImage->save($details['dirname'] . '/' . $thumbname, false); } else { if ($details['category'] == 'image') { $tmpThumb = new Image($details['path']); $tmpThumb->mime = 'image/png'; $tmpThumb->thumbnail($thumbnailWH, $thumbnailWH)->save($details['dirname'] . '/' . $thumbname); } else { unset($thumbname); } } // Generate a title from the filename automatically $title = str_replace(array('-', '_', '+'), ' ', pathinfo($details['name'], PATHINFO_FILENAME)); $uploadedItems[] = array('title' => trim(ucfirst(strtolower($title))), 'desc' => '', 'type' => $details['category'], 'file' => $dirname . '/' . $details['basename'], 'thumbnail' => isset($thumbname) ? $dirname . '/' . $thumbname : ''); } } if (isset($thumbImage)) { $thumbImage->destroy(); } return $uploadedItems; } catch (Uploader_NotEnabled $e) { $msg = t('Sorry, it appears file uploads are disabled within your PHP configuration'); } catch (Uploader_MaxFileSize $e) { $msg = sprintf(t('Selected file exceeds the maximum allowed file size of %s'), zula_human_readable($e->getMessage())); } catch (Uploader_InvalidMime $e) { $msg = t('Sorry, the uploaded file is of the wrong file type'); } catch (Uploader_Exception $e) { $logMsg = $e->getMessage(); $msg = t('Oops, an error occurred while uploading your files'); } catch (Image_Exception $e) { $logMsg = $e->getMessage(); $msg = t('Oops, an error occurred while processing an image'); } // Cleanup and end processing, it failed. if (isset($file->dirname)) { zula_full_rmdir($file->dirname); } if (isset($logMsg)) { $this->_log->message($logMsg, Log::L_WARNING); } throw new Media_Exception($msg); }
/** * Similar to the origianl rmdir() function zula_except this * one will remove all files and other directories inside * of it instead of just failing. * * @param string $dir * @return bool */ function zula_full_rmdir($dir) { if (!zula_is_writable($dir) || !zula_is_writable(pathinfo($dir, PATHINFO_DIRNAME))) { return false; } // Create new instance of the directory class $d = dir($dir); while (false !== ($entry = $d->read())) { if ($entry == '.' || $entry == '..') { continue; } $entry = $dir . '/' . $entry; if (is_dir($entry)) { if (!zula_full_rmdir($entry)) { return false; } continue; } if (!@unlink($entry)) { $d->close(); return false; } } $d->close(); rmdir($dir); return true; }
/** * Deletes a media item from a category if it exists * * @return string */ public function deleteSection() { $this->setTitle(t('Delete media item')); // Attempt to remove the single media item try { $itemId = $this->_router->getArgument('id'); $item = $this->_model()->getItem($itemId); // Check permission to parent category resource $resource = 'media-cat_moderate_' . $item['cat_id']; if ($this->_acl->resourceExists($resource) && $this->_acl->check($resource)) { if ($this->_input->checkToken('get')) { $this->_model()->deleteItem($item['id']); zula_full_rmdir($item['path_fs'] . '/' . dirname($item['filename'])); $this->_event->success(t('Deleted media item')); // Redirect back to the parent media category try { $category = $this->_model()->getCategory($item['cat_id']); return zula_redirect($this->_router->makeUrl('media', 'cat', $category['identifier'])); } catch (Media_CatNoExist $e) { } } else { $this->_event->error(Input::csrfMsg()); } } else { throw new Module_NoPermission(); } } catch (Router_ArgNoExist $e) { $this->_event->error(t('No media item selected')); } catch (Media_ItemNoExist $e) { $this->_event->error(t('Media item does not exist')); } return zula_redirect($this->_router->makeUrl('media')); }
/** * Deletes a theme by removing it's directory * * @return bool */ public function delete() { return zula_full_rmdir($this->getDetail('path')); }
/** * Bridges between deleting, or purging a category. * * @return bool */ public function bridgeSection() { $type = $this->_input->has('post', 'media_purge') ? 'purge' : 'delete'; if (!$this->_acl->resourceExists('media_' . $type . '_category') || !$this->_acl->check('media_' . $type . '_category')) { throw new Module_NoPermission(); } else { if ($this->_input->checkToken()) { // Attempt to purge or delete try { $delCount = 0; $mediaDir = $this->_zula->getDir('uploads') . '/media'; foreach ($this->_input->post('media_cat_ids') as $cid) { $resource = 'media-cat_moderate_' . $cid; if ($this->_acl->resourceExists($resource) && $this->_acl->check($resource)) { try { $method = $type == 'delete' ? 'deleteCategory' : 'purgeCategory'; $this->_model()->{$method}($cid); // Remove all media items zula_full_rmdir($mediaDir . '/' . $cid); ++$delCount; } catch (Media_CategoryNoExist $e) { } } } $this->_event->success($type == 'delete' ? t('Deleted selected categories') : t('Purged selected categories')); } catch (Input_KeyNoExist $e) { $this->_event->error(t('No media categories selected')); } } else { $this->_event->error(Input::csrfMsg()); } } return zula_redirect($this->_router->makeUrl('media', 'config')); }