Quran::minimize()   A
last analyzed

Complexity

Conditions 4
Paths 6

Size

Total Lines 16
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 6
nc 6
nop 1
dl 0
loc 16
ccs 6
cts 6
cp 1
crap 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace FaizShukri\Quran;
4
5
use FaizShukri\Quran\Repositories\Source\SourceInterface;
6
use FaizShukri\Quran\Repositories\Source\XMLRepository;
7
use FaizShukri\Quran\Exceptions\AyahNotProvided;
8
use FaizShukri\Quran\Exceptions\WrongArgument;
9
use FaizShukri\Quran\Exceptions\ExceedLimit;
10
use FaizShukri\Quran\Supports\Config;
11
12
class Quran
13
{
14
    /**
15
     * Quran application version.
16
     *
17
     * @var string
18
     */
19
    const VERSION = '2.0.1';
20
21
    private $config;
22
23
    private $translations = ['ar'];
24
25
    private $source;
26
27 60
    public function __construct(array $config = array())
28
    {
29 60
        $this->config = new Config($config);
30
31
        // By default, source is XML
32 60
        $this->setSource(new XMLRepository());
33 30
    }
34
35
    /**
36
     * Set quran source either XML, Sql.
37
     *
38
     * @param \FaizShukri\Quran\Repositories\Source\SourceInterface $source
39
     */
40 60
    public function setSource(SourceInterface $source)
41
    {
42 60
        $this->source = $source;
43 60
        $this->source->setConfig($this->config);
44 60
        $this->source->initialize();
45 30
    }
46
47
    /**
48
     * Get source variable.
49
     *
50
     * @return \FaizShukri\Quran\Repositories\Source\SourceInterface $source
51
     */
52 8
    public function getSource()
53
    {
54 8
        return $this->source;
55
    }
56
57
    /**
58
     * Set translations to be used.
59
     *
60
     * @param array|string $translations
61
     *
62
     * @return self
63
     */
64 34
    public function translation($translations)
65
    {
66 34
        if (is_string($translations)) {
67 32
            $translations = explode(',', str_replace(' ', '', $translations));
68
        }
69
70 34
        if (sizeof($translations) > $this->config->get('limit.translation')) {
71 2
            throw new ExceedLimit('Too much translation provided. Your limit is ' . $this->config->get('limit.translation') . ' only.');
0 ignored issues
show
Bug introduced by
Are you sure $this->config->get('limit.translation') of type array|string can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

71
            throw new ExceedLimit('Too much translation provided. Your limit is ' . /** @scrutinizer ignore-type */ $this->config->get('limit.translation') . ' only.');
Loading history...
72
        }
73
74 32
        $this->translations = $translations;
75
76 32
        return $this;
77
    }
78
79
    /**
80
     * Get ayah.
81
     *
82
     * @param string $args String of supported format of ayah
83
     *
84
     * @return string|array Ayah
85
     *
86
     * @throws AyahNotProvided
87
     * @throws WrongArgument
88
     */
89 64
    public function get($args)
90
    {
91 64
        $args = explode(':', $args);
92 64
        $result = [];
93 64
        $surah = $args[0];
94
95 64
        if (sizeof($args) <= 1) {
96 4
            throw new AyahNotProvided();
97
        }
98
99
        // Parse ayah arguments into array of ayah
100 60
        $ayah = $this->parseSurah($args[1]);
101
102 60
        if (sizeof($ayah) > $this->config->get('limit.ayah')) {
103 2
            throw new ExceedLimit('Too much ayah provided. Your limit is ' . $this->config->get('limit.ayah') . ' only.');
0 ignored issues
show
Bug introduced by
Are you sure $this->config->get('limit.ayah') of type array|string can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

103
            throw new ExceedLimit('Too much ayah provided. Your limit is ' . /** @scrutinizer ignore-type */ $this->config->get('limit.ayah') . ' only.');
Loading history...
104
        }
105
106
        // Check if Surah and Ayah is in correct format
107 58
        if (!is_numeric($surah) || sizeof($ayah) === 0) {
108 6
            throw new WrongArgument();
109
        }
110
111
        // Get text for all translation
112 52
        foreach ($this->translations as $translation) {
113 52
            $result[$translation] = $this->source->ayah($surah, $ayah, $translation);
114
        }
115
116 46
        return $this->config->get('structure', 'minimal') == 'fixed' ? $result : $this->minimize($result);
117
    }
118
119
    /**
120
     * Get surah information.
121
     *
122
     * @return object Chapter information of a chapter
123
     */
124 12
    public function surah($surah = null)
125
    {
126 12
        return $this->source->surah($surah);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->source->surah($surah) also could return the type array which is incompatible with the documented return type object.
Loading history...
127
    }
128
129
    /**
130
     * Parse the ayah requested of a certain surah. The format of ayah will
131
     * be translated into an array or ayah.
132
     *
133
     * @param string $surah
134
     *
135
     * @return array Array of ayah
136
     */
137 60
    private function parseSurah($surah)
138
    {
139 60
        $result = [];
140
141 60
        foreach ((is_array($surah) ? $surah : explode(',', $surah)) as $comma) {
142 60
            $dash = explode('-', $comma);
143
144
            // Skip any invalid ayah
145 60
            if (!is_numeric($dash[0]) || (isset($dash[1]) && !is_numeric($dash[1]))) {
146 6
                continue;
147
            }
148
149
            // Single ayah, just push it into array.
150 56
            if (sizeof($dash) === 1) {
151 50
                array_push($result, intval($dash[0]));
152
            } // Range ayah, so we create all ayah in between.
153
            else {
154 35
                for ($i = $dash[0]; $i <= $dash[1]; ++$i) {
155 14
                    array_push($result, intval($i));
156
                }
157
            }
158
        }
159
160 60
        return $result;
161
    }
162
163
    /**
164
     * Sort array in ascending by it's key.
165
     *
166
     * @param array $arr
167
     *
168
     * @return array
169
     */
170 20
    private function sortArray(array $arr)
171
    {
172 20
        ksort($arr, SORT_NUMERIC);
173
174 20
        return $arr;
175
    }
176
177
    /**
178
     * Reduce the array level by remove unnecessary parent.
179
     *
180
     * @param array $array
181
     *
182
     * @return array
183
     */
184 38
    private function minimize(array $array)
185
    {
186 38
        foreach ($array as $key => $translation) {
187
188
            // If one ayah is requested, we remove it's key
189 38
            if (sizeof($translation) === 1) {
190 18
                $array[$key] = $translation[key($translation)];
191
            } // Else we maintain current format, but in sorted form
192
            else {
193 29
                $array[$key] = $this->sortArray($translation);
194
            }
195
        }
196
197
        // If one translation is requested, we remove it's key.
198
        // Else just return the current format
199 38
        return (sizeof($array) > 1) ? $array : $array[key($array)];
200
    }
201
202
    /**
203
     * Get the Quran Application version.
204
     *
205
     * @return string
206
     */
207 2
    public static function version()
208
    {
209 2
        return 'v' . static::VERSION;
210
    }
211
}
212