Localization_Parser   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 209
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 59
dl 0
loc 209
rs 10
c 1
b 0
f 0
wmc 14

10 Methods

Rating   Name   Duplication   Size   Complexity  
A requireValidLanguageID() 0 16 2
A getLanguageIDs() 0 3 1
A requireValidFile() 0 15 2
A createLanguageInstance() 0 19 2
A parseString() 0 9 1
A isExtensionSupported() 0 5 1
A parseFile() 0 11 1
A isFileSupported() 0 3 1
A __construct() 0 4 1
A createLanguage() 0 10 2
1
<?php
2
/**
3
 * File containing the {@link Localization_Parser} class.
4
 * @package Localization
5
 * @subpackage Parser
6
 * @see Localization_Parser
7
 */
8
9
declare(strict_types=1);
10
11
namespace AppLocalize;
12
13
use AppUtils\FileHelper;
14
use function AppUtils\parseVariable;
15
16
/**
17
 * File-based parsing engine that extracts translatable
18
 * application strings from PHP and Javascript code.
19
 *
20
 * Uses the built-in PHP tokenizer and Tim Whitlock's
21
 * jtokenizer for parsing javascript files. 
22
 *
23
 * @package Localization
24
 * @subpackage Parser
25
 * @author Sebastian Mordziol <[email protected]>
26
 */
27
class Localization_Parser
28
{
29
    const ERROR_INVALID_LANGUAGE_ID = 40601;
30
    const ERROR_UNSUPPORTED_FILE_EXTENSION = 40602;
31
    const ERROR_INVALID_LANGUAGE_CLASS = 40603;
32
    
33
   /**
34
    * @var Localization_Scanner
35
    */
36
    protected $scanner;
37
    
38
   /**
39
    * @var Localization_Scanner_StringsCollection
40
    */
41
    protected $collection;
42
43
    /**
44
     * @var array<string,string>
45
     */
46
    protected $languageMappings = array(
47
        'js' => 'Javascript',
48
        'php' => 'PHP'
49
    );
50
    
51
    public function __construct(Localization_Scanner $scanner)
52
    {
53
        $this->scanner = $scanner;
54
        $this->collection = $scanner->getCollection();
55
    }
56
    
57
   /**
58
    * Parses a source file. Must have a valid supported file extension.
59
    * 
60
    * @param string $path
61
    * @return Localization_Parser_Language
62
    * @throws Localization_Exception
63
    * 
64
    * @see Localization_Parser::ERROR_UNSUPPORTED_FILE_EXTENSION
65
    */
66
    public function parseFile(string $path) : Localization_Parser_Language
67
    {
68
        $this->requireValidFile($path);
69
         
70
        $ext = FileHelper::getExtension($path);
71
        
72
        $language = $this->createLanguage($this->languageMappings[$ext]);
73
        
74
        $language->parseFile($path);
75
        
76
        return $language;
77
    }
78
    
79
   /**
80
    * Parses the string for the specified language.
81
    * 
82
    * @param string $languageID
83
    * @param string $code
84
    * @return Localization_Parser_Language
85
    * @throws Localization_Exception
86
    * 
87
    * @see Localization_Parser::ERROR_INVALID_LANGUAGE_ID
88
    */
89
    public function parseString(string $languageID, string $code) : Localization_Parser_Language
90
    {
91
        $this->requireValidLanguageID($languageID);
92
        
93
        $language = $this->createLanguage($languageID);
94
        
95
        $language->parseString($code);
96
        
97
        return $language;
98
    }
99
100
    /**
101
     * @param string $path
102
     * @throws Localization_Exception
103
     * @see Localization_Parser::ERROR_UNSUPPORTED_FILE_EXTENSION
104
     */
105
    protected function requireValidFile(string $path) : void
106
    {
107
        $ext = FileHelper::getExtension($path);
108
        
109
        if($this->isExtensionSupported($ext)) {
110
            return;
111
        }
112
        
113
        throw new Localization_Exception(
114
            sprintf('Unsupported file extension [%s].', $ext),
115
            sprintf(
116
                'Tried parsing the file [%s].',
117
                $path
118
            ),
119
            self::ERROR_UNSUPPORTED_FILE_EXTENSION
120
        );
121
    }
122
123
    /**
124
     * @param string $languageID
125
     * @throws Localization_Exception
126
     * @see Localization_Parser::ERROR_INVALID_LANGUAGE_ID
127
     */
128
    protected function requireValidLanguageID(string $languageID) : void
129
    {
130
        $values = $this->getLanguageIDs();
131
        
132
        if(in_array($languageID, $values)) {
133
            return;
134
        }
135
136
        throw new Localization_Exception(
137
            'Unknown language ID',
138
            sprintf(
139
                'The language ID [%s] is not a known ID. Valid IDs are: [%s].',
140
                $languageID,
141
                implode(', ', $values)
142
            ),
143
            self::ERROR_INVALID_LANGUAGE_ID
144
        );
145
    }
146
    
147
   /**
148
    * Retrieves a list of all language IDs that are supported.
149
    * @return string[] IDs list like "PHP", "Javascript"
150
    */
151
    public function getLanguageIDs() : array
152
    {
153
        return array_values($this->languageMappings);
154
    }
155
    
156
   /**
157
    * @var array<string,Localization_Parser_Language>
158
    */
159
    protected $languageParsers = array();
160
161
    /**
162
     * Creates a parser for the specified language, e.g. "PHP".
163
     * NOTE: Existing parser instances are re-used.
164
     *
165
     * @param string $languageID
166
     * @return Localization_Parser_Language
167
     *
168
     * @throws Localization_Exception
169
     * @see Localization_Parser::ERROR_INVALID_LANGUAGE_ID
170
     * @see Localization_Parser::ERROR_INVALID_LANGUAGE_CLASS
171
     */
172
    public function createLanguage(string $languageID) : Localization_Parser_Language
173
    {
174
        $this->requireValidLanguageID($languageID);
175
        
176
        if(!isset($this->languageParsers[$languageID])) 
177
        {
178
            $this->languageParsers[$languageID] = $this->createLanguageInstance($languageID);
179
        }
180
        
181
        return $this->languageParsers[$languageID];
182
    }
183
184
    /**
185
     * @param string $id
186
     * @return Localization_Parser_Language
187
     * @throws Localization_Exception
188
     * @see Localization_Parser::ERROR_INVALID_LANGUAGE_CLASS
189
     */
190
    private function createLanguageInstance(string $id) : Localization_Parser_Language
191
    {
192
        $class = Localization_Parser_Language::class.'_'.$id;
193
194
        $object = new $class($this);
195
196
        if($object instanceof Localization_Parser_Language)
197
        {
198
            return $object;
199
        }
200
201
        throw new Localization_Exception(
202
            'Invalid parser language class',
203
            sprintf(
204
                'The created instance [%s] does not extend the base class [%s].',
205
                parseVariable($object)->enableType()->toString(),
206
                Localization_Parser_Language::class
207
            ),
208
            self::ERROR_INVALID_LANGUAGE_CLASS
209
        );
210
    }
211
212
   /**
213
    * Whether the specified file extension is supported.
214
    * 
215
    * @param string $ext
216
    * @return bool
217
    */
218
    public function isExtensionSupported(string $ext) : bool
219
    {
220
        $ext = strtolower($ext);
221
        
222
        return isset($this->languageMappings[$ext]);
223
    }
224
225
    /**
226
     * Checks if the target file is a file that can be
227
     * parsed, which means that it must have a supported 
228
     * file extension.
229
     *
230
     * @param string $file
231
     * @return boolean
232
     */
233
    public function isFileSupported(string $file) : bool
234
    {
235
        return $this->isExtensionSupported(FileHelper::getExtension($file));
236
    }
237
}
238