fixed materiau samples mélange bug
This commit is contained in:
@@ -16,7 +16,7 @@ type: materio_samples_field
|
|||||||
settings: { }
|
settings: { }
|
||||||
module: materio_samples
|
module: materio_samples
|
||||||
locked: false
|
locked: false
|
||||||
cardinality: 4
|
cardinality: -1
|
||||||
translatable: true
|
translatable: true
|
||||||
indexes: { }
|
indexes: { }
|
||||||
persist_with_no_fields: false
|
persist_with_no_fields: false
|
||||||
|
|||||||
+124
-106
@@ -5,7 +5,7 @@ namespace Drupal\materio_samples\Plugin\Field\FieldWidget;
|
|||||||
use Drupal\Core\Field\FieldItemListInterface;
|
use Drupal\Core\Field\FieldItemListInterface;
|
||||||
use Drupal\Core\Field\WidgetBase;
|
use Drupal\Core\Field\WidgetBase;
|
||||||
use Drupal\Core\Form\FormStateInterface;
|
use Drupal\Core\Form\FormStateInterface;
|
||||||
use Drupal\taxonomy\Entity\Term;
|
use Drupal\user\Entity\User;
|
||||||
use Drupal\workflow\Entity\WorkflowManager;
|
use Drupal\workflow\Entity\WorkflowManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -23,130 +23,148 @@ use Drupal\workflow\Entity\WorkflowManager;
|
|||||||
class SamplesDefaultWidget extends WidgetBase {
|
class SamplesDefaultWidget extends WidgetBase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* Loads the showroom terms in a deterministic order.
|
||||||
|
*
|
||||||
|
* A stable secondary sort on tid avoids the non-deterministic ordering of
|
||||||
|
* terms sharing the same weight.
|
||||||
|
*
|
||||||
|
* @return \Drupal\taxonomy\Entity\Term[]
|
||||||
|
* The showroom terms keyed by term id.
|
||||||
*/
|
*/
|
||||||
public function form(FieldItemListInterface $items, array &$form, FormStateInterface $form_state, $get_delta = NULL) {
|
protected function getShowroomTerms() {
|
||||||
// construct "manually" the list of items
|
|
||||||
$vid = $this->fieldDefinition->getSetting('vid');
|
$vid = $this->fieldDefinition->getSetting('vid');
|
||||||
$query = \Drupal::entityQuery('taxonomy_term')
|
$storage = \Drupal::entityTypeManager()->getStorage('taxonomy_term');
|
||||||
->sort('weight', 'DESC')
|
$tids = $storage->getQuery()
|
||||||
// ->sort('tid', 'DESC')
|
->condition('vid', $vid)
|
||||||
->accessCheck()
|
->sort('weight', 'DESC')
|
||||||
->condition('vid', $vid);
|
->sort('tid', 'ASC')
|
||||||
$tids = $query->execute();
|
->accessCheck(FALSE)
|
||||||
$terms = Term::loadMultiple($tids);
|
->execute();
|
||||||
|
return $storage->loadMultiple($tids);
|
||||||
|
}
|
||||||
|
|
||||||
// define the cardinality, this will remove the add_more btn
|
/**
|
||||||
$this->fieldDefinition->getFieldStorageDefinition()->setCardinality(count($terms));
|
* Returns the showroom ids owned by the current user (field_showroom).
|
||||||
|
*
|
||||||
$locations = [];
|
* @return array
|
||||||
foreach ($items as $delta => $item) {
|
* An array keyed by showroom term id.
|
||||||
$locations[$item->target_id] = $item->location;
|
*/
|
||||||
}
|
protected function getOwnedShowroomIds() {
|
||||||
|
$owned = [];
|
||||||
$delta = 0;
|
$user = User::load(\Drupal::currentUser()->id());
|
||||||
foreach ($terms as $term) {
|
if ($user) {
|
||||||
// remove masqué
|
foreach ($user->get('field_showroom')->referencedEntities() as $showroom) {
|
||||||
$sid = WorkflowManager::getCurrentStateId($term, 'field_workflow');
|
$owned[$showroom->id()] = TRUE;
|
||||||
if($sid == 'workflow_hidden') continue;
|
|
||||||
$location = isset($locations[$term->id()]) ? $locations[$term->id()] : '';
|
|
||||||
$value = array(
|
|
||||||
'location' => $location,
|
|
||||||
'target_id'=> $term->id()
|
|
||||||
);
|
|
||||||
$items->set($delta, $value);
|
|
||||||
$delta ++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// then call the normal form
|
|
||||||
$elements = parent::form($items, $form, $form_state, $get_delta);
|
|
||||||
// dsm($elements);
|
|
||||||
|
|
||||||
// Arrange the form object to remove draggable table stuff
|
|
||||||
$elements['widget']['#cardinality_multiple'] = FALSE;
|
|
||||||
for ($i=0; $i <= $delta ; $i++) {
|
|
||||||
if(isset($elements['widget'][$i]['_weight'])){
|
|
||||||
$elements['widget'][$i]['_weight']['#type'] = 'hidden';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return $owned;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*
|
||||||
|
* Renders exactly one row per showroom term. The identity of each value is
|
||||||
|
* its target_id: we never reindex by delta nor mutate $items, and we do not
|
||||||
|
* override the storage cardinality.
|
||||||
|
*/
|
||||||
|
protected function formMultipleElements(FieldItemListInterface $items, array &$form, FormStateInterface $form_state) {
|
||||||
|
// Map existing values by showroom id (identity = target_id, not delta).
|
||||||
|
$locations = [];
|
||||||
|
foreach ($items as $item) {
|
||||||
|
if (!$item->isEmpty() && $item->target_id) {
|
||||||
|
$locations[$item->target_id] = $item->location;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$language = \Drupal::languageManager()->getCurrentLanguage()->getId();
|
||||||
|
$entity_repository = \Drupal::service('entity.repository');
|
||||||
|
$can_edit_any = \Drupal::currentUser()->hasPermission('materio_samples_edit_any_sample');
|
||||||
|
$owned = $this->getOwnedShowroomIds();
|
||||||
|
|
||||||
|
$elements = [];
|
||||||
|
$delta = 0;
|
||||||
|
foreach ($this->getShowroomTerms() as $term) {
|
||||||
|
$tid = $term->id();
|
||||||
|
$is_hidden = WorkflowManager::getCurrentStateId($term, 'field_workflow') === 'workflow_hidden';
|
||||||
|
$location = $locations[$tid] ?? '';
|
||||||
|
|
||||||
|
// Preserve values of workflow-hidden showrooms so a save never drops
|
||||||
|
// them, but do not display an editable row.
|
||||||
|
if ($is_hidden) {
|
||||||
|
if ($location !== '') {
|
||||||
|
$elements[$delta] = [
|
||||||
|
'target_id' => ['#type' => 'value', '#value' => $tid],
|
||||||
|
'location' => ['#type' => 'value', '#value' => $location],
|
||||||
|
];
|
||||||
|
$delta++;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$term_trans = $entity_repository->getTranslationFromContext($term, $language);
|
||||||
|
$disabled = !($can_edit_any || isset($owned[$tid]));
|
||||||
|
|
||||||
|
$elements[$delta] = [
|
||||||
|
// target_id is a non-editable value: it always round-trips and cannot
|
||||||
|
// be tampered with, keeping location <-> showroom paired.
|
||||||
|
'target_id' => ['#type' => 'value', '#value' => $tid],
|
||||||
|
'location' => [
|
||||||
|
'#type' => 'textfield',
|
||||||
|
'#title' => $term_trans->getName(),
|
||||||
|
'#default_value' => $location,
|
||||||
|
'#size' => 10,
|
||||||
|
'#maxlength' => 15,
|
||||||
|
'#disabled' => $disabled,
|
||||||
|
'#attributes' => ['class' => ['container-inline']],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
$delta++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// #cardinality_multiple = FALSE => the field_multiple_value_form theme
|
||||||
|
// renders each row as-is, with no draggable table, no weight, no
|
||||||
|
// add-more/remove buttons.
|
||||||
|
$elements += [
|
||||||
|
'#theme' => 'field_multiple_value_form',
|
||||||
|
'#field_name' => $this->fieldDefinition->getName(),
|
||||||
|
'#cardinality' => $this->fieldDefinition->getFieldStorageDefinition()->getCardinality(),
|
||||||
|
'#cardinality_multiple' => FALSE,
|
||||||
|
'#required' => $this->fieldDefinition->isRequired(),
|
||||||
|
'#title' => $this->fieldDefinition->getLabel(),
|
||||||
|
'#description' => $this->getFilteredDescription(),
|
||||||
|
'#max_delta' => $delta > 0 ? $delta - 1 : 0,
|
||||||
|
];
|
||||||
|
|
||||||
return $elements;
|
return $elements;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
|
*
|
||||||
|
* Required by WidgetBase but unused: the whole widget is built in
|
||||||
|
* formMultipleElements().
|
||||||
*/
|
*/
|
||||||
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
|
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
|
||||||
$language = \Drupal::languageManager()->getCurrentLanguage()->getId();
|
|
||||||
|
|
||||||
// get default values
|
|
||||||
$target_id = isset($items[$delta]->target_id) ? $items[$delta]->target_id : 0;
|
|
||||||
$location = isset($items[$delta]->location) ? $items[$delta]->location : '';
|
|
||||||
// dsm($target_id);
|
|
||||||
|
|
||||||
// return nothing if target_id is null
|
|
||||||
if(!$target_id) return;
|
|
||||||
|
|
||||||
$term = Term::load($target_id);
|
|
||||||
|
|
||||||
// translate the term
|
|
||||||
$term = \Drupal::service('entity.repository')->getTranslationFromContext($term, $language);
|
|
||||||
|
|
||||||
// dsm($element);
|
|
||||||
// $element['#attributes'] = array('class' => array('container-inline'));
|
|
||||||
// $element['container'] = [
|
|
||||||
// '#type' => 'container',
|
|
||||||
// '#field_prefix' => '<div class="container-inline">',
|
|
||||||
// '#field_suffix' => '</div>',
|
|
||||||
// ];
|
|
||||||
|
|
||||||
$disabled = true;
|
|
||||||
// get current user
|
|
||||||
$user = \Drupal\user\Entity\User::load(\Drupal::currentUser()->id());
|
|
||||||
if($user->hasPermission('materio_samples_edit_any_sample')){
|
|
||||||
// check perms to edit any
|
|
||||||
$disabled = false;
|
|
||||||
}else if($disabled){
|
|
||||||
// get user showroom if any
|
|
||||||
$showrooms = $user->get('field_showroom')->referencedEntities();
|
|
||||||
// enable/disable field reagarding showroom
|
|
||||||
foreach($showrooms as $showroom){
|
|
||||||
if($term->id() == $showroom->id()){
|
|
||||||
$disabled = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$element['target_id'] = [
|
|
||||||
'#type' => 'hidden',
|
|
||||||
'#default_value' => $target_id,
|
|
||||||
];
|
|
||||||
$element['location'] = [
|
|
||||||
'#title' => $term->getName(),
|
|
||||||
'#type' => 'textfield',
|
|
||||||
'#default_value' => $location,
|
|
||||||
'#size' => 10,
|
|
||||||
'#maxlength' => 15,
|
|
||||||
'#attributes' => ['class' => ['container-inline']],
|
|
||||||
'#disabled' => $disabled,
|
|
||||||
];
|
|
||||||
// return ['value' => $element];
|
|
||||||
return $element;
|
return $element;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function validate($element, FormStateInterface $form_state) {
|
|
||||||
// dsm($element);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function massageFormValues(array $values, array $form, FormStateInterface $form_state) {
|
public function massageFormValues(array $values, array $form, FormStateInterface $form_state) {
|
||||||
// foreach ($values as $key => $value) {
|
// Keep only the two real properties, correctly paired, and drop helper keys
|
||||||
// $values[$key]['value']['target_id'] = (int)$values[$key]['value']['target_id'];
|
// (_weight, _original_delta) added by the core value extraction.
|
||||||
// }
|
$massaged = [];
|
||||||
// dsm($values);
|
foreach ($values as $value) {
|
||||||
return $values;
|
if (empty($value['target_id'])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$massaged[] = [
|
||||||
|
'target_id' => (int) $value['target_id'],
|
||||||
|
'location' => $value['location'] ?? '',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return $massaged;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user