如何从Laravel 8.x上传文档到Rackspace



我正在使用Laravel 8。x用于我的新项目,并且需要支持Zend中的遗留Live web应用程序,该应用程序使用Rackspace CDN存储文件。所以,我需要从Laravel 8的新应用程序上传Rackspace CDN中的文件。x我可以在Amazon S3上成功上传文件,但是无法在Rackspace上上传。我尝试了league/flysystem-rackspace,但在当前的Laravel版本中不支持。

控制器

public function store(Request $request)
{
$uploadImage = $request->file('file');
$filename = time().str_replace(' ', '_', 
$uploadImage->getClientOriginalName());
$path = $request->file('file')->storePubliclyAs(
config('app.cdn_dir'),
$filename,
'rackspace'
);
}

配置文件系统/

'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'rackspace' => [
'driver'    => 'rackspace',
'username'  => env('CDN_USERNAME'),
'key'       => env('CDN_KEY'),
'container' => env('CDN_CONTAINER'),
'endpoint'  => env('CDN_ENDPOINT', 'https://identity.api.rackspacecloud.com/v2.0/'),
'region'    => 'IAD',
'url_type'  => 'publicURL',
'url' => env('CDN_URL'), 
],
],

误差

错误:类'SymfonyComponentEventDispatcherEvent'未找到文件D: laragon www crm 供应商狂饮狂饮 src 狂饮常见 Event.php10号线

我在升级到Laravel 8后也遇到了同样的问题。我设法让它工作基于这个pr评论,这是当他们从Laravel和这个草案开始使用较新的php-opencloud sdk。

Rackspace提供者:

<?php
namespace AppProviders;
use IlluminateSupportServiceProvider;
use IlluminateSupportFacadesStorage;
use LeagueFlysystemFilesystem;
use AppServicesRackspaceRackspaceAdapter;
use OpenStackOpenStack;
use OpenStackCommonTransportUtils as TransportUtils;
use OpenStackIdentityv2Service;
use GuzzleHttpClient;
use GuzzleHttpHandlerStack;
class RackspaceServiceProvider extends ServiceProvider  {
/**
* Register services.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap services.
*
* @return void
*/
public function boot()
{
Storage::extend('rackspace', function ($app, $config) {
$httpClient = new Client([
'base_uri' => TransportUtils::normalizeUrl($config['authUrl']),
'handler'  => HandlerStack::create(),
]);
$options = [
'authUrl'         => $config['authUrl'],
'region'          => $config['region'],
'username'        => $config['username'],
'password'        => $config['password'],
'tenantId'        => $config['tenantid'],
'identityService' => Service::factory($httpClient),
];
$openstack = new OpenStack($options);
$store = $openstack->objectStoreV1([
'catalogName' => 'cloudFiles',
]);
$account = $store->getAccount();
$container = $store->getContainer($config['container']);
return new Filesystem(
new RackspaceAdapter($container, $account), $config
);
});
}
}

和适配器:

<?php
declare(strict_types=1);
namespace AppServicesRackspace;
use CarbonCarbon;
use Exception;
use GuzzleHttpPsr7Utils;
use LeagueFlysystemAdapterAbstractAdapter;
use LeagueFlysystemAdapterPolyfillNotSupportingVisibilityTrait;
use LeagueFlysystemAdapterPolyfillStreamedCopyTrait;
use LeagueFlysystemConfig;
use LeagueFlysystemUtil;
use OpenStackCommonErrorBadResponseError;
use OpenStackObjectStorev1ModelsAccount;
use OpenStackObjectStorev1ModelsContainer;
use OpenStackObjectStorev1ModelsStorageObject;
use Throwable;
// Based off https://github.com/thephpleague/flysystem-rackspace/pull/26
final class RackspaceAdapter extends AbstractAdapter
{
use StreamedCopyTrait;
use NotSupportingVisibilityTrait;
private $container;
private $prefix;
private $account;
public function __construct(Container $container, Account $account, string $prefix = '')
{
$this->setPathPrefix($prefix);
$this->account = $account;
$this->container = $container;
}
public function getContainer(): Container
{
return $this->container;
}
protected function getObject(string $path): StorageObject
{
$location = $this->applyPathPrefix($path);
return $this->container->getObject($location);
}
protected function getPartialObject(string $path): StorageObject
{
$location = $this->applyPathPrefix($path);
return $this->container->getObject($location);
}
public function write($path, $contents, Config $config)
{
$location = $this->applyPathPrefix($path);
$headers = $config->get('headers', []);
$response = $this->container->createObject([
'name' => $location,
'content' => $contents,
'headers' => $headers,
]);
return $this->normalizeObject($response);
}
/**
* {@inheritdoc}
*/
public function update($path, $contents, Config $config)
{
$object = $this->getObject($path);
$object->setContent($contents);
$object->setEtag(null);
$response = $object->update();
if (!$response->lastModified) {
return false;
}
return $this->normalizeObject($response);
}
/**
* {@inheritdoc}
*/
public function rename($path, $newpath)
{
$object = $this->getObject($path);
$newlocation = $this->applyPathPrefix($newpath);
$destination = sprintf('/%s/%s', $this->container->name, ltrim($newlocation, '/'));
try {
$object->copy(['destination' => $destination]);
} catch (Throwable $exception) {
return false;
}
$object->delete();
return true;
}
/**
* {@inheritdoc}
*/
public function delete($path)
{
try {
$location = $this->applyPathPrefix($path);
$this->container->getObject($location)->delete();
} catch (Throwable $exception) {
return false;
}
return true;
}
/**
* {@inheritdoc}
*/
public function deleteDir($dirname)
{
$location = $this->applyPathPrefix($dirname);
$objects = $this->container->listObjects(['prefix' => $location]);
try {
foreach ($objects as $object) {
/* @var $object StorageObject */
$object->delete();
}
} catch (Throwable $exception) {
return false;
}
return true;
}
/**
* {@inheritdoc}
*/
public function createDir($dirname, Config $config)
{
$headers = $config->get('headers', []);
$headers['Content-Type'] = 'application/directory';
$extendedConfig = (new Config())->setFallback($config);
$extendedConfig->set('headers', $headers);
return $this->write($dirname, '', $extendedConfig);
}
/**
* {@inheritdoc}
*/
public function writeStream($path, $resource, Config $config)
{
$location = $this->applyPathPrefix($path);
$headers = $config->get('headers', []);
$response = $this->container->createObject([
'name' => $location,
'stream' => Utils::streamFor($resource),
'headers' => $headers,
]);
return $this->normalizeObject($response);
}
/**
* {@inheritdoc}
*/
public function updateStream($path, $resource, Config $config)
{
return $this->update($path, $resource, $config);
}
/**
* {@inheritdoc}
*/
public function has($path)
{
try {
$location = $this->applyPathPrefix($path);
$exists = $this->container->objectExists($location);
} catch (BadResponseError | Exception $exception) {
return false;
}
return $exists;
}
/**
* {@inheritdoc}
*/
public function read($path)
{
$object = $this->getObject($path);
$data = $this->normalizeObject($object);
$stream = $object->download();
$data['contents'] = $stream->read($object->contentLength);
$stream->close();
return $data;
}
/**
* {@inheritdoc}
*/
public function readStream($path)
{
$object = $this->getObject($path);
$responseBody = $object->download();
$responseBody->rewind();
return ['stream' => $responseBody->detach()];
}
/**
* {@inheritdoc}
*/
public function listContents($directory = '', $recursive = false)
{
$response = [];
$marker = null;
$location = $this->applyPathPrefix($directory);
while (true) {
$objectList = $this->container->listObjects(['prefix' => $location, 'marker' => $marker]);
if (null === $objectList->current()) {
break;
}
$response = array_merge($response, iterator_to_array($objectList));
$marker = end($response)->name;
}
return Util::emulateDirectories(array_map([$this, 'normalizeObject'], $response));
}
/**
* {@inheritdoc}
*/
protected function normalizeObject(StorageObject $object)
{
$name = $object->name;
$name = $this->removePathPrefix($name);
$mimetype = explode('; ', $object->contentType);
return [
'type' => ((in_array('application/directory', $mimetype)) ? 'dir' : 'file'),
'dirname' => Util::dirname($name),
'path' => $name,
'timestamp' => $object->lastModified,
'mimetype' => reset($mimetype),
'size' => $object->contentLength,
];
}
/**
* {@inheritdoc}
*/
public function getMetadata($path)
{
$object = $this->getPartialObject($path);
return $this->normalizeObject($object);
}
/**
* {@inheritdoc}
*/
public function getSize($path)
{
return $this->getMetadata($path);
}
/**
* {@inheritdoc}
*/
public function getMimetype($path)
{
return $this->getMetadata($path);
}
/**
* {@inheritdoc}
*/
public function getTimestamp($path)
{
return $this->getMetadata($path);
}
/**
* @param string $path
*/
public function applyPathPrefix($path): string
{
$encodedPath = join('/', array_map('rawurlencode', explode('/', $path)));
return parent::applyPathPrefix($encodedPath);
}
/**
* Get the URL for the file at the given path.
*
* @param  string $path
* @return string
*/
protected function getUrl($path)
{
return (string) $this->container->getObject($path)->getPublicUri();
}
/**
* Get a temporary URL for the file at the given path.
*
* @param  string  $path
* @param  DateTimeInterface  $expiration
* @param  array  $options
* @return string
*/
public function getTemporaryUrl($path, $expiration, array $options = [])
{
$object = $this->container->getObject($path);
$url = $object->getPublicUri();
$expires = Carbon::now()->diffInSeconds($expiration);
$method = strtoupper($options['method'] ?? 'GET');
$expiry = time() + (int) $expires;
// check for proper method
if ($method != 'GET' && $method != 'PUT') {
throw new Exception(sprintf(
'Bad method [%s] for TempUrl; only GET or PUT supported',
$method
));
}
if (!($secret = $this->account->getMetadata()['Temp-Url-Key'])) {
throw new Exception('Cannot produce temporary URL without an account secret.');
}
// if ($forcePublicUrl === true) {
//     $url->setHost($this->getService()->getEndpoint()->getPublicUrl()->getHost());
// }
$urlPath = urldecode($url->getPath());
$body = sprintf("%sn%dn%s", $method, $expiry, $urlPath);
$hash = hash_hmac('sha1', $body, $secret);
return sprintf('%s?temp_url_sig=%s&temp_url_expires=%d', $url, $hash, $expiry);
}
}

Rackspace config infilesystems.php

'rackspace' => [
'driver'    => 'rackspace',
'username'  => env('RACKSPACE_USERNAME'),
'key'       => env('RACKSPACE_KEY'),
'container' => env('RACKSPACE_CONTAINER'),
'password'  => env('RACKSPACE_PASSWORD'),
'authUrl'   => 'https://lon.identity.api.rackspacecloud.com/v2.0/',
'region'    => env('RACKSPACE_REGION', 'LON'),
'tenantid'    => env('RACKSPACE_TENANTID', '1'),
'url_type'  => 'publicURL',
],

然后在app.php中添加提供商。

这是一个粗略的实现,因为只测试了创建、删除和获取临时url。

身份验证通过使用Identity v2.0工作,因为Rackspace不支持v3https://php-openstack-sdk.readthedocs.io/en/latest/services/identity/v2/authentication.html

临时url方法基于旧的repo中的函数https://github.com/rackspace/php-opencloud

相关内容

  • 没有找到相关文章

最新更新