Skip to content

Commit

Permalink
feat(core): 增加文件本地驱动,增加用户测试代码
Browse files Browse the repository at this point in the history
  • Loading branch information
medz committed Aug 31, 2018
1 parent 9c7eae8 commit 42bf3c6
Show file tree
Hide file tree
Showing 20 changed files with 394 additions and 102 deletions.
8 changes: 6 additions & 2 deletions app/FileStorage/Channels/ChannelInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use Illuminate\Http\Request;
use Zhiyi\Plus\FileStorage\TaskInterface;
use Zhiyi\Plus\FileStorage\FileMateInterface;
use Zhiyi\Plus\FileStorage\FileMetaInterface;
use Zhiyi\Plus\FileStorage\ResourceInterface;
use Zhiyi\Plus\FileStorage\Filesystems\FilesystemInterface;

Expand All @@ -20,5 +20,9 @@ public function setFilesystem(FilesystemInterface $filesystem): void;

public function createTask(): TaskInterface;

public function meta(): FileMateInterface;
public function meta(): FileMetaInterface;

public function url(?string $rule = null): string;

public function callback(): void;
}
14 changes: 11 additions & 3 deletions app/FileStorage/Channels/PublicChannel.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use Zhiyi\Plus\AppInterface;
use Zhiyi\Plus\FileStorage\TaskInterface;
use Zhiyi\Plus\FileStorage\Task;
use Zhiyi\Plus\FileStorage\FileMateInterface;
use Zhiyi\Plus\FileStorage\FileMetaInterface;

class PublicChannel extends AbstractChannel
{
Expand All @@ -24,8 +24,16 @@ public function createTask(): TaskInterface
return $this->filesystem->createTask($this->request, $this->resource);
}

public function meta(): FileMateInterface
public function meta(): FileMetaInterface
{
return $this->filesystem->mate($this->resource);
return $this->filesystem->meta($this->resource);
}

public function url(?string $rule = null): string
{
return $this->filesystem->url($this->resource->getPath(), $rule);
}

public function callback(): void
{}
}
18 changes: 17 additions & 1 deletion app/FileStorage/FileMetaInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
namespace Zhiyi\Plus\FileStorage;

use \Zhiyi\Plus\Models\User;
use Illuminate\Contracts\Support\Arrayable;
use Zhiyi\Plus\FileStorage\Pay\PayInterface;

interface FileMetaInterface
interface FileMetaInterface extends Arrayable
{
/**
* Has the file is image.
Expand All @@ -33,10 +34,25 @@ public function getSize(): int;
*/
public function getMimeType(): string;

/**
* Get the storage vendor name.
* @return string
*/
public function getVendorName(): string;

/**
* Get the resource pay info.
* @param \Zhiyi\Plus\Models\User $user
* @return \Zhiyi\Plus\FileStorage\Pay\PayInterface
*/
public function getPay(User $user): ?PayInterface;

public function url(): string;

/**
* Get the instance as an array.
*
* @return array
*/
public function toArray(): array;
}
2 changes: 1 addition & 1 deletion app/FileStorage/FilesystemManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public function createLocalDriver(): Filesystems\FilesystemInterface
$filesystem = $this
->app
->make(\Illuminate\Contracts\Filesystem\Factory::class)
->disk(setting('core:file-local-select', 'local'));
->disk(setting('core', 'file:local-filesystem-select', 'local'));

return new Filesystems\LocalFilesystem($filesystem);
}
Expand Down
2 changes: 1 addition & 1 deletion app/FileStorage/Filesystems/FilesystemInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

interface FilesystemInterface
{
public function meta(ResourceInterface $resource): ?FileMetaInterface;
public function meta(ResourceInterface $resource): FileMetaInterface;

public function url(string $path, ?string $rule = null): string;

Expand Down
134 changes: 134 additions & 0 deletions app/FileStorage/Filesystems/Local/FileMeta.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
<?php

declare(strict_types=1);

namespace Zhiyi\Plus\FileStorage\Filesystems\Local;

use Closure;
use Exception;
use Zhiyi\Plus\Models\User;
use Zhiyi\Plus\FileStorage\ImageDimension;
use Zhiyi\Plus\FileStorage\Pay\PayInterface;
use Zhiyi\Plus\FileStorage\ResourceInterface;
use Zhiyi\Plus\FileStorage\FileMetaInterface;
use Zhiyi\Plus\FileStorage\Traits\HasImageTrait;
use Zhiyi\Plus\FileStorage\ImageDimensionInterface;
use Illuminate\Contracts\Filesystem\Filesystem as FilesystemContract;

class FileMeta implements FileMetaInterface
{
use HasImageTrait;

protected $filesystem;
protected $resource;
protected $dimension;

public function __construct(FilesystemContract $filesystem, ResourceInterface $resource)
{
$this->filesystem = $filesystem;
$this->resource = $resource;
}

protected function useCustomTypes(): ?Closure
{
return function () {
return [
'image/jpeg',
'image/png',
'image/gif',
'image/bmp',
'image/webp',
];
};
}

/**
* Has the file is image.
* @return bool
*/
public function hasImage(): bool
{
return $this->hasImageType(
$this->getMimeType()
);
}

/**
* Get image file dimension.
* @return \Zhiyi\Plus\FileStorage\ImageDimensionInterface
*/
public function getImageDimension(): ImageDimensionInterface
{
if (! $this->hasImage()) {
throw new Exception('调用的资源并非图片或者是不支持的图片资源');
} elseif ($this->dimension instanceof ImageDimensionInterface) {
return $this->dimension;
};

$realPath = $this->filesystem->path(
$this->resource->getPath()
);
list($width, $height) = getimagesize($realPath);

return $this->dimension = new ImageDimension((float) $width, (float) $height);
}

/**
* Get the file size (Byte).
* @return int
*/
public function getSize(): int
{
return $this->filesystem->getSize(
$this->resource->getPath()
);
}

/**
* Get the resource mime type.
* @return string
*/
public function getMimeType(): string
{
return $this->filesystem->mimeType(
$this->resource->getPath()
);
}

/**
* Get the resource pay info.
* @param \Zhiyi\Plus\Models\User $user
* @return \Zhiyi\Plus\FileStorage\Pay\PayInterface
*/
public function getPay(User $user): ?PayInterface
{
return null;
}

/**
* Get the storage vendor name.
* @return string
*/
public function getVendorName(): string
{
return 'local';
}

public function url(): string
{
return route('storage:local-get', [
'channel' => $this->resource->getChannel(),
'path' => base64_encode($this->resource->getPath()),
]);
}

/**
* Get the instance as an array.
*
* @return array
*/
public function toArray(): array
{
return [1, 2];
}
}
21 changes: 17 additions & 4 deletions app/FileStorage/Filesystems/LocalFilesystem.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
use Zhiyi\Plus\FileStorage\FileMetaInterface;
use function Zhiyi\Plus\setting;
use Illuminate\Contracts\Filesystem\Filesystem as FilesystemContract;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Support\Facades\Auth;

class LocalFilesystem implements FilesystemInterface
{
Expand All @@ -22,10 +24,9 @@ public function __construct(FilesystemContract $filesystem)
$this->filesystem = $filesystem;
}

public function meta(ResourceInterface $resource): ?FileMetaInterface
public function meta(ResourceInterface $resource): FileMetaInterface
{
$meta = $this->filesystem->getMetadata($resource->getPath());
dd($meta);
return new Local\FileMeta($this->filesystem, $resource);
}

public function url(string $path, ?string $rule = null): string
Expand All @@ -47,8 +48,10 @@ public function createTask(Request $request, ResourceInterface $resource): TaskI
'channel' => $resource->getChannel(),
'path' => base64_encode($resource->getPath()),
]);
$user = $this->guard()->user();

return new Task($uri, 'PUT', null, null, [
return new Task($resource, $uri, 'PUT', null, null, [
'Authorization' => 'Bearer '.$this->guard()->login($user),
'x-plus-storage-filename' => $request->input('filename'),
'x-plus-storage-hash' => $request->input('hash'),
'x-plus-storage-size' => $request->input('size'),
Expand All @@ -60,4 +63,14 @@ public function put(string $path, $content): bool
{
return (bool) $this->filesystem->put($path, $content);
}

/**
* Get the guard to be used during authentication.
*
* @return \Illuminate\Contracts\Auth\Guard
*/
public function guard(): Guard
{
return Auth::guard('api');
}
}
1 change: 1 addition & 0 deletions app/FileStorage/Http/Controllers/CreateTask.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public function __invoke(Request $request, StorageInterface $storage)
'headers' => $task->getHeaders(),
'form' => $task->getForm(),
'file_key' => $task->getFileKey(),
'node' => $task->getNode(),
], JsonResponse::HTTP_CREATED);
}
}
33 changes: 31 additions & 2 deletions app/FileStorage/Http/Controllers/Local.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Support\Facades\Auth;

class Local extends Controller
{
Expand All @@ -24,14 +26,29 @@ public function __construct(StorageInterface $storage)
{
$this
->middleware('signed')
->only(['put'/* , 'show' */]);
$this
->middleware('auth:api')
->only(['put']);

$this->storage = $storage;
}

public function show()
public function get(Request $request, string $channel, string $path)
{
// todo.
$resource = new Resource($channel, base64_decode($path));
$rule = $request->query('rule', null);
// $meta = $this->storage->meta($resource);
// dd(
// [
// 'size' => $meta->getSize(),
// 'mime' => $meta->getMimeType(),
// 'dimension' => [
// 'width' => $meta->getImageDimension()->getWidth(),
// 'height' => $meta->getImageDimension()->getHeight(),
// ]
// ]
// );
}

public function put(Request $request, FactoryContract $cache, string $channel, string $path): Response
Expand All @@ -52,11 +69,23 @@ public function put(Request $request, FactoryContract $cache, string $channel, s
throw new HttpException('储存文件失败');
}

$this->storage->callback($resource);
$expiresAt = (new Carbon)->addHours(
setting('core', 'file:put-signature-expires-at', 1)
);
$cache->put($signature, 1, $expiresAt);
$this->guard()->invalidate();

return new Response('', Response::HTTP_NO_CONTENT);
}

/**
* Get the guard to be used during authentication.
*
* @return \Illuminate\Contracts\Auth\Guard
*/
public function guard(): Guard
{
return Auth::guard('api');
}
}
4 changes: 2 additions & 2 deletions app/FileStorage/Http/MakeRoutes.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ protected function registerLocalFilesystemRoutes(): void

protected function registerChannelCallbackRoutes(): void
{
$this->router->group(['prefix' => 'api/v2', 'middleware' => ['api']], function (RegistrarContract $router) {
$this->router->group(['prefix' => 'api/v2'], function (RegistrarContract $router) {
$router
->post('storage/{channel}:{path}', Controllers\Callback::class)
->name('storage:callback');
Expand All @@ -45,7 +45,7 @@ protected function registerChannelCallbackRoutes(): void

protected function registerCreateTaskRoutes(): void
{
$this->router->group(['prefix' => 'api/v2', 'middleware' => ['api']], function (RegistrarContract $router) {
$this->router->group(['prefix' => 'api/v2'], function (RegistrarContract $router) {
$router
->post('storage', Controllers\CreateTask::class)
->name('storage:create-task');
Expand Down

0 comments on commit 42bf3c6

Please sign in to comment.