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

5 #28

Closed
wants to merge 23 commits into from
28 changes: 28 additions & 0 deletions config/schema/rethinkdb.schema.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,31 @@
field.storage_settings.rethinkdb:
type: mapping
label: 'RethinkDB reference storage settings'
mapping:
target_type:
type: string
label: 'Type of entity to reference'
handler:
type: string
label: 'Type of entity to reference'
handler_settings:
type: string
label: 'Type of entity to reference'

field.field_settings.rethinkdb:
type: mapping
label: 'RethinkDB refernec field settings'
mapping:
handler:
type: string
label: 'Type of entity to reference'
handler_settings:
type: mapping
mapping:
search_key:
type: string
label: 'foo'

rethinkdb.database:
type: config_object
label: 'RethinkDB Config config'
Expand Down
7 changes: 5 additions & 2 deletions modules/rethinkdb_example/src/Entity/RethinkMessages.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@
* label = @Translation("RethinkDB messages"),
* base_table = "rethinkdb_messages",
* translatable = FALSE,
* reference = "rethinkdb",
* entity_keys = {
* "id" = "id"
* },
* handlers = {
* "storage" = "Drupal\rethinkdb\RethinkStorage"
* },
* entity_keys = {}
* }
* )
*/
class RethinkMessages extends AbstractRethinkDbEntity {
Expand Down
19 changes: 19 additions & 0 deletions rethinkdb.module
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

/**
* Implements hook_field_widget_info_alter().
*/
function rethinkdb_field_widget_info_alter(array &$info) {

// Notify entity reference widget filed they apply to RethinkDB field as well.
$fields = [
'options_select',
'options_buttons',
'entity_reference_autocomplete',
'entity_reference_autocomplete_tags',
];

foreach ($fields as $field) {
$info[$field]['field_types'][] = 'rethinkdb';
}
}
10 changes: 9 additions & 1 deletion src/Entity/AbstractRethinkDbEntity.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\StringTranslation\TranslatableMarkup;

/**
* Wrapping the base content entity class. This is used when we need to add
Expand Down Expand Up @@ -63,7 +65,13 @@ public function delete() {
}

public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
return [];
$fields = [];
$fields[$entity_type->getKey('id')] = BaseFieldDefinition::create('string')
->setLabel(new TranslatableMarkup('ID'))
->setReadOnly(TRUE)
->setSetting('unsigned', TRUE);

return $fields;
}

}
9 changes: 8 additions & 1 deletion src/Entity/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class Query extends QueryBase implements QueryInterface {
'<' => 'lt',
'<=' => 'le',
'CONTAINS' => 'match',
'IN' => 'args',
];

/**
Expand Down Expand Up @@ -65,7 +66,13 @@ protected function addConditions() {
throw new RqlException("The operator {$operator} does not allowed. Only " . implode(', ', array_keys($this->operators)));
}

$row = \r\row($condition['field'])->{$this->operators[$operator]}($condition['value']);
if ($operator == 'IN') {
$row = \r\args($condition['value']);
}
else {
$row = \r\row($condition['field'])->{$this->operators[$operator]}($condition['value']);
}

$this->table = $this->table->filter($row);
}

Expand Down
148 changes: 148 additions & 0 deletions src/Plugin/EntityReferenceSelection/RethinkDBSelection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
<?php

namespace Drupal\rethinkdb\Plugin\EntityReferenceSelection;

use Drupal\Component\Utility\Html;
use Drupal\Core\Database\Query\SelectInterface;
use Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection;
use Drupal\Core\Form\FormStateInterface;

/**
* Plugin implementation of the 'selection' entity_reference for RethinkDB.
*
* @EntityReferenceSelection(
* id = "rethinkdb",
* label = @Translation("RethinkDB entities selection based"),
* group = "rethinkdb"
* )
*/
class RethinkDBSelection extends DefaultSelection {

/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$form = [];

$key = empty($this->configuration['handler_settings']['search_key']) ? '' : $this->configuration['handler_settings']['search_key'];
$form['search_key'] = [
'#type' => 'textfield',
'#title' => $this->t('Search field'),
'#description' => $this->t('The key on which the query will match the text to input of the user.'),
'#default_value' => $key,
'#required' => TRUE,
];

return $form;
}

/**
* {@inheritdoc}
*/
public function getReferenceableEntities($match = NULL, $match_operator = 'CONTAINS', $limit = 0) {
$query = $this->buildEntityQuery($match, $match_operator);
if ($limit > 0) {
$query->range(0, $limit);
}

$entity_ids = $query->execute();

if (empty($entity_ids)) {
return array();
}

$entities = \Drupal::entityTypeManager()
->getStorage($this->configuration['target_type'])
->loadMultiple($entity_ids);

$handler_settings = $this->configuration['handler_settings'];
$options = array();

foreach ($entities as $entity) {
$value = $entity->getValues();
$options[$this->configuration['target_type']][$value['id']] = Html::escape($value[$handler_settings['search_key']]);
}

return $options;
}

/**
* {@inheritdoc}
*/
public function countReferenceableEntities($match = NULL, $match_operator = 'CONTAINS') {
return $this->buildEntityQuery($match, $match_operator)
->count()
->execute();
}

/**
* {@inheritdoc}
*/
public function validateReferenceableEntities(array $ids) {
$result = array();

if ($ids) {
return $this->buildEntityQuery()
->condition('id', reset($ids))
->execute();
}

return $result;
}

/**
* {@inheritdoc}
*/
public function validateReferenceableNewEntities(array $entities) {
return array_filter($entities, function ($entity) {
if (isset($this->configuration['handler_settings']['target_bundles'])) {
return in_array($entity->bundle(), $this->configuration['handler_settings']['target_bundles']);
}
return TRUE;
});
}

/**
* Builds an EntityQuery to get referenceable entities.
*
* @param string|null $match
* (Optional) Text to match the label against. Defaults to NULL.
* @param string $match_operator
* (Optional) The operation the matching should be done with. Defaults
* to "CONTAINS".
*
* @return \Drupal\Core\Entity\Query\QueryInterface
* The EntityQuery object with the basic conditions and sorting applied to
* it.
*/
protected function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
$handler_settings = $this->configuration['handler_settings'];

$query = $this->entityManager->getStorage($this->configuration['target_type'])->getQuery();

if (isset($match)) {
if ($match_operator == '=' && preg_match("/.+\s\((\S+)\)/", $match, $matches)) {
$query->condition('id', $matches[1], $match_operator);
}
else {
$query->condition($handler_settings['search_key'], $match, $match_operator);
}
}

// Add the sort option.
if (!empty($handler_settings['sort'])) {
$sort_settings = $handler_settings['sort'];
if ($sort_settings['field'] != '_none') {
$query->sort($sort_settings['field'], $sort_settings['direction']);
}
}

return $query;
}

/**
* {@inheritdoc}
*/
public function entityQueryAlter(SelectInterface $query) { }

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

namespace Drupal\rethinkdb\Plugin\Field\FieldFormatter;

use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Form\FormStateInterface;

/**
* Plugin for displaying RethinkDB referenced document property.
*
* @FieldFormatter(
* id = "rethinkdb_entity_reference",
* label = @Translation("RethinkDB document property"),
* description = @Translation("Display a specific property of the document."),
* field_types = {
* "rethinkdb"
* }
* )
*/
class RethinkDbEntityReferenceFieldFormatter extends FormatterBase {

/**
* {@inheritdoc}
*/
public static function defaultSettings() {
return array(
'key' => '',
) + parent::defaultSettings();
}

/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$elements['key'] = array(
'#type' => 'textfield',
'#title' => t('Property name'),
'#description' => $this->t('Which key of the document would you like to display.'),
'#default_value' => $this->getSetting('key'),
'#required' => TRUE,
);

return $elements;
}

/**
* {@inheritdoc}
*/
public function settingsSummary() {
$summary = array();

if ($key = $this->getSetting('key')) {
$params = [
'%key' => $key,
];
$text = $this->t('Display %key from the JSON document', $params);
}
else {
$text = t('No property to display');
}

$summary[] = $text;

return $summary;
}

/**
* {@inheritdoc}
*/
public function viewElements(FieldItemListInterface $items, $langcode) {
$elements = [];

foreach ($items as $item) {
$entity = $item->getValue();
$values = $entity->getValues();
$elements[] = [
'#plain_text' => $values[$this->getSetting('key')],
];
}

return $elements;
}

}
24 changes: 24 additions & 0 deletions src/Plugin/Field/FieldType/RethinkDBFieldItemList.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace Drupal\rethinkdb\Plugin\Field\FieldType;

use Drupal\Core\Field\EntityReferenceFieldItemList;
use Drupal\Core\Form\FormStateInterface;

/**
* Represents a configurable entity file field.
*/
class RethinkDBFieldItemList extends EntityReferenceFieldItemList {

/**
* {@inheritdoc}
*/
public function defaultValuesForm(array &$form, FormStateInterface $form_state) { }

/**
* {@inheritdoc}
*/
public function getConstraints() {
return [];
}
}
Loading