Completed
Push — master ( 2da7a8...7e6b77 )
by Faiz
01:55
created

XMLRepository::surah()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 34
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 5

Importance

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