jacmaes
9/9/2013 - 9:14 AM

create table from repeater

create table from repeater

<?php

class RepeaterTable extends WireData implements Module {

  public static function getModuleInfo() {
		return array(
			'title' => 'RepeaterTable', 
			'version' => 100, 
			'summary' => 'RepeaterTable',
			'singular' => false, 
			'autoload' => false
			);
	}
	
	// empty init()
	public function init() {
	}

	public $thead = true; // (bool) true/false, render thead ?
	public $indent = false; // (mixed) false/int, where int is the level of indentation

	public function render($string) {

		$array = explode("|", $string);
		
		// return if repeater is empty
		if(!count($array)) return;
	   
		$repeater = new PageArray;

		// check if items are repeaters
		foreach($array as $numerical) {
			// build 
			$id = (int) $numerical;
			$p = wire('pages')->get($id);

			// filter for repeaters
			$template = $p->template;
			// set error true if template name doesn't start with repeater_
			$error = strpos($template->name, 'repeater_') === 0 ? false : true;
			// error found, break loop, $error is true
			if ($error) break; 
	
			$repeater->add($p); 
		}

		// after error, return
		if($error) return;

		// page ID of page where the repeater is used
		$pid = (int) str_replace("for-page-", "", $p->parent->name);
		// field ID of the repeater field
		$fid = (int) str_replace("for-field-", "", $p->parent->parent->name);
		// current repeater field name
		$name = wire("pages")->get($pid)->fields->get($fid)->name;

		$fields = $template->fields;
		$rows = count($repeater);
		$columns = count($fields);
		$cells = $columns * $rows;
		$i = 1; // needed for classname thead

		// build markup
		$out  = "<table class='table-{$name}'>";

		if($this->thead) {
			$out .= "<thead><tr>";
			foreach ($fields as $field) $out .= "<th class='col-".$i++."'>{$field->label}</th>";             
			$out .= "</tr></thead>";
		}

		/**
		 * Create Table markup
		 *
		 */

		$out .= "<tbody><tr class='row-1'>";
		for($i = 0; $i < $cells; $i++) {
			// every column +1 & restart every row
			$column_index = $i%$columns;
			// every row +1
			$row_index = ($i/$columns)%$cells;
			// $page object
			$row = $repeater->eq($row_index);
			// $field  object
			$field = $row->fields->eq($column_index);
			// add td, every cell
			$out .= "<td class='col-" . ($column_index + 1) ."'>{$row->$field}</td>";
			// close close & open tr in the middle of the table
			$out .= ($i+1)%$columns===0 && ($i+1)<$cells ? "</tr><tr class='row-".($row_index + 2)."'>" : null;
		}
		$out .= "</tr></tbody></table>";

		/**
		 * For the HTML purist, indent table to a certain level
		 *
		 */

		if($this->indent !== false && is_int($this->indent)) {
			// indentation level
			$i = "\n" . str_repeat("\t" , $this->indent);
			$search = array("<table","</table","<thead","</thead","<tbody","</tbody","<tr","</tr","<th ","<td");
			$replace = array("$i<table","$i</table","$i\t<thead","$i\t</thead","$i\t<tbody","$i\t</tbody","$i\t\t<tr","$i\t\t</tr","$i\t\t\t<th ","$i\t\t\t<td");
			$out = str_replace($search, $replace, $out);
		}

		return $out;
	}
}