GoogleFonts::sortFonts()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 13
ccs 0
cts 9
cp 0
rs 9.8333
c 0
b 0
f 0
cc 3
nc 3
nop 0
crap 12
1
<?php
2
namespace Fonts;
3
4
use GuzzleHttp\Client;
5
6
class GoogleFonts
7
{
8
9
    const WEBFONTURL = 'https://www.googleapis.com/webfonts/v1/webfonts';
10
    
11
    const SORT_BY = [
12
        'alpha',
13
        'date',
14
        'popularity',
15
        'style',
16
        'trending'
17
    ];
18
    
19
    /**
20
     * Google API key string
21
     * @var string
22
     */
23
    private $apiKey;
24
    
25
    /**
26
     * The location where the temporary JSON file should be stored
27
     * @var string
28
     */
29
    protected $file_location;
30
31
    /**
32
     * how fonts should be sorted when retrieved from Google
33
     * @var string
34
     */
35
    public $sortOrder = 'popularity';
36
    
37
    /**
38
     * This is the original font array retrieved from Google
39
     * @var array
40
     */
41
    protected $fontList;
42
    
43
    /**
44
     * This is the array of fonts ordered into types
45
     * @var array
46
     */
47
    protected $orderedList;
48
    
49
    /**
50
     * Error message to be displayed if no fonts exists
51
     * @var string
52
     */
53
    public $error_message = 'Error: No fonts exist with the given parameters';
54
    
55
    /**
56
     * Constructor
57
     * @param string|false $apiKey This should either be set to your Google API key or left empty
58
     */
59 1
    public function __construct($apiKey = false)
60
    {
61 1
        $this->setAPIKey($apiKey);
62 1
        $this->setFontFileLocation(dirname(dirname(__FILE__)).'/fonts/');
63 1
    }
64
    
65
    /**
66
     * Sets the Google API Key
67
     * @param string|false $apiKey This needs to be your Google API Key
68
     * @return $this
69
     */
70 1
    public function setApiKey($apiKey)
71
    {
72 1
        if (is_string($apiKey) && !empty(trim($apiKey))) {
73 1
            $this->apiKey = trim($apiKey);
74
        }
75 1
        return $this;
76
    }
77
    
78
    /**
79
     * Returns the Google API key if it has been set else will return false
80
     * @return string|false This sill be the set Google API key or false
81
     */
82 1
    public function getApiKey()
83
    {
84 1
        if (is_string($this->apiKey)) {
85 1
            return $this->apiKey;
86
        }
87 1
        return false;
88
    }
89
    
90
    /**
91
     * Sets the file locations where the font lists are stored
92
     * @param string $location This should be the location that you wish to store the font list files
93
     * @return $this
94
     */
95 1
    public function setFontFileLocation($location)
96
    {
97 1
        if (!empty(trim($location)) && is_string($location)) {
98 1
            $this->file_location = trim($location);
99 1
            if (!is_dir($location)) {
100 1
                mkdir($location, 0777, true);
101
            }
102
        }
103 1
        return $this;
104
    }
105
    
106
    /**
107
     * This is the location where the fonts file is stored
108
     * @return string Returns the file storage location
109
     */
110 1
    public function getFontFileLocation()
111
    {
112 1
        return $this->file_location;
113
    }
114
    
115
    /**
116
     * Returns an array of weights available
117
     * @return array|string If any weights exist will return an array else will return the error_message
118
     */
119
    public function getFontWeights()
120
    {
121
        return $this->listFontTypes();
122
    }
123
    
124
    /**
125
     * Returns an array of subsets available
126
     * @return array|string If any subsets exist will return an array else will return the error_message
127
     */
128
    public function getFontSubsets()
129
    {
130
        return $this->listFontTypes('subset');
131
    }
132
    
133
    /**
134
     * Returns an array of types/categories available
135
     * @return array|string If any types/categories exist will return an array else will return the error_message
136
     */
137
    public function getFontTypes()
138
    {
139
        return $this->listFontTypes('type');
140
    }
141
    
142
    /**
143
     * Returns all of the fonts available with the selected weight/italic value
144
     * @param string $weight This should be the weight value
145
     * @return array|string
146
     */
147
    public function getFontsByWeight($weight)
148
    {
149
        if ($weight == '400') {
150
            $weight = 'regular';
151
        }
152
        if ($weight == '400italic') {
153
            $weight = 'italic';
154
        }
155
        return $this->listFonts(strtolower($weight));
156
    }
157
    
158
    /**
159
     * Returns an array of fonts available with a given subset
160
     * @param string $subset This should be the subset you ant to list the fonts by
161
     * @return array|string If any fonts exists an array will be returned else the error message will be returned
162
     */
163
    public function getFontsBySubset($subset)
164
    {
165
        return $this->listFonts(strtolower($subset), 'subset');
166
    }
167
    
168
    /**
169
     * Returns an array of fonts available with a given type/category
170
     * @param string $style This should be the font type that you want to list fonts by
171
     * @return array|string If any fonts exists an array will be returned else the error message will be returned
172
     */
173
    public function getFontsByType($style)
174
    {
175
        return $this->listFonts(strtolower($style), 'type');
176
    }
177
    
178
    /**
179
     * Sorts all of the retrieve fonts into a custom array
180
     * @param array|string $types This should be what you want to sort the fonts on
181
     * @param array $font this should be the font information array
182
     * @param string $style The main array item that you want to sort the font within e.g. weight, subset or category
183
     */
184
    protected function sortFontType($types, $font, $style = 'type')
185
    {
186
        if (is_array($types)) {
187
            foreach ($types as $type) {
188
                $this->orderedList[$style][$type][$font['family']] = [($style === 'weight' ? 'file' : 'files') => ($style === 'weight' ? $font['files'][$type] : $font['files'])];
189
            }
190
        } else {
191
            $this->orderedList[$style][$types][$font['family']] = ['files' => $font['files']];
192
        }
193
    }
194
    
195
    /**
196
     * Retrieve a list of all of the fonts from Google Fonts API
197
     */
198
    protected function retrieveFonts()
199
    {
200
        $guzzle = new Client();
201
        $fonts = $guzzle->request('GET', $this->googleFontsURI());
202
        if ($fonts->getStatusCode() === 200) {
203
            $this->fontList = json_decode($fonts->getBody(), true);
204
        }
205
    }
206
    
207
    /**
208
     * The Google fonts URL will be returned with the path information
209
     * @return string
210
     */
211
    public function googleFontsURI()
212
    {
213
        return self::WEBFONTURL . '?' . $this->buildQueryString();
214
    }
215
    
216
    /**
217
     * Builds the formatted URI path to retrieve the list of fonts from Google
218
     * @return string
219
     */
220
    protected function buildQueryString()
221
    {
222
        $queryString = [];
223
        $queryString['key'] = $this->getApiKey();
224
        if ($this->sortOrder) {
225
            $queryString['sort'] = $this->sortOrder;
226
        }
227
        return http_build_query($queryString);
228
    }
229
    
230
    /**
231
     * Retrieves the ordered Google Fonts file
232
     * @return boolean Returns true on success and false on failure
233
     */
234
    protected function getJSONFile()
235
    {
236
        if (!is_array($this->orderedList)) {
237
            if (file_exists($this->getFontFileLocation().'/fonts.json') && ((time() - filemtime($this->getFontFileLocation().'/fonts.json')) < 86400)) {
238
                $this->orderedList = json_decode(file_get_contents($this->getFontFileLocation().'fonts.json'), true);
239
                return true;
240
            }
241
        }
242
        return $this->sortFonts();
243
    }
244
    
245
    /**
246
     * Sorts all of the fonts into a custom JSON file
247
     * @return boolean If the file has successfully been created will return true else retruns false
248
     */
249
    protected function sortFonts()
250
    {
251
        $this->retrieveFonts();
252
        if (is_array($this->fontList)) {
253
            foreach ($this->fontList['items'] as $font) {
254
                $this->sortFontType($font['category'], $font);
255
                $this->sortFontType($font['variants'], $font, 'weight');
256
                $this->sortFontType($font['subsets'], $font, 'subset');
257
            }
258
            return $this->createJSONFile();
259
        }
260
        return false;
261
    }
262
    
263
    /**
264
     * Creates the temporary file containing the list of fonts
265
     * @return boolean Returns true on success false on failure
266
     */
267
    protected function createJSONFile()
268
    {
269
        $fp = fopen($this->getFontFileLocation().'/fonts.json', 'w');
270
        fwrite($fp, json_encode($this->orderedList));
271
        return fclose($fp);
272
    }
273
    
274
    /**
275
     * List all of the types available
276
     * @param string $list The type that you are listing
277
     * @return array|string If any types exist an array will be returned else will return the error message
278
     */
279 View Code Duplication
    protected function listFontTypes($list = 'weight')
280
    {
281
        $this->getJSONFile();
282
        if (array_key_exists($list, $this->orderedList)) {
283
            $array = array_keys($this->orderedList[$list]);
284
            sort($array);
285
            return $array;
286
        }
287
        return $this->error_message;
288
    }
289
    
290
    /**
291
     * Returns an ordered list of the Google Fonts available
292
     * @param string $option This should be the $option that you want all of the fonts for
293
     * @param string $list This needs to be the value that you are searching on
294
     * @return array|string If any fonts exist for the given parameters an array will be returned else will return the error message
295
     */
296 View Code Duplication
    protected function listFonts($option, $list = 'weight')
297
    {
298
        $this->getJSONFile();
299
        if (array_key_exists($option, $this->orderedList[$list])) {
300
            $array = array_keys($this->orderedList[$list][$option]);
301
            return $array;
302
        }
303
        return $this->error_message;
304
    }
305
}
306