Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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

Large diffs are not rendered by default.

36 changes: 0 additions & 36 deletions resources/dist/build/assets/statamic-structured-data-BYx9Vy5k.js

This file was deleted.

36 changes: 36 additions & 0 deletions resources/dist/build/assets/statamic-structured-data-DPSSUs1M.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions resources/dist/build/manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"resources/js/components/StructuredDataFieldEditor.vue": {
"file": "assets/StructuredDataFieldEditor-BKrOdERS.js",
"file": "assets/StructuredDataFieldEditor-C7js4TAQ.js",
"name": "StructuredDataFieldEditor",
"src": "resources/js/components/StructuredDataFieldEditor.vue",
"isDynamicEntry": true,
Expand All @@ -9,7 +9,7 @@
]
},
"resources/js/statamic-structured-data.js": {
"file": "assets/statamic-structured-data-BYx9Vy5k.js",
"file": "assets/statamic-structured-data-DPSSUs1M.js",
"name": "statamic-structured-data",
"src": "resources/js/statamic-structured-data.js",
"isEntry": true,
Expand Down
5 changes: 4 additions & 1 deletion resources/js/components/fieldtypes/StructuredDataPreview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ const { expose } = Fieldtype.use(emit, fieldtypeProps);

defineExpose(expose);

const { values } = injectPublishContext();
const { values, site } = injectPublishContext();
const { proxy } = getCurrentInstance();

const axiosInstance = proxy?.$axios ?? window?.axios ?? window?.Statamic?.$axios;
Expand All @@ -105,6 +105,8 @@ const currentEntryId = computed(() => {
return publishValues.id;
});

const currentSite = computed(() => site?.value ?? null);

const hasTemplates = computed(() => {
return templateIds.value && templateIds.value.length > 0;
});
Expand Down Expand Up @@ -209,6 +211,7 @@ const fetchTemplateData = async templateIdsToFetch => {
params: {
ids: templateIdsToFetch,
entry_id: currentEntryId.value,
site: currentSite.value,
},
});

Expand Down
4 changes: 2 additions & 2 deletions src/Fieldtypes/StructuredDataBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,9 @@ protected function getStructuredDataObjects(): Collection
return $terms->map(function ($term) {
/** @var LocalizedTerm $term */
return [
'title' => $term->get('title'),
'title' => $term->title,
'slug' => $term->slug(),
'object_data' => $term->get('object_data'),
'object_data' => $term->object_data,
];
});
}
Expand Down
19 changes: 17 additions & 2 deletions src/Http/Controllers/StructuredDataController.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,25 @@ public function getTemplates(Request $request): JsonResponse
{
/** @var array<int|string>|null $templateIds */
$templateIds = $request->input('ids', []);
$siteHandle = $request->input('site');

if (is_string($siteHandle) && $siteHandle !== '') {
Site::setCurrent($siteHandle);
}

$contentEntry = Entry::find($request->input('entry_id'));

if (! $contentEntry) {
$contentEntry = Term::find($request->input('entry_id'));

if (
$contentEntry instanceof TermContract
&& is_string($siteHandle)
&& $siteHandle !== ''
&& method_exists($contentEntry, 'in')
) {
$contentEntry = $contentEntry->in($siteHandle);
}
}

if (! $contentEntry instanceof EntryContract && ! $contentEntry instanceof TermContract) {
Expand All @@ -73,7 +88,7 @@ public function getTemplates(Request $request): JsonResponse
return null;
}

$structuredData = $entry->get('schema_data');
$structuredData = $entry->schema_data;

if ($structuredData === null) {
return null;
Expand All @@ -84,7 +99,7 @@ public function getTemplates(Request $request): JsonResponse

return [
'id' => $entry->id(),
'title' => $entry->get('title'),
'title' => $entry->title,
'structuredData' => $transformedData,
];
})
Expand Down
30 changes: 20 additions & 10 deletions src/Services/StructuredDataService.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Justbetter\StatamicStructuredData\Services;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Justbetter\StatamicStructuredData\Parser\StructuredDataParser;
use Justbetter\StatamicStructuredData\Services\Transformers\FieldTransformerFactory;
use Justbetter\StatamicStructuredData\Support\RunwaySupport;
Expand Down Expand Up @@ -47,7 +48,7 @@ public function getJsonLdScripts(EntryContract|Page|LocalizedTerm|TermContract|M
}

/** @var array<int, array<string, mixed>>|null $schemas */
$schemas = $template->get('schema_data');
$schemas = $template->schema_data;
$schemas = $schemas ?? [];

if (empty($schemas)) {
Expand Down Expand Up @@ -227,7 +228,7 @@ protected function transformField(array $field, EntryContract|Page|LocalizedTerm
}

/**
* @return array<int|string, mixed>
* @return array<int, string>
*/
public function getTemplates(EntryContract|Page|LocalizedTerm|TermContract|Model $item, ?string $resourceHandle = null): array
{
Expand All @@ -237,17 +238,11 @@ public function getTemplates(EntryContract|Page|LocalizedTerm|TermContract|Model
}

if ($item instanceof Entry) {
/** @var array<int|string, mixed>|null $templates */
$templates = $item->get('structured_data_templates');

return is_array($templates) ? $templates : [];
return $this->extractTemplateIds($item->structured_data_templates);
}

if ($item instanceof LocalizedTerm) {
/** @var array<int|string, mixed>|null $templates */
$templates = $item->get('structured_data_templates');

return is_array($templates) ? $templates : [];
return $this->extractTemplateIds($item->structured_data_templates);
}

if ($item instanceof Model) {
Expand All @@ -263,6 +258,21 @@ public function getTemplates(EntryContract|Page|LocalizedTerm|TermContract|Model
return [];
}

/**
* @return array<int, string>
*/
protected function extractTemplateIds(mixed $templates): array
{
if (! $templates instanceof Collection) {
return [];
}

/** @var array<int, string> $ids */
$ids = $templates->pluck('id')->toArray();

return $ids;
}

/**
* @return array<int, string>
*/
Expand Down
47 changes: 21 additions & 26 deletions tests/Unit/Fieldtypes/StructuredDataBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@
use Justbetter\StatamicStructuredData\Services\PresetService;
use Justbetter\StatamicStructuredData\Services\ReplicatorFieldService;
use Justbetter\StatamicStructuredData\Tests\TestCase;
use Mockery;
use Mockery\MockInterface;
use PHPUnit\Framework\Attributes\Test;
use Statamic\Entries\Entry;
use Statamic\Facades\Collection as CollectionFacade;
use Statamic\Facades\Site;
use Statamic\Facades\Taxonomy as TaxonomyFacade;
use Statamic\Facades\Term as TermFacade;
use Statamic\Fields\Field;
use Statamic\Query\EloquentQueryBuilder;
use Statamic\Taxonomies\LocalizedTerm;
use Statamic\Sites\Site as SiteInstance;
use Statamic\Taxonomies\Taxonomy;
use Statamic\Taxonomies\Term;

class StructuredDataBuilderTest extends TestCase
{
Expand Down Expand Up @@ -232,28 +232,23 @@ public function get_structured_data_objects_returns_terms_when_taxonomy_and_site
$presetService = $this->mock(PresetService::class);
$replicatorFieldService = $this->mock(ReplicatorFieldService::class);

/** @var SiteInstance $site */
$site = Site::selected() ?? Site::default();
$siteHandle = $site->handle();

/** @var Taxonomy $taxonomy */
$taxonomy = TaxonomyFacade::make('structured_data_objects');
$taxonomy->save();
$site = $this->mock(\Statamic\Sites\Site::class, function ($mock): void {
$mock->shouldReceive('handle')->andReturn('default');
});
$term = $this->mock(LocalizedTerm::class, function ($mock): void {
$mock->shouldReceive('get')->with('title')->andReturn('Test Object');
$mock->shouldReceive('slug')->andReturn('test-object');
$mock->shouldReceive('get')->with('object_data')->andReturn(['test' => 'data']);
});

$queryBuilder = $this->mock(EloquentQueryBuilder::class, function ($mock) use ($term): void {
$mock->shouldReceive('where')->with('site', 'default')->andReturnSelf();
$mock->shouldReceive('get')->andReturn(collect([$term]));
});

$taxonomyMock = Mockery::mock($taxonomy)->makePartial();
$taxonomyMock->shouldReceive('queryTerms')->andReturn($queryBuilder);

TaxonomyFacade::shouldReceive('findByHandle')->with('structured_data_objects')->andReturn($taxonomyMock);
Site::shouldReceive('selected')->andReturn($site);
$taxonomy->sites([$siteHandle])->save();

/** @var Term $term */
$term = TermFacade::make('test-object');
$term
->taxonomy($taxonomy)
->dataForLocale($siteHandle, [
'title' => 'Test Object',
'object_data' => ['test' => 'data'],
]);
$term->in($siteHandle)->published(true)->save();

/** @var PresetService $presetService */
/** @var ReplicatorFieldService $replicatorFieldService */
Expand All @@ -269,9 +264,9 @@ public function get_structured_data_objects_returns_terms_when_taxonomy_and_site
$this->assertNotEmpty($result);
/** @var array<string, mixed> $firstItem */
$firstItem = $result->first();
$this->assertArrayHasKey('title', $firstItem);
$this->assertArrayHasKey('slug', $firstItem);
$this->assertArrayHasKey('object_data', $firstItem);
$this->assertSame('Test Object', $firstItem['title']);
$this->assertSame('test-object', $firstItem['slug']);
$this->assertSame(['test' => 'data'], $firstItem['object_data']);
}

#[Test]
Expand Down
2 changes: 2 additions & 0 deletions tests/Unit/Http/Controllers/StructuredDataControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ public function get_templates_returns_templates_for_term(): void
$taxonomy->save();
$contentTerm = $this->mock(LocalizedTerm::class, function ($mock) use ($taxonomy): void {
$mock->shouldReceive('taxonomy')->andReturn($taxonomy);
$mock->shouldReceive('in')->with('nl')->andReturnSelf();
});

$templateCollection = CollectionFacade::make('structured_data_templates');
Expand All @@ -180,6 +181,7 @@ public function get_templates_returns_templates_for_term(): void
$request = Request::create('/test', 'GET', [
'ids' => ['template-123'],
'entry_id' => 'test-term',
'site' => 'nl',
]);

\Statamic\Facades\Entry::shouldReceive('find')->with('test-term')->andReturn(null);
Expand Down
42 changes: 30 additions & 12 deletions tests/Unit/Services/StructuredDataServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Justbetter\StatamicStructuredData\Tests\Unit\Services;

use Illuminate\Support\Collection;
use Justbetter\StatamicStructuredData\Parser\StructuredDataParser;
use Justbetter\StatamicStructuredData\Services\StructuredDataService;
use Justbetter\StatamicStructuredData\Services\Transformers\FieldTransformerFactory;
Expand Down Expand Up @@ -30,12 +31,27 @@ protected function createBlogEntry(array $templates = []): Entry
->id('entry-123');

if ($templates) {
$blogEntry->set('structured_data_templates', $templates);
$blogEntry->set('structured_data_templates', $this->templatesCollection($templates));
}

return $blogEntry;
}

/**
* @param array<int, string> $ids
* @return Collection<int, Entry>
*/
protected function templatesCollection(array $ids): Collection
{
$collection = CollectionFacade::find('structured_data_templates')
?? CollectionFacade::make('structured_data_templates');
$collection->save();

return collect($ids)->map(
fn (string $id): Entry => (new Entry)->collection($collection)->id($id)
);
}

/** @param array<string, mixed> $schemaData */
protected function createTemplateEntry(array $schemaData = []): Entry
{
Expand Down Expand Up @@ -75,7 +91,7 @@ public function get_json_ld_scripts_returns_empty_array_when_template_not_found(
$blogEntry = (new Entry)
->collection($blogCollection)
->id('entry-123')
->set('structured_data_templates', ['template-123']);
->set('structured_data_templates', $this->templatesCollection(['template-123']));

EntryFacade::shouldReceive('find')->with('template-123')->andReturn(null);

Expand All @@ -99,7 +115,7 @@ public function get_json_ld_scripts_returns_empty_array_when_template_has_no_sch
$blogEntry = (new Entry)
->collection($blogCollection)
->id('entry-123')
->set('structured_data_templates', ['template-123']);
->set('structured_data_templates', $this->templatesCollection(['template-123']));

$templateEntry = (new Entry)
->collection($templatesCollection)
Expand Down Expand Up @@ -127,7 +143,7 @@ public function get_json_ld_scripts_returns_scripts_when_template_has_schema_dat
$entry = (new Entry)
->collection($collection)
->id('entry-123')
->set('structured_data_templates', ['template-123']);
->set('structured_data_templates', $this->templatesCollection(['template-123']));

$template = (new Entry)
->collection($templatesCollection)
Expand Down Expand Up @@ -170,7 +186,7 @@ public function get_json_ld_scripts_handles_page_instance(): void
$entry = (new Entry)
->collection($collection)
->id('entry-123')
->set('structured_data_templates', ['template-123']);
->set('structured_data_templates', $this->templatesCollection(['template-123']));

$template = (new Entry)
->collection($templatesCollection)
Expand Down Expand Up @@ -214,7 +230,7 @@ public function get_json_ld_scripts_handles_localized_term(): void
$taxonomy = TaxonomyFacade::make('categories');
$taxonomy->save();
$term = $this->mock(LocalizedTerm::class, function (MockInterface $mock): void {
$mock->shouldReceive('get')->with('structured_data_templates')->andReturn([]);
$mock->shouldReceive('augmentedValue')->with('structured_data_templates')->andReturn([]);
});

$parser = $this->mock(StructuredDataParser::class);
Expand All @@ -238,7 +254,7 @@ public function get_json_ld_scripts_skips_invalid_schemas(): void
$entry = (new Entry)
->collection($collection)
->id('entry-123')
->set('structured_data_templates', ['template-123']);
->set('structured_data_templates', $this->templatesCollection(['template-123']));

$template = (new Entry)
->collection($templatesCollection)
Expand Down Expand Up @@ -275,7 +291,7 @@ public function get_json_ld_scripts_handles_exceptions(): void
$entry = (new Entry)
->collection($collection)
->id('entry-123')
->set('structured_data_templates', ['template-123']);
->set('structured_data_templates', $this->templatesCollection(['template-123']));

$template = (new Entry)
->collection($templatesCollection)
Expand Down Expand Up @@ -615,7 +631,7 @@ public function get_templates_handles_entry(): void
$entry = (new Entry)
->collection($collection)
->id('entry-123')
->set('structured_data_templates', ['template-123', 'template-456']);
->set('structured_data_templates', $this->templatesCollection(['template-123', 'template-456']));

$parser = $this->mock(StructuredDataParser::class);
/** @var StructuredDataParser $parser */
Expand All @@ -640,7 +656,7 @@ public function get_templates_handles_page(): void
$entry = (new Entry)
->collection($collection)
->id('entry-123')
->set('structured_data_templates', ['template-123']);
->set('structured_data_templates', $this->templatesCollection(['template-123']));

$page = $this->mock(Page::class, function (MockInterface $mock) use ($entry): void {
$mock->shouldReceive('entry')->andReturn($entry);
Expand All @@ -666,7 +682,9 @@ public function get_templates_handles_localized_term(): void
$taxonomy = TaxonomyFacade::make('categories');
$taxonomy->save();
$term = $this->mock(LocalizedTerm::class, function (MockInterface $mock): void {
$mock->shouldReceive('get')->with('structured_data_templates')->andReturn(['template-123']);
$mock->shouldReceive('augmentedValue')->with('structured_data_templates')->andReturn(
$this->templatesCollection(['template-123'])
);
});

$parser = $this->mock(StructuredDataParser::class);
Expand Down Expand Up @@ -725,7 +743,7 @@ public function get_json_ld_scripts_skips_non_array_parsed_schemas(): void
$entry = (new Entry)
->collection($collection)
->id('entry-123')
->set('structured_data_templates', ['template-123']);
->set('structured_data_templates', $this->templatesCollection(['template-123']));

$template = (new Entry)
->collection($templatesCollection)
Expand Down
Loading