Skip to content

Commit

Permalink
Fix asset validation issues on upload
Browse files Browse the repository at this point in the history
  • Loading branch information
timkelty committed Dec 15, 2023
1 parent de92bbc commit 3b4b2be
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 46 deletions.
22 changes: 22 additions & 0 deletions src/Helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,28 @@ public static function setMemoryLimit(int|string $limit, int|string $offset = 0)
return $memoryLimit;
}

public static function removeAttributeFromRule(array $rule, string $attributeToRemove): ?array
{
$attributes = Collection::wrap($rule[0])
->reject(fn($attribute) => $attribute === $attributeToRemove);

if ($attributes->isEmpty()) {
return null;
}

$rule[0] = $attributes->all();

return $rule;
}

public static function removeAttributeFromRules(array $rules, string $attributeToRemove): array
{
return Collection::make($rules)
->map(fn($rule) => Helper::removeAttributeFromRule($rule, $attributeToRemove))
->filter()
->all();
}

/**
* A version of tableExists that doesn't rely on the cache component
*/
Expand Down
92 changes: 54 additions & 38 deletions src/Module.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@

use Craft;
use craft\base\Event;
use craft\base\Model;
use craft\cloud\fs\AssetsFs;
use craft\cloud\fs\StorageFs;
use craft\cloud\fs\TmpFs;
use craft\cloud\web\assets\uploader\UploaderAsset;
use craft\cloud\web\ResponseBehavior;
use craft\console\Application as ConsoleApplication;
use craft\debug\Module as DebugModule;
use craft\elements\Asset;
use craft\events\DefineRulesEvent;
use craft\events\RegisterComponentTypesEvent;
use craft\events\RegisterTemplateRootsEvent;
use craft\fs\Temp;
Expand Down Expand Up @@ -55,7 +58,7 @@ public function init(): void
? 'craft\\cloud\\cli\\controllers'
: 'craft\\cloud\\controllers';

$this->registerEventHandlers();
$this->registerGlobalEventHandlers();
$this->validateConfig();
}

Expand Down Expand Up @@ -96,43 +99,6 @@ public function getConfig(): Config
return $this->_config;
}

protected function registerEventHandlers(): void
{
Event::on(
ImageTransforms::class,
ImageTransforms::EVENT_REGISTER_IMAGE_TRANSFORMERS,
static function(RegisterComponentTypesEvent $event) {
$event->types[] = ImageTransformer::class;
}
);

Event::on(
FsService::class,
FsService::EVENT_REGISTER_FILESYSTEM_TYPES,
static function(RegisterComponentTypesEvent $event) {
$event->types[] = AssetsFs::class;
}
);

Event::on(
View::class,
View::EVENT_REGISTER_CP_TEMPLATE_ROOTS,
function(RegisterTemplateRootsEvent $e) {
$e->roots[$this->id] = sprintf('%s/templates', $this->getBasePath());
}
);

Event::on(
CraftVariable::class,
CraftVariable::EVENT_INIT,
function(\yii\base\Event $e) {
/** @var CraftVariable $craftVariable */
$craftVariable = $e->sender;
$craftVariable->set('cloud', Module::class);
}
);
}

protected function bootstrapCloud(ConsoleApplication|WebApplication $app): void
{
// Set Craft memory limit to just below PHP's limit
Expand Down Expand Up @@ -207,6 +173,48 @@ protected function bootstrapCloud(ConsoleApplication|WebApplication $app): void
'staticCaching' => StaticCaching::class,
]);

$this->registerCloudEventHandlers();
}

protected function registerGlobalEventHandlers(): void
{
Event::on(
ImageTransforms::class,
ImageTransforms::EVENT_REGISTER_IMAGE_TRANSFORMERS,
static function(RegisterComponentTypesEvent $event) {
$event->types[] = ImageTransformer::class;
}
);

Event::on(
FsService::class,
FsService::EVENT_REGISTER_FILESYSTEM_TYPES,
static function(RegisterComponentTypesEvent $event) {
$event->types[] = AssetsFs::class;
}
);

Event::on(
View::class,
View::EVENT_REGISTER_CP_TEMPLATE_ROOTS,
function(RegisterTemplateRootsEvent $e) {
$e->roots[$this->id] = sprintf('%s/templates', $this->getBasePath());
}
);

Event::on(
CraftVariable::class,
CraftVariable::EVENT_INIT,
function(\yii\base\Event $e) {
/** @var CraftVariable $craftVariable */
$craftVariable = $e->sender;
$craftVariable->set('cloud', Module::class);
}
);
}

protected function registerCloudEventHandlers(): void
{
Event::on(
View::class,
View::EVENT_BEFORE_RENDER_PAGE_TEMPLATE,
Expand All @@ -230,6 +238,14 @@ protected function bootstrapCloud(ConsoleApplication|WebApplication $app): void
ClearCaches::EVENT_REGISTER_CACHE_OPTIONS,
[$this->get('staticCaching'), 'handleRegisterCacheOptions'],
);

Event::on(
Asset::class,
Model::EVENT_DEFINE_RULES,
function(DefineRulesEvent $e) {
$e->rules = Helper::removeAttributeFromRules($e->rules, 'tempFilePath');
}
);
}

protected function validateConfig(): void
Expand Down
10 changes: 7 additions & 3 deletions src/controllers/AssetsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,13 @@ public function actionCreateAsset(): Response
$asset->width = $width;
$asset->height = $height;

// Setting newFolderId and not folderId, so that validation on newLocation occurs
// Setting newFolderId, so that extension validation on newLocation occurs
$asset->newFolderId = $folder->id;

// Setting these so that Asset::_relocateFile doesn't try to download
$asset->folderId = $folder->id;
$asset->folderPath = $folder->path;

if (!$selectionCondition) {
$asset->newFilename = $targetFilename;
}
Expand All @@ -169,7 +173,7 @@ public function actionCreateAsset(): Response
$asset->title = Assets::filename2Title(pathinfo($originalFilename, PATHINFO_FILENAME));
}

// Saving without Asset::SCENARIO_CREATE, as it requires a tempFilePath
$asset->setScenario(Asset::SCENARIO_CREATE);
$saved = $elementsService->saveElement($asset);

// In case of error, let user know about it.
Expand Down Expand Up @@ -330,7 +334,7 @@ public function replaceAssetFile(Asset $asset, string $filename, string $targetF
$asset->avoidFilenameConflicts = true;
$asset->setFilename($filename);
$asset->newFilename = $targetFilename;

$asset->setScenario(Asset::SCENARIO_REPLACE);
$saved = Craft::$app->getElements()->saveElement($asset);

if ($assets->hasEventHandlers($assets::EVENT_AFTER_REPLACE_ASSET)) {
Expand Down
13 changes: 8 additions & 5 deletions src/web/assets/uploader/src/Uploader.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Craft.CloudUploader = Craft.BaseUploader.extend(
const matches = file.name.match(/\.([a-z0-4_]+)$/i);
const fileExtension = matches[1];

if (this._extensionList.includes(fileExtension.toLowerCase())) {
if (!this._extensionList.includes(fileExtension.toLowerCase())) {
this._rejectedFiles.type.push('“' + file.name + '”');
valid = false;
}
Expand Down Expand Up @@ -99,13 +99,16 @@ Craft.CloudUploader = Craft.BaseUploader.extend(

this.processErrorMessages();

this.element.dispatchEvent(new Event('fileuploadstart'));
if (this._validFileCounter > 0) {
this.element.dispatchEvent(new Event('fileuploadstart'));

for (const file of validFiles) {
await this.uploadFile(file);
this._inProgressCounter--;
for (const file of validFiles) {
await this.uploadFile(file);
this._inProgressCounter--;
}
}

this._validFileCounter = 0;
this._totalBytes = 0;
this._uploadedBytes = 0;
this._lastUploadedBytes = 0;
Expand Down

0 comments on commit 3b4b2be

Please sign in to comment.