admin/vendor/zgldh/laravel-upload-manager/src/UploadManager.php

307 lines
7.7 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php namespace zgldh\UploadManager;
use Illuminate\Support\Str;
use Symfony\Component\HttpFoundation\File\UploadedFile;
/**
* Created by PhpStorm.
* User: zgldh
* Date: 2015/7/23
* Time: 16:50
*/
class UploadManager
{
/**
* @var UploadStrategyInterface
*/
private $strategy = null;
/**
* @var null The name of default disk
*/
private $diskName = null;
/**
* @var array zgldh\UploadManager\Validators\Base
*/
private $validatorGroups = null;
private $errors = null;
/**
* UploadManager constructor.
* @throws \Exception
*/
public function __construct()
{
$this->strategy = self::getStrategy();
$this->withDisk();
}
/**
* @return UploadManager
*/
public static function getInstance()
{
return \App::make('upload-manager');
}
/**
* @return UploadStrategyInterface
*/
public static function getStrategy()
{
return \App::make('zgldh\UploadManager\UploadStrategyInterface');
}
/**
* 得到已上传文件的URL
* @param $disk
* @param $path
* @return string
*/
public function getUploadUrl($disk, $path)
{
$url = '';
$methodName = 'get' . ucfirst(Str::camel($disk)) . 'Url';
if (method_exists($this->strategy, $methodName)) {
$url = $this->strategy->$methodName($path);
}
return $url;
}
/**
* 设置默认disk名字
* @param $diskName config/filesystems.php disks数组内的key
* @return $this
* @throws \Exception
*/
public function withDisk($diskName = null)
{
if ($diskName == null) {
$this->diskName = \Config::get('upload.base_storage_disk');
} elseif (\Config::has('filesystems.disks.' . $diskName)) {
$this->diskName = $diskName;
} else {
throw new BadDiskException("Bad disk name: " . $diskName);
}
return $this;
}
/**
* 设置验证机制, 要在upload、update之前调用
* @param $validatorGroups 验证组的名字
* @return $this
*/
public function withValidator($validatorGroups)
{
if (!is_array($validatorGroups)) {
$validatorGroups = [$validatorGroups];
}
$this->validatorGroups = $validatorGroups;
return $this;
}
/**
* 核心上传
* @param $upload Upload object
* @param $uploadedFilePath string (path)
* @param $file UploadedFile / string
* @param $preCallback function
* @return bool
*/
private function coreUpload($upload, $uploadedFilePath, $file, $preCallback)
{
try {
$newName = $this->strategy->makeFileName($file);
$path = $this->strategy->makeStorePath($newName);
$content = file_get_contents($uploadedFilePath);
UploadValidator::validate($content, $this->validatorGroups);
$upload->path = $path;
$upload->disk = $this->diskName;
$upload->size = strlen($content);
if (is_callable($preCallback)) {
$upload = $preCallback($upload);
}
if (!$upload) {
unset($content);
return false;
}
$disk = \Storage::disk($upload->disk);
if ($disk->put($upload->path, $content) == false) {
return false;
}
} catch (UploadException $e) {
$this->storeErrors($e);
return false;
}
return $upload;
}
private function newUploadModel()
{
$modelClassName = config('upload.upload_model');
$model = app($modelClassName);
return $model;
}
/**
* 保存上传文件,生成上传对象
* @param $file
* @param null $preCallback
* @return Upload|bool
*/
public function upload($file, $preCallback = null)
{
if (is_string($file)) {
return $this->uploadByUrl($file, $preCallback);
}
$upload = $this->newUploadModel();
$upload->disk = $this->diskName;
$uploadedFilePath = $file->getPathname();
$upload = $this->coreUpload($upload, $uploadedFilePath, $file, $preCallback);
return $upload;
}
/**
* 从URL获取文件并保存生成上传对象
* @param $url
* @param null $preCallback
* @return Upload|bool
*/
public function uploadByUrl($url, $preCallback = null)
{
$upload = $this->newUploadModel();
$upload->disk = $this->diskName;
$uploadedFilePath = $url;
$upload = $this->coreUpload($upload, $uploadedFilePath, $url, $preCallback);
return $upload;
}
/**
* 用已上传文件更新一个上传对象
* @param $upload
* @param UploadedFile $file
* @param null $preCallback
* @return bool
*/
public function update(&$upload, $file, $preCallback = null)
{
if (is_string($file)) {
return $this->updateByUrl($upload, $file, $preCallback);
}
$oldDisk = $upload->disk;
$oldPath = $upload->path;
$uploadedFilePath = $file->getPathname();
$result = $this->coreUpload($upload, $uploadedFilePath, $file, $preCallback);
if ($result) {
$this->removeOldFile($oldDisk, $oldPath);
$upload = $result;
} else {
$upload->disk = $oldDisk;
$upload->path = $oldPath;
return false;
}
return true;
}
/**
* 用URL更新一个上传对象
* @param $upload
* @param $url
* @param null $preCallback
* @return bool
*/
public function updateByUrl(&$upload, $url, $preCallback = null)
{
$oldDisk = $upload->disk;
$oldPath = $upload->path;
$uploadedFilePath = $url;
$result = $this->coreUpload($upload, $uploadedFilePath, $url, $preCallback);
if ($result) {
$this->removeOldFile($oldDisk, $oldPath);
$upload = $result;
} else {
$upload->disk = $oldDisk;
$upload->path = $oldPath;
return false;
}
return true;
}
private function removeOldFile($disk, $path)
{
if ($disk && $path) {
$disk = \Storage::disk($disk);
if ($disk) {
$disk->delete($path);
}
}
}
public function storeErrors(UploadException $e)
{
\Log::error($e);
$this->errors = $e->errors;
//TODO
}
/**
* @return null
*/
public function getErrors()
{
return $this->errors;
}
/**
* 得到第一个错误信息
* @return mixed
*/
public function getFirstErrorMessage()
{
if (isset($this->errors[0])) {
reset($this->errors);
$error = each($this->errors);
reset($this->errors);
return $error['value'];
}
}
/**
* 删除未使用的上传对象。
* @param int $userId 上传者ID
* @param string $type 上传类型
*/
public function removeUnUsedUploads($userId = null, $type = null)
{
$unusedLifetime = config('upload.unused_lifetime', -1);
if ($unusedLifetime === -1) {
return;
}
$upload = $this->newUploadModel();
$upload = $upload->unUsed();
$expiredTime = date('Y-m-d H:i:s', time() - $unusedLifetime);
$upload = $upload->where('created_at', '<', $expiredTime);
if ($userId) {
$upload = $upload->where('user_id', $userId);
}
if ($type) {
$upload = $upload->where('type', $type);
}
return $upload->delete();
}
}