Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
93 commits
Select commit Hold shift + click to select a range
475c9a2
add method to get ajax uploaders
pxpm Feb 6, 2024
02114ab
Apply fixes from StyleCI
StyleCIBot Feb 6, 2024
bbc9f72
use an abstract class
pxpm Feb 7, 2024
7fabff2
wip
pxpm Feb 8, 2024
a39688e
Apply fixes from StyleCI
StyleCIBot Feb 8, 2024
722e1e4
refactor uploaders
pxpm Feb 9, 2024
b0da85b
Apply fixes from StyleCI
StyleCIBot Feb 9, 2024
793d722
refactor rules
pxpm Feb 11, 2024
16f95cf
Apply fixes from StyleCI
StyleCIBot Feb 11, 2024
d61b63f
move ajax to PRO, cleanup
pxpm Feb 11, 2024
98e9ab2
Apply fixes from StyleCI
StyleCIBot Feb 11, 2024
8613050
make attributes available for all subfields
pxpm Feb 20, 2024
f56105b
fix tests
pxpm Mar 21, 2024
91d8d67
wip
pxpm Mar 21, 2024
debf60e
Apply fixes from StyleCI
StyleCIBot Mar 21, 2024
cd9a0ed
upload multiple and upload properly working :pray:
pxpm Mar 22, 2024
edc8052
fixes
pxpm Mar 22, 2024
7a61789
Apply fixes from StyleCI
StyleCIBot Mar 22, 2024
40e5daf
allow the configuration of valueWithoutPath call.
pxpm Apr 10, 2024
d97e51b
fix valid upload inside repeatables
pxpm Apr 17, 2024
be2e3ec
Apply fixes from StyleCI
StyleCIBot Apr 17, 2024
ed68ba8
fix condition
pxpm Apr 18, 2024
25026b3
cleanup
pxpm Apr 18, 2024
ecdd81e
fix
pxpm Apr 18, 2024
478bc96
Apply fixes from StyleCI
StyleCIBot Apr 18, 2024
1347306
fix use case for enabling validation after entry is created
pxpm Apr 19, 2024
988d2b1
Apply fixes from StyleCI
StyleCIBot Apr 19, 2024
83fd68c
dont save array keys
pxpm Apr 22, 2024
fd7803d
fix ajax validation
pxpm Apr 22, 2024
7c24742
fix validation messages
pxpm Apr 23, 2024
d1fa05f
Apply fixes from StyleCI
StyleCIBot Apr 23, 2024
559279d
fixes ValidUpload
pxpm Apr 26, 2024
7f44e5f
Apply fixes from StyleCI
StyleCIBot Apr 26, 2024
1a03b10
dont json encode if casted in the model
pxpm Apr 26, 2024
65366a6
Apply fixes from StyleCI
StyleCIBot Apr 26, 2024
fc181ea
fix previous file identification in repeatable
pxpm Apr 27, 2024
0c917a2
Apply fixes from StyleCI
StyleCIBot Apr 27, 2024
df9513f
fix getting values
pxpm Apr 30, 2024
0ee9c6c
Apply fixes from StyleCI
StyleCIBot Apr 30, 2024
5c35e56
add fake fields support
pxpm Apr 30, 2024
2391cd2
Apply fixes from StyleCI
StyleCIBot Apr 30, 2024
ca80235
wip add uploaders tests
pxpm May 9, 2024
91c61d7
Apply fixes from StyleCI
StyleCIBot May 9, 2024
6d082a9
wip
pxpm May 10, 2024
a3d36d5
Apply fixes from StyleCI
StyleCIBot May 10, 2024
29575fe
add pro columns
pxpm May 10, 2024
0ebd324
fix test suite
pxpm May 10, 2024
78568f0
fix tests
pxpm May 10, 2024
84db01a
ffix tests
pxpm May 10, 2024
7f1a9a0
remove unused test views
pxpm May 13, 2024
2b1dab1
add uploaders to test coverage
pxpm May 13, 2024
9de030b
Apply fixes from StyleCI
StyleCIBot May 13, 2024
24e81dc
add coverage folder to gitignore
pxpm May 13, 2024
d9f70d0
make tests run faster by not reloading db when not necessary
pxpm May 14, 2024
1fba34e
add coverage to validation tests
pxpm May 14, 2024
1585474
add fake tests to uploaders
pxpm May 14, 2024
2463dde
Apply fixes from StyleCI
StyleCIBot May 14, 2024
d214c87
add more tests
pxpm May 14, 2024
f20be91
Apply fixes from StyleCI
StyleCIBot May 14, 2024
7eea011
wip
pxpm May 15, 2024
ead2407
Apply fixes from StyleCI
StyleCIBot May 15, 2024
a677ecf
wip
pxpm May 16, 2024
8aa2df6
wip
pxpm May 16, 2024
f8ceffe
Apply fixes from StyleCI
StyleCIBot May 16, 2024
960c74b
wip
pxpm May 17, 2024
c1f896d
Apply fixes from StyleCI
StyleCIBot May 17, 2024
9f4b7b9
add more upload assets
pxpm May 17, 2024
7dcf5d5
fixes
pxpm May 17, 2024
1cfc6c6
Apply fixes from StyleCI
StyleCIBot May 17, 2024
2418a82
fix single file
pxpm May 17, 2024
3328605
Apply fixes from StyleCI
StyleCIBot May 17, 2024
1a2cf2f
add image column
pxpm May 21, 2024
f1c7a91
fix tests
pxpm May 22, 2024
c3bd9aa
Apply fixes from StyleCI
StyleCIBot May 22, 2024
882702a
remove hardcoded macro names
pxpm May 22, 2024
8d4ef96
Apply fixes from StyleCI
StyleCIBot May 22, 2024
2a5efea
remove double loop, fix single file uploader
pxpm May 26, 2024
c60cf44
Apply fixes from StyleCI
StyleCIBot May 26, 2024
7256029
use a big increments and unsigned for primary key
pxpm Jun 27, 2024
619a070
handle pivot file deletion
pxpm Jun 27, 2024
4b28ebf
Apply fixes from StyleCI
StyleCIBot Jun 27, 2024
1c443d7
register events for relation models
pxpm Jun 27, 2024
8eec75a
Apply fixes from StyleCI
StyleCIBot Jun 27, 2024
e8f1494
fix typo
pxpm Jun 28, 2024
24746c4
Apply fixes from StyleCI
StyleCIBot Jun 28, 2024
17580ef
fix relationship uploaders
pxpm Jun 28, 2024
ca149be
Apply fixes from StyleCI
StyleCIBot Jun 28, 2024
57caad7
wip
pxpm Jul 4, 2024
f15888c
Apply fixes from StyleCI
StyleCIBot Jul 4, 2024
8215e8d
wip
pxpm Aug 6, 2024
25c1c5e
Apply fixes from StyleCI
StyleCIBot Aug 6, 2024
a99cd51
update temporary time key
pxpm Oct 9, 2024
17f353b
save objects in the macro
pxpm Nov 7, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ composer.lock
.phpunit.result.cache
src/public/packages/
/.phpunit.cache
coverage/

7 changes: 5 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,12 @@
]
},
"scripts": {
"test": "vendor/bin/phpunit --testdox",
"test": [
"@putenv XDEBUG_MODE=off",
"vendor/bin/phpunit"
],
"test-failing": "vendor/bin/phpunit --order-by=defects --stop-on-failure",
"test-coverage": "XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-text"
"test-coverage": "XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-html=coverage"
},
"extra": {
"branch-alias": {
Expand Down
3 changes: 3 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<include>
<directory suffix=".php">./src/app/Library/CrudPanel/Traits/</directory>
<directory>./src/app/Library/Validation/</directory>
<directory>./src/app/Library/Uploaders/</directory>
<directory suffix=".php">./src/app/Library/CrudPanel/</directory>
<directory suffix=".php">./src/app/Models/Traits/</directory>
<file>./src/app/Library/Widget.php</file>
Expand All @@ -35,9 +36,11 @@
</source>
<php>
<env name="APP_ENV" value="testing"/>
<env name="APP_KEY" value="AckfSECXIvnK5r28GVIWUAxmbBSjTsmF"/>
<env name="BCRYPT_ROUNDS" value="12"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_FOREIGN_KEYS" value="true"/>
<env name="DB_DATABASE" value=":memory:"/>
<env name="MAIL_MAILER" value="array"/>
<env name="QUEUE_CONNECTION" value="sync"/>
Expand Down
4 changes: 2 additions & 2 deletions src/app/Library/CrudPanel/Traits/FieldsProtectedMethods.php
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,8 @@ protected function makeSureSubfieldsHaveNecessaryAttributes($field)
$subfield['name'] = Str::replace(' ', '', $subfield['name']);

$subfield['parentFieldName'] = $field['name'];
$subfield['baseFieldName'] = is_array($subfield['name']) ? implode(',', $subfield['name']) : $subfield['name'];
$subfield['baseFieldName'] = Str::afterLast($subfield['baseFieldName'], '.');

if (! isset($field['model'])) {
// we're inside a simple 'repeatable' with no model/relationship, so
Expand All @@ -294,8 +296,6 @@ protected function makeSureSubfieldsHaveNecessaryAttributes($field)
$currentEntity = $subfield['baseEntity'] ?? $field['entity'];
$subfield['baseModel'] = $subfield['baseModel'] ?? $field['model'];
$subfield['baseEntity'] = isset($field['baseEntity']) ? $field['baseEntity'].'.'.$currentEntity : $currentEntity;
$subfield['baseFieldName'] = is_array($subfield['name']) ? implode(',', $subfield['name']) : $subfield['name'];
$subfield['baseFieldName'] = Str::afterLast($subfield['baseFieldName'], '.');
}

$field['subfields'][$key] = $this->makeSureFieldHasNecessaryAttributes($subfield);
Expand Down
28 changes: 25 additions & 3 deletions src/app/Library/Uploaders/MultipleFiles.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,16 @@ public function uploadFiles(Model $entry, $value = null)
}
}

return isset($entry->getCasts()[$this->getName()]) ? $previousFiles : json_encode($previousFiles);
$previousFiles = array_values($previousFiles);

if (empty($previousFiles)) {
return null;
}

return isset($entry->getCasts()[$this->getName()]) || $this->isFake() ? $previousFiles : json_encode($previousFiles);
}

/** @codeCoverageIgnore */
public function uploadRepeatableFiles($files, $previousRepeatableValues, $entry = null)
{
$fileOrder = $this->getFileOrderFromRequest();
Expand All @@ -73,11 +80,26 @@ public function uploadRepeatableFiles($files, $previousRepeatableValues, $entry
}
}
}
// create a temporary variable that we can unset keys
// everytime one is found. That way we avoid iterating
// already handled keys (notice we do a deep array copy)
$tempFileOrder = array_map(function ($item) {
return $item;
}, $fileOrder);

foreach ($previousRepeatableValues as $previousRow => $previousFiles) {
foreach ($previousFiles ?? [] as $key => $file) {
$key = array_search($file, $fileOrder, true);
if ($key === false) {
$previousFileInArray = array_filter($tempFileOrder, function ($items, $key) use ($file, $tempFileOrder) {
$found = array_search($file, $items ?? [], true);
if ($found !== false) {
Arr::forget($tempFileOrder, $key.'.'.$found);

return true;
}

return false;
}, ARRAY_FILTER_USE_BOTH);
if ($file && ! $previousFileInArray) {
Storage::disk($this->getDisk())->delete($file);
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/app/Library/Uploaders/SingleBase64Image.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

/** @codeCoverageIgnore */
class SingleBase64Image extends Uploader
{
public function uploadFiles(Model $entry, $value = null)
Expand Down Expand Up @@ -51,7 +52,7 @@ public function uploadRepeatableFiles($values, $previousRepeatableValues, $entry
}
}

$imagesToDelete = array_diff($previousRepeatableValues, $values);
$imagesToDelete = array_diff(array_filter($previousRepeatableValues), $values);

foreach ($imagesToDelete as $image) {
Storage::disk($this->getDisk())->delete($image);
Expand All @@ -65,7 +66,7 @@ protected function shouldUploadFiles($value): bool
return $value && is_string($value) && Str::startsWith($value, 'data:image');
}

protected function shouldKeepPreviousValueUnchanged(Model $entry, $entryValue): bool
public function shouldKeepPreviousValueUnchanged(Model $entry, $entryValue): bool
{
return $entry->exists && is_string($entryValue) && ! Str::startsWith($entryValue, 'data:image');
}
Expand Down
13 changes: 9 additions & 4 deletions src/app/Library/Uploaders/SingleFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public function uploadFiles(Model $entry, $value = null)
return $previousFile;
}

/** @codeCoverageIgnore */
public function uploadRepeatableFiles($values, $previousRepeatableValues, $entry = null)
{
$orderedFiles = $this->getFileOrderFromRequest();
Expand All @@ -53,9 +54,13 @@ public function uploadRepeatableFiles($values, $previousRepeatableValues, $entry
}

foreach ($previousRepeatableValues as $row => $file) {
if ($file && ! isset($orderedFiles[$row])) {
$orderedFiles[$row] = null;
Storage::disk($this->getDisk())->delete($file);
if ($file) {
if (! isset($orderedFiles[$row])) {
$orderedFiles[$row] = null;
}
if (! in_array($file, $orderedFiles)) {
Storage::disk($this->getDisk())->delete($file);
}
}
}

Expand All @@ -65,7 +70,7 @@ public function uploadRepeatableFiles($values, $previousRepeatableValues, $entry
/**
* Single file uploaders send no value when they are not dirty.
*/
protected function shouldKeepPreviousValueUnchanged(Model $entry, $entryValue): bool
public function shouldKeepPreviousValueUnchanged(Model $entry, $entryValue): bool
{
return is_string($entryValue);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ public function repeats(string $repeatableContainerName): self;

public function relationship(bool $isRelation): self;

public function fake(bool|string $isFake): self;

/**
* Getters.
*/
Expand Down Expand Up @@ -60,4 +62,10 @@ public function canHandleMultipleFiles(): bool;
public function isRelationship(): bool;

public function getPreviousFiles(Model $entry): mixed;

public function getValueWithoutPath(?string $value = null): ?string;

public function isFake(): bool;

public function getFakeAttribute(): bool|string;
}
17 changes: 15 additions & 2 deletions src/app/Library/Uploaders/Support/RegisterUploadEvents.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ private function registerSubfieldEvent(array $subfield, bool $registerModelEvent
$uploader = $this->getUploader($subfield, $this->uploaderConfiguration);
$crudObject = $this->crudObject->getAttributes();
$uploader = $uploader->repeats($crudObject['name']);
$uploader = $uploader->fake((isset($crudObject['fake']) && $crudObject['fake']) ? ($crudObject['store_in'] ?? 'extras') : false);

// If this uploader is already registered bail out. We may endup here multiple times when doing modifications to the crud object.
// Changing `subfields` properties will call the macros again. We prevent duplicate entries by checking
Expand Down Expand Up @@ -139,6 +140,14 @@ private function setupModelEvents(string $model, UploaderInterface $uploader): v
$uploader->deleteUploadedFiles($entry);
});

// if the uploader is a relationship and handles repeatable files, we will also register the deleting event on the
// parent model. that way we can control the deletion of the files when the parent model is deleted.
if ($uploader->isRelationship() && $uploader->handleRepeatableFiles) {
app('crud')->model::deleting(function ($entry) use ($uploader) {
$uploader->deleteUploadedFiles($entry);
});
}

app('UploadersRepository')->markAsHandled($uploader->getIdentifier());
}

Expand All @@ -154,9 +163,13 @@ private function setupModelEvents(string $model, UploaderInterface $uploader): v
*/
private function getUploader(array $crudObject, array $uploaderConfiguration): UploaderInterface
{
$customUploader = isset($uploaderConfiguration['uploader']) && class_exists($uploaderConfiguration['uploader']);
$hasCustomUploader = isset($uploaderConfiguration['uploader']);

if ($hasCustomUploader && ! is_a($uploaderConfiguration['uploader'], UploaderInterface::class, true)) {
throw new Exception('Invalid uploader class provided for '.$this->crudObjectType.' type: '.$crudObject['type']);
}

if ($customUploader) {
if ($hasCustomUploader) {
return $uploaderConfiguration['uploader']::for($crudObject, $uploaderConfiguration);
}

Expand Down
Loading