/
Parser.php
128 lines (111 loc) · 3.13 KB
/
Parser.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<?php
namespace SilverStripe\i18n\TextCollection;
use SilverStripe\i18n\i18n;
use SilverStripe\View\SSTemplateParser;
/**
* Parser that scans through a template and extracts the parameters to the _t and <%t calls
*/
class Parser extends SSTemplateParser
{
/**
* List of all entities
*
* @var array
*/
protected $entities = [];
/**
* Current entity
*
* @var array
*/
protected $currentEntity = [];
/**
* Key of current entity
*
* @var string
*/
protected $currentEntityKey = null;
/*
* Show warning if default omitted
*
* @var bool
*/
protected $warnIfEmpty = true;
/**
* @param string $string
* @param bool $warnIfEmpty
*/
public function __construct($string, $warnIfEmpty = true)
{
parent::__construct();
$this->string = $string;
$this->pos = 0;
$this->depth = 0;
$this->regexps = [];
$this->warnIfEmpty = $warnIfEmpty;
}
public function Translate__construct(&$res)
{
$this->currentEntity = [];
$this->currentEntityKey = null;
}
public function Translate_Entity(&$res, $sub)
{
// Collapse escaped slashes
$this->currentEntityKey = str_replace('\\\\', '\\', $sub['text'] ?? ''); // key
}
public function Translate_Default(&$res, $sub)
{
$this->currentEntity['default'] = $sub['String']['text']; // default
}
public function Translate_Context(&$res, $sub)
{
$this->currentEntity['comment'] = $sub['String']['text']; //comment
}
public function Translate__finalise(&$res)
{
// Validate entity
$entity = $this->currentEntity;
if (empty($entity['default'])) {
if ($this->warnIfEmpty) {
trigger_error("Missing localisation default for key " . $this->currentEntityKey, E_USER_NOTICE);
}
return;
}
// Detect plural forms
$plurals = i18n::parse_plurals($entity['default']);
if ($plurals) {
unset($entity['default']);
$entity = array_merge($entity, $plurals);
}
// If only default is set, simplify
if (count($entity ?? []) === 1 && !empty($entity['default'])) {
$entity = $entity['default'];
}
$this->entities[$this->currentEntityKey] = $entity;
}
/**
* Parses a template and returns any translatable entities
*
* @param string $template String to parse for translations
* @param bool $warnIfEmpty Show warnings if default omitted
* @return array Map of keys -> values
*/
public static function getTranslatables($template, $warnIfEmpty = true)
{
// Run the parser and throw away the result
$parser = new Parser($template, $warnIfEmpty);
if (substr($template ?? '', 0, 3) == pack("CCC", 0xef, 0xbb, 0xbf)) {
$parser->pos = 3;
}
$parser->match_TopTemplate();
return $parser->getEntities();
}
/**
* @return array
*/
public function getEntities()
{
return $this->entities;
}
}