Completed
Push — master ( a698e3...6cfee9 )
by Maxime
02:49 queued 01:09
created

EnumExtractor::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 4
1
<?php
2
3
/*
4
 * This file is part of the "elao/enum" package.
5
 *
6
 * Copyright (C) Elao
7
 *
8
 * @author Elao <[email protected]>
9
 */
10
11
namespace Elao\Enum\Bridge\Symfony\Translation\Extractor;
12
13
use Elao\Enum\ReadableEnum;
14
use Symfony\Component\Finder\Finder;
15
use Symfony\Component\Finder\SplFileInfo;
16
use Symfony\Component\Translation\Extractor\ExtractorInterface;
17
use Symfony\Component\Translation\MessageCatalogue;
18
19
class EnumExtractor implements ExtractorInterface
20
{
21
    /**
22
     * @var array<string, string>
23
     */
24
    private $paths;
25
26
    /**
27
     * @var string
28
     */
29
    private $domain;
30
31
    /**
32
     * @var string
33
     */
34
    private $fileNamePattern;
35
36
    /**
37
     * @var array<string>
38
     */
39
    private $ignore;
40
41
    /**
42
     * @var string
43
     */
44
    private $prefix = '';
45
46
    /**
47
     * @var bool
48
     */
49
    private $hasRun = false;
50
51
    /**
52
     * @param array<string, string> $paths
53
     * @param array<string>         $ignore
54
     */
55
    public function __construct(array $paths, string $domain, string $fileNamePattern, array $ignore)
56
    {
57
        $this->paths = $paths;
58
        $this->domain = $domain;
59
        $this->fileNamePattern = $fileNamePattern;
60
        $this->ignore = $ignore;
61
    }
62
63
    public function setPrefix($prefix): void
64
    {
65
        $this->prefix = $prefix;
66
    }
67
68
    /**
69
     * @param array|string $resource
70
     */
71
    public function extract($resource, MessageCatalogue $catalog): void
72
    {
73
        // Ensure it runs only once.
74
        if ($this->hasRun) {
75
            return;
76
        }
77
        $this->hasRun = true;
78
79
        $finder = new Finder();
80
81
        foreach ($this->paths as $dir => $settings) {
82
            // Normalize namespace.
83
            $namespace = rtrim($settings['namespace'], '\\') . '\\';
84
85
            /** @var SplFileInfo $file */
86
            foreach ($finder->files()->name($this->fileNamePattern)->in($dir) as $file) {
87
                foreach ($this->ignore as $ignore) {
88
                    if (fnmatch($ignore, $file->getPathname())) {
89
                        continue 2;
90
                    }
91
                }
92
93
                // Get file pathinfo and clear dirname.
94
                $path = pathinfo($file->getRelativePathname());
95
                if ($path['dirname'] === '.') {
96
                    $path['dirname'] = '';
97
                } else {
98
                    $path['dirname'] .= '/';
99
                }
100
101
                // Build class name and check if it's a ReadableEnum instance.
102
                /** @var ReadableEnum $class */
103
                $class = $namespace . strtr($path['dirname'] . $path['filename'], ['/' => '\\']);
104
                if (!is_a($class, ReadableEnum::class, true)) {
105
                    continue;
106
                }
107
108
                $readables = $class::readables();
109
                foreach ($readables as $k => $enum) {
110
                    $enum = (string) $enum;
111
                    if ('' === $enum) {
112
                        continue;
113
                    }
114
115
                    $catalog->set($enum, $this->prefix . $enum, $this->domain);
116
                    $metadata = $catalog->getMetadata($enum, $this->domain) ?? [];
117
                    $normalizedFilename = preg_replace('{[\\\\/]+}', '/', $file->getPathName());
118
                    $metadata['sources'][] = $normalizedFilename . ':' . $k;
119
                    $catalog->setMetadata($enum, $metadata, $this->domain);
120
                }
121
            }
122
        }
123
    }
124
}
125