monster_menus-9.0.x-dev/modules/mm_fields/src/Plugin/Field/FieldWidget/MMFieldWidgetBase.php
modules/mm_fields/src/Plugin/Field/FieldWidget/MMFieldWidgetBase.php
<?php
/**
* @file
* Contains \Drupal\mm_fields\Plugin\Field\FieldWidget\MMCatlist.
*/
namespace Drupal\mm_fields\Plugin\Field\FieldWidget;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\monster_menus\Constants;
use Drupal\node\Entity\NodeType;
class MMFieldWidgetBase extends WidgetBase {
/**
* @var $summaries
* Holds the configuration form field summaries generated by
* mmFieldSettingsForm().
*/
protected $summaries = [];
/**
* @var $form
* Holds the configuration form generated by mmFieldSettingsForm().
*/
protected $form = [];
/**
* @inheritdoc
*/
public static function defaultSettings() {
return [
'mm_list_readonly' => FALSE,
'mm_list_show_info' => TRUE,
'mm_list_min' => 0,
'mm_list_max' => 0,
] + parent::defaultSettings();
}
/**
* Get a list of widget types handled by this class. This is used by
* mm_fields_form_field_storage_config_edit_form_alter() to determine if the
* widget whose settings are being edited is one we need to alter.
*/
public static function widgetTypes() {
return ['mm_catlist', 'mm_grouplist', 'mm_userlist', 'mm_nodelist'];
}
/**
* @inheritdoc
*/
public function settingsForm(array $form = NULL, FormStateInterface $form_state = NULL) {
if (empty($this->form)) {
$widget_type = $this->getPluginId();
$this->form = [];
$this->summaries = [];
$this->form['mm_list_readonly'] = [
'#type' => 'checkbox',
'#title' => $this->t('Read-only'),
'#default_value' => $this->getSetting('mm_list_readonly'),
'#description' => $this->t('If checked, the user can see the details of the entries in the list, but not change them'),
];
$this->summaries[] = $this->t('Read-only: @yesno', ['@yesno' => $this->getSetting('mm_list_readonly') ? $this->t('Yes') : $this->t('No')]);
if ($widget_type != 'mm_userlist') {
$this->form['mm_list_show_info'] = [
'#type' => 'checkbox',
'#title' => $this->t('Show an entry\'s details when clicked'),
'#default_value' => $this->getSetting('mm_list_show_info'),
];
if ($this->getSetting('mm_list_show_info')) {
$this->summaries[] = $this->t('Show details');
}
}
$this->form['mm_list_min'] = [
'#type' => 'number',
'#min' => 0,
'#title' => $this->t('Minimum number of entries'),
'#default_value' => $this->getSetting('mm_list_min'),
'#description' => $this->t('Set to 0 for no minimum'),
];
$this->summaries[] = $this->getSetting('mm_list_min') ? $this->formatPlural($this->getSetting('mm_list_min'), 'Minimum: 1 value', 'Minimum: @count values') : $this->t('No minimum');
$this->form['mm_list_max'] = [
'#type' => 'number',
'#min' => 0,
'#title' => $this->t('Maximum number of entries'),
'#default_value' => $this->getSetting('mm_list_max'),
'#description' => $this->t('Set to 0 for no limit'),
];
$this->summaries[] = $this->getSetting('mm_list_max') ? $this->formatPlural($this->getSetting('mm_list_max'), 'Maximum: 1 value', 'Maximum: @count values') : $this->t('No maximum');
if ($widget_type != 'mm_userlist') {
if ($default = $this->getSetting('mm_list_popup_start')) {
$default = [$default => mm_content_get_name($default)];
}
$this->form['mm_list_popup_start'] = [
'#type' => $widget_type == 'mm_nodelist' ? 'mm_catlist' : $widget_type,
'#title' => $this->t('Initial location to display when choosing:'),
'#default_value' => $default,
'#element_validate' => [[static::class, 'validatePopupStart']],
'#mm_list_max' => 1,
];
}
if ($widget_type == 'mm_catlist' || $widget_type == 'mm_nodelist') {
$x = mm_ui_strings(FALSE);
$options = [
Constants::MM_PERMS_WRITE => $this->t('delete it or change its settings', $x),
Constants::MM_PERMS_SUB => $this->t('append @subthings to it', $x),
Constants::MM_PERMS_APPLY => $this->t('add content to it', $x),
Constants::MM_PERMS_READ => $this->t('read it', $x),
];
$this->form['mm_list_enabled'] = [
'#type' => 'select',
'#title' => $this->t('In order to <em>expand</em> a @thing and see its @subthings, the user must be able to', $x),
'#options' => $options,
'#default_value' => $this->getSetting('mm_list_enabled'),
];
$this->form['mm_list_selectable'] = [
'#type' => 'select',
'#title' => $this->t('In order to <em>select</em> a @thing, the user must be able to', $x),
'#options' => $options,
'#default_value' => $this->getSetting('mm_list_selectable'),
];
if ($widget_type == 'mm_nodelist') {
$this->form['mm_list_selectable']['#title'] = $this->t('In order to <em>select nodes</em> from this page, the user must be able to', $x);
$node_types = [];
/** @var NodeType $node_type */
foreach (NodeType::loadMultiple() as $type => $node_type) {
$node_types[$type] = $node_type->get('name');
}
$this->form['mm_list_nodetypes'] = [
'#type' => 'checkboxes',
'#title' => $this->t('Allowed node types'),
'#description' => $this->t('If no node types are selected above, then any type of node may be selected in the node chooser.'),
'#options' => $node_types,
'#default_value' => $this->getSetting('mm_list_nodetypes'),
];
}
}
}
if ($form) {
$this->form += $form;
}
return $this->form;
}
/**
* Convert the value of mm_list_popup_start to a usable state.
*
* @param $element
* The form element.
* @param FormStateInterface $form_state
* The form state.
*/
public static function validatePopupStart(&$element, FormStateInterface &$form_state) {
$mmtids = array_keys($element['#value']);
$form_state->setValueForElement($element, $mmtids ? $mmtids[0] : NULL);
}
/**
* {@inheritdoc}
*/
public function settingsSummary() {
if (empty($this->summaries)) {
$this->settingsForm();
}
return $this->summaries;
}
/**
* {@inheritdoc}
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
if ($delta > 0) {
return [];
}
$instance = $this->fieldDefinition;
$widget_type = $this->getPluginId();
$values = [];
if ($items) {
if ($widget_type == 'mm_nodelist') {
foreach ($items as $item) {
if (!empty($item->nid)) {
mm_ui_mm_nodelist_setup($values, $item->nid, $item->mmtid);
}
elseif (!empty($item->mmtid)) {
$tree = mm_content_get($item->mmtid);
if ($tree) {
$values[$tree->mmtid] = mm_content_get_name($tree) . ' ' . t('(all)');
}
}
}
}
else {
$ids = [];
foreach ($items as $item) {
if (isset($item->value)) {
$ids[] = $item->value;
}
}
if ($widget_type == 'mm_userlist') {
foreach ($ids as $uid) {
$values[$uid] = mm_ui_uid2name($uid);
}
}
else {
$tree = mm_content_get($ids);
if ($tree) {
foreach ($tree as $item) {
$values[$item->mmtid] = mm_content_get_name($item);
}
}
}
}
}
$result = [
'#type' => $widget_type,
'#default_value' => $values,
'#description' => $instance->getDescription(),
'#element_validate' => [[static::class, 'validateMMList']],
'#mm_list_field_name' => $instance->getName(),
'#mm_list_bundle_name' => $instance->getTargetBundle(),
'#mm_list_bundle_type' => $instance->getTargetEntityTypeId(),
'#title' => $element['#title'],
];
foreach ($this->getSettings() as $name => $value) {
if ($name == 'mm_list_show_info') {
$result['#mm_list_no_info'] = empty($value);
}
else if ($name != 'mm_list_nodetypes') {
$result["#$name"] = $value;
}
}
// Ensure that the "Default value" field on the config form has no minimum.
if ($form_state->getBuildInfo()['form_id'] == 'field_config_edit_form') {
$result['#mm_list_min'] = 0;
}
if ($widget_type == 'mm_userlist' && empty($this->getSetting('mm_list_readonly'))) {
$choose_name = $instance->getName() . '-choose';
$result['#mm_list_autocomplete_name'] = TRUE;
return [
$instance->getName() => $result,
$choose_name => [
'#type' => 'textfield',
'#title' => $result['#mm_list_max'] == 1 ? $this->t('Choose the user') : $this->t('Add a user'),
'#autocomplete_route_name' => 'monster_menus.autocomplete',
'#description' => mm_autocomplete_desc(),
'#size' => 30,
'#maxlength' => 40,
],
];
}
// Return a nested array, because each "row" has a weight.
return [$instance->getName() => $result];
}
/**
* Convert the field's value to a usable state and validate the number of
* entries.
*
* @param $element
* The form element.
* @param FormStateInterface $form_state
* The form state.
*/
public static function validateMMList(&$element, FormStateInterface &$form_state) {
$new = [];
foreach (array_keys($element['#value']) as $mmtid) {
if ($element['#type'] === 'mm_nodelist') {
$mmtid_node = explode('/', $mmtid);
$new[] = ['mmtid' => $mmtid_node[0], 'nid' => $mmtid_node[1]];
}
else {
$new[] = ['value' => $mmtid];
}
}
if (!empty($element['#mm_list_min']) && count($new) < $element['#mm_list_min']) {
$name = preg_replace('{\]$}', '-choose]', $element['#name']);
if (!empty($element['#mm_list_max'])) {
if ($element['#mm_list_max'] == $element['#mm_list_min']) {
$form_state->setErrorByName($name, \Drupal::translation()->formatPlural($element['#mm_list_min'], '@title: An entry is required.', '@title: @count entries are required.', ['@title' => $element['#title']]));
}
else {
$form_state->setErrorByName($name, t('@title: From @min to @max entries are required.', ['@title' => $element['#title'], '@min' => $element['#mm_list_min'], '@max' => $element['#mm_list_max']]));
}
}
else {
$form_state->setErrorByName($name, \Drupal::translation()->formatPlural($element['#mm_list_min'], '@title: An entry is required.', '@title: At least @count entries are required.', ['@title' => $element['#title']]));
}
}
else {
$temp_elem = $element;
$temp_elem['#parents'] = array_slice($temp_elem['#parents'], 0, -1);
$form_state->setValueForElement($temp_elem, $new);
}
}
}
