-
Notifications
You must be signed in to change notification settings - Fork 32
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
Typed Relation #3
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
df7ffdd
add token requirement
seth-shaw-unlv f72321d
add TypedRelation field
seth-shaw-unlv 8118167
added field_linked_agent
seth-shaw-unlv 2411c11
coding standards
seth-shaw-unlv a8890f7
more schema relationship predicates
seth-shaw-unlv 2c20cbe
remove unused variable
seth-shaw-unlv File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
46 changes: 46 additions & 0 deletions
46
config/install/field.field.node.person.field_linked_agent.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
uuid: f7e611af-b0d6-4325-81dc-52839a6c56be | ||
langcode: en | ||
status: true | ||
dependencies: | ||
config: | ||
- field.storage.node.field_linked_agent | ||
- node.type.corporate_body | ||
- node.type.family | ||
- node.type.person | ||
module: | ||
- controlled_access_terms | ||
id: node.person.field_linked_agent | ||
field_name: field_linked_agent | ||
entity_type: node | ||
bundle: person | ||
label: 'Linked Agent' | ||
description: '' | ||
required: false | ||
translatable: false | ||
default_value: { } | ||
default_value_callback: '' | ||
settings: | ||
handler: 'default:node' | ||
handler_settings: | ||
target_bundles: | ||
corporate_body: corporate_body | ||
family: family | ||
person: person | ||
sort: | ||
field: _none | ||
auto_create: 0 | ||
auto_create_bundle: family | ||
rel_types: | ||
'schema:knows': Knows | ||
'schema:alumniOf': Alumni Of | ||
'schema:children': Children | ||
'schema:colleague': Colleague | ||
'schema:follows': Follows | ||
'schema:knowsAbout': Knows About | ||
'schema:parent': Parent | ||
'schema:relatedTo': Related To | ||
'schema:sibling': Sibling | ||
'schema:sponsor': Sponsor | ||
'schema:spouse': Spouse | ||
'schema:worksFor': Works For (use only with Corporate Bodies) | ||
field_type: typed_relation |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
uuid: 5eadb639-a448-437d-b048-e2b92b040cf6 | ||
langcode: en | ||
status: true | ||
dependencies: | ||
module: | ||
- controlled_access_terms | ||
- node | ||
id: node.field_linked_agent | ||
field_name: field_linked_agent | ||
entity_type: node | ||
type: typed_relation | ||
settings: | ||
target_type: node | ||
module: controlled_access_terms | ||
locked: false | ||
cardinality: -1 | ||
translatable: true | ||
indexes: { } | ||
persist_with_no_fields: false | ||
custom_storage: false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,3 +8,4 @@ dependencies: | |
- name | ||
- auto_entitylabel | ||
- geolocation | ||
- token |
38 changes: 38 additions & 0 deletions
38
src/Plugin/Field/FieldFormatter/TypedRelationFormatter.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<?php | ||
|
||
namespace Drupal\controlled_access_terms\Plugin\Field\FieldFormatter; | ||
|
||
use Drupal\Core\Field\Plugin\Field\FieldFormatter\EntityReferenceLabelFormatter; | ||
use Drupal\Core\Field\FieldItemListInterface; | ||
|
||
/** | ||
* Plugin implementation of the 'TypedRelationFormatter'. | ||
* | ||
* @FieldFormatter( | ||
* id = "typed_relation_default", | ||
* label = @Translation("Typed Relation Formatter"), | ||
* field_types = { | ||
* "typed_relation" | ||
* } | ||
* ) | ||
*/ | ||
class TypedRelationFormatter extends EntityReferenceLabelFormatter { | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function viewElements(FieldItemListInterface $items, $langcode) { | ||
$elements = parent::viewElements($items, $langcode); | ||
|
||
foreach ($items as $delta => $item) { | ||
|
||
$rel_types = $item->getRelTypes(); | ||
$rel_type = isset($rel_types[$item->rel_type]) ? $rel_types[$item->rel_type] : $item->rel_type; | ||
|
||
$elements[$delta]['#prefix'] = $rel_type . ': '; | ||
} | ||
|
||
return $elements; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
<?php | ||
|
||
namespace Drupal\controlled_access_terms\Plugin\Field\FieldType; | ||
|
||
use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem; | ||
use Drupal\Core\Field\FieldStorageDefinitionInterface; | ||
use Drupal\Core\Form\FormStateInterface; | ||
use Drupal\Core\Render\Element\FormElement; | ||
use Drupal\Core\TypedData\DataDefinition; | ||
|
||
/** | ||
* Implements a Typed Relation field. | ||
* | ||
* @FieldType( | ||
* id = "typed_relation", | ||
* label = @Translation("Typed Relation"), | ||
* module = "controlled_access_terms", | ||
* description = @Translation("Implements a typed relation field"), | ||
* default_formatter = "typed_relation_default", | ||
* default_widget = "typed_relation_default", | ||
* list_class = "\Drupal\Core\Field\EntityReferenceFieldItemList", | ||
* ) | ||
*/ | ||
class TypedRelation extends EntityReferenceItem { | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public static function schema(FieldStorageDefinitionInterface $field_definition) { | ||
$schema = parent::schema($field_definition); | ||
$schema['columns']['rel_type'] = [ | ||
'type' => 'text', | ||
'size' => 'tiny', | ||
'not null' => TRUE, | ||
]; | ||
|
||
return $schema; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) { | ||
$properties = parent::propertyDefinitions($field_definition); | ||
$properties['rel_type'] = DataDefinition::create('string') | ||
->setLabel(t('Type')) | ||
->setRequired(TRUE); | ||
|
||
return $properties; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function isEmpty() { | ||
$parentEmpty = parent::isEmpty(); | ||
|
||
// All must have a value. | ||
if ($this->rel_type !== NULL && | ||
!empty($this->rel_type) && | ||
!($parentEmpty) | ||
) { | ||
return FALSE; | ||
} | ||
|
||
return TRUE; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public static function defaultFieldSettings() { | ||
return ['rel_types' => []] + parent::defaultFieldSettings(); | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function fieldSettingsForm(array $form, FormStateInterface $form_state) { | ||
$element = parent::fieldSettingsForm($form, $form_state); | ||
|
||
$element['rel_types'] = [ | ||
'#type' => 'textarea', | ||
'#title' => t('Available Relations'), | ||
'#default_value' => $this->encodeTextSettingsField($this->getSetting('rel_types')), | ||
'#element_validate' => [[get_class($this), 'validateValues']], | ||
'#required' => TRUE, | ||
'#min' => 1, | ||
'#description' => '<p>' . t('Enter one value per line, in the format key|label.') . | ||
'<br/>' . t('The key is the stored value. The label will be used in displayed values and edit forms.') . | ||
'<br/>' . t("Keys may not contain dots ('.'). They will be removed if used.") . | ||
'<br/>' . t('The label is optional: if a line contains a single string, it will be used as key and label.') . | ||
'</p>', | ||
]; | ||
|
||
return $element; | ||
} | ||
|
||
/** | ||
* Convience method allowing the Formatter to get the rel_types. | ||
* | ||
* @return array | ||
* The array of relation types | ||
*/ | ||
public function getRelTypes() { | ||
return $this->getSetting('rel_types'); | ||
} | ||
|
||
/** | ||
* Encodes pipe-delimited key/value pairs. | ||
* | ||
* @param array $settings | ||
* The array of key/value pairs to encode. | ||
* | ||
* @return string | ||
* The string of encoded key/value pairs. | ||
*/ | ||
protected function encodeTextSettingsField(array $settings) { | ||
$output = ''; | ||
foreach ($settings as $key => $value) { | ||
$output .= "$key|$value\n"; | ||
} | ||
return $output; | ||
} | ||
|
||
/** | ||
* Extracts pipe-delimited key/value pairs. | ||
* | ||
* @param string $string | ||
* The raw string to extract values from. | ||
* | ||
* @return array|null | ||
* The array of extracted key/value pairs, or NULL if the string is invalid. | ||
* | ||
* @see \Drupal\options\Plugin\Field\FieldType\ListItemBase::extractAllowedValues() | ||
*/ | ||
protected static function extractPipedValues($string) { | ||
$values = []; | ||
|
||
$list = explode("\n", $string); | ||
$list = array_map('trim', $list); | ||
$list = array_filter($list, 'strlen'); | ||
|
||
foreach ($list as $position => $text) { | ||
// Check for an explicit key. | ||
$matches = []; | ||
if (preg_match('/(.*)\|(.*)/', $text, $matches)) { | ||
// Trim key and value to avoid unwanted spaces issues. | ||
// Also remove dots in keys (which aren't permitted.) | ||
$key = str_replace('.', '', trim($matches[1])); | ||
$value = trim($matches[2]); | ||
} | ||
// Otherwise use the value as key and value. | ||
else { | ||
$key = $value = $text; | ||
} | ||
|
||
$values[$key] = $value; | ||
} | ||
|
||
return $values; | ||
} | ||
|
||
/** | ||
* Callback for settings form. | ||
* | ||
* @param \Drupal\Core\Render\Element\FormElement $element | ||
* An associative array containing the properties and children of the | ||
* generic form element. | ||
* @param \Drupal\Core\Form\FormStateInterface $form_state | ||
* The current state of the form for the form this element belongs to. | ||
* | ||
* @see \Drupal\Core\Render\Element\FormElement::processPattern() | ||
*/ | ||
public static function validateValues(FormElement $element, FormStateInterface $form_state) { | ||
$values = static::extractPipedValues($element['#value']); | ||
|
||
if (!is_array($values)) { | ||
$form_state->setError($element, t('Allowed values list: invalid input.')); | ||
} | ||
else { | ||
// We may want to validate key values in the future... | ||
$form_state->setValueForElement($element, $values); | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand what is going on here. Is this adding in the schema? Could/should this be a yaml file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to the Drupal 8 "Create a custom field type" documentation: "FieldItemInterface::schema() should be overridden, in order to tell the system how to store the value(s) for the field." Every example of custom fields I've seen does it.