|
1 | 1 | <?php |
2 | 2 |
|
3 | | -namespace Cable8mm\GoodCodeParser; |
| 3 | +namespace Cable8mm\GoodCode; |
4 | 4 |
|
5 | | -use Cable8mm\GoodCodeParser\Enums\GoodCodeType; |
6 | | -use Cable8mm\GoodCodeParser\Parsers\SetGood; |
| 5 | +use BadFunctionCallException; |
| 6 | +use Cable8mm\GoodCode\Enums\GoodCodeType; |
| 7 | +use InvalidArgumentException; |
7 | 8 |
|
8 | 9 | /** |
9 | 10 | * Make set code, option code and so on. |
10 | 11 | */ |
11 | 12 | class GoodCode |
12 | 13 | { |
| 14 | + const SET_CODE_DELIMITER = 'zz'; |
| 15 | + |
| 16 | + const SET_CODE_DELIMITER_COUNT = 'x'; |
| 17 | + |
| 18 | + private GoodCodeType $type; |
| 19 | + |
| 20 | + public function __construct( |
| 21 | + private string $code, |
| 22 | + private GoodCodeType $originType, |
| 23 | + ) { |
| 24 | + $this->type = GoodCodeType::of($code); |
| 25 | + } |
| 26 | + |
| 27 | + public function code(): string |
| 28 | + { |
| 29 | + return $this->code; |
| 30 | + } |
| 31 | + |
| 32 | + public function originalType(): GoodCodeType |
| 33 | + { |
| 34 | + return $this->originType; |
| 35 | + } |
| 36 | + |
| 37 | + public function type(): GoodCodeType |
| 38 | + { |
| 39 | + return $this->type; |
| 40 | + } |
| 41 | + |
| 42 | + /** |
| 43 | + * Output value for good code. |
| 44 | + * If the code is set code, it will be array of good values. |
| 45 | + * If the code is normal code, it will be good code string. |
| 46 | + * the code shouldn't be option, complex and gift code. |
| 47 | + */ |
| 48 | + public function value(): int|string|array |
| 49 | + { |
| 50 | + if ($this->type == GoodCodeType::OPTION || $this->type == GoodCodeType::GIFT || $this->type == GoodCodeType::COMPLEX) { |
| 51 | + return throw new BadFunctionCallException('Only complex and set code types are supported'); |
| 52 | + } |
| 53 | + |
| 54 | + if ($this->type == GoodCodeType::SET) { |
| 55 | + return self::getSetCodes($this->code); |
| 56 | + } |
| 57 | + |
| 58 | + return $this->code; |
| 59 | + } |
| 60 | + |
| 61 | + /** |
| 62 | + * Get ID from GIF and COM codes. |
| 63 | + * |
| 64 | + * @param string $code GIF or COM code |
| 65 | + * @return int The method returns ID |
| 66 | + */ |
| 67 | + public static function getId(string $code): int |
| 68 | + { |
| 69 | + return (int) preg_replace('/[^0-9]/', '', $code); |
| 70 | + } |
| 71 | + |
| 72 | + /** |
| 73 | + * Create GoodCode instance from given code string and callback function |
| 74 | + * |
| 75 | + * @param string $code `good_code`, `set_code`, `option_code` |
| 76 | + * @param ?callable $callback Function to call |
| 77 | + * @param ?string $option `option_good_option` name |
| 78 | + * @return GoodCode The method returns GoodCode instance. |
| 79 | + */ |
| 80 | + public static function of(string $code, ?string $option = null, ?callable $callback = null): GoodCode |
| 81 | + { |
| 82 | + $type = $originalType = GoodCodeType::of($code); |
| 83 | + |
| 84 | + if ($type == GoodCodeType::OPTION) { |
| 85 | + $code = $callback(self::getId($code), $option); |
| 86 | + $type = GoodCodeType::of($code); |
| 87 | + } |
| 88 | + |
| 89 | + if ($type == GoodCodeType::COMPLEX || $type == GoodCodeType::GIFT) { |
| 90 | + $code = $callback(self::getId($code)); |
| 91 | + } |
| 92 | + |
| 93 | + return new GoodCode($code, $originalType); |
| 94 | + } |
| 95 | + |
13 | 96 | /** |
14 | 97 | * Make SetCode from key-value set code array. |
15 | 98 | * |
16 | 99 | * @param array $setCodes key-value set code array |
17 | | - * @return string The method returns the SetCode |
| 100 | + * @return GoodCode The method returns GoodCode instance with the SetCode array |
18 | 101 | * |
19 | | - * @example GoodCode::makeSetCode(['7369'=>4,'4235'=>6]) set7369x4ZZ4235x6 |
| 102 | + * @example GoodCode::setCodeOf(['7369'=>4,'4235'=>6]) |
20 | 103 | */ |
21 | | - public static function makeSetCode(array $setCodes): string |
| 104 | + public static function setCodeOf(array $setCodes): GoodCode |
22 | 105 | { |
23 | | - return GoodCodeType::SET->prefix().implode(SetGood::DELIMITER, array_map(function ($v, $k) { |
24 | | - return $k.SetGood::DELIMITER_COUNT.$v; |
25 | | - }, $setCodes, array_keys($setCodes))); |
| 106 | + return new GoodCode( |
| 107 | + self::makeSetCode($setCodes), |
| 108 | + GoodCodeType::SET |
| 109 | + ); |
26 | 110 | } |
27 | 111 |
|
28 | 112 | /** |
29 | | - * Make set code key-value array from SetCode. |
| 113 | + * Make SetCode from key-value set code array. |
30 | 114 | * |
31 | | - * @param string $setCode SetCode |
32 | | - * @return array key-value set code |
| 115 | + * @param array $setCodes key-value set code array |
| 116 | + * @return string The method returns GoodCode instance with the SetCode string |
33 | 117 | * |
34 | | - * @example GoodCode::setCodes('set7369x4ZZ4235x6) ['7369'=>4,'4235'=>6] |
| 118 | + * @example GoodCode::setCodeOf(['7369'=>4,'4235'=>6]) |
35 | 119 | */ |
36 | | - public static function getSetCodes(string $setCode): array |
| 120 | + private static function makeSetCode(array $setCodes): string |
37 | 121 | { |
38 | | - return (new GoodCodeParser($setCode)) |
39 | | - ->with(SetGood::class) |
40 | | - ->get(); |
| 122 | + return GoodCodeType::SET->prefix().implode(self::SET_CODE_DELIMITER, array_map(function ($v, $k) { |
| 123 | + return $k.self::SET_CODE_DELIMITER_COUNT.$v; |
| 124 | + }, $setCodes, array_keys($setCodes))); |
41 | 125 | } |
42 | 126 |
|
43 | 127 | /** |
44 | | - * Get ID from GIF and COM codes. |
| 128 | + * Find set-good code by parsing. A set of good code aka set-code is a combination of two more goods codes. |
45 | 129 | * |
46 | | - * @param string $code GIF or COM code |
47 | | - * @return int The method returns ID |
| 130 | + * @param string $setCode "set1232x3ZZ322ZZ4313x4" means "1232" x 3 + "322" x 4 + "4313" x 4. "1232", "322" and "4312" are good codes. |
| 131 | + * @return array The method returns good code array |
| 132 | + * |
| 133 | + * @throws InvalidArgumentException |
48 | 134 | */ |
49 | | - public static function getId(string $code): int |
| 135 | + public static function getSetCodes(string $setCode): array |
50 | 136 | { |
51 | | - return (int) preg_replace('/[^0-9]/', '', $code); |
| 137 | + $escape = preg_replace('/^'.GoodCodeType::SET->prefix().'/i', '', $setCode); |
| 138 | + |
| 139 | + $goodCodes = explode(self::SET_CODE_DELIMITER, $escape); |
| 140 | + |
| 141 | + $parsedCodes = []; |
| 142 | + |
| 143 | + foreach ($goodCodes as $code) { |
| 144 | + if (preg_match('/'.self::SET_CODE_DELIMITER_COUNT.'/i', $code)) { |
| 145 | + [$k, $v] = explode(self::SET_CODE_DELIMITER_COUNT, $code); |
| 146 | + } else { |
| 147 | + [$k, $v] = [$code, 1]; |
| 148 | + } |
| 149 | + $parsedCodes[$k] = $v; |
| 150 | + } |
| 151 | + |
| 152 | + return $parsedCodes; |
52 | 153 | } |
53 | 154 | } |
0 commit comments