Skip to content

Commit

Permalink
Merge pull request #28 from TheDragonCode/4.x
Browse files Browse the repository at this point in the history
Added JSON formatting
  • Loading branch information
andrey-helldar authored Jun 2, 2023
2 parents 8876866 + 0d4b6f6 commit 6c84e24
Show file tree
Hide file tree
Showing 16 changed files with 401 additions and 89 deletions.
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,44 @@ return [
];
```

#### As JSON

```php
use DragonCode\PrettyArray\Services\File;
use DragonCode\PrettyArray\Services\Formatter;

$service = Formatter::make();

$service->asJson();

$formatted = $service->raw($array);

File::make($formatted)
->store('foo.json');
```

Result in stored file `foo.json`:

```json
{
"foo": 1,
"bar": 2,
"baz": 3,
"qwerty": "qaz",
"baq": {
"0": "qwe",
"1": "rty",
"asd": "zxc"
},
"asdfgh": {
"foobarbaz": "qwe",
"2": "rty",
"qawsed": "zxc"
},
"2": "'iop'"
}
```

## License

This package is licensed under the [MIT License](LICENSE).
Expand Down
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@
"php": "^8.0",
"ext-dom": "*",
"ext-mbstring": "*",
"dragon-code/contracts": "^2.6",
"dragon-code/support": "^6.0"
"dragon-code/contracts": "^2.20",
"dragon-code/support": "^6.11.2"
},
"require-dev": {
"phpunit/phpunit": "^9.0 || ^10.0"
"phpunit/phpunit": "^9.6 || ^10.2"
},
"suggest": {
"symfony/thanks": "Give thanks (in the form of a GitHub) to your fellow PHP package maintainers"
Expand Down
6 changes: 5 additions & 1 deletion src/Concerns/HasCases.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,18 @@ trait HasCases
* @param int $type
*
* @throws \DragonCode\PrettyArray\Exceptions\UnknownCaseTypeException
*
* @return \DragonCode\PrettyArray\Concerns\HasCases
*/
public function setCase(int $type = self::NO_CASE): void
public function setCase(int $type = self::NO_CASE): static
{
if ($type < 0 || $type > 4) {
throw new UnknownCaseTypeException($type);
}

$this->case = $type;

return $this;
}

protected function convertKeysCase(array $array): array
Expand Down
31 changes: 28 additions & 3 deletions src/Services/File.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

use DragonCode\Support\Concerns\Makeable;
use DragonCode\Support\Facades\Filesystem\File as Storage;
use DragonCode\Support\Facades\Helpers\Str;
use DragonCode\Support\Facades\Tools\Stub;
use DragonCode\Support\Tools\Stub as StubTool;

Expand All @@ -39,12 +40,36 @@ public function load(string $filename): array
return Storage::load($filename);
}

public function store(string $path, string $stub = StubTool::PHP_ARRAY): void
public function store(string $path, ?string $stub = null): void
{
$content = Stub::replace($stub, [
Storage::store($path, $this->resolveContent($path, $stub));
}

protected function resolveContent(string $path, ?string $stub): string
{
return $this->content(
$this->stub($stub, $path)
);
}

protected function content(string $stub): string
{
return Stub::replace($stub, [
'{{slot}}' => $this->content,
]);
}

protected function stub(?string $stub, string $path): string
{
if ($stub) {
return $stub;
}

Storage::store($path, $content);
return $this->isJson($path) ? StubTool::JSON : StubTool::PHP_ARRAY;
}

protected function isJson(string $path): bool
{
return Str::of($path)->lower()->endsWith('.json');
}
}
96 changes: 19 additions & 77 deletions src/Services/Formatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,22 @@

use DragonCode\Contracts\Pretty\Arr\Caseable;
use DragonCode\PrettyArray\Concerns\HasCases;
use DragonCode\PrettyArray\Concerns\HasCastable;
use DragonCode\PrettyArray\Services\Formatters\Json;
use DragonCode\PrettyArray\Services\Formatters\Php;
use DragonCode\Support\Concerns\Makeable;
use DragonCode\Support\Facades\Helpers\Arr;

class Formatter implements Caseable
{
use HasCases;
use HasCastable;
use Makeable;
use HasCases;

protected bool $key_as_string = false;

protected bool $equals_align = false;

protected bool $is_simple = false;

protected int $pad_length = 4;

protected string $line_break = PHP_EOL;
protected bool $as_json = false;

public function setKeyAsString(): void
{
Expand All @@ -54,81 +51,26 @@ public function setSimple(): void
$this->is_simple = true;
}

public function raw(array $array, int $pad = 1): string
{
if (empty($array)) {
return '[]';
}

$array = $this->convertKeysCase($array);

$keys_size = $this->sizeKeys($array);
$pad_length = $this->pad_length * $pad;

$formatted = '[' . $this->line_break;

foreach ($array as $key => $value) {
$key = $this->key($key, $keys_size);
$value = $this->value($value, $pad + 1);

$row = $this->is_simple
? "$value," . $this->line_break
: "$key => $value," . $this->line_break;

$formatted .= $this->pad($row, $pad_length);
}

return $formatted . $this->pad(']', $pad_length - $this->pad_length);
}

protected function pad(string $value, int $pad = 1, $type = STR_PAD_LEFT): string
{
$pad += $type === STR_PAD_LEFT ? strlen($value) : 2;

return str_pad($value, $pad, ' ', $type);
}

protected function value($value, int $pad = 1): mixed
public function asJson(bool $json = true): void
{
if (! empty($value) && (is_array($value) || is_object($value))) {
return $this->raw($value, $pad);
}

return $this->castValue($value);
$this->as_json = $json;
}

protected function key(mixed $key, int $size = 0): string
public function raw(array $array, int $pad = 1): string
{
$key = $this->isStringKey($key) ? "'{$key}'" : $key;

if (! $this->equals_align) {
return $key;
if ($this->as_json) {
return Json::make()
->setCase($this->case)
->setKeyAsString($this->key_as_string)
->setSimple($this->is_simple)
->get($array, $pad);
}

return $this->pad($key, $this->keySizeCollision($key, $size), STR_PAD_RIGHT);
}

protected function sizeKeys(array $array): int
{
$sizes = Arr::of($array)->keys()->longestStringLength();

return $this->key_as_string ? $sizes + 2 : $sizes;
}

protected function keySizeCollision($key, int $size): int
{
$collision = is_numeric($key) ? 0 : ($this->isAlignAndString() ? -2 : 0);

return $size + $collision;
}

protected function isStringKey($key): bool
{
return $this->key_as_string || ! is_numeric($key);
}

protected function isAlignAndString(): bool
{
return $this->equals_align && $this->key_as_string;
return Php::make()
->setCase($this->case)
->setKeyAsString($this->key_as_string)
->setSimple($this->is_simple)
->setEqualsAlign($this->equals_align)
->get($array, $pad);
}
}
66 changes: 66 additions & 0 deletions src/Services/Formatters/Base.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

/*
* This file is part of the "dragon-code/pretty-array" project.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @author Andrey Helldar <[email protected]>
*
* @copyright 2023 Andrey Helldar
*
* @license MIT
*
* @see https://github.com/TheDragonCode/pretty-array
*/

declare(strict_types=1);

namespace DragonCode\PrettyArray\Services\Formatters;

use DragonCode\Contracts\Pretty\Arr\Caseable;
use DragonCode\PrettyArray\Concerns\HasCases;
use DragonCode\PrettyArray\Concerns\HasCastable;
use DragonCode\Support\Concerns\Makeable;

abstract class Base implements Caseable
{
use HasCases;
use HasCastable;
use Makeable;

protected bool $key_as_string = false;

protected bool $is_simple = false;

abstract public function get(array $array, int $pad = 1): string;

abstract protected function key(mixed $key, int $size = 0): string;

public function setKeyAsString(bool $as): static
{
$this->key_as_string = $as;

return $this;
}

public function setSimple(bool $simple): static
{
$this->is_simple = $simple;

return $this;
}

protected function pad(string $value, int $pad = 1, $type = STR_PAD_LEFT): string
{
$pad += $type === STR_PAD_LEFT ? strlen($value) : 2;

return str_pad($value, $pad, ' ', $type);
}

protected function isStringKey($key): bool
{
return $this->key_as_string || ! is_numeric($key);
}
}
72 changes: 72 additions & 0 deletions src/Services/Formatters/Json.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

/*
* This file is part of the "dragon-code/pretty-array" project.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @author Andrey Helldar <[email protected]>
*
* @copyright 2023 Andrey Helldar
*
* @license MIT
*
* @see https://github.com/TheDragonCode/pretty-array
*/

declare(strict_types=1);

namespace DragonCode\PrettyArray\Services\Formatters;

class Json extends Base
{
protected int $flags = JSON_UNESCAPED_SLASHES ^ JSON_PRETTY_PRINT ^ JSON_UNESCAPED_UNICODE;

public function get(array $array, int $pad = 1): string
{
if (empty($array)) {
return $this->encode($array);
}

$array = $this->convertKeysCase($array);

return $this->encode($this->prepare($array));
}

protected function key(mixed $key, int $size = 0): string
{
return (string) $key;
}

protected function prepare(array $array): array
{
$result = [];

foreach ($array as $key => $value) {
$key = $this->key($key);
$value = $this->value($value);

match ($this->is_simple) {
true => $result[] = $value,
false => $result[$key] = $value
};
}

return $result;
}

protected function value($value): mixed
{
if (! empty($value) && (is_array($value) || is_object($value))) {
return $this->prepare($value);
}

return $value;
}

protected function encode(mixed $value): string
{
return json_encode($value, $this->flags);
}
}
Loading

0 comments on commit 6c84e24

Please sign in to comment.