You are here

class LinkitPluginEntity in Linkit 7.2

@file Define Linkit entity plugin.

Hierarchy

Expanded class hierarchy of LinkitPluginEntity

1 string reference to 'LinkitPluginEntity'
entity.inc in plugins/linkit_plugins/entity.inc
Linkit Entity Plugin.

File

plugins/linkit_plugins/linkit-plugin-entity.class.php, line 6
Define Linkit entity plugin.

View source
class LinkitPluginEntity extends LinkitPlugin {

  /**
   * Entity field query instance.
   *
   * @var Resource
   */
  var $query;

  /**
   * The entity info array of an entity type.
   *
   * @var array
   */
  var $entity_info;

  /**
   * The name of the property that contains the entity label.
   *
   * @var string
   */
  var $entity_field_label;

  /**
   * The name of the property of the bundle object that contains the name of
   * the bundle object.
   *
   * @var string
   */
  var $entity_key_bundle;

  /**
   * Plugin specific settings.
   *
   * @var arrayu
   */
  var $conf;

  /**
   * Initialize this plugin with the plugin, profile, and entity specific
   * variables.
   *
   * @param object $profile
   *   The Linkit profile to use.
   * @param array $plugin
   *   The plugin array.
   */
  function __construct($plugin, $profile) {
    parent::__construct($plugin, $profile);

    // Load the corresponding entity.
    $this->entity_info = entity_get_info($this->plugin['entity_type']);

    // Set bundle key name.
    if (isset($this->entity_info['entity keys']['bundle']) && !isset($this->entity_key_bundle)) {
      $this->entity_key_bundle = $this->entity_info['entity keys']['bundle'];
    }

    // Set the label field name.
    if (!isset($this->entity_field_label)) {
      $this->entity_field_label = $this->entity_info['entity keys']['label'];
    }

    // Make a shortcut for the profile data settings for this plugin.
    $this->conf = isset($this->profile->data[$this->plugin['name']]) ? $this->profile->data[$this->plugin['name']] : array();
  }

  /**
   * Build the label that will be used in the search result for each row.
   */
  function buildLabel($entity) {
    return check_plain(entity_label($this->plugin['entity_type'], $entity));
  }

  /**
   * Build an URL based in the path and the options.
   */
  function buildPath($entity, $options = array()) {

    // Create the URI for the entity.
    $uri = entity_uri($this->plugin['entity_type'], $entity);

    // We have to set alias to TRUE as we don't want an alias back.
    $options += array(
      'alias' => TRUE,
    );
    return parent::buildPath($uri['path'], $options);
  }

  /**
   * Build the search row description.
   *
   * If there is a "result_description", run it thro token_replace.
   *
   * @param object $data
   *   An entity object that will be used in the token_place function.
   *
   * @see token_replace()
   */
  function buildDescription($data) {
    $description = token_replace(check_plain($this->conf['result_description']), array(
      $this->plugin['entity_type'] => $data,
    ), array(
      'clear' => TRUE,
    ));
    if (isset($this->conf['reverse_menu_trail']) && $this->conf['reverse_menu_trail']) {
      $description .= $this
        ->buildReverseMenuTrail($data);
    }
    return $description;
  }

  /**
   * Builds a reverse menu trail for the entity.
   *
   * @param object $data
   *   An entity object.
   */
  function buildReverseMenuTrail($data) {
    $vars = array();
    $output = '';
    $uri = entity_uri($this->plugin['entity_type'], $data);
    if (isset($uri['path'])) {
      $menu_link_fields = array(
        'link_title',
        'link_path',
        'plid',
        'menu_name',
      );
      $menu_items = db_select('menu_links', 'ml')
        ->fields('ml', $menu_link_fields)
        ->condition('link_path', $uri['path'])
        ->execute()
        ->fetchAll(PDO::FETCH_ASSOC);
      foreach ($menu_items as $menu_item) {
        $vars['reverse_menu_trail'] = array();
        while ($menu_item['plid']) {
          $menu_item = db_select('menu_links', 'ml')
            ->fields('ml', $menu_link_fields)
            ->condition('mlid', $menu_item['plid'])
            ->execute()
            ->fetchAssoc();
          if (isset($menu_item['link_title'])) {
            $vars['reverse_menu_trail'][] = $menu_item['link_title'];
          }
        }
        $output .= !empty($vars['reverse_menu_trail']) ? theme('linkit_reverse_menu_trail', $vars) : '';
      }
    }
    return $output;
  }

  /**
   * When "group_by_bundle" is active, we need to add the bundle name to the
   * group, else just return the entity label.
   *
   * @return a string with the group name.
   */
  function buildGroup($entity) {

    // Get the entity label.
    $group = $this->entity_info['label'];

    // If the entities by this entity should be grouped by bundle, get the
    // name and append it to the group.
    if (isset($this->conf['group_by_bundle']) && $this->conf['group_by_bundle']) {
      $bundles = $this->entity_info['bundles'];
      $bundle_name = $bundles[$entity->{$this->entity_key_bundle}]['label'];
      $group .= ' · ' . check_plain($bundle_name);
    }
    return $group;
  }

  /**
   * Start a new EntityFieldQuery instance.
   */
  function getQueryInstance() {
    $this->query = new EntityFieldQuery();
    $this->query
      ->entityCondition('entity_type', $this->plugin['entity_type']);

    // Add the default sort on the enity label.
    $this->query
      ->propertyOrderBy($this->entity_field_label, 'ASC');
  }

  /**
   * The autocomplete callback function for the Linkit Entity plugin.
   *
   * @return
   *   An associative array whose values are an
   *   associative array containing:
   *   - title: A string to use as the search result label.
   *   - description: (optional) A string with additional information about the
   *     result item.
   *   - path: The URL to the item.
   *   - group: (optional) A string with the group name for the result item.
   *     Best practice is to use the plugin name as group name.
   *   - addClass: (optional) A string with classes to add to the result row.
   */
  function autocomplete_callback() {
    $matches = array();

    // Get the EntityFieldQuery instance.
    $this
      ->getQueryInstance();

    // Add the search condition to the query object.
    $this->query
      ->propertyCondition($this->entity_field_label, '%' . db_like($this->search_string) . '%', 'LIKE')
      ->addTag('linkit_entity_autocomplete')
      ->addTag('linkit_' . $this->plugin['entity_type'] . '_autocomplete');

    // Add access tag for the query.
    // There is also a runtime access check that uses entity_access().
    $this->query
      ->addTag($this->plugin['entity_type'] . '_access');

    // Bundle check.
    if (isset($this->entity_key_bundle) && isset($this->conf['bundles'])) {
      if ($bundles = array_filter($this->conf['bundles'])) {
        $this->query
          ->propertyCondition($this->entity_key_bundle, $bundles, 'IN');
      }
    }

    // Execute the query.
    $result = $this->query
      ->execute();
    if (!isset($result[$this->plugin['entity_type']])) {
      return array();
    }
    $ids = array_keys($result[$this->plugin['entity_type']]);

    // Load all the entities with all the ids we got.
    $entities = entity_load($this->plugin['entity_type'], $ids);
    foreach ($entities as $entity) {

      // Check the access againt the definded entity access callback.
      if (entity_access('view', $this->plugin['entity_type'], $entity) === FALSE) {
        continue;
      }
      $matches[] = array(
        'title' => $this
          ->buildLabel($entity),
        'description' => $this
          ->buildDescription($entity),
        'path' => $this
          ->buildPath($entity),
        'group' => $this
          ->buildGroup($entity),
        'addClass' => $this
          ->buildRowClass($entity),
      );
    }
    return $matches;
  }

  /**
   * Generate a settings form for this handler.
   * Uses the standard Drupal FAPI.
   * The element will be attached to the "data" key.
   *
   * @return
   *   An array containing any custom form elements to be displayed in the
   *   profile editing form
   */
  function buildSettingsForm() {
    $form[$this->plugin['name']] = array(
      '#type' => 'fieldset',
      '#title' => t('!type plugin settings', array(
        '!type' => $this
          ->ui_title(),
      )),
      '#collapsible' => TRUE,
      '#collapsed' => TRUE,
      '#tree' => TRUE,
      '#states' => array(
        'invisible' => array(
          'input[name="data[plugins][' . $this->plugin['name'] . '][enabled]"]' => array(
            'checked' => FALSE,
          ),
        ),
      ),
    );

    // Get supported tokens for the entity type.
    $tokens = linkit_extract_tokens($this->plugin['entity_type']);

    // A short description in within the search result for each row.
    $form[$this->plugin['name']]['result_description'] = array(
      '#title' => t('Result format'),
      '#type' => 'textfield',
      '#default_value' => isset($this->conf['result_description']) ? $this->conf['result_description'] : '',
      '#size' => 120,
      '#maxlength' => 255,
      '#description' => t('Available tokens: %tokens.', array(
        '%tokens' => implode(', ', $tokens),
      )),
    );

    // If the token module is installed, lets make some fancy stuff with the
    // token chooser.
    if (module_exists('token')) {

      // Unset the regular description if token module is enabled.
      unset($form[$this->plugin['name']]['result_description']['#description']);

      // Display the user documentation of placeholders.
      $form[$this->plugin['name']]['token_help'] = array(
        '#title' => t('Replacement patterns'),
        '#type' => 'fieldset',
        '#collapsible' => TRUE,
        '#collapsed' => TRUE,
      );
      $form[$this->plugin['name']]['token_help']['help'] = array(
        '#theme' => 'token_tree',
        '#token_types' => array(
          $this->plugin['entity_type'],
        ),
      );
    }

    // If there is bundles, add some default settings features.
    if (count($this->entity_info['bundles']) > 1) {
      $bundles = array();

      // Extract the bundle data.
      foreach ($this->entity_info['bundles'] as $bundle_name => $bundle) {
        $bundles[$bundle_name] = $bundle['label'];
      }

      // Filter the possible bundles to use if the entity has bundles.
      $form[$this->plugin['name']]['bundles'] = array(
        '#title' => t('Type filter'),
        '#type' => 'checkboxes',
        '#options' => $bundles,
        '#default_value' => isset($this->conf['bundles']) ? $this->conf['bundles'] : array(),
        '#description' => t('If left blank, all types will appear in autocomplete results.'),
      );

      // Group the results with this bundle.
      $form[$this->plugin['name']]['group_by_bundle'] = array(
        '#title' => t('Group by bundle'),
        '#type' => 'checkbox',
        '#default_value' => isset($this->conf['group_by_bundle']) ? $this->conf['group_by_bundle'] : 0,
      );
    }

    // Reverse menu trail.
    $form[$this->plugin['name']]['reverse_menu_trail'] = array(
      '#title' => t('Add reverse menu trail to description'),
      '#type' => 'checkbox',
      '#default_value' => isset($this->conf['reverse_menu_trail']) ? $this->conf['reverse_menu_trail'] : 0,
      '#description' => t('If the result has a menu item its menu trail will be added in reverse in the description.'),
    );
    return $form;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
LinkitPlugin::broken function Determine if the handler is considered 'broken', meaning it's a a placeholder used when a handler can't be found. 1
LinkitPlugin::buildRowClass function Returns a string with CSS classes that will be added to the search result row for this item. 1
LinkitPlugin::setSearchString function Set the search string.
LinkitPlugin::ui_description function Return a string representing this handler's description in the UI. 2
LinkitPlugin::ui_title function Return a string representing this handler's name in the UI. 2
LinkitPluginEntity::$conf property Plugin specific settings.
LinkitPluginEntity::$entity_field_label property The name of the property that contains the entity label.
LinkitPluginEntity::$entity_info property The entity info array of an entity type.
LinkitPluginEntity::$entity_key_bundle property The name of the property of the bundle object that contains the name of the bundle object.
LinkitPluginEntity::$query property Entity field query instance.
LinkitPluginEntity::autocomplete_callback function The autocomplete callback function for the Linkit Entity plugin. Overrides LinkitPluginInterface::autocomplete_callback 1
LinkitPluginEntity::buildDescription function Build the search row description. Overrides LinkitPlugin::buildDescription 1
LinkitPluginEntity::buildGroup function When "group_by_bundle" is active, we need to add the bundle name to the group, else just return the entity label. Overrides LinkitPlugin::buildGroup 2
LinkitPluginEntity::buildLabel function Build the label that will be used in the search result for each row. Overrides LinkitPlugin::buildLabel 1
LinkitPluginEntity::buildPath function Build an URL based in the path and the options. Overrides LinkitPlugin::buildPath 1
LinkitPluginEntity::buildReverseMenuTrail function Builds a reverse menu trail for the entity.
LinkitPluginEntity::buildSettingsForm function Generate a settings form for this handler. Uses the standard Drupal FAPI. The element will be attached to the "data" key. Overrides LinkitPlugin::buildSettingsForm 3
LinkitPluginEntity::getQueryInstance function Start a new EntityFieldQuery instance. 2
LinkitPluginEntity::__construct function Initialize this plugin with the plugin, profile, and entity specific variables. Overrides LinkitPlugin::__construct 2