PoInitPHP   A
last analyzed

Complexity

Total Complexity 25

Size/Duplication

Total Lines 111
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 25
lcom 1
cbo 3
dl 0
loc 111
ccs 52
cts 52
cp 1
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
D msginitString() 0 63 23
A stripComment() 0 4 1
1
<?php
2
3
namespace Geekwright\Po;
4
5
/**
6
 * PoInitPHP provides 'msginit' like logic which can take a source PHP file,
7
 * recognize gettext like function tokens, and capture the translatable strings
8
 * in a PoFile object.
9
 *
10
 * @category  Extractors
11
 * @package   Po
12
 * @author    Richard Griffith <[email protected]>
13
 * @copyright 2015-2018 Richard Griffith
14
 * @license   GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
15
 * @link      https://github.com/geekwright/Po
16
 */
17
class PoInitPHP extends PoInitAbstract
18
{
19
    /**
20
     * @var string[] $gettextTags tags for gettext constructs, i.e. tag($msgid)
21
     */
22
    protected $gettextTags = array('gettext', 'gettext_noop', '_');
23
24
    /**
25
     * @var string[] $pgettextTags tags for pgettext constructs, i.e. tag($msgctxt, $msgid)
26
     */
27
    protected $pgettextTags = array('pgettext');
28
29
    /**
30
     * @var string[] $ngettextTags tags for ngettext constructs, i.e. tag($msgid, $msgid_plural)
31
     */
32
    protected $ngettextTags = array('ngettext');
33
34
    /**
35
     * Establish the PoFile to use in the Init process
36
     *
37
     * @param PoFile|null $poFile a PoFile object to be used in msginit
38
     */
39 5
    public function __construct(?PoFile $poFile = null)
40
    {
41 5
        $this->poFile = $poFile;
42 5
    }
43
44
    /**
45
     * Inspect the supplied source, capture gettext references as a PoFile object.
46
     *
47
     * @param string $source  php source code
48
     * @param string $refname source identification used for PO reference comments
49
     *
50
     * @return PoFile
51
     */
52 1
    public function msginitString(string $source, string $refname): PoFile
53
    {
54 1
        if (!($this->poFile instanceof PoFile)) {
55 1
            $this->poFile = new PoFile;
56
        }
57
58 1
        $tokens = token_get_all($source);
59
60 1
        $translateTags = array_merge($this->gettextTags, $this->pgettextTags, $this->ngettextTags);
61 1
        $commentText=null;
62 1
        $commentLine=(-10);
63 1
        $tokenCount = count($tokens);
64 1
        $i = 0;
65 1
        while ($i<$tokenCount) {
66 1
            $token = $tokens[$i];
67 1
            if (is_array($token) && $token[0] == T_STRING && in_array($token[1], $translateTags)) {
68 1
                $entry = new PoEntry;
69 1
                $gtt = array();
70 1
                list(, $text, $line) = $token;
71 1
                $entry->add(PoTokens::REFERENCE, $refname . ':' . $line);
72 1
                $gtt['line']=$line;
73 1
                $gtt['function']=$text;
74 1
                $gtt['args'] = array();
75 1
                $la = 1;
76 1
                while (is_array($tokens[$i + $la]) &&  $tokens[$i + $la][0] == T_WHITESPACE) {
77 1
                    $la++;
78
                }
79 1
                if ($tokens[$i + $la] == '(') {
80 1
                    while ((')' != $token=$tokens[$i + $la]) && ($la < 10)) {
81 1
                        if (is_array($token) && (
82 1
                            $token[0] == T_CONSTANT_ENCAPSED_STRING
83 1
                            || $token[0] == T_ENCAPSED_AND_WHITESPACE
84
                        )) {
85 1
                            list(, $text, $line) = $token;
86 1
                            $gtt['args'][]=$text;
87
                        }
88 1
                        $la++;
89
                    }
90 1
                    if (count($gtt['args'])) {
91 1
                        if (in_array($gtt['function'], $this->gettextTags)) {
92 1
                            $entry->set(PoTokens::MESSAGE, $this->escapeForPo($gtt['args'][0]));
93 1
                        } elseif (count($gtt['args'])>1 && in_array($gtt['function'], $this->pgettextTags)) {
94 1
                            $entry->set(PoTokens::CONTEXT, $this->escapeForPo($gtt['args'][0]));
95 1
                            $entry->set(PoTokens::MESSAGE, $this->escapeForPo($gtt['args'][1]));
96 1
                        } elseif (count($gtt['args'])>1 && in_array($gtt['function'], $this->ngettextTags)) {
97 1
                            $entry->set(PoTokens::MESSAGE, $this->escapeForPo($gtt['args'][0]));
98 1
                            $entry->set(PoTokens::PLURAL, $this->escapeForPo($gtt['args'][1]));
99
                        }
100 1
                        $this->checkPhpFormatFlag($entry);
101 1
                        if ($gtt['line']==($commentLine+1)) {
102 1
                            $entry->set(PoTokens::EXTRACTED_COMMENTS, $this->stripComment($commentText));
103
                        }
104 1
                        $this->poFile->mergeEntry($entry);
105
                    }
106
                }
107 1
            } elseif (is_array($token) && $token[0] == T_COMMENT) {
108 1
                list(, $commentText, $commentLine) = $token;
109
            }
110 1
            $i++;
111
        }
112
113 1
        return $this->poFile;
114
    }
115
116
    /**
117
     * Remove comment tags from string
118
     *
119
     * @param string $string raw comment string
120
     *
121
     * @return string
122
     */
123 1
    protected function stripComment(string $string): string
124
    {
125 1
        return trim(str_replace(array('//', '/*', '*/'), '', $string));
126
    }
127
}
128