Skip to content

Commit

Permalink
Merge pull request #117 from Facts-and-Files/feat/import
Browse files Browse the repository at this point in the history
feat: import endpoint
  • Loading branch information
trenc authored Jul 31, 2024
2 parents 31c2fd9 + dffa5a9 commit 5fb49c1
Show file tree
Hide file tree
Showing 36 changed files with 1,451 additions and 455 deletions.
120 changes: 120 additions & 0 deletions src/app/Http/Controllers/ImportController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<?php

namespace App\Http\Controllers;

use App\Http\Controllers\ResponseController;
use App\Http\Resources\ImportResource;
use App\Models\Item;
use App\Models\Story;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Validator;

class ImportController extends ResponseController
{
public function store(Request $request): JsonResponse
{
$data = $request->all();

$inserted = [];
$errors = [];

foreach ($data as $index => $import) {
$validator = Validator::make($import, [
'Story.Dc.Title' => 'required',
'Items' => 'array',
]);

if ($validator->fails()) {
$errors[] = [
'ExternalRecordId' => $import['Story']['ExternalRecordId'],
'RecordId' => $import['Story']['RecordId'],
'dc:title' => $import['Story']['Dc']['Title'],
'error' => $validator->errors()->all()
];
continue;
}

$story = new Story();

// fill non-guarded
$story->fill($import['Story']);

// fill guarded
$story->ExternalRecordId = $import['Story']['ExternalRecordId'] ?? null;
$story->RecordId = $import['Story']['RecordId'] ?? null;

// fill these with accessor/mutator
$story->dc = $import['Story']['Dc'];
$story->dcterms = $import['Story']['Dcterms'];
$story->edm = $import['Story']['Edm'];

try {
$story->save();

if (isset($import['Items']) && is_array($import['Items'])) {
foreach ($import['Items'] as $itemData) {

$itemValidator = Validator::make($itemData, [
'Title' => 'required',
'ImageLink' => 'required',
'OrderIndex' => 'integer'
]);

if ($itemValidator->fails()) {
$errors[] = [
'ExternalRecordId' => $import['Story']['ExternalRecordId'] ?? null,
'RecordId' => $import['Story']['RecordId'] ?? null,
'ItemOrderIndex' => $itemData['OrderIndex'] ?? null,
'ProjectItemId' => $itemData['ProjectItemId'] ?? null,
'error' => $itemValidator->errors()->all()
];

continue;
}

$item = new Item();
// fill non-guarded
$item->fill($itemData);
// fill guarded
$item->StoryId = $story->StoryId;
$item->ProjectItemId = $itemData['ProjectItemId'] ?? null;
$item->save();
}
}

$inserted[] = [
'StoryId' => $story->StoryId,
'ExternalRecordId' => $story->ExternalRecordId,
'RecordId' => $story->RecordId,
'dc:title' => $story->Dc['Title']
];

} catch (\Exception $exception) {
$errors[] = [
'ExternalRecordId' => $story->ExternalRecordId,
'RecordId' => $story->RecordId,
'dc:title' => $story->Dc['Title'],
'error' => $exception->getMessage()
];
}
}

$insertedResource = new ImportResource($inserted);

$insertedCount = count($inserted);
$errorsCount = count($errors);

if ($insertedCount === 0 && $errorsCount > 0) {
return $this->sendError('Invalid data', $errors, 400);
}

if ($insertedCount > 0 && $errorsCount === 0) {
return $this->sendResponse($insertedResource, 'Import successfully inserted.');
}

if ($insertedCount > 0 && $errorsCount > 0) {
return $this->sendPartlyResponse($insertedResource, $errors, 'Import could only partially inserted.');
}
}
}
13 changes: 13 additions & 0 deletions src/app/Http/Resources/ImportResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class ImportResource extends JsonResource
{
public function toArray($request): array
{
return parent::toArray($request);
}
}
3 changes: 1 addition & 2 deletions src/app/Models/Item.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,10 @@ class Item extends Model

protected $primaryKey = 'ItemId';

protected $guarded = ['StoryId', 'ItemId'];
protected $guarded = ['StoryId', 'ItemId', 'ProjectItemId'];

protected $hidden = [
'CompletionStatusId',
'ProjectItemId',
'DatasetId',
'DescriptionLanguage',
'Exported',
Expand Down
175 changes: 104 additions & 71 deletions src/app/Models/Story.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ class Story extends Model

protected $primaryKey = 'StoryId';

protected $fillable = [
'DatasetId',
'HasHtr',
'Dc',
'Public'
protected $guarded = [
'StoryId',
'ExternalRecordId',
'RecordId',
'ImportName'
];

protected $casts = [
Expand All @@ -31,52 +31,45 @@ class Story extends Model
];

protected $hidden = [
'dc:title',
'dc:description',
'edm:landingPage',
'PlaceName',
'PlaceLatitude',
'PlaceLongitude',
'placeZoom',
'PlaceLink',
'PlaceComment',
'PlaceUserId',
'PlaceUserGenerated',
'dc:creator',
'dc:source',
'Summary',
'ParentStory',
'SearchText',
'DateStart',
'DateEnd',
'OrderIndex',
'ImportName',
'edm:country',
'edm:dataProvider',
'edm:provider',
'edm:rights',
'dc:contributor',
'edm:year',
'dc:publisher',
'dc:coverage',
'dc:date',
'dc:type',
'dc:relation',
'dcterms:medium',
'edm:datasetName',
'edm:begin',
'edm:end',
'ProjectId',
'edm:isShownAt',
'edm:language',
'edm:agent',
'dc:rights',
'dc:title',
'dc:description',
'dc:creator',
'dc:source',
'dc:contributor',
'dc:publisher',
'dc:coverage',
'dc:date',
'dc:type',
'dc:relation',
'dc:language',
'edm:language',
'CompletionStatusId',
'dcterms:provenance',
'dc:identifier',
'OldStoryId',
'edm:agent',
'dcterms:created'
'dcterms:medium',
'dcterms:provenance',
'dcterms:created',
'PlaceUserId',
'PlaceUserGenerated',
'Summary',
'ParentStory',
'SearchText',
'DateStart',
'DateEnd',
'OrderIndex',
'ImportName',
'CompletionStatusId',
'OldStoryId'
];

protected $appends = [
Expand Down Expand Up @@ -119,67 +112,107 @@ public function getCompletionStatusAttribute(): CompletionStatus
->completionStatus()
->first(['CompletionStatusId as StatusId', 'Name', 'ColorCode', 'ColorCodeGradient']);

// fallback to a default CompletionStatus instance if none found
if ($plucked === null) {
$plucked = CompletionStatus::find(1);
}

return $plucked;
}

public function getDctermsAttribute(): array
{
return [
'Medium' => $this->attributes['dcterms:medium'],
'Created' => $this->attributes['dcterms:created'],
'Provenance' => $this->attributes['dcterms:provenance'],
'Medium' => $this->attributes['dcterms:medium'] ?? null,
'Created' => $this->attributes['dcterms:created'] ?? null,
'Provenance' => $this->attributes['dcterms:provenance'] ?? null
];
}

public function setDctermsAttribute(array $values): void
{
$this->attributes['dcterms:medium'] = $values['Medium'] ?? $this->attributes['dcterms:medium'] ?? null;
$this->attributes['dcterms:created'] = $values['Created'] ?? $this->attributes['dcterms:created'] ?? null;
$this->attributes['dcterms:provenance'] = $values['Provenance'] ?? $this->attributes['dcterms:provenance'] ?? null;
}

public function getDcAttribute(): array
{
return [
'Title' => $this->attributes['dc:title'],
'Description' => $this->attributes['dc:description'],
'Creator' => $this->attributes['dc:creator'],
'Source' => $this->attributes['dc:source'],
'Contributor' => $this->attributes['dc:contributor'],
'Publisher' => $this->attributes['dc:publisher'],
'Coverage' => $this->attributes['dc:coverage'],
'Date' => $this->attributes['dc:date'],
'Type' => $this->attributes['dc:type'],
'Relation' => $this->attributes['dc:relation'],
'Rights' => $this->attributes['dc:rights'],
'Language' => $this->attributes['dc:language'],
'Identifier' => $this->attributes['dc:identifier']
'Title' => $this->attributes['dc:title'] ?? null,
'Description' => $this->attributes['dc:description'] ?? null,
'Creator' => $this->attributes['dc:creator'] ?? null,
'Source' => $this->attributes['dc:source'] ?? null,
'Contributor' => $this->attributes['dc:contributor'] ?? null,
'Publisher' => $this->attributes['dc:publisher'] ?? null,
'Coverage' => $this->attributes['dc:coverage'] ?? null,
'Date' => $this->attributes['dc:date'] ?? null,
'Type' => $this->attributes['dc:type'] ?? null,
'Relation' => $this->attributes['dc:relation'] ?? null,
'Rights' => $this->attributes['dc:rights'] ?? null,
'Language' => $this->attributes['dc:language'] ?? null,
'Identifier' => $this->attributes['dc:identifier'] ?? null
];
}

public function setDcAttribute(array $values): void
{
$this->attributes['dc:title'] = $values['Title'] ?? $this->attributes['dc:title'];
$this->attributes['dc:title'] = $values['Title'] ?? $this->attributes['dc:title'] ?? null;
$this->attributes['dc:description'] = $values['Description'] ?? $this->attributes['dc:description'] ?? null;
$this->attributes['dc:creator'] = $values['Creator'] ?? $this->attributes['dc:creator'] ?? null;
$this->attributes['dc:source'] = $values['Source'] ?? $this->attributes['dc:source'] ?? null;
$this->attributes['dc:contributor'] = $values['Contributor'] ?? $this->attributes['dc:contributor'] ?? null;
$this->attributes['dc:publisher'] = $values['Publisher'] ?? $this->attributes['dc:publisher'] ?? null;
$this->attributes['dc:coverage'] = $values['Coverage'] ?? $this->attributes['dc:coverage'] ?? null;
$this->attributes['dc:date'] = $values['Date'] ?? $this->attributes['dc:date'] ?? null;
$this->attributes['dc:type'] = $values['Type'] ?? $this->attributes['dc:type'] ?? null;
$this->attributes['dc:relation'] = $values['Relation'] ?? $this->attributes['dc:relation'] ?? null;
$this->attributes['dc:rights'] = $values['Rights'] ?? $this->attributes['dc:rights'] ?? null;
$this->attributes['dc:language'] = $values['Language'] ?? $this->attributes['dc:language'] ?? null;
$this->attributes['dc:identifier'] = $values['Identifier'] ?? $this->attributes['dc:identifier'] ?? null;
}

public function getEdmAttribute(): array
{
return [
'LandingPage' => $this->attributes['edm:landingPage'],
'Country' => $this->attributes['edm:country'],
'DataProvider' => $this->attributes['edm:dataProvider'],
'Provider' => $this->attributes['edm:provider'],
'Rights' => $this->attributes['edm:rights'],
'Year' => $this->attributes['edm:year'],
'DatasetName' => $this->attributes['edm:datasetName'],
'Begin' => $this->attributes['edm:begin'],
'End' => $this->attributes['edm:end'],
'IsShownAt' => $this->attributes['edm:isShownAt'],
'Language' => $this->attributes['edm:language'],
'Agent' => $this->attributes['edm:agent']
'LandingPage' => $this->attributes['edm:landingPage'] ?? null,
'Country' => $this->attributes['edm:country'] ?? null,
'DataProvider' => $this->attributes['edm:dataProvider'] ?? null,
'Provider' => $this->attributes['edm:provider'] ?? null,
'Rights' => $this->attributes['edm:rights'] ?? null,
'Year' => $this->attributes['edm:year'] ?? null,
'DatasetName' => $this->attributes['edm:datasetName'] ?? null,
'Begin' => $this->attributes['edm:begin'] ?? null,
'End' => $this->attributes['edm:end'] ?? null,
'IsShownAt' => $this->attributes['edm:isShownAt'] ?? null,
'Language' => $this->attributes['edm:language'] ?? null,
'Agent' => $this->attributes['edm:agent'] ?? null
];
}

public function setEdmAttribute(array $values): void
{
$this->attributes['edm:landingPage'] = $values['LandingPage'] ?? $this->attributes['edm:landingPage'] ?? null;
$this->attributes['edm:country'] = $values['Country'] ?? $this->attributes['edm:country'] ?? null;
$this->attributes['edm:dataProvider'] = $values['DataProvider'] ?? $this->attributes['edm:dataProvider'] ?? null;
$this->attributes['edm:provider'] = $values['Provider'] ?? $this->attributes['edm:provider'] ?? null;
$this->attributes['edm:rights'] = $values['Rights'] ?? $this->attributes['edm:rights'] ?? null;
$this->attributes['edm:year'] = $values['Year'] ?? $this->attributes['edm:year'] ?? null;
$this->attributes['edm:datasetName'] = $values['DatasetName'] ?? $this->attributes['edm:datasetName'] ?? null;
$this->attributes['edm:begin'] = $values['Begin'] ?? $this->attributes['edm:begin'] ?? null;
$this->attributes['edm:end'] = $values['End'] ?? $this->attributes['edm:end'] ?? null;
$this->attributes['edm:isShownAt'] = $values['IsShownAt'] ?? $this->attributes['edm:isShownAt'] ?? null;
$this->attributes['edm:language'] = $values['Language'] ?? $this->attributes['edm:language'] ?? null;
$this->attributes['edm:agent'] = $values['Agent'] ?? $this->attributes['edm:agent'] ?? null;
}

public function getPlaceAttribute(): array
{
return [
'Name' => $this->attributes['PlaceName'],
'Latitude' => $this->attributes['PlaceLatitude'],
'Longitude' => $this->attributes['PlaceLongitude'],
'Zoom' => $this->attributes['placeZoom']
'Name' => $this->attributes['PlaceName'] ?? null,
'Latitude' => $this->attributes['PlaceLatitude'] ?? null,
'Longitude' => $this->attributes['PlaceLongitude'] ?? null,
'Zoom' => $this->attributes['placeZoom'] ?? null
];
}
}
Loading

0 comments on commit 5fb49c1

Please sign in to comment.