Completed
Push — develop ( 469215...e978c4 )
by Faiz
01:51
created

XMLRepository::initialize()   B

Complexity

Conditions 4
Paths 8

Size

Total Lines 28
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 4.7031

Importance

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