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[$key] = $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, true); } return array_map(function ($x) { return new Column($x); }, array_values((array)$columns)); } /** * Set column ID * @param string $id - GCID */ public function setID($id) { $this->id = $id; } /** * Create from object or array * * @param object|array $obj */ public function __construct($obj) { $b = objBag($obj); if (!$b->has('name') || $b->name == '') { throw new SimpleValidationException('name', "Missing column name."); } if (!$b->has('type') || !in_array($b->type, self::colTypes)) { throw new SimpleValidationException('type', "Missing or invalid column type."); } if ($b->name[0] == '_' || !preg_match(IDENTIFIER_PATTERN, $b->name)) { throw new SimpleValidationException('name', "Column name can contain only letters, digits, and underscore, and must start with a letter."); } if (!$b->has('id') || $b->id[0] == '_') { throw new SimpleValidationException('id', "Invalid or missing column ID"); } $this->id = $b->id; $this->name = $b->name; $this->type = $b->type; $this->title = $b->title ?: $b->name; } /** * @return array with keys {name, title, type} */ public function toArray($decorate=true) { if ($decorate) { return [ 'id' => $this->id, 'name' => $this->name, 'title' => $this->title, 'type' => $this->type, '_new' => $this->isNew, '_remove' => $this->toRemove, '_changed' => $this->modified_attribs, '_orig' => $this->orig_attribs, ]; } else { return [ 'id' => $this->id, '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) || $value === "") return 0; if (is_int($value)) return $value; if (is_bool($value)) return (int)$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!"); case 'float': if (is_null($value) || $value === "") return 0; if (is_int($value) || is_float($value) || is_bool($value)) return (float)$value; if (is_numeric($value)) return floatval($value); throw new SimpleValidationException($this->id, "Could not convert value \"$value\" to float!"); case 'bool': if (is_null($value) || $value === "") return false; return Utils::parseBool($value); case 'string': if (is_null($value)) return ""; 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 json_encode, * which is a value of any type other than a resource. * @since 5.4.0 */ public function jsonSerialize() { return $this->toArray(); } }