*/ class Grocycode { public const PRODUCT = 'p'; public const BATTERY = 'b'; public const CHORE = 'c'; public const RECIPE = 'r'; public const MAGIC = 'grcy'; /** * Constructs a new instance of the Grocycode class. * * Because php doesn't support overloading, this is a proxy * to either setFromCode($code) or setFromData($type, $id, $extra_data = []). */ public function __construct(...$args) { $argc = count($args); if ($argc == 1) { $this->setFromCode($args[0]); return; } elseif ($argc == 2 || $argc == 3) { if ($argc == 2) { $args[] = []; } $this->setFromData($args[0], $args[1], $args[2]); return; } throw new \Exception('No suitable overload found.'); } /** * An array that registers all valid grocycode types. Register yours here by appending to this array. */ public static $Items = [self::PRODUCT, self::BATTERY, self::CHORE, self::RECIPE]; private $type; private $id; private $extra_data = []; /** * Validates a grocycode. * * Returns true, if a supplied $code is a valid grocycode, false otherwise. * * @return bool */ public static function Validate(string $code) { try { $gc = new self($code); return true; } catch (\Exception $e) { return false; } } public function GetId() { return $this->id; } public function GetExtraData() { return $this->extra_data; } public function GetType() { return $this->type; } public function __toString(): string { $arr = array_merge([self::MAGIC, $this->type, $this->id], $this->extra_data); return implode(':', $arr); } /** * Parses a grocycode. */ private function setFromCode($code) { $parts = array_reverse(explode(':', $code)); if (array_pop($parts) != self::MAGIC) { throw new \Exception('Not a grocycode'); } if (!in_array($this->type = array_pop($parts), self::$Items)) { throw new \Exception('Unknown grocycode type'); } $this->id = array_pop($parts); $this->extra_data = array_reverse($parts); } /** * Constructs a grocycode from data. */ private function setFromData($type, $id, $extra_data = []) { if (!is_array($extra_data)) { throw new \Exception('Extra data must be array of string'); } if (!in_array($type, self::$Items)) { throw new \Exception('Unknown grocycode type'); } $this->type = $type; $this->id = $id; $this->extra_data = $extra_data; } }