Skip to content

Commit 6c5a008

Browse files
v1r0xSeverino
andauthored
Release 0.11.1 (#578)
* fix patching entity type (#571) * [0.11.1] Prevent duplicate entity attributes (#570) * check if attribute is already added to entity type * Added missing error messages and error handling --------- Co-authored-by: Severino <severin.opel@hotmail.com> * [0.11.1] Several Fixes (#575) * fix csrf request * fix last editor not visible in entity detail tab * Removed 'base' default value * Fixed modal not closing on entity delete * Fixd absolute download paths * Fixed entity type color not showing * Excluded SQL attribute from export * Fixed color function returning black if value is falsy * fix migration for uploaded files * Moved move logic into store * load plugin pages directly * Fixed missing color update on entity type update * Updated composer to version 2 * added changelog * Plugin un-/publishing now on disk public * fix role update * fix i18n for plugins * fix geodata serialization * fix displaying deleted entity references in attributes * 0.11 fix pre loading time (#573) * Moved all pre functions to a single call * move functions from controller to helper class; fix redundant code * re-add locale init * fix pre-endpoint test * Fixed missing return on getGeometryTypes * Added transaction wrapper for command tests * fix missing cast after geo package update * Fixed wrong language in search (was a0f4dc4) * fix parsing of "malformed" input * fix label ref * Fixed undefined 'bootstrap' * Added 'Bootstrap not defined' on InteractiveMap to changelog * make plugin scripts downloadable * Adjusted changelog * plugin correct script src when plugin is un-/installed * make store method more flexible; only add '/' if needed * use src as param to match <script> attribute; fix adding/removing scripts from <head> * shorten function name; use existing add/delete logic from directory * Moved download routes to api.php * Fixed missing download link * Changed plugin endpoint to use path instead of query param * Directory changes, tests and plugin fix un-/install * use single method to handle file storage again * Fixed validation when non-top entity type is being imported as top-entity * Fixed add attribute validation * add vector tiles for maps * Added env variable VITE_REVERB_AUTH_ENDPOINT * fixed error when entity-type is not found * Fixed when entity_type is undefined * Added error message when entity-type does not exist * Fixed data not returned in patch * Fixed error when generating cite key where bibliography title contained a space separated part of non-alphanumerical characters * Add pinia to spps * Add subpath to session cookie * Removed file routes from api.php * use env(app_url) as cookie path * Updated hot to use config * small reverb improvements * fix reply to comment from notification * move reply to button to header * Fixed avatar being deleted even when file does not exist * Fixed avatar return type --------- Signed-off-by: Vinzenz Rosenkranz <vinzenz.rosenkranz@uni-tuebingen.de> Co-authored-by: Severino <severin.opel@hotmail.com> --------- Signed-off-by: Vinzenz Rosenkranz <vinzenz.rosenkranz@uni-tuebingen.de> Co-authored-by: Severino <severin.opel@hotmail.com>
1 parent b4b2493 commit 6c5a008

70 files changed

Lines changed: 1029 additions & 574 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎CHANGELOG.md‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,28 @@
11
# Changelog
22
All notable changes to this project will be documented in this file.
33

4+
## 0.11.1
5+
### Added
6+
- Unit Tests for Directory.php
7+
### Changed
8+
- Added path value to XSRF cookie to prevent overwriting by another instance at the same domain
9+
- _Show x replies_ button in comment list moved to header
10+
### Fixed
11+
- Login not possible on instances in subfolder
12+
- Last editor not visible in _Entity Detail_ tab
13+
- Modal not closing on deleting _Entity_
14+
- _Avatar_ image and literature download path were absolute
15+
- _Entity Type_ color not showing
16+
- Excluded _SQL_ attribute from export
17+
- Plugin script can now be loaded from private route
18+
- Attributes could be added multiple times to entity-type
19+
- Changing color of entity type
20+
- Changing _sub entity types_ only visible after page reload
21+
- 'Bootstrap not defined' on InteractiveMap
22+
- Fixed add/remove of plugin correctly setup in store and SpPS
23+
- Fixed error when generating cite key where bibliography title contained a space separated part of non-alphanumerical characters
24+
- Reply to comment from notification
25+
426
## 0.11 - Kilcrea
527
### Added
628
- Added websockets for various data synchronization

‎app/Attribute.php‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,30 @@ public function getSelection() {
8484
}
8585
}
8686

87+
public static function getSelectionsFor(&$attributes): array {
88+
$selections = [];
89+
foreach($attributes as $a) {
90+
$selection = $a->getSelection();
91+
if(isset($selection)) {
92+
// Workaround to check if it is a plain array or a assoc array (table columns)
93+
// if assoc array, add each entry to their corresponding id
94+
if(!isset($selection[0])) {
95+
foreach($selection as $id => $sel) {
96+
$selections[$id] = $sel;
97+
}
98+
} else {
99+
$selections[$a->id] = $selection;
100+
}
101+
}
102+
103+
if($a->datatype == 'table') {
104+
$a->columns = Attribute::where('parent_id', $a->id)->get()->keyBy('id');
105+
}
106+
}
107+
108+
return $selections;
109+
}
110+
87111
public function children() {
88112
return $this->hasMany('App\Attribute', 'parent_id');
89113
}

‎app/AttributeTypes/EntityAttribute.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public static function serializeFromEntity(int $id, ?Entity $entity) : array {
4848
return [
4949
"id" => $id,
5050
"name" => isset($entity) ? $entity->name : self::$deleted_string,
51+
"deleted" => !isset($entity),
5152
];
5253
}
5354
}

‎app/AttributeTypes/EntityMultipleAttribute.php‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public static function serialize(mixed $ids) : mixed {
5555
$decodedData = json_decode($ids);
5656
$entityList = Entity::without(['user'])->whereIn('id', $decodedData)->get()->keyBy('id');
5757
return array_map(function($id) use ($entityList) {
58-
return EntityAttribute::serializeFromEntity($id, $entityList[$id]);
58+
return EntityAttribute::serializeFromEntity($id, $entityList[$id] ?? null);
5959
}, $decodedData);
6060
}
6161
}

‎app/AttributeTypes/GeographyAttribute.php‎

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use App\Exceptions\InvalidDataException;
66
use App\Geodata;
77
use App\Utils\StringUtils;
8-
use Exception;
8+
use Clickbar\Magellan\Data\Geometries\Geometry;
99

1010
class GeographyAttribute extends AttributeBase
1111
{
@@ -33,10 +33,18 @@ public static function parseImport(int|float|bool|string $data): mixed {
3333
}
3434

3535
public static function unserialize(mixed $data): mixed {
36-
return Geodata::fromWKT($data);
36+
if($data instanceof Geometry) {
37+
return $data;
38+
} else {
39+
return Geodata::fromWKT($data);
40+
}
3741
}
3842

3943
public static function serialize(mixed $data): mixed {
40-
return Geodata::toWKT($data);
44+
if($data instanceof Geometry) {
45+
return $data;
46+
} else {
47+
return Geodata::wkb2wkt($data);
48+
}
4149
}
4250
}

‎app/AttributeValue.php‎

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@
44

55
use App\Geodata;
66
use App\AttributeTypes\AttributeBase;
7-
use Illuminate\Database\Eloquent\Model;
8-
use Clickbar\Magellan\Database\Eloquent\HasPostgisColumns;
97
use App\Traits\CommentTrait;
108
use App\Traits\ModerationTrait;
9+
use Clickbar\Magellan\Data\Geometries\Geometry;
10+
use Illuminate\Database\Eloquent\Model;
1111
use Spatie\Activitylog\Traits\LogsActivity;
1212
use Spatie\Activitylog\LogOptions;
1313
use Spatie\Searchable\Searchable;
@@ -16,7 +16,6 @@
1616

1717
class AttributeValue extends Model implements Searchable
1818
{
19-
use HasPostgisColumns;
2019
use CommentTrait;
2120
use ModerationTrait;
2221
use LogsActivity;
@@ -55,8 +54,8 @@ class AttributeValue extends Model implements Searchable
5554
'thesaurus_val'
5655
];
5756

58-
protected $postgisColumns = [
59-
'geography_val',
57+
protected $casts = [
58+
'geography_val' => Geometry::class,
6059
];
6160

6261
protected $copyOn = [
@@ -166,27 +165,10 @@ public function setValueFromRaw($strValue, $type = null, $save = false) {
166165
public static function getValueColumn($type) {
167166
return AttributeBase::getFieldFromType($type);
168167
}
169-
168+
170169
public static function generateObject($attributeValues) {
171170
$data = [];
172171
foreach($attributeValues as $attributeValue) {
173-
switch($attributeValue->attribute->datatype) {
174-
case 'entity':
175-
$attributeValue->name = Entity::find($attributeValue->entity_val)->name;
176-
break;
177-
case 'entity-mc':
178-
$names = [];
179-
foreach(json_decode($attributeValue->json_val) as $dec) {
180-
$names[] = Entity::find($dec)->name;
181-
}
182-
$attributeValue->name = $names;
183-
break;
184-
case 'sql':
185-
// SQL will not have any entries in the attribute_values table
186-
break;
187-
default:
188-
break;
189-
}
190172
$value = $attributeValue->getValue();
191173
if($attributeValue->moderation_state == 'pending-delete') {
192174
$attributeValue->value = [];

‎app/Bibliography.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,7 @@ public static function computeCitationKey($fields) {
635635
foreach($words as $word) {
636636
// only keep (ascii) letters and numbers
637637
$word = preg_replace('/[^A-Za-z0-9]/', '', Str::ascii(trim($word)));
638+
if(strlen($word) == 0) continue;
638639
if(strlen($firstWord) == 0 && strlen($word) > 3) {
639640
$firstWord = $word;
640641
}

‎app/Entity.php‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ public function getAllMetadata() {
9090
'creator' => $this->creator,
9191
'editors' => $this->editors,
9292
'metadata' => $this->metadata,
93+
'user' => $this->user,
9394
];
9495
}
9596

@@ -268,6 +269,17 @@ private function moveOrFail(int | null $parentId) {
268269
}
269270
return $query;
270271
}
272+
273+
public function move($parentId, $rank, $user) {
274+
if($rank == null){
275+
if(isset($parentId)) {
276+
$rank = Entity::where('root_entity_id', $parentId)->max('rank') + 1;
277+
}else{
278+
$rank = Entity::whereNull('root_entity_id')->max('rank') + 1;
279+
}
280+
}
281+
Entity::patchRanks($rank, $this->id, $parentId, $user);
282+
}
271283

272284
public static function patchRanks($rank, $id, $parent, $user) {
273285
$entity = Entity::find($id);

‎app/File/Directory.php‎

Lines changed: 59 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
namespace App\File;
44

5-
use Illuminate\Http\Response;
5+
use Illuminate\Http\JsonResponse;
6+
use Illuminate\Http\UploadedFile;
67
use Illuminate\Support\Facades\Storage;
78
use Illuminate\Support\Str;
89
use Symfony\Component\HttpFoundation\BinaryFileResponse;
@@ -21,6 +22,22 @@ public function __construct(string $directory, string $disk = 'local') {
2122
$this->directory = $directory;
2223
}
2324

25+
/**
26+
* Returns the disk name.
27+
* @return string The disk name, e.g. 'local', 'public', etc.
28+
*/
29+
public function getDisk(): string {
30+
return $this->disk;
31+
}
32+
33+
/**
34+
* Returns the directory path.
35+
* @return string The directory path, e.g. 'avatars'
36+
*/
37+
public function getDirectory(): string {
38+
return $this->directory;
39+
}
40+
2441
/**
2542
* Validates if a file is inside the directory.
2643
*
@@ -52,27 +69,60 @@ public function delete(?string $filepath): bool {
5269
return false;
5370
}
5471

72+
// TODO: resource is not (php 8.3) allowed as type, thus $file only typehinted in docblock
5573
/**
5674
* Stores a file inside the directory.
5775
*
5876
* @param string $filename The filename
59-
* @param $file The file
77+
* @param UploadedFile|string|resource $file The file
6078
* @return string The path to the file
6179
*/
62-
public function store(string $filename, $file): string {
63-
return $file->storeAs($this->directory, $filename, $this->disk);
80+
public function store(string $filename, $file): string|false {
81+
if($file instanceof UploadedFile) {
82+
return $file->storeAs($this->directory, $filename, $this->disk);
83+
} else {
84+
$filepath = Str::finish($this->directory, DIRECTORY_SEPARATOR) . $filename;
85+
Storage::disk($this->disk)->put($filepath, $file);
86+
return $filepath;
87+
}
6488
}
6589

6690
/**
6791
* Downloads a file inside the directory.
6892
*
6993
* @param string $filepath The path to the file
70-
* @return Response|BinaryFileResponse The file as BinaryFileResponse or Response if the file is not inside the directory.
94+
* @return JsonResponse|BinaryFileResponse The file as BinaryFileResponse or Response if the file is not inside the directory.
7195
*/
72-
function download(string $filepath): Response | BinaryFileResponse {
73-
if($this->contains($filepath)){
74-
return DownloadHandler::makeFileResponse($filepath);
96+
function download(string $filepath): JsonResponse | BinaryFileResponse {
97+
if($this->contains($filepath)) {
98+
return $this->createFileResponse($filepath);
7599
}
76-
return response()->noContent();
100+
return self::notFound();
101+
}
102+
103+
/**
104+
* Downloads a file relative to the directory.
105+
*
106+
* @param string $filepath The path to the file without the directory prefix.
107+
* @return JsonResponse|BinaryFileResponse The file as BinaryFileResponse or Response if the file is not inside the directory.
108+
*/
109+
function downloadRelative(string $filepath): JsonResponse | BinaryFileResponse {
110+
$storagePath = Str::finish($this->directory, DIRECTORY_SEPARATOR) . $filepath;
111+
return $this->download($storagePath);
112+
}
113+
114+
function createFileResponse(string $filepath): JsonResponse | BinaryFileResponse {
115+
$mime = Storage::disk($this->disk)->mimeType($filepath);
116+
$path = Storage::disk($this->disk)->path($filepath);
117+
return response()->file($path, [
118+
'Content-Type' => $mime,
119+
'Content-Disposition' => 'inline; filename="'. $filepath . '"'
120+
]);
121+
}
122+
123+
private static function notFound(): JsonResponse {
124+
return response()->json([
125+
'error' => __('File not found.')
126+
], 404);
77127
}
78128
}

‎app/File/DownloadHandler.php‎

Lines changed: 0 additions & 22 deletions
This file was deleted.

0 commit comments

Comments
 (0)