Skip to content

Commit

Permalink
Merge pull request #816 from hydephp/improve-make-publication-type-co…
Browse files Browse the repository at this point in the history
…mmand-to-better-integrate-pagination-settings

Refactor publication types to simplify the code and integrate publication pagination settings
  • Loading branch information
caendesilva authored Jan 8, 2023
2 parents 5a61b0a + 1281054 commit 26ac554
Show file tree
Hide file tree
Showing 16 changed files with 153 additions and 135 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@ public function safeHandle(): int

$this->fields = $this->captureFieldsDefinitions();

[$sortField, $sortAscending, $prevNextLinks, $pageSize] = ($this->getPaginationSettings());
[$sortField, $sortAscending, $pageSize] = ($this->getPaginationSettings());

$canonicalField = $this->getCanonicalField();

$creator = new CreatesNewPublicationType($title, $this->fields, $canonicalField->name, $sortField, $sortAscending, $prevNextLinks, $pageSize);
$creator = new CreatesNewPublicationType($title, $this->fields, $canonicalField->name, $sortField, $sortAscending, $pageSize);
$this->output->writeln("Saving publication data to [{$creator->getOutputPath()}]");
$creator->create();

Expand Down Expand Up @@ -188,16 +188,18 @@ protected function addCreatedAtMetaField(): void

protected function getPaginationSettings(): array
{
if ($this->option('use-defaults') || ! $this->confirm('Do you want to configure pagination settings?')) {
return [null, null, null, null];
if ($this->option('use-defaults') || ! $this->confirm('Would you like to enable pagination?')) {
return [null, null, null];
}

return [$this->getSortField(), $this->getSortDirection(), $this->getPrevNextLinks(), $this->getPageSize()];
$this->info("Okay, let's set up pagination! Tip: You can just hit enter to accept the default values.");

return [$this->getSortField(), $this->getSortDirection(), $this->getPageSize()];
}

protected function getSortField(): string
{
return $this->choice('Choose the default field you wish to sort by', $this->fields->pluck('name')->toArray(), '__dateCreated');
return $this->choice('Choose the default field you wish to sort by', $this->fields->pluck('name')->toArray(), 0);
}

protected function getSortDirection(): bool
Expand All @@ -207,11 +209,6 @@ protected function getSortDirection(): bool
return $options[$this->choice('Choose the default sort direction', array_keys($options), 'Ascending')];
}

protected function getPrevNextLinks(): bool
{
return $this->confirm('Generate previous/next links in detail view?', true);
}

protected function getPageSize(): int
{
return (int) $this->askWithValidation('pageSize',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ public function safeHandle(): int
$this->output->write("\n<fg=cyan> Validating publication [$publication->title]</>");
$publication->matter->forget('__createdAt');

foreach ($publication->type->getFieldData() as $field) {
foreach ($publication->type->getFields() as $field) {
$countFields++;
$fieldName = $field['name'];
$pubTypeField = new PublicationFieldDefinition($field['type'], $fieldName);
$fieldName = $field->name;
$pubTypeField = new PublicationFieldDefinition($field->type, $fieldName);

try {
if ($verbose) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ public function __construct(
protected ?string $canonicalField = null,
protected ?string $sortField = null,
protected ?bool $sortAscending = null,
protected ?bool $prevNextLinks = null,
protected ?int $pageSize = null,
) {
$this->directoryName = $this->formatStringForStorage($this->name);
Expand All @@ -43,7 +42,6 @@ protected function handleCreate(): void
[
$this->sortField ?? '__createdAt',
$this->sortAscending ?? true,
$this->prevNextLinks ?? true,
$this->pageSize ?? 25,
],
$this->fields->toArray()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,17 @@ class PaginationSettings implements SerializableContract

public string $sortField = '__createdAt';
public bool $sortAscending = true;
/** @deprecated This setting might be deprecated as its unlikely one would enable page size limits without a way to traverse them */
public bool $prevNextLinks = true;
public int $pageSize = 25;

public static function fromArray(array $data): static
{
return new static(...$data);
}

public function __construct(string $sortField = '__createdAt', bool $sortAscending = true, bool $prevNextLinks = true, int $pageSize = 25)
public function __construct(string $sortField = '__createdAt', bool $sortAscending = true, int $pageSize = 25)
{
$this->sortField = $sortField;
$this->sortAscending = $sortAscending;
$this->prevNextLinks = $prevNextLinks;
$this->pageSize = $pageSize;
}

Expand All @@ -35,7 +32,6 @@ public function toArray(): array
return [
'sortField' => $this->sortField,
'sortAscending' => $this->sortAscending,
'prevNextLinks' => $this->prevNextLinks,
'pageSize' => $this->pageSize,
];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Hyde\Framework\Features\Publications\Models;

use function array_filter;
use function array_merge;
use function dirname;
use Exception;
Expand Down Expand Up @@ -31,11 +32,34 @@ class PublicationType implements SerializableContract
use Serializable;
use InteractsWithDirectories;

public PaginationSettings $pagination;
protected string $directory;
/** The "pretty" name of the publication type */
public string $name;

/**
* The field name that is used as the canonical (or identifying) field of publications.
*
* It's used primarily for generating filenames, and the publications must thus be unique by this field.
*/
public string $canonicalField = '__createdAt';

/** The Blade filename or view identifier used for rendering a single publication */
public string $detailTemplate = 'detail.blade.php';

/** The Blade filename or view identifier used for rendering the index page (or index pages, when using pagination) */
public string $listTemplate = 'list.blade.php';

/** The pagination settings. Set to null to disable pagination. Make sure your list view supports it when enabled. */
public null|PaginationSettings $pagination;

/**
* The front matter fields used for the publications.
*
* @var \Illuminate\Support\Collection<string, \Hyde\Framework\Features\Publications\Models\PublicationFieldDefinition>
*/
public Collection $fields;

/** @var array<array<string, mixed>> */
public array $fields = [];
/** The directory of the publication files */
protected string $directory;

public static function get(string $name): static
{
Expand All @@ -55,38 +79,41 @@ public static function fromFile(string $schemaFile): static
}

public function __construct(
public string $name,
public string $canonicalField = 'identifier',
public string $detailTemplate = 'detail.blade.php',
public string $listTemplate = 'list.blade.php',
array|PaginationSettings $pagination = [],
string $name,
string $canonicalField = '__createdAt',
string $detailTemplate = 'detail.blade.php',
string $listTemplate = 'list.blade.php',
?array $pagination = [],
array $fields = [],
?string $directory = null
) {
$this->fields = $fields;
$this->name = $name;
$this->canonicalField = $canonicalField;
$this->detailTemplate = $detailTemplate;
$this->listTemplate = $listTemplate;
$this->fields = $this->parseFieldData($fields);
$this->directory = $directory ?? Str::slug($name);
$this->pagination = $pagination instanceof PaginationSettings
? $pagination
: PaginationSettings::fromArray($pagination);
$this->pagination = $this->evaluatePaginationSettings($pagination);
}

public function toArray(): array
{
return [
return $this->withoutNullValues([
'name' => $this->name,
'canonicalField' => $this->canonicalField,
'detailTemplate' => $this->detailTemplate,
'listTemplate' => $this->listTemplate,
'pagination' => $this->pagination->toArray(),
'fields' => $this->fields,
];
'pagination' => $this->pagination?->toArray(),
'fields' => $this->fields->toArray(),
]);
}

public function toJson($options = JSON_PRETTY_PRINT): string
{
return json_encode($this->toArray(), $options);
}

/** Get the publication type's identifier */
public function getIdentifier(): string
{
return $this->directory ?? Str::slug($this->name);
Expand All @@ -102,28 +129,14 @@ public function getDirectory(): string
return $this->directory;
}

/**
* Get the raw field definitions for this publication type.
*
* @see self::getFields() to get the deserialized field definitions.
*/
public function getFieldData(): array
{
return $this->fields;
}

/**
* Get the publication fields, deserialized to PublicationFieldDefinition objects.
*
* @see self::getFieldData() to get the raw field definitions.
*
* @return \Illuminate\Support\Collection<string, \Hyde\Framework\Features\Publications\Models\PublicationFieldDefinition>
*/
public function getFields(): Collection
{
return Collection::make($this->fields)->mapWithKeys(function (array $data): array {
return [$data['name'] => new PublicationFieldDefinition(...$data)];
});
return $this->fields;
}

public function getFieldDefinition(string $fieldName): PublicationFieldDefinition
Expand Down Expand Up @@ -188,4 +201,25 @@ protected function getPublicationsSortedByPaginationField(): Collection
return $page->matter($this->pagination->sortField);
}, descending: ! $this->pagination->sortAscending)->values();
}

protected function parseFieldData(array $fields): Collection
{
return Collection::make($fields)->map(function (array $data): PublicationFieldDefinition {
return new PublicationFieldDefinition(...$data);
});
}

protected function evaluatePaginationSettings(array $pagination): ?PaginationSettings
{
if (empty($pagination)) {
return null;
}

return PaginationSettings::fromArray($pagination);
}

protected function withoutNullValues(array $array): array
{
return array_filter($array, fn (mixed $value): bool => ! is_null($value));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ public function test_it_creates_a_new_publication_type()
'canonical',
'sort',
false,
false,
10
);
$creator->create();
Expand All @@ -48,7 +47,6 @@ public function test_it_creates_a_new_publication_type()
"pagination": {
"sortField": "sort",
"sortAscending": false,
"prevNextLinks": false,
"pageSize": 10
},
"fields": []
Expand All @@ -75,7 +73,6 @@ public function test_create_with_default_parameters()
"pagination": {
"sortField": "__createdAt",
"sortAscending": true,
"prevNextLinks": true,
"pageSize": 25
},
"fields": []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,9 @@ public function testWithTagType()
{
$tags = ['test-publication' => ['foo', 'bar', 'baz']];
$this->file('tags.json', json_encode($tags));
$this->pubType->fields = [
(new PublicationFieldDefinition('tag', 'tag', tagGroup: 'test-publication'))->toArray(),
];
$this->pubType->fields = collect([
(new PublicationFieldDefinition('tag', 'tag', tagGroup: 'test-publication')),
]);
$this->pubType->save();
(new SeedsPublicationFiles($this->pubType))->create();

Expand Down Expand Up @@ -187,9 +187,9 @@ protected function firstPublication(): MarkdownDocument

protected function updateSchema(string $type, string $name): void
{
$this->pubType->fields = [
(new PublicationFieldDefinition($type, $name))->toArray(),
];
$this->pubType->fields = collect([
(new PublicationFieldDefinition($type, $name)),
]);
$this->pubType->save();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ public function test_command_selects_the_right_publication_using_the_names()
'listTemplate' => 'list',
'pagination' => [
'pageSize' => 10,
'prevNextLinks' => true,
'sortField' => '__createdAt',
'sortAscending' => true,
],
Expand Down Expand Up @@ -584,7 +583,6 @@ protected function makeSchemaFile(array $merge = []): void
'listTemplate' => 'list',
'pagination' => [
'pageSize' => 10,
'prevNextLinks' => true,
'sortField' => '__createdAt',
'sortAscending' => true,
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public function test_command_creates_publication_type()
'Tag',
], true)
->expectsConfirmation('Field #1 added! Add another field?')
->expectsConfirmation('Do you want to configure pagination settings?', 'yes')
->expectsConfirmation('Would you like to enable pagination?', 'yes')
->expectsChoice('Choose the default field you wish to sort by', '__createdAt', [
'__createdAt',
'publication-title',
Expand All @@ -59,7 +59,6 @@ public function test_command_creates_publication_type()
'Ascending',
'Descending',
])
->expectsConfirmation('Generate previous/next links in detail view?', 'yes')
->expectsQuestion('Enter the page size (0 for no limit)', 10)
->expectsChoice('Choose a canonical name field (this will be used to generate filenames, so the values need to be unique)', 'publication-title', [
'__createdAt',
Expand All @@ -81,7 +80,6 @@ public function test_command_creates_publication_type()
"pagination": {
"sortField": "__createdAt",
"sortAscending": true,
"prevNextLinks": true,
"pageSize": 10
},
"fields": [
Expand Down Expand Up @@ -129,7 +127,7 @@ public function test_with_multiple_fields_of_the_same_name()

->expectsConfirmation('Field #2 added! Add another field?')

->expectsConfirmation('Do you want to configure pagination settings?')
->expectsConfirmation('Would you like to enable pagination?')
->expectsChoice('Choose a canonical name field (this will be used to generate filenames, so the values need to be unique)', 'foo', [
'__createdAt',
'bar',
Expand Down Expand Up @@ -188,7 +186,6 @@ public function testWithTagFieldInput()
"pagination": {
"sortField": "__createdAt",
"sortAscending": true,
"prevNextLinks": true,
"pageSize": 25
},
"fields": [
Expand Down Expand Up @@ -242,7 +239,7 @@ public function testWithTagFieldInputButNoTagsCanPromptToCreateTags()
->expectsOutput("Okay, we're back on track!")
->expectsChoice('Enter tag group for field #1', 'foo', ['foo'], true)
->expectsConfirmation('Field #1 added! Add another field?')
->expectsConfirmation('Do you want to configure pagination settings?')
->expectsConfirmation('Would you like to enable pagination?')
->expectsChoice('Choose a canonical name field (this will be used to generate filenames, so the values need to be unique)', '__createdAt', ['__createdAt'])
->doesntExpectOutput('Error: Can not create a tag field without any tag groups defined in tags.json')
->assertSuccessful();
Expand Down
6 changes: 4 additions & 2 deletions packages/framework/tests/Feature/PublicationListPageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,12 @@ protected function getTestData(): array
'sortField' => 'sort',
'sortAscending' => true,
'pageSize' => 10,
'prevNextLinks' => true,
],
'fields' => [
'foo' => 'bar',
[
'type' => 'string',
'name' => 'Foo',
],
],
];
}
Expand Down
Loading

0 comments on commit 26ac554

Please sign in to comment.