Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[4.x] Add option to link entries by slug #8877

Closed
Closed
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
1 change: 1 addition & 0 deletions resources/lang/en/fieldtypes.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
'date.title' => 'Date',
'entries.config.create' => 'Allow creation of new entries.',
'entries.config.collections' => 'Choose which collections the user can select from.',
'entries.config.link_by' => 'Choose what field to use to link items. If you choose slug make sure slugs are unique in your linked collection(s).',
'entries.config.query_scopes' => 'Choose which query scopes should be applied when retrieving selectable entries.',
'entries.config.search_index' => 'An appropriate search index will be used automatically where possible, but you may define an explicit one.',
'entries.title' => 'Entries',
Expand Down
49 changes: 49 additions & 0 deletions src/Fieldtypes/Entries.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,16 @@ protected function configFieldItems(): array
'instructions' => __('statamic::fieldtypes.entries.config.query_scopes'),
'type' => 'taggable',
],
'link_by' => [
'display' => __('Link By'),
'instructions' => __('statamic::fieldtypes.entries.config.link_by'),
'type' => 'select',
'default' => 'id',
'options' => [
'id' => __('ID'),
'slug' => __('Slug'),
],
],
],
],
];
Expand Down Expand Up @@ -313,6 +323,10 @@ public function augment($values)
$site = $parent->locale();
}

if ($this->config('link_by') == 'slug') {
$values = $this->replaceSlugsWithIds($values);
}

$ids = (new OrderedQueryBuilder(Entry::query(), $ids = Arr::wrap($values)))
->whereIn('id', $ids)
->get()
Expand Down Expand Up @@ -394,6 +408,41 @@ public function filter()
return new EntriesFilter($this);
}

public function process($data)
{
$data = parent::process($data);

if ($this->config('link_by') == 'slug') {
$data = collect($data)->map(function ($item) {
if ($entry = Entry::find($item)) {
return $entry->slug();
}
})->filter()->all();
}

return $data;
}

public function preProcess($data)
{
$data = parent::preProcess($data);

if ($this->config('link_by') == 'slug') {
$data = $this->replaceSlugsWithIds($data);
}

return $data;
}

private function replaceSlugsWithIds($data)
{
return collect($data)->map(function ($item) {
if ($entry = Entry::query()->whereIn('collection', $this->getConfiguredCollections())->where('slug', $item)->first()) {
return $entry->id();
}
})->filter()->all();
}

public function preload()
{
$collection = count($this->getConfiguredCollections()) === 1
Expand Down
22 changes: 22 additions & 0 deletions src/Tags/Concerns/QueriesConditions.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ protected function queryCondition($query, $field, $condition, $value)
return $this->queryInCondition($query, $field, $value);
case 'not_in':
return $this->queryNotInCondition($query, $field, $value);
case 'includes':
return $this->queryIncludesCondition($query, $field, $value);
case 'doesnt_include':
return $this->queryDoesntIncludeCondition($query, $field, $value);
case 'starts_with':
case 'begins_with':
return $this->queryStartsWithCondition($query, $field, $value);
Expand Down Expand Up @@ -161,6 +165,24 @@ protected function queryNotInCondition($query, $field, $value)
return $query->whereNotIn($field, $value);
}

protected function queryIncludesCondition($query, $field, $value)
{
if (is_string($value)) {
$value = $this->getPipedValues($value);
}

return $query->whereJsonContains($field, $value);
}

protected function queryDoesntIncludeCondition($query, $field, $value)
{
if (is_string($value)) {
$value = $this->getPipedValues($value);
}

return $query->whereJsonDoesntContain($field, $value);
}

protected function queryStartsWithCondition($query, $field, $value)
{
return $query->where($field, 'like', "{$value}%");
Expand Down
Loading