Completed
Push — master ( cf1346...b28e72 )
by Faiz
01:57
created

XMLRepository   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 127
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 91.43%

Importance

Changes 5
Bugs 0 Features 4
Metric Value
wmc 18
c 5
b 0
f 4
lcom 1
cbo 5
dl 0
loc 127
rs 10
ccs 64
cts 70
cp 0.9143

6 Methods

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