You are here

function views_timelinejs_plugin_style_timelinejs::render in Views TimelineJS integration 7

Same name and namespace in other branches
  1. 7.3 views_timelinejs_plugin_style_timelinejs.inc \views_timelinejs_plugin_style_timelinejs::render()

Render the display.

Overrides views_plugin_style::render

File

./views_timelinejs_plugin_style_timelinejs.inc, line 404
Views Style.

Class

views_timelinejs_plugin_style_timelinejs
Unformatted style plugin.

Code

function render() {

  // Determine if required fields are mapped.
  $required_mappings = array(
    'date',
    'headline',
  );
  $has_required_mappings = TRUE;
  foreach ($required_mappings as $field_name) {
    if (!$this
      ->getDefinedUsage($field_name)) {
      $has_required_mappings = FALSE;
    }
  }

  // Render if there's enough mapped fields.
  if ($has_required_mappings) {
    $field_mapping = array(
      'startDate' => 'date',
      'endDate' => 'date',
      'headline' => 'headline',
      'text' => 'bodytext',
      'media' => 'media',
      'caption' => 'caption',
      'credit' => 'credit',
      'tag' => 'tag',
    );
    $rows = array();

    // Render fields to trigger rewriting and other field processing.
    $this
      ->render_fields($this->view->result);
    if (!empty($this->options['timeline_config']['start_at_current'])) {

      // Gives you a timestamp of the date
      $date_check = strtotime('now');

      // Holds the difference of the closest date
      $difference = NULL;

      // Holds the index in the array
      $start_at_current = NULL;
    }

    // Build a TimelineJS friendly array from the views data.
    $this->view->row_index = 0;
    foreach ($this->view->result as $count => $row) {
      $data = array();
      $data['asset'] = array();
      $this->view->row_index = $count;

      // Build the data we need.
      foreach ($field_mapping as $target_field => $source_field) {
        $tmp = $this
          ->getDefinedUsage($source_field);

        // Don't render fields that haven't been mapped.
        if (empty($tmp['fieldname']) || !isset($this->view->field[$tmp['fieldname']])) {
          continue;
        }

        // Headline - can use any view field, uses views rendering.
        if ($target_field == 'headline') {
          $headline_field = $this->options['timeline_fields']['headline'];
          $rows[$count][$target_field] = $this->rendered_fields[$count][$headline_field];
        }

        // Body - can use any view field, uses views rendering.
        if ($target_field == 'text') {
          $body_field = $this->options['timeline_fields']['bodytext'];
          $rows[$count][$target_field] = $this->rendered_fields[$count][$body_field];
        }

        // Tag.
        if ($target_field == 'tag') {
          $value = '';

          // Check if if a tag exists.
          if (isset($this->view->field[$tmp['fieldname']])) {
            $value = $this->view->field[$tmp['fieldname']]
              ->get_value($row);
            if (is_array($value)) {
              $value = array_shift($value);
            }
            if ($conversion_callback = views_timelinejs_get_callback($tmp['handler'], $tmp['field_type'], 'tag_sources')) {
              $value = call_user_func($conversion_callback, $value, array(
                'field' => $tmp,
              ));
            }
          }
          $rows[$count][$target_field] = check_plain($value);
        }

        // Start and End date.
        if (in_array($target_field, array(
          'startDate',
          'endDate',
        ))) {
          $date = array();

          // Load field data.
          $value = $this->view->field[$tmp['fieldname']]
            ->get_value($row);

          // If it's a date field, we have an array.
          if (is_array($value)) {
            $value = array_shift($value);
          }

          // Make sure created and changed fields work as date sources.
          if ($tmp['fieldname'] == 'created' || $tmp['fieldname'] == 'changed') {
            $tmp['field_type'] = 'date';
          }
          if ($conversion_callback = views_timelinejs_get_callback($tmp['handler'], $tmp['field_type'], 'date_sources')) {
            $date['formatted'] = call_user_func($conversion_callback, $value, 'csv', array(
              'field' => $tmp,
            ));
            $date['timestamp'] = call_user_func($conversion_callback, $value, 'timestamp', array(
              'field' => $tmp,
            ));
          }
          if (isset($date) && $date) {
            if (is_array($date['formatted'])) {
              if ($target_field == 'startDate') {
                if ($date['formatted']['value'] != "FALSE") {
                  if (!empty($this->options['timeline_config']['start_at_current'])) {

                    // abs to get the absolute difference
                    $diff = abs($date['timestamp']['value'] - $date_check);

                    // If the difference is smaller than the absolute difference of the last date we need to update our values here
                    if ($difference == NULL || $diff < $difference) {
                      $difference = $diff;
                      $start_at_current = $count;
                    }
                  }
                  $rows[$count][$target_field] = check_plain($date['formatted']['value']);
                }
                else {
                  drupal_set_message(t("Could not format date for field %field in node @nid. It won't be shown in timeline.", array(
                    '@nid' => $row->nid,
                    '%field' => $tmp['fieldname'],
                  )), 'error');
                }
              }
              elseif ($target_field == 'endDate' && isset($date['formatted']['value2'])) {
                if ($date['formatted']['value'] != "FALSE") {
                  $rows[$count][$target_field] = check_plain($date['formatted']['value2']);
                }
                else {
                  drupal_set_message(t("Could not format date for field %field in node @nid. It won't be shown in timeline.", array(
                    '@nid' => $row->nid,
                    '%field' => $tmp['fieldname'],
                  )), 'error');
                }
              }
            }
            else {
              $rows[$count][$target_field] = check_plain($date['formatted']);
            }
          }
        }

        // Media URL.
        if ($target_field == 'media' && isset($row->_field_data[$this->view->field[$tmp['fieldname']]->field_alias])) {
          $value = $this->view->field[$tmp['fieldname']]
            ->get_value($row);
          if (empty($value) && !empty($this->view->field[$tmp['fieldname']]->options['empty'])) {
            $token = $this->view->field[$tmp['fieldname']]->options['empty'];
            $token = substr($token, 0, strpos($token, ']'));
            $token = str_replace(array(
              '[',
              ']',
            ), '', $token);

            // We've got to replace the $tmp information for proper handling.
            $tmp['fieldname'] = $token;
            $tmp['field_type'] = $this->view->field[$token]->field_info['type'];
            $tmp['handler'] = $this->view->field[$token]->definition['handler'];
            $tmp['alias'] = $this->view->field[$token]->field_alias;
            $value = $this->view->field[$token]
              ->get_value($row);
          }
          if (is_array($value)) {
            $value = array_shift($value);

            // Allow for imagefield image style selection.
            if (!empty($this->view->field[$tmp['fieldname']]->options['settings']['image_style']) && !empty($value['uri'])) {
              $value['uri'] = image_style_url($this->view->field[$tmp['fieldname']]->options['settings']['image_style'], $value['uri']);
            }
          }
          if ($conversion_callback = views_timelinejs_get_callback($tmp['handler'], $tmp['field_type'], 'media_sources')) {
            $media['formatted'] = call_user_func($conversion_callback, $value, array(
              'field' => $tmp,
            ));
          }
          if ($media['formatted']) {
            $rows[$count]['asset'][$target_field] = check_plain($media['formatted']);
            $rows[$count]['asset']['thumbnail'] = check_plain($media['formatted']);
          }
        }

        // Media Caption, Media Credit - both plain text.
        if (in_array($target_field, array(
          'caption',
          'credit',
        ))) {
          if ($tmp['handler'] != NULL) {
            $v_text = $this->view->field[$tmp['fieldname']]
              ->get_value($row);
            if (is_array($v_text)) {
              $v_text = array_shift($v_text);
            }
            if (!is_string($v_text)) {
              $v_text = $v_text['value'];
            }
            if ($v_text) {
              $rows[$count]['asset'][$target_field] = check_plain($v_text);
            }
          }
        }
      }
    }
    unset($this->view->row_index);

    // Allow other modules to alter timeline rows before rendering by
    // implementing hook_views_timelinejs_rows_alter().
    $view = clone $this->view;
    drupal_alter('views_timelinejs_rows', $rows, $view);
    unset($view);

    // Prepare data array that TimelineJS understands.
    $data = array(
      'timeline' => array(
        'headline' => 'Title',
        'type' => 'default',
        'date' => $rows,
      ),
    );
    if (!empty($this->options['timeline_config']['start_at_current'])) {
      $data['timeline']['start_at_current'] = $start_at_current;
    }
  }
  else {

    // Populate a fake timeline with instructions.
    $date = new DateTime();
    $data = array(
      'timeline' => array(
        'headline' => t('Insufficient field mapping'),
        'type' => 'default',
        'date' => array(
          array(
            'headline' => t('Please configure the field mapping by going to Format: TimelineJS - Settings.'),
            'startDate' => $date
              ->format('Y,m,d,H,i'),
          ),
        ),
      ),
    );
  }

  // Allow other modules to alter timeline data before rendering by
  // implementing hook_views_timelinejs_data_alter().
  $view = clone $this->view;
  drupal_alter('views_timelinejs_data', $data, $view);
  unset($view);

  // Skip rendering if view is being edited or previewed.
  if (!$this->view->editing) {
    return theme('views_timelinejs', array(
      'view' => $this->view,
      'options' => $this->options,
      'rows' => $data,
    ));
  }
  else {
    return '<pre>' . print_r($data, 1) . '</pre>';
  }
}