1<?php 2// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project 3// 4// All Rights Reserved. See copyright.txt for details and a complete list of authors. 5// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details. 6// $Id$ 7 8namespace Tracker\Tabular\Schema; 9 10class Column 11{ 12 const HEADER_PATTERN = '/\[(\*?)(\w+):([^\]]+)\]$/'; 13 14 private $permName; 15 private $label; 16 private $mode; 17 private $isPrimary = false; 18 private $isReadOnly = false; 19 private $isExportOnly = false; 20 private $isUniqueKey = false; 21 private $displayAlign = 'left'; 22 private $renderTransform; 23 private $parseIntoTransform; 24 private $querySources = []; 25 private $incompatibilities = []; 26 private $plainReplacement = null; 27 28 function __construct($permName, $mode) 29 { 30 $this->permName = $permName; 31 $this->mode = $mode; 32 $this->parseIntoTransform = function (& $info, $value) { 33 }; 34 } 35 36 function getLabel() 37 { 38 return $this->label; 39 } 40 41 function setLabel($label) 42 { 43 $this->label = $label; 44 return $this; 45 } 46 47 function getDisplayAlign() 48 { 49 return $this->displayAlign; 50 } 51 52 function setDisplayAlign($align) 53 { 54 $this->displayAlign = $align; 55 return $this; 56 } 57 58 function addIncompatibility($field, $mode) 59 { 60 $this->incompatibilities[] = [$field, $mode]; 61 return $this; 62 } 63 64 function setRenderTransform(callable $transform) 65 { 66 $this->renderTransform = $transform; 67 return $this; 68 } 69 70 function setParseIntoTransform(callable $transform) 71 { 72 $this->parseIntoTransform = $transform; 73 return $this; 74 } 75 76 function setPrimaryKey($pk) 77 { 78 $this->isPrimary = (bool) $pk; 79 return $this; 80 } 81 82 function setReadOnly($readOnly) 83 { 84 $this->isReadOnly = (bool) $readOnly; 85 return $this; 86 } 87 88 function setExportOnly($exportOnly) 89 { 90 $this->isExportOnly = (bool) $exportOnly; 91 return $this; 92 } 93 94 function setUniqueKey($uniqueKey) 95 { 96 $this->isUniqueKey = (bool) $uniqueKey; 97 return $this; 98 } 99 100 function setPlainReplacement($replacement) 101 { 102 $this->plainReplacement = $replacement; 103 return $this; 104 } 105 106 function is($field, $mode) 107 { 108 return $field == $this->permName && $mode == $this->mode; 109 } 110 111 function isPrimaryKey() 112 { 113 return $this->isPrimary; 114 } 115 116 function isReadOnly() 117 { 118 return $this->isReadOnly; 119 } 120 121 function isExportOnly() 122 { 123 return $this->isExportOnly; 124 } 125 126 function isUniqueKey() 127 { 128 return $this->isUniqueKey; 129 } 130 131 function getField() 132 { 133 return $this->permName; 134 } 135 136 function getMode() 137 { 138 return $this->mode; 139 } 140 141 function getEncodedHeader() 142 { 143 if ($this->isReadOnly) { 144 return $this->label; 145 } else { 146 $pk = $this->isPrimary ? '*' : ''; 147 return "{$this->label} [$pk{$this->permName}:{$this->mode}]"; 148 } 149 } 150 151 function getPlainReplacement() 152 { 153 return $this->plainReplacement; 154 } 155 156 function render($value) 157 { 158 return call_user_func_array($this->renderTransform, func_get_args()); 159 } 160 161 function parseInto(& $info, $value) 162 { 163 $c = $this->parseIntoTransform; 164 if (! $this->isReadOnly) { 165 $c($info, $value); 166 } 167 } 168 169 function addQuerySource($name, $field) 170 { 171 $this->querySources[$name] = $field; 172 return $this; 173 } 174 175 function getQuerySources() 176 { 177 return $this->querySources; 178 } 179 180 function validateAgainst(\Tracker\Tabular\Schema $schema) 181 { 182 if ($this->isPrimary && $this->isReadOnly) { 183 throw new \Exception(tr('Primary Key fields cannot be read-only.')); 184 } 185 186 $selfCount = 0; 187 188 foreach ($schema->getColumns() as $column) { 189 if ($column->is($this->permName, $this->mode)) { 190 $selfCount++; 191 } 192 193 foreach ($this->incompatibilities as $entry) { 194 list($field, $mode) = $entry; 195 196 if ($column->is($field, $mode)) { 197 // Skip incompatibility if either field is read-only 198 if ($this->isReadOnly() || $column->isReadOnly()) { 199 continue; 200 } 201 202 throw new \Exception(tr( 203 'Column "%0" cannot co-exist with "%1".', 204 $column->getEncodedHeader(), 205 $this->getEncodedHeader() 206 )); 207 } 208 } 209 } 210 211 if ($selfCount > 1) { 212 throw new \Exception(tr('Column "%0:%1" found multiple times.', $this->permName, $this->mode)); 213 } 214 } 215 216 function withWrappedRenderTransform(callable $callback) 217 { 218 $column = new self($this->permName, $this->mode); 219 $column->label = $this->label; 220 $column->isPrimary = $this->isPrimary; 221 $column->isReadOnly = $this->isReadOnly; 222 $column->isExportOnly = $this->isExportOnly; 223 $column->isUniqueKey = $this->isUniqueKey; 224 $column->displayAlign = $this->displayAlign; 225 $column->parseIntoTransform = $this->parseIntoTransform; 226 $column->querySources = $this->querySources; 227 $column->incompatibilities = $this->incompatibilities; 228 $column->plainReplacement = $this->plainReplacement; 229 230 $column->renderTransform = function () use ($callback) { 231 $value = call_user_func_array($this->renderTransform, func_get_args()); 232 return $callback($value); 233 }; 234 235 return $column; 236 } 237} 238