diff --git a/resources/lang/en/fieldtypes.php b/resources/lang/en/fieldtypes.php index b501d28d335..b6c391b416e 100644 --- a/resources/lang/en/fieldtypes.php +++ b/resources/lang/en/fieldtypes.php @@ -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', diff --git a/src/Fieldtypes/Entries.php b/src/Fieldtypes/Entries.php index 8738c3d1f74..5c5cb03f6ef 100644 --- a/src/Fieldtypes/Entries.php +++ b/src/Fieldtypes/Entries.php @@ -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'), + ], + ], ], ], ]; @@ -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() @@ -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 diff --git a/src/Tags/Concerns/QueriesConditions.php b/src/Tags/Concerns/QueriesConditions.php index 019160c8227..162c3987380 100644 --- a/src/Tags/Concerns/QueriesConditions.php +++ b/src/Tags/Concerns/QueriesConditions.php @@ -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); @@ -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}%");