Skip to content

Commit f6fa76d

Browse files
author
David Nahodyl
committed
Added support for setting filename when inserting files into a container
1 parent e00533c commit f6fa76d

File tree

4 files changed

+69
-25
lines changed

4 files changed

+69
-25
lines changed

README.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,21 @@ Many fields in your FileMaker database will be read-only, such as summaries and
8989
### Container Fields
9090
This package supports both reading and writing container field data. Container fields are retrieved from FileMaker as attributes on your model which will contain a URL which can be used to retrieve the file from the container.
9191

92-
When setting a container field you should set it as an `Illuminate/HTTP/File` object. These attributes will be written back to your container fields along with any other model updates when the `save()` method is called on your model object.
92+
#### Writing to container fields
93+
When setting a container field you should set the value to be an `Illuminate/HTTP/File` or `Illuminate/HTTP/UploadedFile` object. These attributes will be written back to your container fields along with any other model updates when the `save()` method is called on your model object.
94+
```
95+
$file = new File(storage_path('app/public/gator.jpg'));
96+
$newPet->photo = $file;
97+
$newPet->save();
98+
```
99+
100+
#### Custom filenames when inserting files into containers
101+
By default, files are inserted into containers using the filename of the file you are inserting. If you wish to set a new filename when the file is inserted into the container you can do so by passing the file and filename together in an array when setting your container.
102+
```
103+
$file = new File(storage_path('app/public/gator.jpg'));
104+
$newPet->photo = [$file, 'fluffy.jpg'];
105+
$newPet->save();
106+
```
93107

94108
### Renaming and Mapping FileMaker Fields
95109
Sometimes you might be working with a FileMaker database with inconvenient field names. These fields can be remapped to model attributes by setting the `$fieldMapping` attribute. This should be an array of strings, mapping FileMaker Field Name => New Attribute Name. You can then use these names as regular Eloquent attributes and they will work with the correct fields in FileMaker

src/Database/Eloquent/FMModel.php

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Illuminate\Database\Eloquent\Relations\Concerns\AsPivot;
1111
use Illuminate\Database\Eloquent\Relations\Pivot;
1212
use Illuminate\Http\File;
13+
use Illuminate\Http\UploadedFile;
1314
use Illuminate\Support\Collection;
1415
use Illuminate\Support\Str;
1516

@@ -401,11 +402,11 @@ public function getAttributesForFileMakerWrite()
401402
// Remove any fields which have been set to write a file, as they should be handled as containers
402403
foreach ($fieldData as $key => $field){
403404
// remove any containers to be written.
404-
if (is_a($field, File::class)){
405+
// users can set the field to be a File, UploadFile, or array [$file, 'MyFile.pdf']
406+
if ($this->isContainer($field)){
405407
$fieldData->forget($key);
406408
}
407409
}
408-
//$fieldData->forget($this->getContainerFields());
409410
return $fieldData;
410411
}
411412

@@ -419,14 +420,24 @@ public function getContainersToWrite(){
419420
// Track any fields which have been set to write a file, as they should be handled as containers
420421
foreach ($fieldData as $key => $field){
421422
// remove any containers to be written.
422-
if (is_a($field, File::class)){
423+
if ($this->isContainer($field)){
423424
$containers->push($key);
424425
}
425426
}
426427

427428
return $containers;
428429
}
429430

431+
protected function isContainer($field){
432+
return
433+
is_a($field, File::class) ||
434+
is_a($field, UploadedFile::class) ||
435+
(
436+
is_array($field) &&
437+
sizeof($field) === 2
438+
);
439+
}
440+
430441
/**
431442
* Get the table associated with the model.
432443
*

src/Database/Query/FMBaseBuilder.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use BlueFeather\EloquentFileMaker\Services\FileMakerConnection;
99
use Illuminate\Database\Query\Builder;
1010
use Illuminate\Http\File;
11+
use Illuminate\Http\UploadedFile;
1112
use Illuminate\Support\Collection;
1213
use InvalidArgumentException;
1314

@@ -528,7 +529,12 @@ public function portalData($array)
528529
}
529530

530531

531-
public function setContainer($column, File $file)
532+
/**
533+
* @param String $column The name of the container field
534+
* @param File | UploadedFile | array $file The file to be uploaded to the container or a file and filename array ex: [$file, 'MyFile.pdf']
535+
* @return mixed
536+
*/
537+
public function setContainer($column, $file)
532538
{
533539
$this->containerFieldName = $this->getMappedFieldName($column);
534540
$this->containerFile = $file;

src/Services/FileMakerConnection.php

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ class FileMakerConnection extends Connection
3030
protected $retries = 1;
3131

3232

33-
3433
/**
3534
* Set the name of the connected database.
3635
*
@@ -137,7 +136,7 @@ protected function checkResponseForErrors($response)
137136
{
138137
$messages = Arr::get($response, 'messages', []);
139138

140-
if ($messages){
139+
if ($messages) {
141140
foreach ($messages as $message) {
142141
$code = (int)$message['code'];
143142

@@ -157,7 +156,7 @@ protected function checkResponseForErrors($response)
157156
}
158157
}
159158
}
160-
} else{
159+
} else {
161160
$response->throw();
162161
}
163162

@@ -169,12 +168,24 @@ public function uploadToContainerField(FMBaseBuilder $query)
169168
$this->setLayout($query->from);
170169
$url = $this->getRecordUrl() . $query->getRecordId() . '/containers/' . $query->containerFieldName;
171170

172-
$file = $query->containerFile;
171+
/*
172+
* The user can insert an array for the file to specify the file name, so we can check for that here
173+
* The array should be in the format:
174+
* [ $file, 'myFile.pdf' ]
175+
*/
176+
if (is_array($query->containerFile)){
177+
// we have a file and file name
178+
$file = $query->containerFile[0];
179+
$filename = $query->containerFile[1];
180+
} else{
181+
$file = $query->containerFile;
182+
$filename = $file->getFilename();
183+
}
173184

174185
// create a stream resource
175186
$stream = fopen($file->getPathname(), 'r');
176187

177-
$request = Http::attach('upload', $stream, $file->getFilename());
188+
$request = Http::attach('upload', $stream, $filename);
178189
$response = $this->makeRequest('post', $url, [], $request);
179190

180191
return $response;
@@ -323,26 +334,26 @@ public function editRecord(FMBaseBuilder $query)
323334
/**
324335
* Attempt to emulate a sql update in FileMaker
325336
*
326-
* @param FMBaseBuilder $query
327-
* @param array $bindings
337+
* @param FMBaseBuilder $query
338+
* @param array $bindings
328339
* @return int
329340
*/
330341
public function update($query, $bindings = [])
331342
{
332343
// If there's no FM Record ID it means we need to find a set of records and then update the results
333-
if (!$query->getRecordId()){
344+
if (!$query->getRecordId()) {
334345
// There's no FileMaker Record ID
335346
return $this->performFindAndUpdateResults($query);
336347
}
337348

338349
// This is just a single record to edit
339-
try{
350+
try {
340351
// Do the update
341352
$this->editRecord($query);
342-
} catch (FileMakerDataApiException $e){
353+
} catch (FileMakerDataApiException $e) {
343354
// Record is missing is ok for laravel functions
344355
// Throw if it isn't error code 101, which is missing record
345-
if ($e->getCode() !== 101){
356+
if ($e->getCode() !== 101) {
346357
throw $e;
347358
}
348359
// Error 101 - Record Not Found
@@ -358,14 +369,15 @@ public function update($query, $bindings = [])
358369
* @return int
359370
* @throws FileMakerDataApiException
360371
*/
361-
protected function performFindAndUpdateResults(FMBaseBuilder $query){
372+
protected function performFindAndUpdateResults(FMBaseBuilder $query)
373+
{
362374
// find the records in the find request query
363375
$findQuery = clone $query;
364376
$findQuery->fieldData = null;
365377
try {
366378
$results = $this->performFind($findQuery);
367-
} catch (FileMakerDataApiException $e){
368-
if ($e->getCode() === 401){
379+
} catch (FileMakerDataApiException $e) {
380+
if ($e->getCode() === 401) {
369381
// no records match request
370382
// we should exit here
371383
// return 0 to show that no records were updated;
@@ -375,27 +387,28 @@ protected function performFindAndUpdateResults(FMBaseBuilder $query){
375387

376388
$records = $results['response']['data'];
377389
$updatedCount = 0;
378-
foreach ($records as $record){
390+
foreach ($records as $record) {
379391
// update each record
380392
$builder = new FMBaseBuilder($this);
381393
$builder->recordId($record['recordId']);
382394
$builder->fieldData = $query->fieldData;
383395
$builder->layout($query->from);
384-
try{
396+
try {
385397
// Do the update
386398
$this->editRecord($builder);
387399
// Update if we don't get a record missing exception
388400
$updatedCount++;
389-
} catch (FileMakerDataApiException $e){
401+
} catch (FileMakerDataApiException $e) {
390402
// Record is missing is ok for laravel functions
391403
// Throw if it isn't error code 101, which is missing record
392-
if ($e->getCode() !== 101){
404+
if ($e->getCode() !== 101) {
393405
throw $e;
394406
}
395407
}
396408
}
397409

398-
return count($records); }
410+
return count($records);
411+
}
399412

400413
/**
401414
* @param FMBaseBuilder $query
@@ -411,7 +424,7 @@ public function createRecord(FMBaseBuilder $query)
411424
$postData = $this->buildPostDataFromQuery($query);
412425

413426
// fieldData is required for create, so fill a blank value if none exists
414-
if (!isset($postData['fieldData'])){
427+
if (!isset($postData['fieldData'])) {
415428
$postData['fieldData'] = json_decode("{}");
416429
}
417430

0 commit comments

Comments
 (0)