You are here

abstract class GeolocationStyleBase in Geolocation Field 8.3

Geolocation Style Base.

@package Drupal\geolocation\Plugin\views\style

Hierarchy

Expanded class hierarchy of GeolocationStyleBase

File

src/Plugin/views/style/GeolocationStyleBase.php, line 18

Namespace

Drupal\geolocation\Plugin\views\style
View source
abstract class GeolocationStyleBase extends StylePluginBase {

  /**
   * {@inheritdoc}
   */
  protected $usesFields = TRUE;

  /**
   * {@inheritdoc}
   */
  protected $usesRowPlugin = TRUE;

  /**
   * {@inheritdoc}
   */
  protected $usesRowClass = FALSE;

  /**
   * {@inheritdoc}
   */
  protected $usesGrouping = FALSE;

  /**
   * Data provider base.
   *
   * @var \Drupal\geolocation\DataProviderManager
   */
  protected $dataProviderManager = NULL;

  /**
   * {@inheritdoc}
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, $data_provider_manager) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->dataProviderManager = $data_provider_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static($configuration, $plugin_id, $plugin_definition, $container
      ->get('plugin.manager.geolocation.dataprovider'));
  }

  /**
   * {@inheritdoc}
   */
  public function render() {
    if (empty($this->options['geolocation_field'])) {
      \Drupal::messenger()
        ->addMessage('The geolocation based view ' . $this->view
        ->id() . ' views style was called without a geolocation field defined in the views style settings.', 'error');
      return FALSE;
    }
    if (empty($this->view->field[$this->options['geolocation_field']])) {
      \Drupal::messenger()
        ->addMessage('The geolocation based view ' . $this->view
        ->id() . ' views style was called with a non-available geolocation field defined in the views style settings.', 'error');
      return FALSE;
    }
    return parent::render();
  }

  /**
   * Render array from views result row.
   *
   * @param \Drupal\views\ResultRow $row
   *   Result row.
   *
   * @return array
   *   List of location render elements.
   */
  protected function getLocationsFromRow(ResultRow $row) {
    $locations = [];
    $icon_url = NULL;
    if (!empty($this->options['icon_field']) && $this->options['icon_field'] != 'none') {

      /** @var \Drupal\views\Plugin\views\field\Field $icon_field_handler */
      $icon_field_handler = $this->view->field[$this->options['icon_field']];
      if (!empty($icon_field_handler)) {
        $image_items = $icon_field_handler
          ->getItems($row);
        if (!empty($image_items[0]['rendered']['#item']->entity)) {
          $file_uri = $image_items[0]['rendered']['#item']->entity
            ->getFileUri();
          $style = NULL;
          if (!empty($image_items[0]['rendered']['#image_style'])) {

            /** @var \Drupal\image\Entity\ImageStyle $style */
            $style = ImageStyle::load($image_items[0]['rendered']['#image_style']);
          }
          if (!empty($style)) {
            $icon_url = file_url_transform_relative($style
              ->buildUrl($file_uri));
          }
          else {
            $icon_url = file_url_transform_relative(file_create_url($file_uri));
          }
        }
      }
    }
    elseif (!empty($this->options['marker_icon_path'])) {
      $icon_token_uri = $this
        ->viewsTokenReplace($this->options['marker_icon_path'], $this->rowTokens[$row->index]);
      $icon_token_uri = preg_replace('/\\s+/', '', $icon_token_uri);
      $icon_url = file_url_transform_relative(file_create_url($icon_token_uri));
    }
    try {
      $data_provider = $this->dataProviderManager
        ->createInstance($this->options['data_provider_id'], $this->options['data_provider_settings']);
    } catch (\Exception $e) {
      \Drupal::logger('geolocation')
        ->critical('View with non-existing data provider called.');
      return [];
    }
    foreach ($data_provider
      ->getPositionsFromViewsRow($row, $this->view->field[$this->options['geolocation_field']]) as $position) {
      $location = [
        '#type' => 'geolocation_map_location',
        'content' => $this->view->rowPlugin
          ->render($row),
        '#title' => $this
          ->getTitleField($row) ?? '',
        '#label' => $this
          ->getLabelField($row) ?? '',
        '#coordinates' => $position,
        '#weight' => $row->index,
        '#attributes' => [
          'data-views-row-index' => $row->index,
        ],
      ];
      if (!empty($icon_url)) {
        $location['#icon'] = $icon_url;
      }
      if (!empty($location_id)) {
        $location['#id'] = $location_id;
      }
      if ($this->options['marker_row_number']) {
        $markerOffset = $this->view->pager
          ->getCurrentPage() * $this->view->pager
          ->getItemsPerPage();
        $marker_row_number = (int) $markerOffset + (int) $row->index + 1;
        if (empty($location['#label'])) {
          $location['#label'] = $marker_row_number;
        }
        else {
          $location['#label'] = $location['#label'] . ': ' . $location['#label'];
        }
      }
      $locations[] = $location;
    }
    $locations = array_merge($data_provider
      ->getLocationsFromViewsRow($row, $this->view->field[$this->options['geolocation_field']]), $locations);
    $locations = array_merge($data_provider
      ->getShapesFromViewsRow($row, $this->view->field[$this->options['geolocation_field']]), $locations);
    return $locations;
  }

  /**
   * {@inheritdoc}
   */
  protected function defineOptions() {
    $options = parent::defineOptions();
    $options['geolocation_field'] = [
      'default' => '',
    ];
    $options['data_provider_id'] = [
      'default' => 'geolocation_field_provider',
    ];
    $options['data_provider_settings'] = [
      'default' => [],
    ];
    $options['title_field'] = [
      'default' => '',
    ];
    $options['label_field'] = [
      'default' => '',
    ];
    $options['icon_field'] = [
      'default' => '',
    ];
    $options['marker_row_number'] = [
      'default' => FALSE,
    ];
    $options['marker_icon_path'] = [
      'default' => '',
    ];
    return $options;
  }

  /**
   * {@inheritdoc}
   */
  public function buildOptionsForm(&$form, FormStateInterface $form_state) {
    parent::buildOptionsForm($form, $form_state);
    $labels = $this->displayHandler
      ->getFieldLabels();
    $geo_options = [];

    /** @var \Drupal\geolocation\DataProviderInterface[] $data_providers */
    $data_providers = [];
    $title_options = [];
    $label_options = [];
    $icon_options = [];
    $fields = $this->displayHandler
      ->getHandlers('field');

    /** @var \Drupal\views\Plugin\views\field\FieldPluginBase[] $fields */
    foreach ($fields as $field_name => $field) {
      $data_provider_settings = [];
      if ($this->options['geolocation_field'] == $field_name && !empty($this->options['data_provider_settings'])) {
        $data_provider_settings = $this->options['data_provider_settings'];
      }
      if ($data_provider = $this->dataProviderManager
        ->getDataProviderByViewsField($field, $data_provider_settings)) {
        $geo_options[$field_name] = $field
          ->adminLabel() . ' (' . $data_provider
          ->getPluginDefinition()['name'] . ')';
        $data_providers[$field_name] = $data_provider;
      }
      if (!empty($field->options['type']) && $field->options['type'] == 'image') {
        $icon_options[$field_name] = $labels[$field_name];
      }
      if (!empty($field->options['type']) && $field->options['type'] == 'string') {
        $title_options[$field_name] = $labels[$field_name];
        $label_options[$field_name] = $labels[$field_name];
      }
    }
    $form['geolocation_field'] = [
      '#title' => $this
        ->t('Geolocation source field'),
      '#type' => 'select',
      '#default_value' => $this->options['geolocation_field'],
      '#description' => $this
        ->t("The source of geodata for each entity."),
      '#options' => $geo_options,
      '#required' => TRUE,
      '#ajax' => [
        'callback' => [
          get_class($this->dataProviderManager),
          'addDataProviderSettingsFormAjax',
        ],
        'wrapper' => 'data-provider-settings',
        'effect' => 'fade',
      ],
    ];
    $data_provider = NULL;
    $form_state_data_provider_id = NestedArray::getValue($form_state
      ->getUserInput(), [
      'style_options',
      'geolocation_field',
    ]);
    if (!empty($form_state_data_provider_id) && !empty($data_providers[$form_state_data_provider_id])) {
      $data_provider = $data_providers[$form_state_data_provider_id];
    }
    elseif (!empty($data_providers[$this->options['geolocation_field']])) {
      $data_provider = $data_providers[$this->options['geolocation_field']];
    }
    elseif (!empty($data_providers[reset($geo_options)])) {
      $data_provider = $data_providers[reset($geo_options)];
    }
    else {
      return;
    }
    $form['data_provider_id'] = [
      '#type' => 'value',
      '#value' => $data_provider
        ->getPluginId(),
    ];
    $form['data_provider_settings'] = $data_provider
      ->getSettingsForm($this->options['data_provider_settings'], [
      'style_options',
      'map_provider_settings',
    ]);
    $form['data_provider_settings'] = array_replace($form['data_provider_settings'], [
      '#prefix' => '<div id="data-provider-settings">',
      '#suffix' => '</div>',
    ]);
    $form['title_field'] = [
      '#title' => $this
        ->t('Title source field'),
      '#type' => 'select',
      '#default_value' => $this->options['title_field'],
      '#description' => $this
        ->t("The source of the title for each entity. Field type must be 'string'."),
      '#options' => $title_options,
      '#empty_value' => 'none',
    ];
    $form['label_field'] = [
      '#title' => $this
        ->t('Label source field'),
      '#type' => 'select',
      '#default_value' => $this->options['label_field'],
      '#description' => $this
        ->t("The source of the label for each entity. Field type must be 'string'."),
      '#options' => $label_options,
      '#empty_value' => 'none',
    ];

    /*
     * Advanced settings
     */
    $form['advanced_settings'] = [
      '#type' => 'fieldset',
      '#title' => $this
        ->t('Advanced settings'),
    ];
    if ($icon_options) {
      $form['icon_field'] = [
        '#group' => 'style_options][advanced_settings',
        '#title' => $this
          ->t('Icon source field'),
        '#type' => 'select',
        '#default_value' => $this->options['icon_field'],
        '#description' => $this
          ->t("Optional image (field) to use as icon."),
        '#options' => $icon_options,
        '#empty_value' => 'none',
        '#process' => [
          [
            '\\Drupal\\Core\\Render\\Element\\RenderElement',
            'processGroup',
          ],
          [
            '\\Drupal\\Core\\Render\\Element\\Select',
            'processSelect',
          ],
        ],
        '#pre_render' => [
          [
            '\\Drupal\\Core\\Render\\Element\\RenderElement',
            'preRenderGroup',
          ],
        ],
      ];
    }
    $form['marker_icon_path'] = [
      '#group' => 'style_options][advanced_settings',
      '#type' => 'textfield',
      '#title' => $this
        ->t('Marker icon path'),
      '#description' => $this
        ->t('Set relative or absolute path to custom marker icon. Tokens & Views replacement patterns supported. Empty for default.'),
      '#default_value' => $this->options['marker_icon_path'],
    ];
    $form['marker_row_number'] = [
      '#group' => 'style_options][advanced_settings',
      '#title' => $this
        ->t('Show views result row number in marker'),
      '#type' => 'checkbox',
      '#default_value' => $this->options['marker_row_number'],
    ];
  }

  /**
   * Get title value if present.
   *
   * @param \Drupal\views\ResultRow $row
   *   Result Row.
   *
   * @return string|null
   *   Title.
   */
  public function getTitleField(ResultRow $row) : ?string {
    if (!empty($this->options['title_field']) && $this->options['title_field'] != 'none') {
      $title_field = $this->options['title_field'];
      if (!empty($this->rendered_fields[$row->index][$title_field])) {
        return PlainTextOutput::renderFromHtml($this->rendered_fields[$row->index][$title_field]);
      }
      elseif (!empty($this->view->field[$title_field])) {
        return PlainTextOutput::renderFromHtml($this->view->field[$title_field]
          ->render($row));
      }
    }
    return NULL;
  }

  /**
   * Get label value if present.
   *
   * @param \Drupal\views\ResultRow $row
   *   Result Row.
   *
   * @return string|null
   *   Label.
   */
  public function getLabelField(ResultRow $row) : ?string {
    if (!empty($this->options['label_field']) && $this->options['label_field'] != 'none') {
      $label_field = $this->options['label_field'];
      if (!empty($this->rendered_fields[$row->index][$label_field])) {
        return PlainTextOutput::renderFromHtml($this->rendered_fields[$row->index][$label_field]);
      }
      elseif (!empty($this->view->field[$label_field])) {
        return PlainTextOutput::renderFromHtml($this->view->field[$label_field]
          ->render($row));
      }
    }
    return NULL;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
DependencySerializationTrait::$_entityStorages protected property An array of entity type IDs keyed by the property name of their storages.
DependencySerializationTrait::$_serviceIds protected property An array of service IDs keyed by property name used for serialization.
DependencySerializationTrait::__sleep public function 1
DependencySerializationTrait::__wakeup public function 2
GeolocationStyleBase::$dataProviderManager protected property Data provider base.
GeolocationStyleBase::$usesFields protected property Does the style plugin for itself support to add fields to its output. Overrides StylePluginBase::$usesFields
GeolocationStyleBase::$usesGrouping protected property Does the style plugin support grouping of rows. Overrides StylePluginBase::$usesGrouping
GeolocationStyleBase::$usesRowClass protected property Does the style plugin support custom css class for the rows. Overrides StylePluginBase::$usesRowClass
GeolocationStyleBase::$usesRowPlugin protected property Whether or not this style uses a row plugin. Overrides StylePluginBase::$usesRowPlugin
GeolocationStyleBase::buildOptionsForm public function Provide a form to edit options for this plugin. Overrides StylePluginBase::buildOptionsForm 1
GeolocationStyleBase::create public static function Creates an instance of the plugin. Overrides PluginBase::create 1
GeolocationStyleBase::defineOptions protected function Information about options for all kinds of purposes will be held here. Overrides StylePluginBase::defineOptions 1
GeolocationStyleBase::getLabelField public function Get label value if present.
GeolocationStyleBase::getLocationsFromRow protected function Render array from views result row.
GeolocationStyleBase::getTitleField public function Get title value if present.
GeolocationStyleBase::render public function Render the display in this style. Overrides StylePluginBase::render 2
GeolocationStyleBase::__construct public function Constructs a PluginBase object. Overrides PluginBase::__construct 1
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
PluginBase::$configuration protected property Configuration information passed into the plugin. 1
PluginBase::$definition public property Plugins's definition
PluginBase::$displayHandler public property The display object this plugin is for.
PluginBase::$options public property Options for this plugin will be held here.
PluginBase::$pluginDefinition protected property The plugin implementation definition. 1
PluginBase::$pluginId protected property The plugin_id.
PluginBase::$renderer protected property Stores the render API renderer. 3
PluginBase::$view public property The top object of a view. 1
PluginBase::calculateDependencies public function Calculates dependencies for the configured plugin. Overrides DependentPluginInterface::calculateDependencies 14
PluginBase::DERIVATIVE_SEPARATOR constant A string which is used to separate base plugin IDs from the derivative ID.
PluginBase::doFilterByDefinedOptions protected function Do the work to filter out stored options depending on the defined options.
PluginBase::filterByDefinedOptions public function Filter out stored options depending on the defined options. Overrides ViewsPluginInterface::filterByDefinedOptions
PluginBase::getAvailableGlobalTokens public function Returns an array of available token replacements. Overrides ViewsPluginInterface::getAvailableGlobalTokens
PluginBase::getBaseId public function Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface::getBaseId
PluginBase::getDerivativeId public function Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface::getDerivativeId
PluginBase::getPluginDefinition public function Gets the definition of the plugin implementation. Overrides PluginInspectionInterface::getPluginDefinition 3
PluginBase::getPluginId public function Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface::getPluginId
PluginBase::getProvider public function Returns the plugin provider. Overrides ViewsPluginInterface::getProvider
PluginBase::getRenderer protected function Returns the render API renderer. 1
PluginBase::globalTokenForm public function Adds elements for available core tokens to a form. Overrides ViewsPluginInterface::globalTokenForm
PluginBase::globalTokenReplace public function Returns a string with any core tokens replaced. Overrides ViewsPluginInterface::globalTokenReplace
PluginBase::INCLUDE_ENTITY constant Include entity row languages when listing languages.
PluginBase::INCLUDE_NEGOTIATED constant Include negotiated languages when listing languages.
PluginBase::isConfigurable public function Determines if the plugin is configurable.
PluginBase::listLanguages protected function Makes an array of languages, optionally including special languages.
PluginBase::pluginTitle public function Return the human readable name of the display. Overrides ViewsPluginInterface::pluginTitle
PluginBase::preRenderAddFieldsetMarkup public static function Moves form elements into fieldsets for presentation purposes. Overrides ViewsPluginInterface::preRenderAddFieldsetMarkup
PluginBase::preRenderFlattenData public static function Flattens the structure of form elements. Overrides ViewsPluginInterface::preRenderFlattenData
PluginBase::queryLanguageSubstitutions public static function Returns substitutions for Views queries for languages.
PluginBase::setOptionDefaults protected function Fills up the options of the plugin with defaults.
PluginBase::submitOptionsForm public function Handle any special handling on the validate form. Overrides ViewsPluginInterface::submitOptionsForm 16
PluginBase::summaryTitle public function Returns the summary of the settings in the display. Overrides ViewsPluginInterface::summaryTitle 6
PluginBase::themeFunctions public function Provide a full list of possible theme templates used by this style. Overrides ViewsPluginInterface::themeFunctions 1
PluginBase::unpackOptions public function Unpack options over our existing defaults, drilling down into arrays so that defaults don't get totally blown away. Overrides ViewsPluginInterface::unpackOptions
PluginBase::usesOptions public function Returns the usesOptions property. Overrides ViewsPluginInterface::usesOptions 8
PluginBase::viewsTokenReplace protected function Replaces Views' tokens in a given string. The resulting string will be sanitized with Xss::filterAdmin. 1
PluginBase::VIEWS_QUERY_LANGUAGE_SITE_DEFAULT constant Query string to indicate the site default language.
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.
StylePluginBase::$defaultFieldLabels protected property Should field labels be enabled by default. 1
StylePluginBase::$groupingTheme protected property The theme function used to render the grouping set.
StylePluginBase::$rendered_fields protected property Stores the rendered field values, keyed by the row index and field name.
StylePluginBase::$rowTokens protected property Store all available tokens row rows.
StylePluginBase::$usesOptions protected property Denotes whether the plugin has an additional options form. Overrides PluginBase::$usesOptions
StylePluginBase::buildSort public function Called by the view builder to see if this style handler wants to interfere with the sorts. If so it should build; if it returns any non-TRUE value, normal sorting will NOT be added to the query. 1
StylePluginBase::buildSortPost public function Called by the view builder to let the style build a second set of sorts that will come after any other sorts in the view. 1
StylePluginBase::defaultFieldLabels public function Return TRUE if this style enables field labels by default. 1
StylePluginBase::destroy public function Clears a plugin. Overrides PluginBase::destroy
StylePluginBase::elementPreRenderRow public function #pre_render callback for view row field rendering.
StylePluginBase::evenEmpty public function Should the output of the style plugin be rendered even if it's a empty view. 2
StylePluginBase::getField public function Gets a rendered field.
StylePluginBase::getFieldValue public function Get the raw field value.
StylePluginBase::getRowClass public function Return the token replaced row class for the specified row.
StylePluginBase::init public function Overrides \Drupal\views\Plugin\views\PluginBase::init(). Overrides PluginBase::init
StylePluginBase::preRender public function Allow the style to do stuff before each row is rendered.
StylePluginBase::query public function Add anything to the query that we might need to. Overrides PluginBase::query 1
StylePluginBase::renderFields protected function Renders all of the fields for a given style and store them on the object.
StylePluginBase::renderGrouping public function Group records as needed for rendering.
StylePluginBase::renderGroupingSets public function Render the grouping sets.
StylePluginBase::renderRowGroup protected function Renders a group of rows of the grouped view.
StylePluginBase::tokenizeValue public function Take a value and apply token replacement logic to it.
StylePluginBase::trustedCallbacks public static function Lists the trusted callbacks provided by the implementing class. Overrides PluginBase::trustedCallbacks
StylePluginBase::usesFields public function Return TRUE if this style also uses fields. 3
StylePluginBase::usesGrouping public function Returns the usesGrouping property. 3
StylePluginBase::usesRowClass public function Returns the usesRowClass property. 3
StylePluginBase::usesRowPlugin public function Returns the usesRowPlugin property. 10
StylePluginBase::usesTokens public function Return TRUE if this style uses tokens.
StylePluginBase::validate public function Validate that the plugin is correct and can be saved. Overrides PluginBase::validate
StylePluginBase::validateOptionsForm public function Validate the options form. Overrides PluginBase::validateOptionsForm
StylePluginBase::wizardForm public function Provide a form in the views wizard if this style is selected.
StylePluginBase::wizardSubmit public function Alter the options of a display before they are added to the view. 1
TrustedCallbackInterface::THROW_EXCEPTION constant Untrusted callbacks throw exceptions.
TrustedCallbackInterface::TRIGGER_SILENCED_DEPRECATION constant Untrusted callbacks trigger silenced E_USER_DEPRECATION errors.
TrustedCallbackInterface::TRIGGER_WARNING constant Untrusted callbacks trigger E_USER_WARNING errors.