PoHeader   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 176
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 18
lcom 1
cbo 1
dl 0
loc 176
ccs 74
cts 74
cp 1
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A buildStructuredHeaders() 0 18 4
A storeStructuredHeader() 0 13 3
A getHeader() 0 10 2
A setHeader() 0 12 2
A setCreateDate() 0 4 1
A setRevisionDate() 0 4 1
A formatTimestamp() 0 7 2
A buildDefaultHeader() 0 21 1
A dumpEntry() 0 5 1
1
<?php
2
3
namespace Geekwright\Po;
4
5
/**
6
 * A special PoEntry that represents the header of a GNU gettext style PO or POT file.
7
 * The header is the first entry of a PO file. It has an empty string as the "msgid"
8
 * value, and a set of structured strings compose the "msgstr" value. PoHeader exposes
9
 * these structured strings so that the individual values can be fetched or set by name.
10
 *
11
 * @category  Entries
12
 * @package   Po
13
 * @author    Richard Griffith <[email protected]>
14
 * @copyright 2015-2018 Richard Griffith
15
 * @license   GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
16
 * @link      https://github.com/geekwright/Po
17
 */
18
class PoHeader extends PoEntry
19
{
20
    protected $structuredHeaders = null;
21
22
23
    /**
24
     * Create an empty header entry
25
     */
26 16
    public function __construct()
27
    {
28 16
        parent::__construct();
29 16
        $this->entry[PoTokens::MESSAGE] = "";
30 16
    }
31
32
    /**
33
     * Populate the internal structuredHeaders property with contents
34
     * of this entry's "msgstr" value.
35
     *
36
     * @return void
37
     */
38 10
    protected function buildStructuredHeaders(): void
39
    {
40 10
        $this->structuredHeaders = array();
41 10
        $headers = $this->entry[PoTokens::TRANSLATED];
42 10
        $headers = ($headers === null) ? array() : $headers;
43 10
        $full = implode('', $headers);
44 10
        $headers = explode("\n", $full);
45
        // split on ':'
46 10
        $pattern = '/([a-z0-9\-]+):\s*(.*)/i';
47 10
        foreach ($headers as $h) {
48 10
            if (preg_match($pattern, trim($h), $matches)) {
49 10
                $this->structuredHeaders[strtolower($matches[1])] = array(
50 10
                    'key' => $matches[1],
51 10
                    'value' => $matches[2],
52
                );
53
            }
54
        }
55 10
    }
56
57
    /**
58
     * Rebuild the this entry's "msgstr" value using contents of the internal
59
     * structuredHeaders property.
60
     *
61
     * @return boolean true if rebuilt, false if not
62
     */
63 9
    protected function storeStructuredHeader(): bool
64
    {
65 9
        if (is_null($this->structuredHeaders)) {
66 1
            return false;
67
        }
68 9
        $headers = array("");
69
70 9
        foreach ($this->structuredHeaders as $h) {
71 9
            $headers[] = $h['key'] . ': ' . $h['value'] . "\n";
72
        }
73 9
        $this->entry[PoTokens::TRANSLATED] = $headers;
74 9
        return true;
75
    }
76
77
    /**
78
     * Get a header value string by key
79
     *
80
     * @param string $key case insensitive name of header to return
81
     *
82
     * @return string|null header string for key or false if not set
83
     */
84 5
    public function getHeader(string $key): ?string
85
    {
86 5
        $this->buildStructuredHeaders();
87 5
        $lkey = strtolower($key);
88 5
        $header = null;
89 5
        if (isset($this->structuredHeaders[$lkey]['value'])) {
90 5
            $header = $this->structuredHeaders[$lkey]['value'];
91
        }
92 5
        return $header;
93
    }
94
95
    /**
96
     * Set the value of a header string for a key.
97
     *
98
     * @param string $key   name of header to set. If the header exists, the name is
99
     *                      case insensitive. If it is new the given case will be used
100
     * @param string $value value to set
101
     *
102
     * @return void
103
     */
104 9
    public function setHeader(string $key, string $value): void
105
    {
106 9
        $this->buildStructuredHeaders();
107 9
        $lkey = strtolower($key);
108 9
        if (isset($this->structuredHeaders[$lkey])) {
109 3
            $this->structuredHeaders[$lkey]['value'] = $value;
110
        } else {
111 9
            $newHeader = array('key' => $key, 'value' => $value);
112 9
            $this->structuredHeaders[$lkey] = $newHeader;
113
        }
114 9
        $this->storeStructuredHeader();
115 9
    }
116
117
    /**
118
     * Set the POT-Creation-Date header
119
     *
120
     * @param integer|null $time unix timestamp, null to use current
121
     *
122
     * @return void
123
     */
124 9
    public function setCreateDate(?int $time = null): void
125
    {
126 9
        $this->setHeader('POT-Creation-Date', $this->formatTimestamp($time));
127 9
    }
128
129
    /**
130
     * Set the PO-Revision-Date header
131
     *
132
     * @param integer|null $time unix timestamp, null to use current
133
     *
134
     * @return void
135
     */
136 1
    public function setRevisionDate(?int $time = null): void
137
    {
138 1
        $this->setHeader('PO-Revision-Date', $this->formatTimestamp($time));
139 1
    }
140
141
    /**
142
     * Format a timestamp following PO file conventions
143
     *
144
     * @param integer|null $time unix timestamp, null to use current
145
     *
146
     * @return string formatted timestamp
147
     */
148 9
    protected function formatTimestamp(?int $time = null): string
149
    {
150 9
        if (empty($time)) {
151 9
            $time = time();
152
        }
153 9
        return gmdate('Y-m-d H:iO', $time);
154
    }
155
156
    /**
157
     * Create a default header entry
158
     *
159
     * @return void
160
     */
161 9
    public function buildDefaultHeader(): void
162
    {
163 9
        $this->set(PoTokens::MESSAGE, "");
164 9
        $this->set(PoTokens::TRANSLATOR_COMMENTS, 'SOME DESCRIPTIVE TITLE');
165 9
        $this->add(PoTokens::TRANSLATOR_COMMENTS, 'Copyright (C) YEAR HOLDER');
166 9
        $this->add(PoTokens::TRANSLATOR_COMMENTS, 'LICENSE');
167 9
        $this->add(PoTokens::TRANSLATOR_COMMENTS, 'FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.');
168 9
        $this->add(PoTokens::TRANSLATOR_COMMENTS, '');
169 9
        $this->set(PoTokens::FLAG, 'fuzzy');
170 9
        $this->setHeader('Project-Id-Version', 'PACKAGE VERSION');
171 9
        $this->setHeader('Report-Msgid-Bugs-To', 'FULL NAME <EMAIL@ADDRESS>');
172 9
        $this->setCreateDate();
173 9
        $this->setHeader('PO-Revision-Date', 'YEAR-MO-DA HO:MI+ZONE');
174 9
        $this->setHeader('Last-Translator', 'FULL NAME <EMAIL@ADDRESS>');
175 9
        $this->setHeader('Language-Team', 'LANGUAGE <EMAIL@ADDRESS>');
176 9
        $this->setHeader('MIME-Version', '1.0');
177 9
        $this->setHeader('Content-Type', 'text/plain; charset=UTF-8');
178 9
        $this->setHeader('Content-Transfer-Encoding', '8bit');
179 9
        $this->setHeader('Plural-Forms', 'nplurals=INTEGER; plural=EXPRESSION;');
180 9
        $this->setHeader('X-Generator', 'geekwright/po');
181 9
    }
182
183
    /**
184
     * Dump this entry as a po/pot file fragment
185
     *
186
     * @return string
187
     */
188 6
    public function dumpEntry(): string
189
    {
190 6
        $this->set(PoTokens::MESSAGE, "");
191 6
        return parent::dumpEntry();
192
    }
193
}
194