<?php namespace Xentral\Widgets\DataTable\Column; use JsonSerializable; use Xentral\Widgets\DataTable\Exception\InvalidArgumentException; use Xentral\Widgets\DataTable\Feature\ResponsiveFeature; final class Column implements JsonSerializable { /** @var string ALIGN_LEFT */ const ALIGN_LEFT = 'left'; /** @var string ALIGN_RIGHT */ const ALIGN_RIGHT = 'right'; /** @var string ALIGN_CENTER */ const ALIGN_CENTER = 'center'; /** @var string ALIGN_JUSTIFY */ const ALIGN_JUSTIFY = 'justify'; /** @var array $validAlignments */ public static $validAlignments = [ self::ALIGN_LEFT, self::ALIGN_RIGHT, self::ALIGN_CENTER, self::ALIGN_JUSTIFY, ]; /** @var string $name */ private $name; /** @var string $title */ private $title; /** @var bool $visible */ private $visible; /** @var bool $sortable */ private $sortable; /** @var bool $searchable */ private $searchable; /** @var bool $exportable */ private $exportable; /** @var bool $fixed */ private $fixed; /** @var string $alignment */ private $alignment; /** @var string|null $dbColumn */ private $dbColumn; /** @var string|null $width */ private $width; /** @var callable|null $formatter */ private $formatter; /** @var array $properties */ private $properties = []; /** @var array $cssClasses CSS classes */ private $cssClasses = []; /** * @param string $name * @param string $title * @param string $align [left|right|center|justify] * @param string|null $width Column width as CSS value (e.g 20%, 3em, 55px) * @param bool $visible Is column currently visible? Visibility can be changed at runtime * @param bool $sortable * @param bool $searchable * @param bool $exportable * @param bool $fixed If true, column is always visible and visibility can not be changed at runtime * * Fixed columns can't be hidden (ResponsiveFeature, ColumnVisibilityFeature) * * Fixed columns can't be reordered (ColumnReorderFeature) * * @throws InvalidArgumentException */ public function __construct( $name, $title, $align = 'left', $width = null, $visible = true, $sortable = false, $searchable = false, $exportable = false, $fixed = false ) { if (empty($name)) { throw new InvalidArgumentException('Column name can not be empty.'); } $cleanedName = (string)preg_replace('#[^a-z0-9_]#', '', trim($name)); if ($cleanedName !== $name) { throw new InvalidArgumentException(sprintf( 'Name "%s" contains illegal characters. Valid characters are: a-z, 0-9 and underscore.', $name )); } $this->name = (string)$name; $this->title = (string)$title; $this->visible = (bool)$visible; $this->sortable = (bool)$sortable; $this->searchable = (bool)$searchable; $this->exportable = (bool)$exportable; $this->fixed = (bool)$fixed; $this->alignment = (string)$align; $this->width = $width !== null ? (string)$width : null; } /** * Currently hidden column; can be unhidden * * @param string $name * @param string $title * @param string $align [left|right|center|justify] * @param string|null $width Column width as CSS value (e.g 20%, 3em, 55px) * * @return Column */ public static function hidden($name, $title, $align = 'left', $width = null) { return new static($name, $title, $align, $width, false, false, false, false, false); } /** * Visible column; not sortable and not searchable * * @param string $name * @param string $title * @param string $align [left|right|center|justify] * @param string|null $width Column width as CSS value (e.g 20%, 3em, 55px) * * @return Column */ public static function visible($name, $title, $align = 'left', $width = null) { return new static($name, $title, $align, $width, true, false, false, true, false); } /** * Visible and sortable column; not searchable * * @param string $name * @param string $title * @param string $align [left|right|center|justify] * @param string|null $width Column width as CSS value (e.g 20%, 3em, 55px) * * @return Column */ public static function sortable($name, $title, $align = 'left', $width = null) { return new static($name, $title, $align, $width, true, true, false, true, false); } /** * Visible, sortable und searchable column * * @param string $name * @param string $title * @param string $align [left|right|center|justify] * @param string|null $width Column width as CSS value (e.g 20%, 3em, 55px) * * @return Column */ public static function searchable($name, $title, $align = 'left', $width = null) { return new static($name, $title, $align, $width, true, true, true, true, false); } /** * Always visible and with fixed position (for Menu and Selection columns) * * - Always visible; Can't be hidden (ColumnVisibilityFeature) * - Fixed position; Can't be reordered (ColumnReorderFeature) * - Not searchable * - Not sortable * * @param string $name * @param string $title * * @return Column */ public static function fixed($name, $title = '', $align = 'center', $width = null) { $fixed = new static($name, $title, $align, $width, true, false, false, false, true); $fixed->set('responsivePriority', ResponsiveFeature::PRIO_HIGHER); return $fixed; } /** * @return string */ public function getName() { return $this->name; } /** * @return string */ public function getTitle() { return $this->title; } /** * @param string $dbColumn */ public function setDbColumn($dbColumn) { $this->dbColumn = (string)$dbColumn; } /** * @return string|null */ public function getDbColumn() { return $this->dbColumn; } /** * @return string */ public function getAlignment() { return $this->alignment; } /** * @see $validAlignments * * @param string $alignment [left|right|center|justify] */ public function setAlignment($alignment) { if (!in_array($alignment, self::$validAlignments, true)) { throw new InvalidArgumentException(sprintf( 'Alignment "%s" is not valid. Valid alignments: %s', $alignment, implode(', ', self::$validAlignments) )); } $this->alignment = $alignment; } /** * @return callable|null */ public function getFormatter() { return $this->formatter; } /** * @param callable $formatter * * @return void */ public function setFormatter(callable $formatter) { $this->formatter = $formatter; } /** * @return bool */ public function isFixed() { return $this->fixed; } /** * @return bool */ public function isVisible() { return $this->visible; } /** * @return bool */ public function isSortable() { return $this->sortable; } /** * @return bool */ public function isExportable() { return $this->exportable; } /** * @return bool */ public function isSearchable() { return $this->searchable; } /** * @param string $property * * @return bool */ public function has($property) { if (isset($this->{$property})) { return true; } return isset($this->properties[$property]); } /** * @param string $property * * @return mixed|null */ public function get($property) { if (isset($this->{$property})) { return $this->{$property}; } if (isset($this->properties[$property])) { return $this->properties[$property]; } return null; } /** * @param string $property * @param mixed $value * * @return void */ public function set($property, $value) { if (isset($this->{$property})) { $this->{$property} = $value; } $this->properties[$property] = $value; } /** * @param string $className * * @return bool */ public function hasCssClass($className) { return in_array($className, $this->cssClasses, true); } /** * @param string $className * * @return void */ public function addCssClass($className) { $this->cssClasses[] = trim($className); $this->cssClasses = array_unique($this->cssClasses); } /** * @param string $className * * @return void */ public function removeCssClass($className) { $classKey = array_search($className, $this->cssClasses, true); if ($classKey !== false) { unset($this->cssClasses[$classKey]); $this->cssClasses = array_values($this->cssClasses); } } /** * @return array */ public function toArray() { $result = $this->properties; $result['data'] = isset($result['data']) ? $result['data'] : $this->name; $result['name'] = $this->name; $result['title'] = $this->title; $result['exportable'] = $this->exportable; $result['searchable'] = $this->searchable; $result['orderable'] = $this->sortable; $result['visible'] = $this->visible; $result['fixed'] = $this->fixed; if ($this->fixed === true) { $result['visible'] = true; } // Spalte hat keine Daten; z.B. MenĂ¼-Spalte if ($this->dbColumn === null) { //$result['data'] = null; $result['defaultContent'] = isset($result['defaultContent']) ? $result['defaultContent'] : ''; $result['orderable'] = false; $result['searchable'] = false; // $result['data'] = $this->name; // $result['searchable'] = $this->searchable; } $cssClasses = $this->cssClasses; $cssClasses[] = 'dt-' . $this->alignment; $result['className'] = implode(' ', $cssClasses); if ($this->width !== null) { $result['width'] = $this->width; } return $result; } /** * @return array */ public function jsonSerialize() { return $this->toArray(); } }