Completed
Push — master ( e8ecc6...4bc2d8 )
by Faiz
02:14
created

XMLRepository::addTranslation()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 4
ccs 0
cts 2
cp 0
rs 10
cc 1
eloc 1
nc 1
nop 1
crap 2
1
<?php
2
3
namespace FaizShukri\Quran\Repositories\Source;
4
5
use FaizShukri\Quran\Exceptions\AyahInvalid;
6
use FaizShukri\Quran\Exceptions\SurahInvalid;
7
use FaizShukri\Quran\Exceptions\TranslationNotExists;
8
use FaizShukri\Quran\Supports\Config;
9
use FaizShukri\Quran\Supports\Downloader;
10
use FaizShukri\Quran\Supports\XML;
11
12
class XMLRepository implements SourceInterface
13
{
14
    private $config;
15
16 78
    public function setConfig(Config $config)
17
    {
18 78
        $this->config = $config;
19 78
    }
20
21 51
    public function surah($surah = null)
22
    {
23
24
        // Get all chapter
25 51
        if ($surah === null) {
26 3
            $xmlFile = $this->config->get('storage_path').'/quran-data.xml';
27 3
            $xml = new XML($xmlFile);
28 3
            $result = [];
29
30 3
            $xpath = '//suras/sura';
31 3
            $xpathResult = $xml->find($xpath);
32
33 3
            while (list(, $sura) = each($xpathResult)) {
34 3
                $sura = (array) $sura;
35 3
                $sura = current($sura);
36 3
                $result[$sura['index']] = (object) $sura;
37 2
            }
38
39 3
            return $result;
40
        }
41
42 48
        if ($surah < 1 || $surah > 114) {
43 3
            throw new SurahInvalid();
44
        }
45 45
        $xmlFile = $this->config->get('storage_path').'/quran-data.xml';
46 45
        $xml = new XML($xmlFile);
47
48 45
        $xpath = "//suras/sura[@index=$surah]";
49 45
        $xpathResult = $xml->find($xpath);
50
51 45
        $sura = (array) current($xpathResult);
52
53 45
        return $sura['@attributes'];
54
    }
55
56 48
    public function ayah($surah, $ayah, $translation = 'ar')
57
    {
58 48
        $xmlFile = $this->config->get('storage_path').'/'.$translation.'.xml';
59
60
        // If files not exist, get the first match
61 48
        if (!file_exists($xmlFile)) {
62 45
            $xmlFile = $this->firstMatchAvailableTranslation($translation);
63 30
        }
64
65 48
        if ($xmlFile === false) {
66 3
            throw new TranslationNotExists('Translation '.$translation." didn't exists. Please check your config.");
67
        }
68
69 45
        $xml = new XML($xmlFile);
70 45
        $result = [];
71
72 45
        $max_ayah = intval($this->surah($surah)['ayas']);
73
        $xpath = '//sura[@index='.$surah.']/aya['.implode(' or ', array_map(function ($a) use ($max_ayah) {
74 42
                if ($a > $max_ayah) {
75 3
                    throw new AyahInvalid();
76
                }
77
78 39
                return '@index='.$a;
79 42
            }, $ayah)).']';
80
81 39
        $xpathResult = $xml->find($xpath);
82
83 39
        while (list(, $node) = each($xpathResult)) {
84 39
            $node = (array) $node;
85 39
            $verse = current($node);
86 39
            $result[$verse['index']] = $verse['text'];
87 26
        }
88
89 39
        return $result;
90
    }
91
92 78
    public function initialize()
93
    {
94
        // If original quran not exist in storage_path, copy one
95 78
        $quran_source = realpath(__DIR__.'/../../../data/ar.quran.xml');
96 78
        $quran_dest = $this->config->get('storage_path').'/ar.quran.xml';
97
98 78
        $meta_source = realpath(__DIR__.'/../../../data/quran-data.xml');
99 78
        $meta_dest = $this->config->get('storage_path').'/quran-data.xml';
100
101
        // If storage path didn't exist, create it
102 78
        if (!file_exists($this->config->get('storage_path'))) {
103
            mkdir($this->config->get('storage_path'));
104
        }
105
106
        // Copy quran
107 78
        if (!file_exists($quran_dest)) {
108
            copy($quran_source, $quran_dest);
109
        }
110
111
        // Copy metadata
112 78
        if (!file_exists($meta_dest)) {
113
            copy($meta_source, $meta_dest);
114
        }
115
116
        // Sync translation files to storage path
117 78
        $dw = new Downloader($this->config);
118 78
        $dw->sync();
119 78
    }
120
121
    /**
122
     * Get the first match xml from translation.
123
     *
124
     * @param string $translation Translation prefix or short form
125
     *
126
     * @return string|false String of path to the translation if exists, or false otherwise
127
     */
128 45
    private function firstMatchAvailableTranslation($translation)
129
    {
130 45
        $dir = new \DirectoryIterator($this->config->get('storage_path'));
131
132 45
        foreach ($dir as $fileinfo) {
133 45
            if (!$fileinfo->isDot()) {
134 45
                $filename = $fileinfo->getFilename();
135
136
                // If match the first file with translation prefix, return it
137 45
                $yes = preg_match('/^'.$translation.'/', $filename);
138 45
                if ($yes === 1) {
139 43
                    return $this->config->get('storage_path').'/'.$filename;
140
                }
141 16
            }
142 30
        }
143
144 3
        return false;
145
    }
146
147
148
    public function translations()
149
    {
150
        $dir = scandir($this->config->get('storage_path'));
151
        $translations = array_filter($dir, function($a){
152
            return ($a !== "." && $a !== ".." && $a !== 'quran-data.xml');
153
        });
154
155
        return array_values(
156
            array_map(function($a){ return str_replace(".xml", "", $a); }, $translations)
157
        );
158
    }
159
160
    public function addTranslation($translation)
161
    {
162
        // TODO: Implement addTranslation() method.
163
    }
164
}
165