MessageRevisions::getPathname()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 0
crap 1
1
<?php
2
3
namespace Printful\GettextCms;
4
5
use Gettext\Translation;
6
use Gettext\Translations;
7
use Printful\GettextCms\Exceptions\InvalidPathException;
8
use Printful\GettextCms\Interfaces\MessageConfigInterface;
9
use Printful\GettextCms\Structures\RevisionItem;
10
11
class MessageRevisions
12
{
13
    /** @var MessageConfigInterface */
14
    private $config;
15
16
    /**
17
     * Cached instance so we don't read the file each time
18
     * @var RevisionItem
19
     */
20
    private $revisionCache = null;
21
22 16
    public function __construct(MessageConfigInterface $config)
23
    {
24 16
        $this->config = $config;
25 16
    }
26
27
    /**
28
     * Get revisioned domain or the original domain name if revision does not exist for this domain
29
     *
30
     * @param string $locale
31
     * @param string $domain
32
     * @return string
33
     */
34 7
    public function getRevisionedDomain(string $locale, string $domain): string
35
    {
36 7
        if ($locale === $this->config->getDefaultLocale() || !$this->config->useRevisions()) {
37
            // We do not revision default domain because all texts are defined in the code and not cached by gettext
38 2
            return $domain;
39
        }
40
41 6
        if (!$this->revisionCache) {
42 6
            $this->revisionCache = $this->readFromFile();
43
        }
44
45 6
        $revisionedDomain = $this->revisionCache->getRevisionedDomain($locale, $domain);
46
47 6
        return $revisionedDomain ?: $domain;
48
    }
49
50
    /**
51
     * From given translations, create a versioned domain name "domain_XXXXXX"
52
     *
53
     * @param string $domain
54
     * @param Translations $translations
55
     * @return string
56
     */
57 6
    public function generateRevisionedDomain(string $domain, Translations $translations): string
58
    {
59 6
        return $domain . '-' . $this->generateHash($translations);
60
    }
61
62
    private function generateHash(Translations $translations): string
63
    {
64 6
        $array = array_map(function (Translation $t) {
65
            return [
66 6
                $t->getOriginal(),
67 6
                $t->getPlural(),
68 6
                $t->getTranslation(),
69 6
                $t->getPluralTranslations(),
70 6
                $t->getContext(),
71
            ];
72 6
        }, (array)$translations);
73
74 6
        return substr(md5(serialize($array)), 0, 6); // Take only 6, and pray for no collisions
75
    }
76
77
    /**
78
     * Store in revision file that a new revision was created
79
     *
80
     * @param string $locale
81
     * @param string $originalDomain
82
     * @param string $revisionedDomain
83
     * @return bool
84
     * @throws InvalidPathException
85
     */
86 8
    public function saveRevision(string $locale, string $originalDomain, string $revisionedDomain): bool
87
    {
88 8
        if ($locale === $this->config->getDefaultLocale()) {
89
            // No point in saving default locale revision
90 1
            return true;
91
        }
92
93 7
        $revisions = $this->readFromFile();
94
95 7
        $previousRevision = $revisions->getRevisionedDomain($locale, $originalDomain);
96
97 7
        if ($previousRevision === $revisionedDomain) {
98
            // No need to save, because it's the same revision
99 1
            return true;
100
        }
101
102 7
        $revisions->setRevisionedDomain($locale, $originalDomain, $revisionedDomain);
103
104 7
        return $this->writeToFile($revisions);
105
    }
106
107
    /**
108
     * Read revision data from file
109
     *
110
     * @return RevisionItem
111
     */
112 7
    private function readFromFile(): RevisionItem
113
    {
114 7
        $pathname = $this->getPathname();
115
116 7
        if (is_file($pathname)) {
117 5
            return RevisionItem::fromArray(json_decode(file_get_contents($pathname), true));
118
        }
119
120 7
        return new RevisionItem();
121
    }
122
123
    /**
124
     * Write revision data to json file
125
     *
126
     * @param Structures\RevisionItem $revisions
127
     * @return bool
128
     * @throws InvalidPathException
129
     */
130 7
    private function writeToFile(RevisionItem $revisions): bool
131
    {
132
        // Update the cached version
133 7
        $this->revisionCache = $revisions;
134
135 7
        $pathname = $this->getPathname();
136
137 7
        if (!is_dir(dirname($pathname))) {
138 1
            throw new InvalidPathException('Directory does not exist (' . $this->config->getMoDirectory() . ')');
139
        }
140
141 6
        return (bool)file_put_contents($pathname, json_encode($revisions->toArray(), JSON_PRETTY_PRINT));
142
    }
143
144
    /**
145
     * Full path to revision file
146
     *
147
     * @return string
148
     */
149 7
    private function getPathname(): string
150
    {
151 7
        return rtrim($this->config->getMoDirectory(), '/') . '/' . 'revisions.json';
152
    }
153
}