├── LICENSE ├── README.md ├── composer.json └── src ├── Concerns ├── HasCases.php └── HasCastable.php ├── Exceptions └── UnknownCaseTypeException.php └── Services ├── File.php ├── Formatter.php └── Formatters ├── Base.php ├── Json.php └── Php.php /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-2025 Andrey Helldar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pretty Array 2 | 3 | Pretty Array 4 | 5 | [![Stable Version][badge_stable]][link_packagist] 6 | [![Unstable Version][badge_unstable]][link_packagist] 7 | [![Total Downloads][badge_downloads]][link_packagist] 8 | [![Github Workflow Status][badge_build]][link_build] 9 | [![License][badge_license]][link_license] 10 | 11 | > Simple conversion of an array to a pretty view. 12 | 13 | 14 | ## Installation 15 | 16 | To get the latest version of `Pretty Array` package, simply require the project using [Composer](https://getcomposer.org): 17 | 18 | ``` 19 | composer require dragon-code/pretty-array 20 | ``` 21 | 22 | Instead, you may of course manually update your `require` block and run `composer update` if you so choose: 23 | 24 | ```json 25 | { 26 | "require": { 27 | "dragon-code/pretty-array": "^4.0" 28 | } 29 | } 30 | ``` 31 | 32 | ## Introduction 33 | 34 | > Q: Why did you create this package when there is a cooler [symfony/var-exporter](https://github.com/symfony/var-exporter)? 35 | 36 | The big minus of package [symfony/var-exporter](https://github.com/symfony/var-exporter) is that it works differently with numeric keys. 37 | 38 | For example, we have an array: 39 | 40 | ```php 41 | $array = [ 42 | 100 => 'foo', 43 | 200 => 'bar', 44 | 201 => 'baz', 45 | 202 => 'qwe', 46 | 205 => 'ert', 47 | 206 => 'tyu' 48 | ]; 49 | ``` 50 | 51 | When exporting through it, the file will contain the following content: 52 | 53 | ```php 54 | $array = [ 55 | 100 => 'foo', 56 | 200 => 'bar', 57 | 'baz', 58 | 'qwe', 59 | 205 => 'ert', 60 | 'tyu' 61 | ]; 62 | ``` 63 | 64 | > Q: Why do you think this is bad? 65 | 66 | This package has a framework-independent base. However, it was originally developed as an assistant for 67 | the [Laravel Lang: HTTP Statuses](https://github.com/Laravel-Lang/http-statuses) 68 | package. 69 | 70 | This package allows you to publish language translations of the HTTP Status Codes for the Laravel and Lumen frameworks. 71 | 72 | A feature of the framework is that IDEs that help with development do not know how to read the numeric keys of arrays of translation files, so it was necessary to translate 73 | theminto a text equivalent. 74 | 75 | This behavior includes [http-statuses.php](https://github.com/Laravel-Lang/http-statuses/blob/main/source/http-statuses.php) file: 76 | 77 | ```php 78 | 'Unknown Error', 82 | '0' => 'Unknown Error', 83 | 84 | '100' => 'Continue', 85 | '101' => 'Switching Protocols', 86 | '102' => 'Processing', 87 | 88 | '200' => 'OK', 89 | '201' => 'Created', 90 | '202' => 'Accepted', 91 | '203' => 'Non-Authoritative Information', 92 | '204' => 'No Content', 93 | '205' => 'Reset Content', 94 | '206' => 'Partial Content', 95 | '207' => 'Multi-Status', 96 | '208' => 'Already Reported', 97 | '226' => 'IM Used', 98 | 99 | // ... 100 | ``` 101 | 102 | The peculiarity of the package is that it takes the values of the source file and combines it with what is already in the application. Thus, the output is a file with numeric keys 103 | that IDE helpers cannot read: 104 | 105 | ```php 106 | 'Unknown Error', 110 | 0 => 'Unknown Error', 111 | 112 | 100 => 'Continue', 113 | 'Switching Protocols', 114 | 'Processing', 115 | 116 | 200 => 'OK', 117 | '201' => 'Created', 118 | 'Accepted', 119 | 'Non-Authoritative Information', 120 | 'No Content', 121 | 'Reset Content', 122 | 'Partial Content', 123 | 'Multi-Status', 124 | 'Already Reported', 125 | 226 => 'IM Used', 126 | 127 | // ... 128 | ``` 129 | 130 | ## Using 131 | 132 | Source array for all examples: 133 | 134 | ```php 135 | $array = array ( 136 | 'foo' => 1, 137 | 'bar' => 2, 138 | 'baz' => 3, 139 | 'qwerty' => 'qaz', 140 | 'baq' => array ( 141 | 0 => 'qwe', 142 | '1' => 'rty', 143 | 'asd' => 'zxc', 144 | ), 145 | 'asdfgh' => array ( 146 | 'foobarbaz' => 'qwe', 147 | 2 => 'rty', 148 | 'qawsed' => 'zxc', 149 | ), 150 | 2 => 'iop', 151 | ); 152 | ``` 153 | 154 | ### Saving numeric keys without alignment 155 | 156 | ```php 157 | use DragonCode\PrettyArray\Services\Formatter; 158 | 159 | $service = Formatter::make(); 160 | 161 | return $service->raw($array); 162 | ``` 163 | 164 | Result: 165 | 166 | ```text 167 | [ 168 | 'foo' => 1, 169 | 'bar' => 2, 170 | 'baz' => 3, 171 | 'qwerty' => 'qaz', 172 | 'baq' => [ 173 | 0 => 'qwe', 174 | 1 => 'rty', 175 | 'asd' => 'zxc', 176 | ], 177 | 'asdfgh' => [ 178 | 'foobarbaz' => 'qwe', 179 | 2 => 'rty', 180 | 'qawsed' => 'zxc', 181 | ], 182 | 2 => 'iop', 183 | ] 184 | ``` 185 | 186 | ### Saving string keys without alignment 187 | 188 | ```php 189 | use DragonCode\PrettyArray\Services\Formatter; 190 | 191 | $service = Formatter::make(); 192 | $service->setKeyAsString(); 193 | 194 | return $service->raw($array); 195 | ``` 196 | 197 | Result: 198 | 199 | ```text 200 | [ 201 | 'foo' => 1, 202 | 'bar' => 2, 203 | 'baz' => 3, 204 | 'qwerty' => 'qaz', 205 | 'baq' => [ 206 | '0' => 'qwe', 207 | '1' => 'rty', 208 | 'asd' => 'zxc', 209 | ], 210 | 'asdfgh' => [ 211 | 'foobarbaz' => 'qwe', 212 | '2' => 'rty', 213 | 'qawsed' => 'zxc', 214 | ], 215 | '2' => 'iop', 216 | ] 217 | ``` 218 | 219 | ### Saving numeric keys with alignment 220 | 221 | ```php 222 | use DragonCode\PrettyArray\Services\Formatter; 223 | 224 | $service = Formatter::make(); 225 | $service->setEqualsAlign(); 226 | 227 | return $service->raw($array); 228 | ``` 229 | 230 | Result: 231 | 232 | ```text 233 | [ 234 | 'foo' => 1, 235 | 'bar' => 2, 236 | 'baz' => 3, 237 | 'qwerty' => 'qaz', 238 | 'baq' => [ 239 | 0 => 'qwe', 240 | 1 => 'rty', 241 | 'asd' => 'zxc', 242 | ], 243 | 'asdfgh' => [ 244 | 'foobarbaz' => 'qwe', 245 | 2 => 'rty', 246 | 'qawsed' => 'zxc', 247 | ], 248 | 2 => 'iop', 249 | ] 250 | ``` 251 | 252 | ### Saving string keys with alignment 253 | 254 | ```php 255 | use DragonCode\PrettyArray\Services\Formatter; 256 | 257 | $service = Formatter::make(); 258 | $service->setKeyAsString(); 259 | $service->setEqualsAlign(); 260 | 261 | return $service->raw($array); 262 | ``` 263 | 264 | Result: 265 | 266 | ```text 267 | [ 268 | 'foo' => 1, 269 | 'bar' => 2, 270 | 'baz' => 3, 271 | 'qwerty' => 'qaz', 272 | 'baq' => [ 273 | '0' => 'qwe', 274 | '1' => 'rty', 275 | 'asd' => 'zxc', 276 | ], 277 | 'asdfgh' => [ 278 | 'foobarbaz' => 'qwe', 279 | '2' => 'rty', 280 | 'qawsed' => 'zxc', 281 | ], 282 | '2' => 'iop', 283 | ] 284 | ``` 285 | 286 | ### Saving simple array 287 | 288 | ```php 289 | use DragonCode\PrettyArray\Services\Formatter; 290 | 291 | $service = Formatter::make(); 292 | $service->setSimple(); 293 | 294 | return $service->raw($array); 295 | ``` 296 | 297 | Result: 298 | 299 | ```text 300 | [ 301 | 1, 302 | 2, 303 | 3, 304 | 'qaz', 305 | [ 306 | 'qwe', 307 | 'rty', 308 | 'zxc', 309 | ], 310 | [ 311 | 'qwe', 312 | 'rty', 313 | 'zxc', 314 | ], 315 | 'iop', 316 | ] 317 | ``` 318 | 319 | ### Change key case 320 | 321 | ```php 322 | use DragonCode\Contracts\Pretty\Arr\Caseable; 323 | use DragonCode\PrettyArray\Services\Formatter; 324 | 325 | $service = Formatter::make(); 326 | $service->setCase(Caseable::PASCAL_CASE); 327 | 328 | return $service->raw($array); 329 | ``` 330 | 331 | Result: 332 | 333 | ```text 334 | [ 335 | 'Foo' => 1, 336 | 'Bar' => 2, 337 | 'Baz' => 3, 338 | 'QweRty' => 'qaz', 339 | 'Baq' => [ 340 | 0 => 'qwe', 341 | 1 => 'rty', 342 | 'Asd' => 'zxc', 343 | ], 344 | 'AsdFgh' => [ 345 | 'FooBarBaz' => 'qwe', 346 | 2 => 'rty', 347 | 'QawSed' => 'zxc', 348 | ], 349 | 2 => 'iop', 350 | ] 351 | ``` 352 | 353 | The following options are available: 354 | 355 | * camelCase (`DragonCode\Contracts\Pretty\Arr\Caseable::CAMEL_CASE`); 356 | * kebab-case (`DragonCode\Contracts\Pretty\Arr\Caseable::KEBAB_CASE`); 357 | * PascalCase (`DragonCode\Contracts\Pretty\Arr\Caseable::PASCAL_CASE`); 358 | * snake_case (`DragonCode\Contracts\Pretty\Arr\Caseable::SNAKE_CASE`); 359 | * no case (`DragonCode\Contracts\Pretty\Arr\Caseable::NO_CASE`). By default; 360 | 361 | `NO_CASE` means that key register processing will not be performed. 362 | 363 | 364 | ### Storing file 365 | 366 | ```php 367 | use DragonCode\PrettyArray\Services\File; 368 | use DragonCode\PrettyArray\Services\Formatter; 369 | 370 | $service = Formatter::make(); 371 | 372 | $formatted = $service->raw($array); 373 | 374 | File::make($formatted) 375 | ->store('foo.php'); 376 | ``` 377 | 378 | Result in stored file `foo.php`: 379 | 380 | ```php 381 | 1, 385 | 'bar' => 2, 386 | 'baz' => 3, 387 | 'qwerty' => 'qaz', 388 | 'baq' => [ 389 | 0 => 'qwe', 390 | 1 => 'rty', 391 | 'asd' => 'zxc', 392 | ], 393 | 'asdfgh' => [ 394 | 'foobarbaz' => 'qwe', 395 | 2 => 'rty', 396 | 'qawsed' => 'zxc', 397 | ], 398 | 2 => 'iop', 399 | ]; 400 | ``` 401 | 402 | #### As JSON 403 | 404 | ```php 405 | use DragonCode\PrettyArray\Services\File; 406 | use DragonCode\PrettyArray\Services\Formatter; 407 | 408 | $service = Formatter::make(); 409 | 410 | $service->asJson(); 411 | 412 | $formatted = $service->raw($array); 413 | 414 | File::make($formatted) 415 | ->store('foo.json'); 416 | ``` 417 | 418 | Result in stored file `foo.json`: 419 | 420 | ```json 421 | { 422 | "foo": 1, 423 | "bar": 2, 424 | "baz": 3, 425 | "qwerty": "qaz", 426 | "baq": { 427 | "0": "qwe", 428 | "1": "rty", 429 | "asd": "zxc" 430 | }, 431 | "asdfgh": { 432 | "foobarbaz": "qwe", 433 | "2": "rty", 434 | "qawsed": "zxc" 435 | }, 436 | "2": "'iop'" 437 | } 438 | ``` 439 | 440 | ## License 441 | 442 | This package is licensed under the [MIT License](LICENSE). 443 | 444 | 445 | [badge_build]: https://img.shields.io/github/actions/workflow/status/TheDragonCode/pretty-array/phpunit.yml?style=flat-square 446 | 447 | [badge_downloads]: https://img.shields.io/packagist/dt/dragon-code/pretty-array.svg?style=flat-square 448 | 449 | [badge_license]: https://img.shields.io/packagist/l/dragon-code/pretty-array.svg?style=flat-square 450 | 451 | [badge_stable]: https://img.shields.io/github/v/release/TheDragonCode/pretty-array?label=stable&style=flat-square 452 | 453 | [badge_unstable]: https://img.shields.io/badge/unstable-dev--main-orange?style=flat-square 454 | 455 | [link_build]: https://github.com/TheDragonCode/pretty-array/actions 456 | 457 | [link_license]: LICENSE 458 | 459 | [link_packagist]: https://packagist.org/packages/dragon-code/pretty-array 460 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dragon-code/pretty-array", 3 | "description": "Simple conversion of an array to a pretty view", 4 | "license": "MIT", 5 | "type": "library", 6 | "keywords": [ 7 | "pretty array", 8 | "pretty", 9 | "array", 10 | "dragon code", 11 | "dragon", 12 | "andrey helldar" 13 | ], 14 | "authors": [ 15 | { 16 | "name": "Andrey Helldar", 17 | "email": "helldar@dragon-code.pro", 18 | "homepage": "https://dragon-code.pro" 19 | } 20 | ], 21 | "support": { 22 | "issues": "https://github.com/TheDragonCode/pretty-array/issues", 23 | "source": "https://github.com/TheDragonCode/pretty-array" 24 | }, 25 | "funding": [ 26 | { 27 | "type": "boosty", 28 | "url": "https://boosty.to/dragon-code" 29 | }, 30 | { 31 | "type": "yoomoney", 32 | "url": "https://yoomoney.ru/to/410012608840929" 33 | } 34 | ], 35 | "require": { 36 | "php": "^8.0", 37 | "ext-dom": "*", 38 | "ext-mbstring": "*", 39 | "dragon-code/contracts": "^2.20", 40 | "dragon-code/support": "^6.11.2" 41 | }, 42 | "require-dev": { 43 | "phpunit/phpunit": "^9.6 || ^10.0 || ^11.0 || ^12.0" 44 | }, 45 | "suggest": { 46 | "symfony/thanks": "Give thanks (in the form of a GitHub) to your fellow PHP package maintainers" 47 | }, 48 | "minimum-stability": "stable", 49 | "prefer-stable": true, 50 | "autoload": { 51 | "psr-4": { 52 | "DragonCode\\PrettyArray\\": "src" 53 | } 54 | }, 55 | "autoload-dev": { 56 | "psr-4": { 57 | "Tests\\": "tests" 58 | } 59 | }, 60 | "config": { 61 | "allow-plugins": { 62 | "dragon-code/codestyler": true, 63 | "ergebnis/composer-normalize": true, 64 | "friendsofphp/php-cs-fixer": true, 65 | "symfony/thanks": true 66 | }, 67 | "preferred-install": "dist", 68 | "sort-packages": true 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/Concerns/HasCases.php: -------------------------------------------------------------------------------- 1 | 10 | * 11 | * @copyright 2023 Andrey Helldar 12 | * 13 | * @license MIT 14 | * 15 | * @see https://github.com/TheDragonCode/pretty-array 16 | */ 17 | 18 | namespace DragonCode\PrettyArray\Concerns; 19 | 20 | use DragonCode\PrettyArray\Exceptions\UnknownCaseTypeException; 21 | use DragonCode\Support\Facades\Helpers\Str; 22 | 23 | trait HasCases 24 | { 25 | protected int $case = self::NO_CASE; 26 | 27 | /** 28 | * @throws UnknownCaseTypeException 29 | * 30 | * @return HasCases 31 | */ 32 | public function setCase(int $type = self::NO_CASE): static 33 | { 34 | if ($type < 0 || $type > 4) { 35 | throw new UnknownCaseTypeException($type); 36 | } 37 | 38 | $this->case = $type; 39 | 40 | return $this; 41 | } 42 | 43 | protected function convertKeysCase(array $array): array 44 | { 45 | if ($this->case === static::NO_CASE) { 46 | return $array; 47 | } 48 | 49 | $result = []; 50 | 51 | foreach ($array as $key => $value) { 52 | $key = $this->convertKeyCase($key); 53 | 54 | $result[$key] = $value; 55 | } 56 | 57 | return $result; 58 | } 59 | 60 | protected function convertKeyCase(mixed $key): mixed 61 | { 62 | if (! is_string($key)) { 63 | return $key; 64 | } 65 | 66 | return match ($this->case) { 67 | static::KEBAB_CASE => $this->caseTo( 68 | $this->caseTo($key, static::PASCAL_CASE), 69 | static::KEBAB_CASE 70 | ), 71 | 72 | static::CAMEL_CASE => $this->caseTo( 73 | $this->caseTo($key, static::KEBAB_CASE), 74 | static::CAMEL_CASE 75 | ), 76 | 77 | static::SNAKE_CASE => $this->caseTo( 78 | $this->caseTo($key, static::PASCAL_CASE), 79 | static::SNAKE_CASE 80 | ), 81 | 82 | static::PASCAL_CASE => $this->caseTo( 83 | $this->caseTo($key, static::KEBAB_CASE), 84 | static::PASCAL_CASE 85 | ), 86 | 87 | default => $key, 88 | }; 89 | } 90 | 91 | protected function caseTo(mixed $key, int $case = 0): mixed 92 | { 93 | if (! is_string($key)) { 94 | return $key; 95 | } 96 | 97 | return match ($case) { 98 | static::CAMEL_CASE => Str::camel($key), 99 | static::KEBAB_CASE => Str::snake($key, '-'), 100 | static::SNAKE_CASE => Str::snake($key), 101 | static::PASCAL_CASE => Str::studly($key), 102 | default => $key, 103 | }; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/Concerns/HasCastable.php: -------------------------------------------------------------------------------- 1 | 10 | * 11 | * @copyright 2023 Andrey Helldar 12 | * 13 | * @license MIT 14 | * 15 | * @see https://github.com/TheDragonCode/pretty-array 16 | */ 17 | 18 | namespace DragonCode\PrettyArray\Concerns; 19 | 20 | use DragonCode\Support\Facades\Helpers\Boolean; 21 | 22 | trait HasCastable 23 | { 24 | /** 25 | * Castable value. 26 | */ 27 | protected function castValue(mixed $value = null): float|int|string 28 | { 29 | if (is_numeric($value)) { 30 | return $value; 31 | } 32 | 33 | if (is_bool($value)) { 34 | return Boolean::toString($value); 35 | } 36 | 37 | if (is_null($value)) { 38 | return 'null'; 39 | } 40 | 41 | if (is_array($value) || is_object($value)) { 42 | return '[]'; 43 | } 44 | 45 | return "'" . addslashes($value) . "'"; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Exceptions/UnknownCaseTypeException.php: -------------------------------------------------------------------------------- 1 | 10 | * 11 | * @copyright 2023 Andrey Helldar 12 | * 13 | * @license MIT 14 | * 15 | * @see https://github.com/TheDragonCode/pretty-array 16 | */ 17 | 18 | namespace DragonCode\PrettyArray\Exceptions; 19 | 20 | use Exception; 21 | 22 | class UnknownCaseTypeException extends Exception 23 | { 24 | public function __construct(string $type) 25 | { 26 | parent::__construct("Unknown conversion type: $type", 500); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Services/File.php: -------------------------------------------------------------------------------- 1 | 10 | * 11 | * @copyright 2023 Andrey Helldar 12 | * 13 | * @license MIT 14 | * 15 | * @see https://github.com/TheDragonCode/pretty-array 16 | */ 17 | 18 | namespace DragonCode\PrettyArray\Services; 19 | 20 | use DragonCode\Support\Concerns\Makeable; 21 | use DragonCode\Support\Facades\Filesystem\File as Storage; 22 | use DragonCode\Support\Facades\Helpers\Str; 23 | use DragonCode\Support\Facades\Tools\Stub; 24 | use DragonCode\Support\Tools\Stub as StubTool; 25 | 26 | /** 27 | * @method static File make(?string $content = null) 28 | */ 29 | class File 30 | { 31 | use Makeable; 32 | 33 | public function __construct( 34 | protected ?string $content = null 35 | ) {} 36 | 37 | public function load(string $filename): array 38 | { 39 | return Storage::load($filename); 40 | } 41 | 42 | public function store(string $path, ?string $stub = null): void 43 | { 44 | Storage::store($path, $this->resolveContent($path, $stub)); 45 | } 46 | 47 | protected function resolveContent(string $path, ?string $stub): string 48 | { 49 | return $this->content( 50 | $this->stub($stub, $path) 51 | ); 52 | } 53 | 54 | protected function content(string $stub): string 55 | { 56 | return Stub::replace($stub, [ 57 | '{{slot}}' => $this->content, 58 | ]); 59 | } 60 | 61 | protected function stub(?string $stub, string $path): string 62 | { 63 | if ($stub) { 64 | return $stub; 65 | } 66 | 67 | return $this->isJson($path) ? StubTool::JSON : StubTool::PHP_ARRAY; 68 | } 69 | 70 | protected function isJson(string $path): bool 71 | { 72 | return Str::of($path)->lower()->endsWith('.json'); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/Services/Formatter.php: -------------------------------------------------------------------------------- 1 | 10 | * 11 | * @copyright 2023 Andrey Helldar 12 | * 13 | * @license MIT 14 | * 15 | * @see https://github.com/TheDragonCode/pretty-array 16 | */ 17 | 18 | namespace DragonCode\PrettyArray\Services; 19 | 20 | use DragonCode\Contracts\Pretty\Arr\Caseable; 21 | use DragonCode\PrettyArray\Concerns\HasCases; 22 | use DragonCode\PrettyArray\Services\Formatters\Json; 23 | use DragonCode\PrettyArray\Services\Formatters\Php; 24 | use DragonCode\Support\Concerns\Makeable; 25 | 26 | class Formatter implements Caseable 27 | { 28 | use Makeable; 29 | use HasCases; 30 | 31 | protected bool $key_as_string = false; 32 | 33 | protected bool $equals_align = false; 34 | 35 | protected bool $is_simple = false; 36 | 37 | protected bool $as_json = false; 38 | 39 | public function setKeyAsString(): void 40 | { 41 | $this->key_as_string = true; 42 | } 43 | 44 | public function setEqualsAlign(): void 45 | { 46 | $this->equals_align = true; 47 | } 48 | 49 | public function setSimple(): void 50 | { 51 | $this->is_simple = true; 52 | } 53 | 54 | public function asJson(bool $json = true): void 55 | { 56 | $this->as_json = $json; 57 | } 58 | 59 | public function raw(array $array, int $pad = 1): string 60 | { 61 | if ($this->as_json) { 62 | return Json::make() 63 | ->setCase($this->case) 64 | ->setKeyAsString($this->key_as_string) 65 | ->setSimple($this->is_simple) 66 | ->get($array, $pad); 67 | } 68 | 69 | return Php::make() 70 | ->setCase($this->case) 71 | ->setKeyAsString($this->key_as_string) 72 | ->setSimple($this->is_simple) 73 | ->setEqualsAlign($this->equals_align) 74 | ->get($array, $pad); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/Services/Formatters/Base.php: -------------------------------------------------------------------------------- 1 | 10 | * 11 | * @copyright 2023 Andrey Helldar 12 | * 13 | * @license MIT 14 | * 15 | * @see https://github.com/TheDragonCode/pretty-array 16 | */ 17 | 18 | declare(strict_types=1); 19 | 20 | namespace DragonCode\PrettyArray\Services\Formatters; 21 | 22 | use DragonCode\Contracts\Pretty\Arr\Caseable; 23 | use DragonCode\PrettyArray\Concerns\HasCases; 24 | use DragonCode\PrettyArray\Concerns\HasCastable; 25 | use DragonCode\Support\Concerns\Makeable; 26 | 27 | abstract class Base implements Caseable 28 | { 29 | use HasCases; 30 | use HasCastable; 31 | use Makeable; 32 | 33 | protected bool $key_as_string = false; 34 | 35 | protected bool $is_simple = false; 36 | 37 | abstract public function get(array $array, int $pad = 1): string; 38 | 39 | abstract protected function key(mixed $key, int $size = 0): string; 40 | 41 | public function setKeyAsString(bool $as): static 42 | { 43 | $this->key_as_string = $as; 44 | 45 | return $this; 46 | } 47 | 48 | public function setSimple(bool $simple): static 49 | { 50 | $this->is_simple = $simple; 51 | 52 | return $this; 53 | } 54 | 55 | protected function pad(string $value, int $pad = 1, $type = STR_PAD_LEFT): string 56 | { 57 | $pad += $type === STR_PAD_LEFT ? strlen($value) : 2; 58 | 59 | return str_pad($value, $pad, ' ', $type); 60 | } 61 | 62 | protected function isStringKey($key): bool 63 | { 64 | return $this->key_as_string || ! is_numeric($key); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/Services/Formatters/Json.php: -------------------------------------------------------------------------------- 1 | 10 | * 11 | * @copyright 2023 Andrey Helldar 12 | * 13 | * @license MIT 14 | * 15 | * @see https://github.com/TheDragonCode/pretty-array 16 | */ 17 | 18 | declare(strict_types=1); 19 | 20 | namespace DragonCode\PrettyArray\Services\Formatters; 21 | 22 | class Json extends Base 23 | { 24 | protected int $flags = JSON_UNESCAPED_SLASHES ^ JSON_PRETTY_PRINT ^ JSON_UNESCAPED_UNICODE; 25 | 26 | public function get(array $array, int $pad = 1): string 27 | { 28 | if (empty($array)) { 29 | return $this->encode($array); 30 | } 31 | 32 | $array = $this->convertKeysCase($array); 33 | 34 | return $this->encode($this->prepare($array)); 35 | } 36 | 37 | protected function key(mixed $key, int $size = 0): string 38 | { 39 | return (string) $key; 40 | } 41 | 42 | protected function prepare(array $array): array 43 | { 44 | $result = []; 45 | 46 | foreach ($array as $key => $value) { 47 | $key = $this->key($key); 48 | $value = $this->value($value); 49 | 50 | match ($this->is_simple) { 51 | true => $result[] = $value, 52 | false => $result[$key] = $value 53 | }; 54 | } 55 | 56 | return $result; 57 | } 58 | 59 | protected function value($value): mixed 60 | { 61 | if (! empty($value) && (is_array($value) || is_object($value))) { 62 | return $this->prepare($value); 63 | } 64 | 65 | return $value; 66 | } 67 | 68 | protected function encode(mixed $value): string 69 | { 70 | return json_encode($value, $this->flags); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/Services/Formatters/Php.php: -------------------------------------------------------------------------------- 1 | 10 | * 11 | * @copyright 2023 Andrey Helldar 12 | * 13 | * @license MIT 14 | * 15 | * @see https://github.com/TheDragonCode/pretty-array 16 | */ 17 | 18 | declare(strict_types=1); 19 | 20 | namespace DragonCode\PrettyArray\Services\Formatters; 21 | 22 | use DragonCode\Support\Facades\Helpers\Arr; 23 | 24 | class Php extends Base 25 | { 26 | protected bool $equals_align = false; 27 | 28 | protected int $pad_length = 4; 29 | 30 | protected string $line_break = PHP_EOL; 31 | 32 | public function setEqualsAlign(bool $equals): static 33 | { 34 | $this->equals_align = $equals; 35 | 36 | return $this; 37 | } 38 | 39 | public function get(array $array, int $pad = 1): string 40 | { 41 | if (empty($array)) { 42 | return '[]'; 43 | } 44 | 45 | $array = $this->convertKeysCase($array); 46 | 47 | $keys_size = $this->sizeKeys($array); 48 | $pad_length = $this->pad_length * $pad; 49 | 50 | $formatted = '[' . $this->line_break; 51 | 52 | foreach ($array as $key => $value) { 53 | $key = $this->key($key, $keys_size); 54 | $value = $this->value($value, $pad + 1); 55 | 56 | $row = $this->is_simple 57 | ? "$value," . $this->line_break 58 | : "$key => $value," . $this->line_break; 59 | 60 | $formatted .= $this->pad($row, $pad_length); 61 | } 62 | 63 | return $formatted . $this->pad(']', $pad_length - $this->pad_length); 64 | } 65 | 66 | protected function key(mixed $key, int $size = 0): string 67 | { 68 | $key = $this->isStringKey($key) ? "'$key'" : $key; 69 | 70 | if (! $this->equals_align) { 71 | return (string) $key; 72 | } 73 | 74 | return $this->pad((string) $key, $this->keySizeCollision($key, $size), STR_PAD_RIGHT); 75 | } 76 | 77 | protected function value($value, int $pad = 1): mixed 78 | { 79 | if (! empty($value) && (is_array($value) || is_object($value))) { 80 | return $this->get($value, $pad); 81 | } 82 | 83 | return $this->castValue($value); 84 | } 85 | 86 | protected function sizeKeys(array $array): int 87 | { 88 | $sizes = Arr::of($array)->keys()->longestStringLength(); 89 | 90 | return $this->key_as_string ? $sizes + 2 : $sizes; 91 | } 92 | 93 | protected function keySizeCollision($key, int $size): int 94 | { 95 | $collision = is_numeric($key) ? 0 : ($this->isAlignAndString() ? -2 : 0); 96 | 97 | return $size + $collision; 98 | } 99 | 100 | protected function isAlignAndString(): bool 101 | { 102 | return $this->equals_align && $this->key_as_string; 103 | } 104 | } 105 | --------------------------------------------------------------------------------