forena-8.x-1.x-dev/src/FrxPlugin/Template/FrxCrosstab.php

src/FrxPlugin/Template/FrxCrosstab.php
<?php

namespace Drupal\forena\Template;
use Drupal\forena\FrxAPI;

/**
 * Crosstab Report Template
 *
 * @FrxTemplate(id="FrxCrosstab", name="Cross Tab Data")
 *
 */
class FrxCrosstab extends TemplateBase {
  use FrxAPI; 
  public $templateName = 'Crosstab';
  private $headers = array();
  private $dim_columns = array();
  private $group_columns = array();
  private $dim_headers = array();
  private $group_headers = array();
  private $weight;


  /**
   * Crosstab configuration form.
   */
  public function configForm($config) {
    // Load header informationi from parent config.

    $form = parent::configForm($config);
    $this->weight_sort($config['crosstab_columns']);
    $types = array('heading' => t('Heading'), 'crosstab' => t('Crosstab'), 'value' => 'Value', 'ignore' => t('Ignore'));
    $form['crosstab_columns'] = array('#theme' => 'forena_element_draggable',   '#draggable_id' => 'FrxCrosstab-columns');
    foreach ($config['crosstab_columns'] as $key => $col) {
      $ctl = array();
      $ctl['label'] = array(
          '#type' => 'textfield',
          '#size' => 30,
          '#title' => t('Label'),
          '#default_value' => $col['label'],
      );

      $ctl['contents'] = array(
          '#type' => 'textfield',
          '#size' => '30',
          '#title' => t('Data'),
          '#default_value' => $col['contents'],
      );

      $ctl['type'] = array(
          '#type' => 'radios',
          '#title' => t('Type'),
          '#default_value' => $col['type'],
          '#options' => $types,
          '#ajax' => $this->configAjax()
      );

      $ctl['weight'] = array(
          "#type" => 'weight',
          '#title' => t('Weight'),
          '#delta' => 50,
          '#default_value' => $col['weight'],
      );

      $form['crosstab_columns'][$key] = $ctl;
    }
    return $form;
  }


  public function generate() {
    $config['class'] = get_class($this);
    $block = @$config['block'];
    $id = @$config['id'];
    if ($block) {
      $id = $this->idFromBlock($block);
      $config['id'] = $id . '_block';
    }
    $config['class'] = @$config['class'] ? $config['class'] . ' FrxCrosstab' : 'FrxCrosstab';
    $div = $this->blockDiv($config);

    // PUt on the header
    $this->removeChildren($div);
    if (isset($config['header']['value'])) $this->addFragment($div, $config['header']['value']);

    // Decide to inlcude columns
    $found_columns = $this->columns($xml);
    if (!$found_columns) {
      $found_columns = $this->columns($xml, '/*');
      $attrs = array();
    }

    $numeric_columns = $this->numeric_columns;
    $new_columns = @$config['crosstab_columns'] ? FALSE : TRUE;

    foreach ($found_columns as $column => $label) {
      $token = '{' . $column . '}';
      if ($new_columns) {
        $type = isset($numeric_columns[$column]) ? 'value' : 'heading';
      } else {
        $type = 'ignore';
      }
      if (!isset($config['crosstab_columns'][$column])) {
        $this->addColumn($type, '{' . $column . '}', $column, $config);
      }
    }

    // Generate the grouping row
    $group = '';
    $dim = array();
    foreach($config['crosstab_columns'] as $col) {
      if ($col['type'] == 'heading') $group .= $col['contents'];
      if ($col['type'] == 'crosstab') $dim = $col['contents'];
    }
    $r_id = $id . '-renderer';
    $table_frx['renderer'] = 'FrxCrosstab';
    $table_frx['group'] = $group;
    $table_frx['dim'] = $dim;
    $attrs[$id] = $r_id;
    //$attrs = array('foreach' => '*');
    $table = $this->setFirstNode($div, 4, 'table', NULL, $attrs, $table_frx);
    $thead = $this->setFirstNode($table, 6, 'thead');
    $throw = $this->setFirstNode($thead, 8, 'tr');
    $tbody = $this->setFirstNode($table, 6, 'tbody');
    $tdrow = $this->setFirstNode($tbody, 8, 'tr', NULL, array('id' => $id),$attrs);
    if ($config['crosstab_columns']) foreach ($config['crosstab_columns'] as $key => $col) if ($col['type']!=='ignore') {
      if ($col['type']=='heading') {
        $tag = 'th';
      }
      else {
        $tag = 'td';
      }
      if ($col['type'] != 'crosstab') {
        $this->addNode($throw, 10, $tag, $col['label']);
        $this->addNode($tdrow, 10, $tag, $col['contents']);
      }
    }
    if (isset($config['footer']['value'])) $this->addFragment($div, $config['footer']['value']);
  }

  /**
   * Default configuration validator. Simply validates header and footer attributes.
   * @param array $config
   *   configuration 
   * @return array 
   *   errors in configuration. 
   */
  public function configValidate(&$config) {
    $errors = $this->validateTextFormats($config, array('header', 'footer'));
    $dims = 0;
    if (@$config['crosstab_columns']) foreach ($config['crosstab_columns'] as $col) {
      if (@$col['type']=='value') {
        $dims++;
      }
    }
    if ($dims > 1)  $errors[] = t('Too many value columns.  Please select only one');

    return $errors;
  }

  private function addColumn($type, $token, $label,  &$config) {
    $key = trim($token, '{}');
    $this->weight++;
    $config['crosstab_columns'][$key] = array(
        'contents' => $token,
        'label' => $label,
        'type' => $type,
        'weight' => $this->weight,
    );
  }

  /**
   * Extract table configuration from the HTML
   * @see FrxRenderer::scrapeConfig()
   */
  public function scrapeConfig(\SimpleXMLElement $xml) {
    $this->weight = 0;
    $config=array();
    $nodes =  $this->reportDocNode->xpath('//table');
    if ($nodes) {
      $table = $nodes[0];
      $attrs = $this->mergedAttributes($table);
    }
    $config['group'] = $group = $attrs['group'];
    $config['dim']  = $dim = $attrs['dim'];
    $this->extractTemplateHTML($this->reportDocDomNode, $config, array('table'));
    $head_ths = $this->extractXPathInnerHTML('*//thead/tr/th', $this->reportDocDomNode, FALSE);
    $head_tds = $this->extractXPathInnerHTML('*//thead/tr/td', $this->reportDocDomNode, FALSE);
    $body_ths = $this->extractXPathInnerHTML('*//tbody/tr/th', $this->reportDocDomNode, FALSE);
    $body_tds = $this->extractXPathInnerHTML('*//tbody/tr/td', $this->reportDocDomNode, FALSE);
    $heading_cols = array_combine($head_ths, $body_ths);
    $data_cols = array_combine($head_tds, $body_tds);
    // Get the named headers
    foreach($heading_cols as $label=>$token) {
      $this->addColumn('heading', $token, $label, $config);
    }
    // Get the data cells
    if ($dim) {
      $dims = (array)$dim;
      foreach($dims as $dim) {
        $this->addColumn('crosstab', $dim, trim($dim, '{}'), $config);
      }
    }
    foreach($data_cols as $label=>$token) {
      $this->addColumn('value', $token, $label, $config);
    }
    return $config;
  }
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc