Skip to content

Commit

Permalink
Merge pull request #1 from kviatkovskyi/patch
Browse files Browse the repository at this point in the history
Fix issue with empty argument and update.
  • Loading branch information
kviatkovskyi authored Jan 5, 2022
2 parents ccb7042 + 5dcde8c commit fbff3b1
Show file tree
Hide file tree
Showing 8 changed files with 291 additions and 60 deletions.
3 changes: 3 additions & 0 deletions config/schema/viewfield.schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ field.value.viewfield:
vargs:
type: string
label: 'Default view arguments'
settings:
type: string
label: 'Default view settings'
7 changes: 7 additions & 0 deletions src/Plugin/Field/FieldFormatter/ViewfieldDefaultFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\views\Views;
use Drupal\Component\Serialization\Json;

/**
* Plugin implementation of the 'viewfield_default' formatter.
Expand All @@ -35,6 +36,10 @@ public function viewElements(FieldItemListInterface $items, $langcode) {
$entity = $item->getEntity();
list($view_name, $view_display) = explode('|', $item->vname, 2);
$view = Views::getView($view_name);
$settings = [];
if (!empty($item->settings)) {
$settings = Json::decode($item->settings);
}
$elements[$delta] = array(
'#type' => 'viewfield',
'#view' => $view,
Expand All @@ -45,9 +50,11 @@ public function viewElements(FieldItemListInterface $items, $langcode) {
'#entity_type' => $entity->getEntityTypeId(),
'#entity_id' => $entity->id(),
'#entity' => $entity,
'#exposed_settings' => $settings,
'#theme' => 'viewfield_formatter_default',
);
}
return $elements;
}

}
12 changes: 8 additions & 4 deletions src/Plugin/Field/FieldType/ViewfieldItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
use Drupal\Core\Form\FormStateInterface;
use Drupal\views\Views;


/**
* Plugin implementation of the 'viewfield' field type.
*
Expand Down Expand Up @@ -58,14 +57,16 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
'vname' => array(
'type' => 'varchar',
'not null' => FALSE,
// Views requires at least 96 chars for the view name and display, plus
// we need 1 for our delimiter. Round up to a common value of 128.
'length' => 128,
),
'vargs' => array(
'type' => 'varchar',
'not null' => FALSE,
'length' => 255, //viewfield_field_instance_settings_form_validate
'length' => 255,
),
'settings' => array(
'type' => 'text',
'size' => 'normal',
),
),
);
Expand All @@ -79,6 +80,8 @@ public static function propertyDefinitions(FieldStorageDefinitionInterface $fiel
->setLabel(t('View name'));
$properties['vargs'] = DataDefinition::create('string')
->setLabel(t('View args'));
$properties['settings'] = DataDefinition::create('string')
->setLabel(t('View settings'));
return $properties;
}

Expand Down Expand Up @@ -127,4 +130,5 @@ public static function fieldSettingsFormValidate(array $form, FormStateInterface
}
}
}

}
144 changes: 140 additions & 4 deletions src/Plugin/Field/FieldWidget/ViewfieldWidget.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Form\FormState;
use Drupal\Core\Render\Element;
use Drupal\Component\Utility\Html;
use Drupal\views\Views;
use Drupal\Component\Serialization\Json;

/**
* Plugin implementation of the 'viewfield' widget.
Expand All @@ -34,31 +37,137 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
$field_settings = $this->getFieldSettings();
$options = $this->getPotentialReferences($field_settings);

$id = Html::getUniqueId('state-wrapper-' . $items->getName() . '-' . $delta);

$element['#field_name'] = $items->getName();
$element['vname'] = array(
'#type' => 'select',
'#title' => t('Views Field'),
'#options' => $options,
'#empty_value' => 0,
'#ajax' => array(
'callback' => array($this, 'viewsSettings'),
'event' => 'change',
'progress' => array(
'type' => 'throbber',
'message' => NULL,
),
'wrapper' => $id,
),
'#access' => !$field_settings['force_default'],
'#default_value' => isset($items[$delta]->vname) ? $items[$delta]->vname : NULL,
);

$element['settings_wrapper'] = array(
'#type' => 'fieldset',
);

$element['settings_wrapper']['settings_wrapper_form'] = array(
'#type' => 'html_tag',
'#tag' => 'div',
);

$element['settings_wrapper']['settings_wrapper_form']['settings'] = array(
'#type' => 'html_tag',
'#tag' => 'div',
'#attributes' => array(
'id' => $id,
),
);

if (isset($items[$delta]->vname)) {
$view = explode('|', $items[$delta]->vname);
$viewInstance = $this->getView($view[0], $view[1]);
$itemSettings = [];
if (!empty($items[$delta]->settings)) {
$itemSettings = Json::decode($items[$delta]->settings);
}
if ($viewInstance) {
$element['settings_wrapper']['settings_wrapper_form']['settings'] = $this->getViewSettings($viewInstance, $view[1], $itemSettings);
$element['settings_wrapper']['settings_wrapper_form']['settings']['#attributes']['id'] = $id;
}
}

$element['vargs'] = array(
'#type' => 'textfield',
'#title' => t('Arguments'),
'#default_value' => isset($items[$delta]->vargs) ? $items[$delta]->vargs : NULL,
'#access' => !$field_settings['force_default'],
'#description' => t('A comma separated list of arguments to pass to the selected view. '),
'#description' => t('A comma separated list of arguments to pass to the selected view.'),
);

return $element;
}

/**
* Helper function for get exposed filter.
*/
public function getViewSettings($view, $display, $settings) {
$form_state = new FormState();
if ($settings) {
$form_state->setUserInput($settings);
}
$view->initHandlers();
$form = [];
// Let form plugins know this is for exposed widgets.
$form_state->set('exposed', TRUE);
$form['settings'] = [];

// Go through each handler and let it generate its exposed widget.
foreach ($view->display_handler->handlers as $type => $value) {
/** @var \Drupal\views\Plugin\views\ViewsHandlerInterface $handler */
foreach ($view->$type as $id => $handler) {
if ($handler->canExpose() && $handler->isExposed()) {
if ($handler->isAGroup()) {
$handler->groupForm($form, $form_state);
$id = $handler->options['group_info']['identifier'];
}
else {
$handler->buildExposedForm($form, $form_state);
}
if ($info = $handler->exposedInfo()) {
$form['#info']["$type-$id"] = $info;
}
}
}
}
if (!empty($settings)) {
foreach ($settings as $name => $set) {
if ($form[$name]) {
$form[$name]['#default_value'] = $set;
}
}
}
if (isset($form['#info'])) {
foreach ($form['#info'] as $info) {
if (isset($form[$info['value']])) {
$form[$info['value']]['#title'] = $info['label'];
}
}
}

$exposed_form_plugin = $view->display_handler->getPlugin('exposed_form');
$exposed_form_plugin->exposedFormAlter($form, $form_state);

unset($form['actions']);
return $form;
}

public function viewsSettings(array $form, FormStateInterface $form_state) {
$view = $form_state->getTriggeringElement()['#value'];
$view = explode('|', $view);
$viewInstance = $this->getView($view[0], $view[1]);
if ($viewInstance && is_a($viewInstance->getDisplay(), 'Drupal\viewfield\Plugin\views\display\ViewFieldDisplay')) {
return $this->getViewSettings($viewInstance, $view[1]);
}
return [];
}

/**
* Returns a select options list of views displays of enabled and allowed views.
*
* @param array @settings
* The field settings
* @param array $settings
* The field settings.
*
* @return array
* An array with the allowed and enabled views and displays.
Expand All @@ -75,7 +184,7 @@ protected function getPotentialReferences($settings) {
}
}
$options = array();
foreach ($views as $view_name => $view) {
foreach ($views as $view) {
$displays = $view->get('display');
foreach ($displays as $display) {
$options[$view->id() . '|' . $display['id']] = $view->id() . ' - ' . $display['display_title'];
Expand All @@ -84,4 +193,31 @@ protected function getPotentialReferences($settings) {
return $options;
}

/**
* Helper function for retrieve view.
*
* @param string $viewId
* View machinable name to load.
* @param string $display
* Display plugin to load.
*/
public function getView($viewId, $display) {
$view = Views::getView($viewId);
if ($view) {
$view->setDisplay($display);
return $view;
}
return FALSE;
}

/**
* {@inheritdoc}
*/
public function massageFormValues(array $values, array $form, FormStateInterface $formState) {
foreach ($values as $key => $value) {
$values[$key]['settings'] = Json::encode($value['settings_wrapper']['settings_wrapper_form']['settings']);
}
return $values;
}

}
29 changes: 29 additions & 0 deletions src/Plugin/views/display/ViewFieldDisplay.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace Drupal\viewfield\Plugin\views\display;

use Drupal\views\Plugin\views\display\DisplayPluginBase;

/**
* The plugin that handles an embed display.
*
* @ingroup views_display_plugins
*
* @todo: Wait until annotations/plugins support access methods.
* no_ui => !\Drupal::config('views.settings')->get('ui.show.display_embed'),
*
* @ViewsDisplay(
* id = "viewfield",
* title = @Translation("Viewfield"),
* help = @Translation("Provide a display which can be embedded using the views api."),
* theme = "views_view",
* uses_menu_links = FALSE
* )
*/
class ViewFieldDisplay extends DisplayPluginBase {

public function displaysExposed() {
return FALSE;
}

}
54 changes: 54 additions & 0 deletions src/Plugin/views/exposed_form/ViewFieldExposedForm.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace Drupal\viewfield\Plugin\views\exposed_form;

use Drupal\views\Plugin\views\exposed_form\Basic;
use Drupal\Core\Form\FormState;
use Drupal\Core\Form\FormStateInterface;

/**
* Exposed form plugin that provides a basic exposed form.
*
* @ingroup views_exposed_form_plugins
*
* @ViewsExposedForm(
* id = "viewfield_exposed_form",
* title = @Translation("Viewfield Form"),
* help = @Translation("Only for field settings")
* )
*/
class ViewFieldExposedForm extends Basic {
/**
* Render the exposed filter form.
*
* This actually does more than that; because it's using FAPI, the form will
* also assign data to the appropriate handlers for use in building the
* query.
*/
public function renderExposedForm($block = FALSE) {
//return [];
// Deal with any exposed filters we may have, before building.

$form_state = (new FormState())
->setStorage([
'view' => $this->view,
'display' => &$this->view->display_handler->display,
'rerender' => TRUE,
])
->setMethod('get')
->setAlwaysProcess()
->disableRedirect();

// Some types of displays (eg. attachments) may wish to use the exposed
// filters of their parent displays instead of showing an additional
// exposed filter form for the attachment as well as that for the parent.
if (!$this->view->display_handler->displaysExposed() || ($this->view->display_handler->getOption('exposed_block'))) {
$form_state->set('rerender', NULL);
}

$form = \Drupal::formBuilder()->buildForm('\Drupal\views\Form\ViewsExposedForm', $form_state);
return [];
}


}
Loading

0 comments on commit fbff3b1

Please sign in to comment.