관리-도구
편집 파일: MakesCallsToComponent.php
<?php namespace Livewire\Testing\Concerns; use function Livewire\str; use Illuminate\Http\UploadedFile; use Illuminate\Support\Str; use Illuminate\Validation\ValidationException; use Livewire\Controllers\FileUploadHandler; use Livewire\FileUploadConfiguration; use Livewire\Livewire; trait MakesCallsToComponent { public function emit($event, ...$parameters) { return $this->fireEvent($event, ...$parameters); } public function fireEvent($event, ...$parameters) { $this->sendMessage('fireEvent', [ 'event' => $event, 'params' => $parameters, ]); return $this; } public function call($method, ...$parameters) { return $this->runAction($method, ...$parameters); } public function runAction($method, ...$parameters) { $this->sendMessage('callMethod', [ 'method' => $method, 'params' => $parameters, 'ref' => null, ]); return $this; } public function fill($values) { foreach ($values as $name => $value) { $this->set($name, $value); } return $this; } public function set($name, $value = null) { return $this->updateProperty($name, $value); } public function toggle($name) { return $this->set($name, ! $this->get($name)); } public function updateProperty($name, $value = null) { if (is_array($name)) { foreach ($name as $key => $value) { $this->syncInput($key, $value); } return $this; } return $this->syncInput($name, $value); } public function syncInput($name, $value) { if ($value instanceof UploadedFile) { return $this->syncUploadedFiles($name, [$value]); } elseif (is_array($value) && isset($value[0]) && $value[0] instanceof UploadedFile) { return $this->syncUploadedFiles($name, $value, $isMultiple = true); } return $this->sendMessage('syncInput', [ 'name' => $name, 'value' => $value, ]); } public function syncUploadedFiles($name, $files, $isMultiple = false) { // This methhod simulates the calls Livewire's JavaScript // normally makes for file uploads. $this->sendMessage('callMethod', [ 'method' => 'startUpload', 'params' => [$name, collect($files)->map(function ($file) { return [ 'name' => $file->name, 'size' => $file->getSize(), 'type' => $file->getMimeType(), ]; })->toArray(), $isMultiple], ]); // This is where either the pre-signed S3 url or the regular Livewire signed // upload url would do its thing and return a hashed version of the uploaded // file in a tmp directory. $storage = FileUploadConfiguration::storage(); try { $fileHashes = (new FileUploadHandler)->validateAndStore($files, FileUploadConfiguration::disk()); } catch (ValidationException $e) { $this->runAction('uploadErrored', $name, json_encode(['errors' => $e->errors()]), $isMultiple); return $this; } // We are going to encode the file size in the filename so that when we create // a new TemporaryUploadedFile instance we can fake a specific file size. $newFileHashes = collect($files)->zip($fileHashes)->mapSpread(function ($file, $fileHash) { return (string) str($fileHash)->replaceFirst('.', "-size={$file->getSize()}."); })->toArray(); collect($fileHashes)->zip($newFileHashes)->mapSpread(function ($fileHash, $newFileHash) use ($storage) { $storage->move('/'.FileUploadConfiguration::path($fileHash), '/'.FileUploadConfiguration::path($newFileHash)); }); // Now we finish the upload with a final call to the Livewire component // with the temporarily uploaded file path. $this->sendMessage('callMethod', [ 'method' => 'finishUpload', 'params' => [$name, $newFileHashes, $isMultiple], ]); return $this; } public function sendMessage($message, $payload) { $payload['id'] = Str::random(4); $this->lastResponse = $this->pretendWereSendingAComponentUpdateRequest($message, $payload); if (! $this->lastResponse->exception) { $this->updateComponent($this->lastResponse->original); } Livewire::flushState(); return $this; } }