Passed
Push — 1.0.x ( 3a2c37...ccae28 )
by Julien
14:07 queued 06:59
created

NestedNativeArray::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 4
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 6
ccs 5
cts 5
cp 1
crap 1
rs 10
1
<?php
2
3
/**
4
 * This file is part of the Zemit Framework.
5
 *
6
 * (c) Zemit Team <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE.txt
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Zemit\Translate\Adapter;
13
14
use JetBrains\PhpStorm\Deprecated;
15
use Phalcon\Translate\Adapter\AbstractAdapter;
16
use Phalcon\Translate\Exception;
17
use Phalcon\Translate\InterpolatorFactory;
18
19
/**
20
 * NestedNativeArray class is an implementation of the Translate Adapter interface that uses
21
 * a nested array as the translation source.
22
 *
23
 * Usage example:
24
 * ```
25
 * $interpolator = new InterpolatorFactory();
26
 * $options = [
27
 *     'content' => [
28
 *         'en' => [
29
 *             'welcome' => 'Welcome to our website!',
30
 *             'goodbye' => 'Goodbye!',
31
 *         ],
32
 *         'fr' => [
33
 *             'welcome' => 'Bienvenue sur notre site web!',
34
 *             'goodbye' => 'Au revoir!',
35
 *         ],
36
 *     ],
37
 *     'triggerError' => false,
38
 *     'delimiter' => '.',
39
 * ];
40
 *
41
 * $translator = new NestedNativeArray($interpolator, $options);
42
 *
43
 * // Check if translation exists
44
 * $translator->exists('en.welcome'); // returns true
45
 *
46
 * // Get translated string
47
 * $translator->query('fr.goodbye'); // returns 'Au revoir!'
48
 *
49
 * // Get translated string with placeholders
50
 * $translator->query('en.welcome', ['name' => 'John']); // returns 'Welcome to our website, John!'
51
 * ```
52
 *
53
 * @package Zemit\Translate\Adapter
54
 */
55
class NestedNativeArray extends AbstractAdapter implements \ArrayAccess
56
{
57
    /**
58
     * Translation array.
59
     * @var array $translate
60
     */
61
    private array $translate = [];
62
    
63
    /**
64
     * @var bool $triggerError Determines whether to trigger an error or not.
65
     */
66
    private bool $triggerError = false;
67
    
68
    /**
69
     * Sets the value of the delimiter.
70
     *
71
     * @param string $delimiter The delimiter value to set.
72
     */
73
    protected string $delimiter = '.';
74
    
75
    /**
76
     * Zemit\Translate\Adapter\NestedNativeArray constructor
77
     *
78
     * @param InterpolatorFactory $interpolator
79
     * @param array $options [
80
     *     'content' => '',
81
     *     'triggerError' => false,
82
     *     'delimiter' => '.',
83
     * ]
84
     */
85 1
    public function __construct(InterpolatorFactory $interpolator, array $options)
86
    {
87 1
        parent::__construct($interpolator, $options);
88 1
        $this->delimiter = $options['delimiter'] ?? $this->delimiter;
89 1
        $this->triggerError = $options['triggerError'] ?? $this->triggerError;
90 1
        $this->translate = $options['content'] ?? $this->translate;
91
    }
92
    
93
    /**
94
     * Returns whether a translation exists for the given index
95
     *
96
     * @param string $index The translation index to check
97
     * @return bool True if a translation exists for the index, false otherwise
98
     * @deprecated since Zemit 1.0, use has() instead. The replacement method is %class%->has(%parametersList%)
99
     * @see has()
100
     */
101 1
    #[Deprecated(
102
        reason: 'since Zemit 1.0, use has() instead',
103
        replacement: '%class%->has(%parametersList%)'
104
    )]
105
    public function exists(string $index): bool
106
    {
107 1
        return $this->has($index);
108
    }
109
    
110
    /**
111
     * Returns true if the translation for the given index exists, false otherwise.
112
     * @param string $index The index of the translation to check.
113
     * @return bool Returns true if the translation for the given index exists, false otherwise.
114
     */
115 1
    public function has(string $index): bool
116
    {
117 1
        $translate = $this->translate;
118
        
119 1
        if (isset($translate[$index])) {
120 1
            return $translate[$index];
121
        }
122
        
123 1
        foreach (explode($this->delimiter, $index) as $nestedIndex) {
124
            
125 1
            if (is_array($translate) && array_key_exists($nestedIndex, $translate)) {
126 1
                $translate = $translate[$nestedIndex];
127
            }
128
            else {
129 1
                return false;
130
            }
131
        }
132
        
133 1
        return true;
134
    }
135
    
136
    /**
137
     * Returns the index if translation key is not found
138
     * Throws exception if triggerError is enabled and translation key is not found
139
     * 
140
     * @param string $index The translation key
141
     * @return string Returns the index
142
     * @throws Exception Throws exception if triggerError is enabled and translation key is not found
143
     */
144 1
    public function notFound(string $index): string
145
    {
146 1
        if ($this->triggerError) {
147
            throw new Exception('Cannot find translation key: ' . $index);
148
        }
149
    
150 1
        return $index;
151
    }
152
    
153
    /**
154
     * Queries for a translated string based on the given translate key and optional placeholders.
155
     *
156
     * @param string $translateKey The translate key to query for a translated string.
157
     * @param array $placeholders An optional array of placeholders to replace in the translated string.
158
     * @return string The translated string or the not found string if the translate key is not found.
159
     * @throws Exception Throws exception if triggerError is enabled and translation key is not found
160
     */
161 1
    public function query(string $translateKey, array $placeholders = []): string
162
    {
163 1
        $translate = $this->translate;
164
        
165 1
        if (isset($translate[$translateKey])) {
166 1
            return $translate[$translateKey];
167
        }
168
        
169 1
        foreach (explode($this->delimiter, $translateKey) as $nestedIndex) {
170
            
171 1
            if (is_array($translate) && array_key_exists($nestedIndex, $translate)) {
172 1
                $translate = $translate[$nestedIndex];
173
            }
174
            else {
175 1
                return $this->notFound($translateKey);
176
            }
177
        }
178
        
179 1
        return $this->replacePlaceholders($translate, $placeholders);
180
    }
181
    
182
    /**
183
     * Converts the translate data to an array.
184
     *
185
     * @return array The translate data as an array.
186
     */
187
    public function toArray(): array
188
    {
189
        return $this->translate;
190
    }
191
}
192