You are here

mixitup_views.module in MixItUp Views 7

Same filename and directory in other branches
  1. 8.2 mixitup_views.module
  2. 8 mixitup_views.module

Provides a Views style plugin for displaying content with Mixitup filtering.

File

mixitup_views.module
View source
<?php

/**
 * @file
 * Provides a Views style plugin for displaying content with Mixitup filtering.
 */

/**
 * Implements hook_libraries_info().
 */
function mixitup_views_libraries_info() {
  $libraries['mixitup'] = array(
    'name' => 'MixItUp',
    'vendor url' => 'https://mixitup.kunkalabs.com/',
    'download url' => 'https://mixitup.kunkalabs.com/',
    'version arguments' => array(
      'file' => 'jquery.mixitup.min.js',
      'pattern' => '/MixItUp\\s+v?([0-9\\.]+)/',
      'lines' => 2,
      'cols' => 30,
    ),
    'files' => array(
      'js' => array(
        'jquery.mixitup.min.js',
      ),
    ),
  );
  return $libraries;
}

/**
 * Check if the Mixitup library is installed.
 *
 * @return bool
 *   A boolean indicating the installed status.
 */
function mixitup_views_installed() {
  if (($library = libraries_detect('mixitup')) && !empty($library['installed'])) {
    return TRUE;
  }
  else {
    return FALSE;
  }
}

/**
 * Check if the Mixitup library has been loaded.
 *
 * @return bool
 *   A boolean indicating the loaded status.
 */
function mixitup_views_loaded() {
  if (($library = libraries_load('mixitup')) && !empty($library['loaded'])) {
    return TRUE;
  }
  else {
    return FALSE;
  }
}

/**
 * Implements hook_views_api().
 */
function mixitup_views_views_api() {
  return array(
    'api' => 3,
  );
}

/**
 * Implements hook_theme().
 */
function mixitup_views_theme($existing, $type, $theme, $path) {
  return array(
    'mixitup_views_sorting' => array(
      'template' => 'templates/mixitup_views_sorting',
      'arguments' => array(
        'sorts' => NULL,
      ),
    ),
  );
}

/**
 * Preprocess function for views_view_mixitup.tpl.php.
 */
function template_preprocess_views_view_mixitup(&$vars) {

  // Run preprocess function for unformatted style.
  template_preprocess_views_view_unformatted($vars);

  // Get view options.
  $view = $vars['view'];
  $options = $vars['options'];
  if (isset($options['use_sort']) && $options['use_sort'] == 1 && isset($options['sorts'])) {
    $sort_keys = array();
    foreach ($options['sorts'] as $sort_item => $label) {
      if (empty($label)) {
        unset($options['sorts'][$sort_item]);
        continue;
      }
      $sort_keys[$sort_item] = $label;
    }
  }
  if (is_array($vars['view']->result)) {
    mixitup_views_set_nodes_count(count($vars['view']->result));
  }

  // Populates result array with tids info.
  foreach ($vars['view']->result as $id => $result) {
    $vars['view']->result[$id]->classes = mixitup_views_get_rows_classes($result->nid);
    if (!empty($sort_keys)) {
      $sorts = array();
      foreach ($result as $id_field => $val) {
        if (isset($sort_keys[$id_field])) {
          $sorts[] = 'data-' . $id_field . '="' . $val . '"';
        }
      }
      $vars['view']->result[$id]->sorts = implode(' ', $sorts);
    }
  }
  $filters = drupal_get_form('mixitup_views_filters_form', $options);
  $vars['filters'] = drupal_render($filters);

  // Display content in a Mixitup layout.
  $container = '.view-' . drupal_clean_css_identifier($view->name) . '.view-display-id-' . $view->current_display . ' .view-content';
  mixitup_views_apply($container, $options);
}

/**
 * Get default option for mixitup js.
 *
 * @return array
 *   Array of default mixitup params.
 */
function mixitup_views_default_options($convert = FALSE) {
  $options = array(
    'selectors' => array(
      'target' => '.mix',
      'filter' => '.filter',
      'sort' => '.sort',
    ),
    'load' => array(
      'filter' => 'all',
      'sort' => 'default:asc',
    ),
    'animation' => array(
      'enable' => TRUE,
      'effects' => 'fade scale',
      'duration' => 600,
      'easing' => 'ease',
      'perspectiveDistance' => '3000px',
      'perspectiveOrigin' => '50% 50%',
      'queue' => TRUE,
      'queueLimit' => 1,
    ),
    'restrict' => array(
      'vocab' => FALSE,
      'vocab_ids' => array(),
    ),
  );

  // Allow other modules to alter the default options.
  drupal_alter('mixitup_views_default_options', $options);
  if ($convert) {
    $options = _mixitup_views_convert_from_mixitup_options($options);
  }
  return $options;
}

/**
 * Convert mixitup options array to needed.
 *
 * @param array $mixitup_options
 *   Options array in mixitup js style.
 *
 * @return array
 *   Converted array of mixitup params.
 */
function _mixitup_views_convert_from_mixitup_options(array $mixitup_options) {
  $converted_options = array();
  foreach ($mixitup_options as $cat => $options) {
    foreach ($options as $option => $default_value) {
      $converted_options[$cat . '_' . $option] = $default_value;
    }
  }
  return $converted_options;
}

/**
 * Apply mixitup library to container.
 *
 * @param string $container
 *   Container name.
 * @param array $options
 *   Array of mixitup options.
 */
function mixitup_views_apply($container, $options = array()) {
  if (mixitup_views_loaded() && !empty($container)) {

    // For any options not specified, use default options.
    $options += mixitup_views_default_options(TRUE);

    // Set of mixitup settings.
    $mixitup_settings = array(
      'mixitup' => array(
        $container => array(
          'selectors' => array(
            'target' => $options['selectors_target'],
            'filter' => $options['selectors_filter'],
            'sort' => $options['selectors_sort'],
          ),
          'load' => array(
            'filter' => $options['load_filter'],
            'sort' => $options['load_sort'],
          ),
          'animation' => array(
            'enable' => (bool) $options['animation_enable'],
            'effects' => $options['animation_effects'],
            'duration' => (int) $options['animation_duration'],
            'easing' => $options['animation_easing'],
            'perspectiveDistance' => $options['animation_perspectiveDistance'],
            'perspectiveOrigin' => $options['animation_perspectiveOrigin'],
            'queue' => (bool) $options['animation_queue'],
            'queueLimit' => (int) $options['animation_queueLimit'],
          ),
        ),
      ),
      'filters_form_id' => '#mixitup-views-filters-form',
      'reset_id' => '#reset',
      'filtering_type' => isset($options['filter_type']) ? $options['filter_type'] : 'checkboxes',
    );
    drupal_add_css(drupal_get_path('module', 'mixitup_views') . '/css/mixitup_views.css');
    $script_file = drupal_get_path('module', 'mixitup_views') . '/js/mixitup_views.js';

    // Apply the script.
    drupal_add_js($mixitup_settings, 'setting');
    drupal_add_js($script_file);
  }
}

/**
 * Get all node taxonomy id.
 *
 * @param int $nid
 *   Node id.
 *
 * @return array
 *   Array of tids.
 */
function _mixitup_views_get_node_tids($nid) {
  $tids = db_select('taxonomy_index', 'ti')
    ->fields('ti', array(
    'tid',
    'nid',
  ))
    ->condition('ti.nid', $nid)
    ->execute()
    ->fetchAllKeyed();
  return array_keys($tids);
}

/**
 * Get classes string for node.
 *
 * @param int $nid
 *   Node id.
 *
 * @return string
 *   Classes string.
 */
function mixitup_views_get_rows_classes($nid) {
  $tids = _mixitup_views_get_node_tids($nid);
  $classes = array();
  if (!empty($tids)) {
    foreach ($tids as $tid) {
      $classes[] = 'tid_' . $tid;
      mixitup_views_populate_filters($tid, $nid);
    }
  }
  $classes = implode(' ', $classes);
  return $classes;
}

/**
 * Populates structured array of used taxonomy terms.
 *
 * @param int $tid
 *   Taxonomy id.
 * @param int $nid
 *   Node id.
 *
 * @return array
 *   Array with filters.
 */
function mixitup_views_populate_filters($tid, $nid) {
  $filters =& drupal_static(__FUNCTION__);
  $term = taxonomy_term_load($tid);
  $filters[$term->vid]['.tid_' . $term->tid] = $term->name;
  mixitup_views_populate_node_filters($nid, $tid);
  return $filters;
}

/**
 * Collects info regarding wich nodes has a specific tid.
 *
 * @param int $nid
 *   Node id.
 * @param int $tid
 *   Taxonomy id.
 *
 * @return array
 *   Array with tid => array(nids).
 */
function mixitup_views_populate_node_filters($nid, $tid) {
  $node_filters =& drupal_static(__FUNCTION__);
  $node_filters[$tid][] = $nid;
  return $node_filters;
}

/**
 * Set nodes count for mixitup views.
 *
 * @param int $count
 *   Number of nodes.
 *
 * @return int $nodes_count
 *   Nodes count.
 */
function mixitup_views_set_nodes_count($count) {
  $nodes_count =& drupal_static(__FUNCTION__);
  $nodes_count = $count;
  return $nodes_count;
}

/**
 * Unset unneeded terms.
 *
 * If all records share same terms (One or more). In that case it
 * doesn't make sense to show all terms.
 *
 * @param array $terms
 *   Terms array.
 *
 * @return array $terms
 *   Filtered array of terms.
 */
function mixitup_views_filter_terms(array $terms) {
  $node_filters =& drupal_static('mixitup_views_populate_node_filters');
  $nodes_count =& drupal_static('mixitup_views_set_nodes_count');
  if ($node_filters) {
    foreach ($node_filters as $tid => $nids) {
      if (count($nids) == $nodes_count) {
        unset($terms['.tid_' . $tid]);
      }
    }
  }
  return $terms;
}

/**
 * Filters form.
 */
function mixitup_views_filters_form($form, &$form_state, $options) {
  $filters =& drupal_static('mixitup_views_populate_filters');
  $form = array();
  if (isset($filters)) {
    foreach ($filters as $vid => $terms) {

      // Show only selected vocabularies.
      if ($options['restrict_vocab'] == 1 && (!isset($options['restrict_vocab_ids'][$vid]) || $options['restrict_vocab_ids'][$vid] == 0)) {
        unset($filters[$vid]);
        continue;
      }

      // If all nodes have just one term tagged, it doesn't make sense
      // to show a term and clear filters link.
      if (count($terms) < 2) {
        unset($filters[$vid]);
        continue;
      }
      $vocab = taxonomy_vocabulary_load($vid);
      $terms = mixitup_views_filter_terms($terms);
      if (isset($options['filter_type'])) {
        switch ($options['filter_type']) {
          case 'checkboxes':
            $form['filter_' . $vid] = array(
              '#type' => 'checkboxes',
              '#title' => $vocab->name,
              '#options' => $terms,
              '#attributes' => array(
                'class' => array(
                  'mixitup_views_filter',
                ),
                'vid' => $vid,
              ),
              '#multiple' => TRUE,
            );
            break;
          case 'select':
            $form['filter_' . $vid] = array(
              '#type' => 'select',
              '#title' => $vocab->name,
              '#options' => array(
                '' => t('All'),
              ) + $terms,
              '#attributes' => array(
                'class' => array(
                  'mixitup_views_filter',
                ),
                'vid' => $vid,
              ),
              '#multiple' => FALSE,
            );
            break;
        }
      }
    }
    if ($filters) {
      $form['reset'] = array(
        '#markup' => l(t('Clear Filters'), '', array(
          'fragment' => 'reset',
          'external' => TRUE,
          'attributes' => array(
            'id' => 'reset',
          ),
        )),
      );
    }
  }
  if (isset($options['use_sort']) && $options['use_sort'] == 1 && isset($options['sorts'])) {
    $form['sort'] = array(
      '#markup' => theme('mixitup_views_sorting', array(
        'sorts' => $options['sorts'],
      )),
    );
  }
  return $form;
}

/**
 * Implements hook_help().
 */
function mixitup_views_help($path, $arg) {
  switch ($path) {
    case 'admin/help#mixitup_views':
      $path = dirname(__FILE__) . '/README.txt';
      if (file_exists($path)) {
        $readme = file_get_contents($path);
      }
      if (!isset($readme)) {
        return NULL;
      }
      $output = '<pre>' . $readme . '</pre>';
      return $output;
  }
}

Functions

Namesort descending Description
mixitup_views_apply Apply mixitup library to container.
mixitup_views_default_options Get default option for mixitup js.
mixitup_views_filters_form Filters form.
mixitup_views_filter_terms Unset unneeded terms.
mixitup_views_get_rows_classes Get classes string for node.
mixitup_views_help Implements hook_help().
mixitup_views_installed Check if the Mixitup library is installed.
mixitup_views_libraries_info Implements hook_libraries_info().
mixitup_views_loaded Check if the Mixitup library has been loaded.
mixitup_views_populate_filters Populates structured array of used taxonomy terms.
mixitup_views_populate_node_filters Collects info regarding wich nodes has a specific tid.
mixitup_views_set_nodes_count Set nodes count for mixitup views.
mixitup_views_theme Implements hook_theme().
mixitup_views_views_api Implements hook_views_api().
template_preprocess_views_view_mixitup Preprocess function for views_view_mixitup.tpl.php.
_mixitup_views_convert_from_mixitup_options Convert mixitup options array to needed.
_mixitup_views_get_node_tids Get all node taxonomy id.