diff --git a/app/Behaviors/ImportsData.php b/app/Behaviors/ImportsData.php index cf6ffe82..30690d1c 100644 --- a/app/Behaviors/ImportsData.php +++ b/app/Behaviors/ImportsData.php @@ -212,8 +212,8 @@ protected function import($source, $model, $endpoint, $current = 1) foreach ($json->data as $datum) { // TODO: Careful, this conflicts w/ partial imports – running on one endpoint counts for all! // Break if this is a partial import + this datum is older than last run - if ($this->isPartial && isset($datum->{$model::$sourceLastUpdateDateField})) { - $sourceTime = new Carbon($datum->{$model::$sourceLastUpdateDateField}); + if ($this->isPartial && isset($datum->{$transformer::$sourceLastUpdateDateField})) { + $sourceTime = new Carbon($datum->{$transformer::$sourceLastUpdateDateField}); $sourceTime->timezone = config('app.timezone'); if ($this->since->gt($sourceTime)) { diff --git a/app/Console/Commands/Import/ImportEnhancerFull.php b/app/Console/Commands/Import/ImportEnhancerFull.php index ef468c16..e1bea560 100644 --- a/app/Console/Commands/Import/ImportEnhancerFull.php +++ b/app/Console/Commands/Import/ImportEnhancerFull.php @@ -35,6 +35,7 @@ protected function importEndpoints() $this->importEndpoint('agents'); $this->importEndpoint('artworks'); $this->importEndpoint('artwork-types'); + $this->importEndpoint('places'); $this->importEndpoint('terms'); } diff --git a/app/Console/Commands/Report/ReportPlaces.php b/app/Console/Commands/Report/ReportPlaces.php new file mode 100644 index 00000000..a4aed1f3 --- /dev/null +++ b/app/Console/Commands/Report/ReportPlaces.php @@ -0,0 +1,56 @@ +argument('artistId'); + + $items = Agent::findOrFail($artistId) + ->createdArtworks + ->pluck('places') + ->collapse() + ->unique('citi_id') + ->sortBy([ + ['citi_id', 'asc'], + ]) + ->values(); + + $csv = Writer::createFromString(''); + + $csv->insertOne([ + 'id', + 'title', + 'latitude', + 'longitude', + ]); + + foreach ($items as $item) { + $row = [ + 'id' => $item->citi_id, + 'title' => $item->title, + 'latitude' => $item->latitude, + 'longitude' => $item->longitude, + ]; + + $this->info(json_encode(array_values($row))); + $csv->insertOne($row); + } + + Storage::put('places-for-' . $artistId . '.csv', $csv->getContent()); + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 7c35ab0d..537f968d 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -76,6 +76,11 @@ protected function schedule(Schedule $schedule) ->withoutOverlapping(self::FOR_ONE_YEAR) ->sendOutputTo(storage_path('logs/import-queues-last-run.log')); + $schedule->command('import:enhancer') + ->everyMinute() + ->withoutOverlapping(self::FOR_ONE_YEAR) + ->sendOutputTo(storage_path('logs/import-enhancer-last-run.log')); + // API-231, API-232: Temporary remediation! Artworks can't touch artists. $schedule->command('scout:import', [ \App\Models\Collections\Agent::class, diff --git a/app/Http/Controllers/LinkedArtController.php b/app/Http/Controllers/LinkedArtController.php new file mode 100644 index 00000000..f462ab95 --- /dev/null +++ b/app/Http/Controllers/LinkedArtController.php @@ -0,0 +1,559 @@ + 'https://linked.art/ns/v1/linked-art.json', + 'id' => route('ld.object', ['id' => $artwork]), + 'type' => 'HumanMadeObject', + ]; + + $item = array_merge_recursive( + $item, + $this->getArtworkType($artwork), + $this->getIdentifiers($artwork), + $this->getTitles($artwork), + $this->getCurrentOwner($artwork), + $this->getProduction($artwork), + $this->getDimensions($artwork), + $this->getMaterial($artwork), + $this->getSupportMaterial($artwork), + $this->getMaterialStatement($artwork), + $this->getDimensionStatement($artwork), + $this->getSubject($artwork), + $this->getRepresentation($artwork), + $this->getCreditStatement($artwork), + $this->getProvenanceStatement($artwork), + $this->getBibliographyStatement($artwork), + $this->getExhibitionStatement($artwork), + $this->getExtraLinkedArtJson($artwork), + ); + + return $item; + } + + private function getArtworkType($artwork): array + { + if (!$artworkType = $artwork->artworkType) { + return []; + } + + if (!$artworkType->aat_id) { + return []; + } + + return [ + 'classified_as' => [ + [ + 'id' => 'http://vocab.getty.edu/aat/' . $artworkType->aat_id, + 'type' => 'Type', + '_label' => $artworkType->title, + ], + ], + ]; + } + + private function getIdentifiers($artwork): array + { + $identifiers = []; + + if ($artwork->main_id) { + $identifiers[] = [ + 'type' => 'Identifier', + 'content' => $artwork->main_id, + 'classified_as' => [ + [ + 'id' => 'http://vocab.getty.edu/aat/300312355', + 'type' => 'Type', + '_label' => 'accession number', + ], + ], + ]; + } + + if (empty($identifiers)) { + return []; + } + + return [ + 'identified_by' => $identifiers, + ]; + } + + private function getTitles($artwork): array + { + if (empty($artwork->title)) { + return []; + } + + return [ + 'identified_by' => [ + [ + 'type' => 'Name', + 'content' => $artwork->title, + 'language' => [ + [ + 'id' => 'http://vocab.getty.edu/aat/300388277', + 'type' => 'Language', + '_label' => 'English', + ], + ], + 'classified_as' => [ + [ + 'id' => 'http://vocab.getty.edu/aat/300404670', + 'type' => 'Type', + '_label' => 'Preferred terms', + ], + ], + ], + ], + ]; + } + + /** + * TODO: Do we need to handle loans? + */ + private function getCurrentOwner($artwork): array + { + return [ + 'current_owner' => [ + [ + 'id' => 'http://vocab.getty.edu/ulan/500304669', + 'type' => 'Group', + '_label' => 'Art Institute of Chicago', + ], + ], + ]; + } + + private function getProduction($artwork): array + { + $production = [ + 'type' => 'Production', + ]; + + $artists = $artwork + ->artists + ->filter(fn ($artist) => !empty($artist->ulan_id)) + ->unique('ulan_id') + ->map(fn ($artist) => [ + 'id' => 'http://vocab.getty.edu/ulan/' . $artist->ulan_id, + 'type' => 'Actor', + ]) + ->values() + ->all(); + + if (count($artists) > 0) { + $production['carried_out_by'] = $artists; + } + + $techniques = collect($artwork + ->techniques) + ->filter(fn ($technique) => !empty($technique->aat_id)) + ->unique('aat_id') + ->map(fn ($technique) => [ + 'id' => 'http://vocab.getty.edu/aat/' . $technique->aat_id, + // ...do we need to capture type during reconciliation? + 'type' => 'Type', + '_label' => $technique->title, + ]) + ->values() + ->all(); + + if (count($techniques) > 0) { + $production['technique'] = $techniques; + } + + // TODO: Provide `took_place_at` [API-12] + + $timespan = [ + 'type' => 'TimeSpan', + 'begin_of_the_begin' => !empty($artwork->date_start) + ? (new Carbon($artwork->date_start . '-01-01T00:00:00Z'))->toIso8601ZuluString() + : null, + 'end_of_the_end' => !empty($artwork->date_end) + ? (new Carbon($artwork->date_end . '-12-31T23:59:59Z'))->toIso8601ZuluString() + : null, + ]; + + if (!empty($artwork->date_display)) { + $timespan['identified_by'] = [ + [ + 'type' => 'Name', + 'content' => $artwork->date_display, + 'language' => [ + [ + 'id' => 'http://vocab.getty.edu/aat/300388277', + 'type' => 'Language', + '_label' => 'English', + ] + ] + ] + ]; + } + + $production['timespan'] = $timespan; + + return [ + 'produced_by' => $production, + ]; + } + + private function getDimensions($artwork): array + { + $dimensions = []; + + $unit = [ + 'id' => 'http://vocab.getty.edu/aat/300379097', + 'type' => 'MeasurementUnit', + '_label' => 'millimeters', + ]; + + if (!empty($artwork->dimension_width)) { + $dimensions[] = [ + 'type' => 'Dimension', + 'value' => $artwork->dimension_width, + 'classified_as' => [ + [ + 'id' => 'http://vocab.getty.edu/aat/300055647', + 'type' => 'Type', + '_label' => 'width', + ], + ], + 'unit' => $unit, + ]; + } + + if (!empty($artwork->dimension_height)) { + $dimensions[] = [ + 'type' => 'Dimension', + 'value' => $artwork->dimension_height, + 'classified_as' => [ + [ + 'id' => 'http://vocab.getty.edu/aat/300055644', + 'type' => 'Type', + '_label' => 'height', + ], + ], + 'unit' => $unit, + ]; + } + + return [ + 'dimension' => $dimensions, + ]; + } + + private function getMaterial($artwork): array + { + $materials = collect($artwork + ->materials) + ->filter(fn ($material) => !empty($material->aat_id)) + ->unique('aat_id') + ->map(fn ($material) => [ + 'id' => 'http://vocab.getty.edu/aat/' . $material->aat_id, + 'type' => 'Material', + '_label' => $material->title, + ]) + ->values() + ->all(); + + if (count($materials) < 1) { + return []; + } + + return [ + 'made_of' => $materials, + ]; + } + + private function getSupportMaterial($artwork): array + { + if (empty($artwork->support_aat_id)) { + return []; + } + + return [ + 'part' => [ + [ + 'type' => 'HumanMadeObject', + 'classified_as' => [ + [ + 'id' => 'http://vocab.getty.edu/aat/300014844', + 'type' => 'Type', + '_label' => 'Support', + ], + ], + 'made_of' => [ + [ + 'id' => 'http://vocab.getty.edu/aat/' . $artwork->support_aat_id, + 'type' => 'Material', + ], + ], + ], + ], + ]; + } + + private function getMaterialStatement($artwork): array + { + if (empty($artwork->medium_display)) { + return []; + } + + return [ + 'referred_to_by' => [ + [ + 'type' => 'LinguisticObject', + 'content' => $artwork->medium_display, + 'classified_as' => [ + [ + 'id' => 'http://vocab.getty.edu/aat/300435429', + 'type' => 'Type', + '_label' => 'Material Statement', + 'classified_as' => [ + [ + 'id' => 'http://vocab.getty.edu/aat/300418049', + 'type' => 'Type', + '_label' => 'Brief Text', + ], + ], + ], + ], + ], + ], + ]; + } + + private function getDimensionStatement($artwork): array + { + if (empty($artwork->dimensions)) { + return []; + } + + return [ + 'referred_to_by' => [ + [ + 'type' => 'LinguisticObject', + 'content' => $artwork->dimensions, + 'classified_as' => [ + [ + 'id' => 'http://vocab.getty.edu/aat/300435430', + 'type' => 'Type', + '_label' => 'Dimension Statement', + 'classified_as' => [ + [ + 'id' => 'http://vocab.getty.edu/aat/300418049', + 'type' => 'Type', + '_label' => 'Brief Text', + ], + ], + ], + ], + ], + ], + ]; + } + + private function getSubject($artwork): array + { + $subjects = collect($artwork + ->subjects) + ->filter(fn ($subject) => !empty($subject->aat_id)) + ->unique('aat_id') + ->map(fn ($subject) => [ + 'type' => 'VisualItem', + 'classified_as' => [ + [ + 'id' => 'http://vocab.getty.edu/aat/' . $subject->aat_id, + 'type' => 'Type', + '_label' => $subject->title, + ], + ], + ]) + ->values() + ->all(); + + if (count($subjects) < 1) { + return []; + } + + return [ + 'shows' => $subjects, + ]; + } + + /** + * TODO: Provide non-preferred images + */ + private function getRepresentation($artwork): array + { + if (empty($artwork->image)) { + return []; + } + + return [ + 'representation' => [ + [ + 'id' => config('aic.config_documentation.iiif_url') . '/' . Asset::getHashedId($artwork->image->getKey()), + 'type' => 'VisualItem', + 'conforms_to' => [ + [ + 'id' => 'http://iiif.io/api/image' + ], + ], + 'classified_as' => [ + [ + 'id' => 'http://vocab.getty.edu/aat/300215302', + 'type' => 'Type', + '_label' => 'digital images', + ], + ], + ], + ], + ]; + } + + private function getCreditStatement($artwork): array + { + if (empty($artwork->credit_line)) { + return []; + } + + return [ + 'referred_to_by' => [ + [ + 'type' => 'LinguisticObject', + 'classified_as' => [ + [ + 'id' => 'http://vocab.getty.edu/aat/300026687', + 'type' => 'Type', + '_label' => 'Credit Statement', + 'classified_as' => [ + [ + 'id' => 'http://vocab.getty.edu/aat/300418049', + 'type' => 'Type', + '_label' => 'Brief Text', + ], + ], + ], + ], + 'content' => $artwork->credit_line + ], + ], + ]; + } + + private function getProvenanceStatement($artwork): array + { + if (empty($artwork->provenance)) { + return []; + } + + return [ + 'referred_to_by' => [ + [ + 'type' => 'LinguisticObject', + 'classified_as' => [ + [ + 'id' => 'http://vocab.getty.edu/aat/300435438', + 'type' => 'Type', + '_label' => 'Provenance Statement', + 'classified_as' => [ + [ + 'id' => 'http://vocab.getty.edu/aat/300418049', + 'type' => 'Type', + '_label' => 'Brief Text', + ], + ], + ], + ], + 'content' => $artwork->provenance + ], + ], + ]; + } + + private function getBibliographyStatement($artwork): array + { + if (empty($artwork->publication_history)) { + return []; + } + + return [ + 'referred_to_by' => [ + [ + 'type' => 'LinguisticObject', + 'classified_as' => [ + [ + 'id' => 'http://vocab.getty.edu/aat/300026497', + 'type' => 'Type', + '_label' => 'Bibliography Statement', + 'classified_as' => [ + [ + 'id' => 'http://vocab.getty.edu/aat/300418049', + 'type' => 'Type', + '_label' => 'Brief Text', + ], + ], + ], + ], + 'content' => $artwork->publication_history + ], + ], + ]; + } + + private function getExhibitionStatement($artwork): array + { + if (empty($artwork->exhibition_history)) { + return []; + } + + return [ + 'referred_to_by' => [ + [ + 'type' => 'LinguisticObject', + 'classified_as' => [ + [ + 'id' => 'http://vocab.getty.edu/aat/300435424', + 'type' => 'Type', + '_label' => 'Exhibition Statement', + 'classified_as' => [ + [ + 'id' => 'http://vocab.getty.edu/aat/300418049', + 'type' => 'Type', + '_label' => 'Brief Text', + ], + ], + ], + ], + 'content' => $artwork->exhibition_history + ], + ], + ]; + } + + private function getExtraLinkedArtJson($artwork): array + { + if (empty($artwork->linked_art_json)) { + return []; + } + + // convert object to array recursively + return json_decode(json_encode($artwork->linked_art_json), true); + } +} diff --git a/app/Models/BaseModel.php b/app/Models/BaseModel.php index 637f6b86..5f25bd89 100644 --- a/app/Models/BaseModel.php +++ b/app/Models/BaseModel.php @@ -34,13 +34,6 @@ class BaseModel extends AbstractModel use Transformable, Documentable, HasFactory; - /** - * The name of the field that the source API provides a last updated timestamp in. - * - * @var string - */ - public static $sourceLastUpdateDateField = 'modified_at'; - /** * String that indicates the sub-namespace of the child models. Used for dynamic model retrieval. * diff --git a/app/Models/Collections/Artwork.php b/app/Models/Collections/Artwork.php index f675c894..66e4236a 100644 --- a/app/Models/Collections/Artwork.php +++ b/app/Models/Collections/Artwork.php @@ -22,6 +22,7 @@ class Artwork extends CollectionsModel 'is_public_domain' => 'boolean', 'is_zoomable' => 'boolean', 'is_on_view' => 'boolean', + 'linked_art_json' => 'object', ]; protected $primaryKey = 'citi_id'; diff --git a/app/Models/Collections/Asset.php b/app/Models/Collections/Asset.php index 88c9eeff..7ffa6f68 100644 --- a/app/Models/Collections/Asset.php +++ b/app/Models/Collections/Asset.php @@ -18,9 +18,6 @@ class Asset extends CollectionsModel public const TEXT = 'text'; public const VIDEO = 'video'; - // WEB-1870: We can't set this conditionally; default to NetX over LAKE - // public static $sourceLastUpdateDateField = 'indexed_at'; - protected static $assetType; protected $primaryKey = 'lake_guid'; diff --git a/app/Models/Web/EventOccurrence.php b/app/Models/Web/EventOccurrence.php index ca59a33d..795b3612 100644 --- a/app/Models/Web/EventOccurrence.php +++ b/app/Models/Web/EventOccurrence.php @@ -10,9 +10,6 @@ */ class EventOccurrence extends WebModel { - - public static $sourceLastUpdateDateField = 'updated_at'; - protected $keyType = 'string'; protected $casts = [ diff --git a/app/Models/WebModel.php b/app/Models/WebModel.php index 455979c7..f295a500 100644 --- a/app/Models/WebModel.php +++ b/app/Models/WebModel.php @@ -10,8 +10,6 @@ class WebModel extends BaseModel use ElasticSearchable; - public static $sourceLastUpdateDateField = 'last_updated'; - protected static $source = 'Web'; protected $casts = [ diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 9426e681..11bd3dd4 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -44,6 +44,10 @@ public function boot() ->namespace($this->namespace) ->group(base_path('routes/api.php')); + Route::prefix('la') + ->namespace($this->namespace) + ->group(base_path('routes/la.php')); + Route::middleware('web') ->namespace($this->namespace) ->group(base_path('routes/web.php')); diff --git a/app/Transformers/Inbound/BaseTransformer.php b/app/Transformers/Inbound/BaseTransformer.php index 97f80e4f..2e34cea2 100644 --- a/app/Transformers/Inbound/BaseTransformer.php +++ b/app/Transformers/Inbound/BaseTransformer.php @@ -11,6 +11,14 @@ class BaseTransformer extends AbstractTransformer { + /** + * The name of the field that the source API provides a last updated timestamp in. + * + * @todo Move this to inbound transformers! Argh! + * + * @var string + */ + public static $sourceLastUpdateDateField = 'modified_at'; /** * If this property is true, all fields will be copied from the datum to serve as the diff --git a/app/Transformers/Inbound/Enhancer/AbstractEnhancerTransformer.php b/app/Transformers/Inbound/Enhancer/AbstractEnhancerTransformer.php index 480f0b45..773ffa6b 100644 --- a/app/Transformers/Inbound/Enhancer/AbstractEnhancerTransformer.php +++ b/app/Transformers/Inbound/Enhancer/AbstractEnhancerTransformer.php @@ -8,6 +8,8 @@ abstract class AbstractEnhancerTransformer extends BaseTransformer { + public static $sourceLastUpdateDateField = 'updated_at'; + protected $passthrough = false; public function shouldSave(Model $instance, $datum, $isNew = null) diff --git a/app/Transformers/Inbound/Enhancer/Artwork.php b/app/Transformers/Inbound/Enhancer/Artwork.php index 3d0ed205..4a9ddf48 100644 --- a/app/Transformers/Inbound/Enhancer/Artwork.php +++ b/app/Transformers/Inbound/Enhancer/Artwork.php @@ -13,6 +13,7 @@ protected function getExtraFields(Datum $datum) 'support_aat_id' => $datum->support_aat_id, 'dimension_width' => $datum->width, 'dimension_height' => $datum->height, + 'linked_art_json' => $datum->linked_art_json, ]; } } diff --git a/app/Transformers/Inbound/Enhancer/Place.php b/app/Transformers/Inbound/Enhancer/Place.php new file mode 100644 index 00000000..0e884554 --- /dev/null +++ b/app/Transformers/Inbound/Enhancer/Place.php @@ -0,0 +1,16 @@ + $datum->tgn_id, + ]; + } +} diff --git a/app/Transformers/Inbound/Web/EventOccurrence.php b/app/Transformers/Inbound/Web/EventOccurrence.php index 269d7d5e..0adbcec0 100644 --- a/app/Transformers/Inbound/Web/EventOccurrence.php +++ b/app/Transformers/Inbound/Web/EventOccurrence.php @@ -8,6 +8,7 @@ class EventOccurrence extends WebTransformer { + public static $sourceLastUpdateDateField = 'updated_at'; protected $passthrough = true; diff --git a/app/Transformers/Inbound/WebTransformer.php b/app/Transformers/Inbound/WebTransformer.php index 21a92e87..f5ded648 100644 --- a/app/Transformers/Inbound/WebTransformer.php +++ b/app/Transformers/Inbound/WebTransformer.php @@ -6,6 +6,8 @@ class WebTransformer extends BaseTransformer { + public static $sourceLastUpdateDateField = 'last_updated'; + /** * Get dates from source data. Meant to be overwritten. * diff --git a/app/Transformers/Outbound/Collections/Place.php b/app/Transformers/Outbound/Collections/Place.php index e6febf95..c914d10f 100644 --- a/app/Transformers/Outbound/Collections/Place.php +++ b/app/Transformers/Outbound/Collections/Place.php @@ -10,11 +10,28 @@ class Place extends BaseTransformer protected function getFields() { return [ + 'latitude' => [ + 'doc' => 'Latitude coordinate of the center of the room', + 'type' => 'number', + 'elasticsearch' => 'float', + 'is_restricted' => true, + ], + 'longitude' => [ + 'doc' => 'Longitude coordinate of the center of the room', + 'type' => 'number', + 'elasticsearch' => 'float', + 'is_restricted' => true, + ], 'type' => [ 'doc' => 'Type always takes one of the following values: AIC Gallery, AIC Storage, No location', 'type' => 'string', 'elasticsearch' => 'keyword', ], + 'tgn_id' => [ + 'doc' => 'Reconciled identifier of this object in the Getty\'s Thesauraus of Geographic Names (TGN)', + 'type' => 'number', + 'elasticsearch' => 'integer', + ], ]; } diff --git a/config/resources/inbound.php b/config/resources/inbound.php index f902c333..9122953e 100644 --- a/config/resources/inbound.php +++ b/config/resources/inbound.php @@ -93,6 +93,10 @@ 'model' => \App\Models\Collections\ArtworkType::class, 'transformer' => \App\Transformers\Inbound\Enhancer\ArtworkType::class, ], + 'places' => [ + 'model' => \App\Models\Collections\Place::class, + 'transformer' => \App\Transformers\Inbound\Enhancer\Place::class, + ], 'terms' => [ 'model' => \App\Models\Collections\CategoryTerm::class, 'transformer' => \App\Transformers\Inbound\Enhancer\Term::class, diff --git a/database/migrations/2022_03_21_165514_add_tgn_id_to_places.php b/database/migrations/2022_03_21_165514_add_tgn_id_to_places.php new file mode 100644 index 00000000..34a556a6 --- /dev/null +++ b/database/migrations/2022_03_21_165514_add_tgn_id_to_places.php @@ -0,0 +1,22 @@ +integer('tgn_id')->signed()->nullable()->after('title'); + }); + } + + public function down() + { + Schema::table('places', function (Blueprint $table) { + $table->dropColumn('tgn_id'); + }); + } +} diff --git a/database/migrations/2022_03_30_230115_add_linked_art_json_to_artworks.php b/database/migrations/2022_03_30_230115_add_linked_art_json_to_artworks.php new file mode 100644 index 00000000..fbad7175 --- /dev/null +++ b/database/migrations/2022_03_30_230115_add_linked_art_json_to_artworks.php @@ -0,0 +1,23 @@ +json('linked_art_json')->nullable()->after('provenance'); + + }); + } + + public function down() + { + Schema::table('artworks', function (Blueprint $table) { + $table->dropColumn('linked_art_json'); + }); + } +} diff --git a/routes/api.php b/routes/api.php index 66f281e0..4db51cee 100644 --- a/routes/api.php +++ b/routes/api.php @@ -10,17 +10,6 @@ use App\Http\Controllers\ArtworkController; use App\Http\Controllers\AssetController; -/* -|-------------------------------------------------------------------------- -| API Routes -|-------------------------------------------------------------------------- -| -| Here is where you can register API routes for your application. These -| routes are loaded by the RouteServiceProvider within a group which -| is assigned the "api" middleware group. Enjoy building your API! -| -*/ - app('url')->forceRootUrl(config('aic.proxy_url')); app('url')->forceScheme(config('aic.proxy_scheme')); diff --git a/routes/la.php b/routes/la.php new file mode 100644 index 00000000..43151d78 --- /dev/null +++ b/routes/la.php @@ -0,0 +1,10 @@ +forceRootUrl(config('aic.proxy_url')); +app('url')->forceScheme(config('aic.proxy_scheme')); + +use App\Http\Controllers\LinkedArtController; + +Route::group(['prefix' => 'v1'], function () { + Route::get('objects/{id}', [LinkedArtController::class, 'showObject'])->name('ld.object'); +});