datatable.directory codebase https://datatable.directory/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
datatable.directory/app/Tables/Column.php

209 lines
5.6 KiB

6 years ago
<?php
namespace App\Tables;
6 years ago
use Illuminate\Contracts\Support\Arrayable;
6 years ago
use JsonSerializable;
use MightyPork\Exceptions\SimpleValidationException;
6 years ago
use MightyPork\Exceptions\NotApplicableException;
use MightyPork\Utils\Utils;
/**
* Helper class representing one column in a data table.
*
* @property-read bool $id_modified
* @property-read bool $type_modified
* @property-read bool $name_modified
* @property-read bool $title_modified
*
* @property-read string $id_orig
* @property-read string $type_orig
* @property-read string $name_orig
* @property-read string $title_orig
6 years ago
*/
class Column implements JsonSerializable, Arrayable
6 years ago
{
const colTypes = [
'int', 'bool', 'float', 'string'
];
// marked public to make keyBy() work
public $id;
public $type;
public $name;
public $title;
6 years ago
/** @var bool - column is marked to be deleted by a changeset */
public $toRemove = false;
/** @var bool - column is new in this changeset */
public $isNew = false;
/** @var array - original attrib values if edited in a changeset */
private $orig_attribs = [];
/** @var array - list of attrib names that are modified by a changeset */
private $modified_attribs = [];
/**
* Mark for removal (used in editing GUI)
*/
public function markForRemoval()
{
$this->toRemove = true;
}
/**
* Mark this column as new
*/
public function markAsNew()
{
$this->isNew = true;
}
/**
* Modify by a changeset
*
* @param array $columnObject
*/
public function modifyByChangeset(array $columnObject)
{
foreach ((array)$columnObject as $key => $value) {
if ($value != $this->$key) {
$this->modified_attribs[] = $key;
$this->orig_attribs[] = $this->$key;
$this->$key = $value;
}
}
}
public function __get($name)
{
if (ends_with($name, '_modified')) {
$basename = str_replace('_modified', '', $name);
if (property_exists($this, $basename)) {
return in_array($basename, $this->modified_attribs);
}
}
if (ends_with($name, '_orig')) {
$basename = str_replace('_orig', '', $name);
if (property_exists($this, $basename)) {
return $this->orig_attribs[$basename];
}
}
throw new NotApplicableException("No such column property: $name");
}
/**
* @param $columns
* @return Column[]
*/
public static function columnsFromJson($columns)
{
if (is_string($columns)) {
$columns = json_decode($columns);
}
return array_map(function ($x) {
return new Column($x);
}, $columns);
}
/**
* Set column ID
* @param string $id - GCID
*/
public function setID($id)
6 years ago
{
$this->id = $id;
6 years ago
}
/**
* Create from object or array
*
* @param $obj
*/
public function __construct($obj)
{
$b = objBag($obj);
if (!$b->has('name')) throw new NotApplicableException('Missing name in column');
if (!$b->has('type')) throw new NotApplicableException('Missing type in column');
if ($b->name[0] == '_') { // global row ID
throw new NotApplicableException("Column name can't start with underscore.");
}
if (!in_array($b->type, self::colTypes)) {
throw new NotApplicableException("\"$b->type\" is not a valid column type.");
}
$this->id = $b->get('id', null);
6 years ago
$this->name = $b->name;
$this->type = $b->type;
$this->title = $b->title ?: $b->name;
}
6 years ago
/**
* @return array with keys {name, title, type}
*/
public function toArray()
{
return [
'id' => $this->id,
6 years ago
'name' => $this->name,
'title' => $this->title,
'type' => $this->type,
];
}
/**
* Convert a value to the target type, validating it in the process
*
* @param mixed $value
* @return bool|float|int|string
*/
public function cast($value)
{
switch ($this->type) {
case 'int':
if (is_null($value)) return 0;
6 years ago
if (is_int($value)) return $value;
if (is_float($value)) return round($value);
if (is_numeric($value)) return intval($value);
throw new SimpleValidationException($this->id, "Could not convert value \"$value\" to int!");
6 years ago
case 'float':
if (is_null($value)) return 0;
6 years ago
if (is_int($value) || is_float($value)) return (float)$value;
if (is_numeric($value)) return floatval($value);
throw new SimpleValidationException($this->id, "Could not convert value \"$value\" to float!");
6 years ago
case 'bool':
if (is_null($value)) return false;
6 years ago
return Utils::parseBool($value);
case 'string':
if (is_null($value)) return "";
6 years ago
return "$value";
default:
throw new \LogicException("Illegal column type: \"$this->type\"");
}
}
/**
* Specify data which should be serialized to JSON
* @link http://php.net/manual/en/jsonserializable.jsonserialize.php
* @return mixed data which can be serialized by <b>json_encode</b>,
* which is a value of any type other than a resource.
* @since 5.4.0
*/
public function jsonSerialize()
{
return $this->toArray();
}
}