Files
grocy/helpers/Grocycode.php
T

120 lines
2.3 KiB
PHP
Raw Normal View History

2021-06-12 17:21:12 +02:00
<?php
namespace Grocy\Helpers;
/**
2023-05-19 18:08:26 +02:00
* A class that abstracts Grocycode.
2021-06-12 17:21:12 +02:00
*
2023-05-19 18:08:26 +02:00
* Grocycode is a simple, easily serializable format to reference
* stuff within Grocy. It consists of n (n ≥ 3) double-colon seperated parts:
2021-06-12 17:21:12 +02:00
*
* 1. The magic `grcy`
* 2. A type identifer, must match `[a-z]+` (i.e. only lowercase ascii, minimum length 1 character)
* 3. An object id
* 4. Any number of further data fields, double-colon seperated.
*
* @author Katharina Bogad <katharina@hacked.xyz>
*/
class Grocycode
{
public const PRODUCT = 'p';
public const BATTERY = 'b';
public const CHORE = 'c';
2022-02-11 17:49:30 +01:00
public const RECIPE = 'r';
2021-06-12 17:21:12 +02:00
public const MAGIC = 'grcy';
2021-07-16 17:32:08 +02:00
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.');
}
2022-02-11 17:49:30 +01:00
public static $Items = [self::PRODUCT, self::BATTERY, self::CHORE, self::RECIPE];
2021-06-12 17:21:12 +02:00
private $type;
private $id;
private $extra_data = [];
public static function Validate(string $code)
{
try
{
$gc = new self($code);
return true;
}
catch (\Exception $e)
2021-06-12 17:21:12 +02:00
{
return false;
}
}
2021-07-16 17:32:08 +02:00
public function GetId()
2021-06-12 17:21:12 +02:00
{
2021-07-16 17:32:08 +02:00
return $this->id;
}
2021-06-12 17:21:12 +02:00
2021-07-16 17:32:08 +02:00
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);
2021-06-12 17:21:12 +02:00
}
private function setFromCode($code)
{
$parts = array_reverse(explode(':', $code));
2021-06-12 17:21:12 +02:00
if (array_pop($parts) != self::MAGIC)
{
2023-05-19 18:08:26 +02:00
throw new \Exception('Not a Grocycode');
2021-06-12 17:21:12 +02:00
}
if (!in_array($this->type = array_pop($parts), self::$Items))
{
2023-05-19 18:08:26 +02:00
throw new \Exception('Unknown Grocycode type');
2021-06-12 17:21:12 +02:00
}
$this->id = array_pop($parts);
$this->extra_data = array_reverse($parts);
2021-06-12 17:21:12 +02:00
}
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))
{
2023-05-19 18:08:26 +02:00
throw new \Exception('Unknown Grocycode type');
2021-06-12 17:21:12 +02:00
}
$this->type = $type;
$this->id = $id;
$this->extra_data = $extra_data;
}
}