[ Index ]

PHP Cross Reference of Drupal 6 (yi-drupal)

title

Body

[close]

/sites/all/modules/views/handlers/ -> views_handler_field.inc (source)

   1  <?php
   2  /**
   3   * @defgroup views_field_handlers Views' field handlers
   4   * @{
   5   * Handlers to tell Views how to build and display fields.
   6   *
   7   */
   8  
   9  /**
  10   * Base field handler that has no options and renders an unformatted field.
  11   *
  12   * Definition terms:
  13   * - additional fields: An array of fields that should be added to the query
  14   *                      for some purpose. The array is in the form of:
  15   *                      array('identifier' => array('table' => tablename,
  16   *                      'field' => fieldname); as many fields as are necessary
  17   *                      may be in this array.
  18   * - click sortable: If TRUE, this field may be click sorted.
  19   */
  20  class views_handler_field extends views_handler {
  21    var $field_alias = 'unknown';
  22    var $aliases = array();
  23  
  24    /**
  25     * Construct a new field handler.
  26     */
  27    function construct() {
  28      parent::construct();
  29  
  30      $this->additional_fields = array();
  31      if (!empty($this->definition['additional fields'])) {
  32        $this->additional_fields = $this->definition['additional fields'];
  33      }
  34  
  35      if (!isset($this->options['exclude'])) {
  36        $this->options['exclude'] = '';
  37      }
  38    }
  39  
  40    /**
  41     * Determine if this field can allow advanced rendering.
  42     *
  43     * Fields can set this to FALSE if they do not wish to allow
  44     * token based rewriting or link-making.
  45     */
  46    function allow_advanced_render() {
  47      return TRUE;
  48    }
  49  
  50    function init(&$view, $options) {
  51      parent::init($view, $options);
  52  
  53      $this->options += array(
  54        'exclude' => FALSE,
  55      );
  56    }
  57  
  58    /**
  59     * Called to add the field to a query.
  60     */
  61    function query() {
  62      $this->ensure_my_table();
  63      // Add the field.
  64      $this->field_alias = $this->query->add_field($this->table_alias, $this->real_field);
  65  
  66      $this->add_additional_fields();
  67    }
  68  
  69    /**
  70     * Add 'additional' fields to the query.
  71     *
  72     * @param $fields
  73     * An array of fields. The key is an identifier used to later find the
  74     * field alias used. The value is either a string in which case it's
  75     * assumed to be a field on this handler's table; or it's an array in the
  76     * form of
  77     * @code array('table' => $tablename, 'field' => $fieldname) @endcode
  78     */
  79    function add_additional_fields($fields = NULL) {
  80      if (!isset($fields)) {
  81        // notice check
  82        if (empty($this->additional_fields)) {
  83          return;
  84        }
  85        $fields = $this->additional_fields;
  86      }
  87      if (!empty($fields) && is_array($fields)) {
  88        foreach ($fields as $identifier => $info) {
  89          if (is_array($info)) {
  90            if (isset($info['table'])) {
  91              $table_alias = $this->query->ensure_table($info['table'], $this->relationship);
  92            }
  93            else {
  94              $table_alias = $this->table_alias;
  95            }
  96            if (empty($table_alias)) {
  97              vpr(t('Handler @handler tried to add additional_field @identifier but @table could not be added!', array('@handler' => $this->definition['handler'], '@identifier' => $identifier, '@table' => $info['table'])));
  98              $this->aliases[$identifier] = 'broken';
  99              continue;
 100            }
 101            $this->aliases[$identifier] = $this->query->add_field($table_alias, $info['field']);
 102          }
 103          else {
 104            $this->aliases[$info] = $this->query->add_field($this->table_alias, $info);
 105          }
 106        }
 107      }
 108    }
 109  
 110    /**
 111     * Called to determine what to tell the clicksorter.
 112     */
 113    function click_sort($order) {
 114      $this->query->add_orderby($this->table_alias, $this->real_field, $order, $this->field_alias);
 115    }
 116  
 117    /**
 118     * Determine if this field is click sortable.
 119     */
 120    function click_sortable() {
 121      return !empty($this->definition['click sortable']);
 122    }
 123  
 124    /**
 125     * Get this field's label.
 126     */
 127    function label() {
 128      if (!isset($this->options['label'])) {
 129        return '';
 130      }
 131      return $this->options['label'];
 132    }
 133  
 134    /**
 135     * Return DIV or SPAN based upon the field's element type.
 136     */
 137    function element_type() {
 138      if (isset($this->definition['element type'])) {
 139        return $this->definition['element type'];
 140      }
 141  
 142      return 'span';
 143    }
 144  
 145    function option_definition() {
 146      $options = parent::option_definition();
 147  
 148      $options['label'] = array('default' => $this->definition['title'], 'translatable' => TRUE);
 149      $options['alter'] = array(
 150        'contains' => array(
 151          'alter_text' => array('default' => FALSE),
 152          'text' => array('default' => '', 'translatable' => TRUE),
 153          'make_link' => array('default' => FALSE),
 154          'path' => array('default' => '', 'translatable' => TRUE),
 155          'absolute' => array('default' => '', 'translatable' => FALSE),
 156          'alt' => array('default' => '', 'translatable' => TRUE),
 157          'rel' => array('default' => ''),
 158          'link_class' => array('default' => ''),
 159          'prefix' => array('default' => '', 'translatable' => TRUE),
 160          'suffix' => array('default' => '', 'translatable' => TRUE),
 161          'target' => array('default' => '', 'translatable' => TRUE),
 162          'trim' => array('default' => FALSE),
 163          'max_length' => array('default' => ''),
 164          'word_boundary' => array('default' => TRUE),
 165          'ellipsis' => array('default' => TRUE),
 166          'strip_tags' => array('default' => FALSE),
 167          'html' => array('default' => FALSE),
 168        ),
 169      );
 170      $options['empty'] = array('default' => '', 'translatable' => TRUE);
 171      $options['hide_empty'] = array('default' => FALSE);
 172      $options['empty_zero'] = array('default' => FALSE);
 173      $options['hide_alter_empty'] = array('default' => TRUE);
 174  
 175      return $options;
 176    }
 177  
 178    /**
 179     * Default options form that provides the label widget that all fields
 180     * should have.
 181     */
 182    function options_form(&$form, &$form_state) {
 183      $form['label'] = array(
 184        '#type' => 'textfield',
 185        '#title' => t('Label'),
 186        '#default_value' => isset($this->options['label']) ? $this->options['label'] : '',
 187        '#description' => t('The label for this field that will be displayed to end users if the style requires it.'),
 188      );
 189      $form['exclude'] = array(
 190        '#type' => 'checkbox',
 191        '#title' => t('Exclude from display'),
 192        '#default_value' => $this->options['exclude'],
 193        '#description' => t('Check this box to not display this field, but still load it in the view.  Use this option to not show a grouping field in each record, or when doing advanced theming.'),
 194      );
 195  
 196      if ($this->allow_advanced_render()) {
 197        $form['alter']['#tree'] = TRUE;
 198        $form['alter']['alter_text'] = array(
 199          '#type' => 'checkbox',
 200          '#title' => t('Rewrite the output of this field'),
 201          '#description' => t('If checked, you can alter the output of this field by specifying a string of text with replacement tokens that can use any existing field output.'),
 202          '#default_value' => $this->options['alter']['alter_text'],
 203        );
 204  
 205        $form['alter']['text'] = array(
 206          '#title' => t('Text'),
 207          '#type' => 'textarea',
 208          '#default_value' => $this->options['alter']['text'],
 209          '#description' => t('The text to display for this field. You may include HTML. You may enter data from this view as per the "Replacement patterns" below.'),
 210          '#process' => array('views_process_dependency'),
 211          '#dependency' => array(
 212            'edit-options-alter-alter-text' => array(1)
 213          ),
 214        );
 215  
 216        $form['alter']['make_link'] = array(
 217          '#type' => 'checkbox',
 218          '#title' => t('Output this field as a link'),
 219          '#description' => t('If checked, this field will be made into a link. The destination must be given below.'),
 220          '#default_value' => $this->options['alter']['make_link'],
 221        );
 222        $form['alter']['path'] = array(
 223          '#title' => t('Link path'),
 224          '#type' => 'textfield',
 225          '#default_value' => $this->options['alter']['path'],
 226          '#description' => t('The Drupal path or absolute URL for this link. You may enter data from this view as per the "Replacement patterns" below.'),
 227          '#process' => array('views_process_dependency'),
 228          '#dependency' => array(
 229            'edit-options-alter-make-link' => array(1)
 230          ),
 231          '#maxlength' => 255,
 232        );
 233         $form['alter']['absolute'] = array(
 234           '#type' => 'checkbox',
 235           '#title' => t('Use absolute path'),
 236           '#default_value' => $this->options['alter']['absolute'],
 237           '#process' => array('views_process_dependency'),
 238           '#dependency' => array(
 239             'edit-options-alter-make-link' => array(1)
 240           ),
 241         );
 242  
 243        $form['alter']['link_class'] = array(
 244          '#title' => t('Link class'),
 245          '#type' => 'textfield',
 246          '#default_value' => $this->options['alter']['link_class'],
 247          '#description' => t('The CSS class to apply to the link.'),
 248          '#process' => array('views_process_dependency'),
 249          '#dependency' => array(
 250            'edit-options-alter-make-link' => array(1)
 251          ),
 252        );
 253        $form['alter']['alt'] = array(
 254          '#title' => t('Alt text'),
 255          '#type' => 'textfield',
 256          '#default_value' => $this->options['alter']['alt'],
 257          '#description' => t('Text to place as "alt" text which most browsers display as a tooltip when hovering over the link.'),
 258          '#process' => array('views_process_dependency'),
 259          '#dependency' => array(
 260            'edit-options-alter-make-link' => array(1)
 261          ),
 262        );
 263        $form['alter']['rel'] = array(
 264          '#title' => t('Rel Text'),
 265          '#type' => 'textfield',
 266          '#default_value' => $this->options['alter']['rel'],
 267          '#description' => t('Include Rel attribute for use in lightbox2 or other javascript utility.'),
 268          '#process' => array('views_process_dependency'),
 269          '#dependency' => array(
 270            'edit-options-alter-make-link' => array(1)
 271          ),
 272        );
 273        $form['alter']['prefix'] = array(
 274          '#title' => t('Prefix text'),
 275          '#type' => 'textfield',
 276          '#default_value' => $this->options['alter']['prefix'],
 277          '#description' => t('Any text to display before this link. You may include HTML.'),
 278          '#process' => array('views_process_dependency'),
 279          '#dependency' => array(
 280            'edit-options-alter-make-link' => array(1)
 281          ),
 282        );
 283        $form['alter']['suffix'] = array(
 284          '#title' => t('Suffix text'),
 285          '#type' => 'textfield',
 286          '#default_value' => $this->options['alter']['suffix'],
 287          '#description' => t('Any text to display after this link. You may include HTML.'),
 288          '#process' => array('views_process_dependency'),
 289          '#dependency' => array(
 290            'edit-options-alter-make-link' => array(1)
 291          ),
 292        );
 293        $form['alter']['target'] = array(
 294          '#title' => t('Target'),
 295          '#type' => 'textfield',
 296          '#default_value' => $this->options['alter']['target'],
 297          '#description' => t("Target of the link, such as _blank, _parent or an iframe's name. This field is rarely used."),
 298          '#process' => array('views_process_dependency'),
 299          '#dependency' => array(
 300            'edit-options-alter-make-link' => array(1)
 301          ),
 302        );
 303  
 304  
 305        // Get a list of the available fields and arguments for token replacement.
 306        $options = array();
 307        foreach ($this->view->display_handler->get_handlers('field') as $field => $handler) {
 308          $options[t('Fields')]["[$field]"] = $handler->ui_name();
 309          // We only use fields up to (and including) this one.
 310          if ($field == $this->options['id']) {
 311            break;
 312          }
 313        }
 314        $count = 0; // This lets us prepare the key as we want it printed.
 315        foreach ($this->view->display_handler->get_handlers('argument') as $arg => $handler) {
 316          $options[t('Arguments')]['%' . ++$count] = t('@argument title', array('@argument' => $handler->ui_name()));
 317          $options[t('Arguments')]['!' . $count] = t('@argument input', array('@argument' => $handler->ui_name()));
 318        }
 319  
 320        $this->document_self_tokens($options[t('Fields')]);
 321  
 322        // Default text.
 323        $output = t('<p>You must add some additional fields to this display before using this field. These fields may be marked as <em>Exclude from display</em> if you prefer. Note that due to rendering order, you cannot use fields that come after this field; if you need a field not listed here, rearrange your fields.</p>');
 324        // We have some options, so make a list.
 325        if (!empty($options)) {
 326          $output = t('<p>The following tokens are available for this field. Note that due to rendering order, you cannot use fields that come after this field; if you need a field not listed here, rearrange your fields.
 327  If you would like to have the characters %5B and %5D please use the html entity codes \'%5B\' or  \'%5D\' or they will get replaced with empty space.</p>');
 328          foreach (array_keys($options) as $type) {
 329            if (!empty($options[$type])) {
 330              $items = array();
 331              foreach ($options[$type] as $key => $value) {
 332                $items[] = $key . ' == ' . $value;
 333              }
 334              $output .= theme('item_list', $items, $type);
 335            }
 336          }
 337        }
 338        // This construct uses 'hidden' and not markup because process doesn't
 339        // run. It also has an extra div because the dependency wants to hide
 340        // the parent in situations like this, so we need a second div to
 341        // make this work.
 342        $form['alter']['help'] = array(
 343          '#type' => 'hidden',
 344          '#id' => 'views-tokens-help',
 345          '#prefix' => '<div><fieldset id="views-tokens-help"><legend>' . t('Replacement patterns') . '</legend>' . $output . '</fieldset></div>',
 346          '#process' => array('views_process_dependency'),
 347          '#dependency' => array(
 348            'edit-options-alter-make-link' => array(1),
 349            'edit-options-alter-alter-text' => array(1),
 350          ),
 351        );
 352  
 353        $form['alter']['trim'] = array(
 354          '#type' => 'checkbox',
 355          '#title' => t('Trim this field to a maximum length'),
 356          '#description' => t('If checked, this field be trimmed to a maximum length in characters.'),
 357          '#default_value' => $this->options['alter']['trim'],
 358        );
 359  
 360        $form['alter']['max_length'] = array(
 361          '#title' => t('Maximum length'),
 362          '#type' => 'textfield',
 363          '#default_value' => $this->options['alter']['max_length'],
 364          '#description' => t('The maximum number of characters this field can be.'),
 365          '#process' => array('views_process_dependency'),
 366          '#dependency' => array(
 367            'edit-options-alter-trim' => array(1)
 368          ),
 369        );
 370  
 371        $form['alter']['word_boundary'] = array(
 372          '#type' => 'checkbox',
 373          '#title' => t('Trim only on a word boundary'),
 374          '#description' => t('If checked, this field be trimmed only on a word boundary. This is guaranteed to be the maximum characters stated or less. If there are no word boundaries this could trim a field to nothing.'),
 375          '#default_value' => $this->options['alter']['word_boundary'],
 376          '#process' => array('views_process_dependency'),
 377          '#dependency' => array(
 378            'edit-options-alter-trim' => array(1)
 379          ),
 380        );
 381  
 382        $form['alter']['ellipsis'] = array(
 383          '#type' => 'checkbox',
 384          '#title' => t('Add an ellipsis'),
 385          '#description' => t('If checked, a "..." will be added if a field was trimmed.'),
 386          '#default_value' => $this->options['alter']['ellipsis'],
 387          '#process' => array('views_process_dependency'),
 388          '#dependency' => array(
 389            'edit-options-alter-trim' => array(1)
 390          ),
 391        );
 392  
 393        $form['alter']['html'] = array(
 394          '#type' => 'checkbox',
 395          '#title' => t('Field can contain HTML'),
 396          '#description' => t('If checked, HTML corrector will be run to ensure tags are properly closed after trimming.'),
 397          '#default_value' => $this->options['alter']['html'],
 398          '#process' => array('views_process_dependency'),
 399          '#dependency' => array(
 400            'edit-options-alter-trim' => array(1)
 401          ),
 402        );
 403  
 404        $form['alter']['strip_tags'] = array(
 405          '#type' => 'checkbox',
 406          '#title' => t('Strip HTML tags'),
 407          '#description' => t('If checked, all HTML tags will be stripped.'),
 408          '#default_value' => $this->options['alter']['strip_tags'],
 409          '#process' => array('views_process_dependency'),
 410        );
 411      }
 412  
 413      $form['empty'] = array(
 414        '#type' => 'textfield',
 415        '#title' => t('Empty text'),
 416        '#default_value' => $this->options['empty'],
 417        '#description' => t('If the field is empty, display this text instead.'),
 418      );
 419  
 420      $form['empty_zero'] = array(
 421        '#type' => 'checkbox',
 422        '#title' => t('Count the number 0 as empty'),
 423        '#default_value' => $this->options['empty_zero'],
 424        '#description' => t('If the field contains the number zero, display the empty text instead'),
 425      );
 426  
 427      $form['hide_empty'] = array(
 428        '#type' => 'checkbox',
 429        '#title' => t('Hide if empty'),
 430        '#default_value' => $this->options['hide_empty'],
 431        '#description' => t('Enable to hide this field if it is empty. Note that the field label or rewritten output may still be displayed. To hide labels, check the style or row style settings for empty fields. To hide rewritten content, check the Hide rewriting if empty checkbox.'),
 432      );
 433  
 434      $form['hide_alter_empty'] = array(
 435        '#type' => 'checkbox',
 436        '#title' => t('Do not rewrite if empty'),
 437        '#default_value' => $this->options['hide_alter_empty'],
 438      );
 439    }
 440  
 441    /**
 442     * Provide extra data to the administration form
 443     */
 444    function admin_summary() {
 445      return $this->label();
 446    }
 447  
 448    /**
 449     * Run before any fields are rendered.
 450     *
 451     * This gives the handlers some time to set up before any handler has
 452     * been rendered.
 453     *
 454     * @param $values
 455     *   An array of all objects returned from the query.
 456     */
 457    function pre_render($values) { }
 458  
 459    /**
 460     * Render the field.
 461     *
 462     * @param $values
 463     *   The values retrieved from the database.
 464     */
 465    function render($values) {
 466      $value = $values->{$this->field_alias};
 467      return check_plain($value);
 468    }
 469  
 470    /**
 471     * Render a field using advanced settings.
 472     *
 473     * This renders a field normally, then decides if render-as-link and
 474     * text-replacement rendering is necessary.
 475     */
 476    function advanced_render($values) {
 477      if ($this->allow_advanced_render() && method_exists($this, 'render_item')) {
 478        $raw_items = $this->get_items($values);
 479      }
 480      else {
 481        $this->last_render = $value = $this->render($values);
 482        $this->original_value = $value;
 483      }
 484  
 485      if ($this->allow_advanced_render()) {
 486        $tokens = NULL;
 487        if (method_exists($this, 'render_item')) {
 488          $items = array();
 489          foreach ($raw_items as $count => $item) {
 490            $this->last_render = $this->render_item($count, $item);
 491            $this->original_value = $this->last_render;
 492  
 493            $alter = $item + $this->options['alter'];
 494            $items[] = $this->render_text($alter);
 495          }
 496  
 497          $value = $this->render_items($items);
 498        }
 499        else {
 500          $value = $this->render_text($this->options['alter']);
 501        }
 502  
 503        // This happens here so that render_as_link can get the unaltered value of
 504        // this field as a token rather than the altered value.
 505        $this->last_render = $value;
 506      }
 507  
 508      if (empty($this->last_render)) {
 509        if (($this->last_render !== 0 && $this->last_render !== '0') || !empty($this->options['empty_zero'])) {
 510          $alter = $this->options['alter'];
 511          $alter['alter_text'] = 1;
 512          $alter['text'] = $this->options['empty'];
 513          $this->last_render = $this->render_text($alter);
 514        }
 515      }
 516  
 517      return $this->last_render;
 518    }
 519  
 520    /**
 521     * Perform an advanced text render for the item.
 522     *
 523     * This is separated out as some fields may render lists, and this allows
 524     * each item to be handled individually.
 525     */
 526    function render_text($alter) {
 527      $value = trim($this->last_render);
 528  
 529      if (!empty($alter['alter_text']) && $alter['text'] !== '') {
 530        $tokens = $this->get_render_tokens($alter);
 531        $value = $this->render_altered($alter, $tokens);
 532      }
 533  
 534      if ((($this->options['hide_empty'] && empty($value)) || ($this->options['hide_alter_empty'] && empty($this->original_value))) && ($value !== 0 || $this->options['empty_zero'])) {
 535        return '';
 536      }
 537  
 538      if (!empty($alter['strip_tags'])) {
 539        $value = strip_tags($value);
 540      }
 541  
 542      if (!empty($alter['trim']) && !empty($alter['max_length'])) {
 543        $value = $this->render_trim_text($alter, $value);
 544      }
 545  
 546      if (!empty($alter['make_link']) && !empty($alter['path'])) {
 547        if (!isset($tokens)) {
 548         $tokens = $this->get_render_tokens($alter);
 549        }
 550        $value = $this->render_as_link($alter, $value, $tokens);
 551      }
 552  
 553      return $value;
 554    }
 555  
 556    /**
 557     * Render this field as altered text, from a fieldset set by the user.
 558     */
 559    function render_altered($alter, $tokens) {
 560      // Filter this right away as our substitutions are already sanitized.
 561      $value = filter_xss_admin($alter['text']);
 562      $value = strtr($value, $tokens);
 563  
 564      return $value;
 565    }
 566  
 567    /**
 568     * Trim the field down to the specified length.
 569     */
 570    function render_trim_text($alter, $value) {
 571      if (!empty($alter['strip_tags'])) {
 572        // NOTE: It's possible that some external fields might override the
 573        // element type so if someone from, say, CCK runs into a bug here,
 574        // this may be why =)
 575        $this->definition['element type'] = 'span';
 576      }
 577      return views_trim_text($alter, $value);
 578    }
 579  
 580    /**
 581     * Render this field as a link, with the info from a fieldset set by
 582     * the user.
 583     */
 584    function render_as_link($alter, $text, $tokens) {
 585      $value = '';
 586  
 587      if (!empty($alter['prefix'])) {
 588        $value .= filter_xss_admin(strtr($alter['prefix'], $tokens));
 589      }
 590  
 591      $options = array(
 592        'html' => TRUE,
 593        'absolute' => !empty($alter['absolute']) ? TRUE : FALSE,
 594      );
 595  
 596      // $path will be run through check_url() by l() so we do not need to
 597      // sanitize it ourselves.
 598      $path = $alter['path'];
 599  
 600      // html_entity_decode removes <front>, so check whether its different to front.
 601      if ($path != '<front>') {
 602        // Use strip tags as there should never be HTML in the path.
 603        // However, we need to preserve special characters like " that
 604        // were removed by check_plain().
 605        $path = strip_tags(html_entity_decode(strtr($path, $tokens)));
 606      }
 607  
 608      // If the path is empty do not build a link around the given text and return
 609      // it as is.
 610      if (empty($path)) {
 611        return $text;
 612      }
 613  
 614      // Parse the URL and move any query and fragment parameters out of the path.
 615      $url = parse_url($path);
 616      if (isset($url['query'])) {
 617        $path = strtr($path, array('?' . $url['query'] => ''));
 618        $options['query'] = $url['query'];
 619      }
 620      if (isset($url['fragment'])) {
 621        $path = strtr($path, array('#' . $url['fragment'] => ''));
 622        // If the path is empty we want to have a fragment for the current site.
 623        if ($path == '') {
 624          $options['external'] = TRUE;
 625        }
 626        $options['fragment'] = $url['fragment'];
 627      }
 628  
 629      $alt = strtr($alter['alt'], $tokens);
 630      // Set the title attribute of the link only if it improves accessibility
 631      if ($alt && $alt != $text) {
 632        $options['attributes']['title'] = html_entity_decode($alt, ENT_QUOTES);
 633      }
 634  
 635      $class = strtr($alter['link_class'], $tokens);
 636      if ($class) {
 637        $options['attributes']['class'] = $class;
 638      }
 639  
 640      if (!empty($alter['rel']) && $rel = strtr($alter['rel'], $tokens)) {
 641        $options['attributes']['rel'] = $rel;
 642      }
 643  
 644      $target = check_plain(trim(strtr($alter['target'],$tokens)));
 645      if (!empty($target)) {
 646        $options['attributes']['target'] = $target;
 647      }
 648  
 649      // Allow the addition of arbitrary attributes to links. Additional attributes
 650      // currently can only be altered in preprocessors and not within the UI.
 651      if (isset($alter['link_attributes']) && is_array($alter['link_attributes'])) {
 652        foreach ($alter['link_attributes'] as $key => $attribute) {
 653          if (!isset($options['attributes'][$key])) {
 654            $options['attributes'][$key] = strtr($attribute, $tokens);
 655          }
 656        }
 657      }
 658  
 659      // If the query and fragment were programatically assigned overwrite any
 660      // parsed values.
 661      if (isset($alter['query'])) {
 662        $options['query'] = strtr($alter['query'], $tokens);
 663      }
 664      if (isset($alter['alias'])) {
 665        // Alias is a boolean field, so no token.
 666        $options['alias'] = $alter['alias'];
 667      }
 668      if (isset($alter['fragment'])) {
 669        $options['fragment'] = strtr($alter['fragment'], $tokens);
 670      }
 671      if (isset($this->options['alter']['language'])) {
 672        $options['language'] = $this->options['alter']['language'];
 673      }
 674  
 675      $value .= l($text, $path, $options);
 676  
 677      if (!empty($alter['suffix'])) {
 678        $value .= filter_xss_admin(strtr($alter['suffix'], $tokens));
 679      }
 680  
 681      return $value;
 682    }
 683  
 684    /**
 685     * Get the 'render' tokens to use for advanced rendering.
 686     *
 687     * This runs through all of the fields and arguments that
 688     * are available and gets their values. This will then be
 689     * used in one giant str_replace().
 690     */
 691    function get_render_tokens($item) {
 692      $tokens = array();
 693      if (!empty($this->view->build_info['substitutions'])) {
 694        $tokens = $this->view->build_info['substitutions'];
 695      }
 696      $count = 0;
 697      foreach ($this->view->display_handler->get_handlers('argument') as $arg => $handler) {
 698        $token = '%' . ++$count;
 699        if (!isset($tokens[$token])) {
 700          $tokens[$token] = '';
 701        }
 702  
 703        // Use strip tags as there should never be HTML in the path.
 704        // However, we need to preserve special characters like " that
 705        // were removed by check_plain().
 706        $tokens['!' . $count] = isset($this->view->args[$count - 1]) ? strip_tags(html_entity_decode($this->view->args[$count - 1])) : '';
 707      }
 708  
 709      // Now add replacements for our fields.
 710      foreach ($this->view->display_handler->get_handlers('field') as $field => $handler) {
 711        if (isset($handler->last_render)) {
 712          $tokens["[$field]"] = $handler->last_render;
 713        }
 714        else {
 715          $tokens["[$field]"] = '';
 716        }
 717        $this->add_self_tokens($tokens, $item);
 718  
 719        // We only use fields up to (and including) this one.
 720        if ($field == $this->options['id']) {
 721          break;
 722        }
 723      }
 724  
 725      return $tokens;
 726    }
 727  
 728    /**
 729     * Add any special tokens this field might use for itself.
 730     *
 731     * This method is intended to be overridden by items that generate
 732     * fields as a list. For example, the field that displays all terms
 733     * on a node might have tokens for the tid and the term.
 734     *
 735     * By convention, tokens should follow the format of [token-subtoken]
 736     * where token is the field ID and subtoken is the field. If the
 737     * field ID is terms, then the tokens might be [terms-tid] and [terms-name].
 738     */
 739    function add_self_tokens(&$tokens, $item) { }
 740  
 741    /**
 742     * Document any special tokens this field might use for itself.
 743     *
 744     * @see add_self_tokens() for details.
 745     */
 746    function document_self_tokens(&$tokens) { }
 747  
 748    /**
 749     * Call out to the theme() function, which probably just calls render() but
 750     * allows sites to override output fairly easily.
 751     */
 752    function theme($values) {
 753      return theme($this->theme_functions(), $this->view, $this, $values);
 754    }
 755  
 756    function theme_functions() {
 757      $themes = array();
 758      $hook = 'views_view_field';
 759  
 760      $display = $this->view->display[$this->view->current_display];
 761  
 762      if (!empty($display)) {
 763        $themes[] = $hook . '__' . $this->view->name  . '__' . $display->id . '__' . $this->options['id'];
 764        $themes[] = $hook . '__' . $this->view->name  . '__' . $display->id;
 765        $themes[] = $hook . '__' . $display->id . '__' . $this->options['id'];
 766        $themes[] = $hook . '__' . $display->id;
 767        if ($display->id != $display->display_plugin) {
 768          $themes[] = $hook . '__' . $this->view->name  . '__' . $display->display_plugin . '__' . $this->options['id'];
 769          $themes[] = $hook . '__' . $this->view->name  . '__' . $display->display_plugin;
 770          $themes[] = $hook . '__' . $display->display_plugin . '__' . $this->options['id'];
 771          $themes[] = $hook . '__' . $display->display_plugin;
 772        }
 773      }
 774      $themes[] = $hook . '__' . $this->view->name . '__' . $this->options['id'];
 775      $themes[] = $hook . '__' . $this->view->name;
 776      $themes[] = $hook . '__' . $this->options['id'];
 777      $themes[] = $hook;
 778  
 779      return $themes;
 780    }
 781  }
 782  
 783  /**
 784   * A special handler to take the place of missing or broken handlers.
 785   */
 786  class views_handler_field_broken extends views_handler_field {
 787    function ui_name($short = FALSE) {
 788      return t('Broken/missing handler');
 789    }
 790  
 791    function ensure_my_table() { /* No table to ensure! */ }
 792    function query() { /* No query to run */ }
 793    function options_form(&$form, &$form_state) {
 794      $form['markup'] = array(
 795        '#prefix' => '<div class="form-item description">',
 796        '#value' => t('The handler for this item is broken or missing and cannot be used. If a module provided the handler and was disabled, re-enabling the module may restore it. Otherwise, you should probably delete this item.'),
 797      );
 798    }
 799  
 800    /**
 801     * Determine if the handler is considered 'broken'
 802     */
 803    function broken() { return TRUE; }
 804  }
 805  
 806  /**
 807   * Render a numeric value as a size.
 808   */
 809  class views_handler_field_file_size extends views_handler_field {
 810    function option_definition() {
 811      $options = parent::option_definition();
 812  
 813      $options['file_size_display'] = array('default' => 'formatted');
 814  
 815      return $options;
 816    }
 817  
 818    function options_form(&$form, &$form_state) {
 819      parent::options_form($form, $form_state);
 820      $form['file_size_display'] = array(
 821        '#title' => t('File size display'),
 822        '#type' => 'select',
 823        '#options' => array(
 824          'formatted' => t('Formatted (in KB or MB)'),
 825          'bytes' => t('Raw bytes'),
 826        ),
 827      );
 828    }
 829  
 830    function render($values) {
 831      if ($values->{$this->field_alias}) {
 832        switch ($this->options['file_size_display']) {
 833          case 'bytes':
 834            return $values->{$this->field_alias};
 835          case 'formatted':
 836          default:
 837            return format_size($values->{$this->field_alias});
 838        }
 839      }
 840      else {
 841        return '';
 842      }
 843    }
 844  }
 845  
 846  /**
 847   * A handler to run a field through simple XSS filtering
 848   */
 849  class views_handler_field_xss extends views_handler_field {
 850    function render($values) {
 851      $value = $values->{$this->field_alias};
 852      return filter_xss($value);
 853    }
 854  }
 855  
 856  /**
 857   * @}
 858   */
 859  


Generated: Mon Jul 9 18:01:44 2012 Cross-referenced by PHPXref 0.7