Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
88.24% covered (warning)
88.24%
15 / 17
75.00% covered (warning)
75.00%
6 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
SnakeCaseSlug
88.24% covered (warning)
88.24%
15 / 17
75.00% covered (warning)
75.00%
6 / 8
10.16
0.00% covered (danger)
0.00%
0 / 1
 getRegularExpression
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 fromClass
80.00% covered (warning)
80.00%
4 / 5
0.00% covered (danger)
0.00%
0 / 1
3.07
 fromText
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 humanize
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 toCamelCaseSlug
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 toPascalCaseSlug
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 toKebabCaseSlug
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 createRandom
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2namespace Apie\Core\Identifiers;
3
4use Apie\Core\Attributes\Description;
5use Apie\Core\Attributes\FakeMethod;
6use Apie\Core\ValueObjects\Interfaces\HasRegexValueObjectInterface;
7use Apie\Core\ValueObjects\IsStringWithRegexValueObject;
8use Faker\Generator;
9use ReflectionClass;
10use ReflectionMethod;
11use ReflectionProperty;
12
13/**
14 * Indicate an identifier written with underscores and lowercase only(pascal_case).
15 */
16#[FakeMethod('createRandom')]
17#[Description('Lowercase text written with underscores for separate words, for example "example_object"')]
18class SnakeCaseSlug implements HasRegexValueObjectInterface
19{
20    use IsStringWithRegexValueObject;
21
22    public static function getRegularExpression(): string
23    {
24        return '/^[a-z0-9]+(_[a-z0-9]+)*$/';
25    }
26
27    /**
28     * @param ReflectionClass<object>|ReflectionMethod|ReflectionProperty|string $class
29     */
30    public static function fromClass(ReflectionClass|ReflectionMethod|ReflectionProperty|string $class): self
31    {
32        if (is_object($class)) {
33            $shortName = $class instanceof ReflectionClass ? $class->getShortName() : $class->name;
34            $short = preg_replace('/([a-z])([A-Z])/', '$1_$2', $shortName);
35        } else {
36            $short = $class;
37        }
38        return static::fromNative(strtolower($short));
39    }
40
41    public static function fromText(string $text): self
42    {
43        // Replace camelCase with snake_case
44        $text = preg_replace('/([a-z])([A-Z])/', '$1_$2', $text);
45        // Replace any non-alphanumeric character with underscore
46        $text = preg_replace('/[^a-zA-Z0-9]+/', '_', $text);
47        // Convert to lowercase
48        $text = strtolower($text);
49        // Remove leading/trailing underscores
50        $text = trim($text, '_');
51        // Collapse multiple underscores into one
52        $text = preg_replace('/_+/', '_', $text);
53        return static::fromNative($text);
54    }
55
56    public function humanize(): string
57    {
58        return str_replace('_', ' ', $this->internal);
59    }
60
61    public function toCamelCaseSlug(): CamelCaseSlug
62    {
63        return new CamelCaseSlug(lcfirst(str_replace('_', '', ucwords($this->internal, '_'))));
64    }
65
66    public function toPascalCaseSlug(): PascalCaseSlug
67    {
68        return new PascalCaseSlug(str_replace('_', '', ucwords($this->internal, '_')));
69    }
70
71    public function toKebabCaseSlug(): KebabCaseSlug
72    {
73        return new KebabCaseSlug(str_replace('_', '-', $this->internal));
74    }
75
76    public static function createRandom(Generator $faker): static
77    {
78        return static::fromNative(CamelCaseSlug::createRandom($faker)->toSnakeCaseSlug()->toNative());
79    }
80}