Completed
Push — master ( 07376c...713fec )
by Ventimiglia
03:34
created

Firebase::quoteOrderByQueryParam()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 6
nc 3
nop 1
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 31 and the first side effect is on line 12.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
declare(strict_types = 1);
3
namespace ZendFirebase;
4
5
use Interfaces\FirebaseInterface;
6
use GuzzleHttp\Client;
7
use ZendFirebase\Stream\StreamClient;
8
use Monolog\Logger;
9
use Monolog\Handler\StreamHandler;
10
use Monolog\Handler\FirePHPHandler;
11
use Monolog\Formatter\LineFormatter;
12
require 'Interfaces/FirebaseInterface.php';
13
require 'Stream/StreamClient.php';
14
15
/**
16
 * PHP7 FIREBASE LIBRARY (http://samuelventimiglia.it/)
17
 *
18
 *
19
 * @link https://github.com/Samuel18/zend_Firebase
20
 * @copyright Copyright (c) 2016-now Ventimiglia Samuel - Biasin Davide
21
 * @license BSD 3-Clause License
22
 *
23
 */
24
25
/**
26
 * This class do rest operations to firebase server
27
 *
28
 * @author ghostbyte
29
 * @package ZendFirebase
30
 */
31
class Firebase extends FirebaseResponce implements FirebaseInterface
32
{
33
34
    /**
35
     * Default Timeout
36
     *
37
     * @var integer $timeout
38
     */
39
    private $timeout = 30;
40
41
    /**
42
     * Format of datetime of logs
43
     *
44
     * @var string $dateFormatLog
45
     */
46
    private $dateFormatLog = "Y n j, g:i a";
47
48
    /**
49
     * DateTime of log filename
50
     *
51
     * @var string $dateFormatLogFilename
52
     */
53
    private static $dateFormatLogFilename;
54
55
    /**
56
     * Authentication object
57
     *
58
     * @var $auth
59
     */
60
    private $auth;
61
62
    /**
63
     * Create new Client
64
     *
65
     * @var $client
66
     */
67
    private $client;
68
69
    /**
70
     * Responce from firebase
71
     *
72
     * @var mixed $response
73
     */
74
    private $response;
75
76
    /**
77
     * Create new Firebase client object
78
     * Remember to install PHP CURL extention
79
     *
80
     * @param Config\FirebaseAuth $auth
81
     */
82
    public function __construct(\ZendFirebase\Config\FirebaseAuth $auth)
83
    {
84
        $this->checkDipendenties($auth);
85
        
86
        // store object into variable
87
        $this->auth = $auth;
88
        
89
        $this->gulleClientInit();
90
    }
91
92
    /**
93
     * Create new guzzle client
94
     */
95
    private function gulleClientInit()
96
    {
97
        
98
        /* create new client */
99
        $this->client = new Client([
100
            'base_uri' => $this->auth->getBaseURI(),
101
            'timeout' => $this->getTimeout(),
102
            'headers' => $this->getRequestHeaders()
103
        ]);
104
    }
105
106
    /**
107
     * Controll of all dipendenties
108
     *
109
     * @param \ZendFirebase\Config\FirebaseAuth $auth
110
     */
111
    private function checkDipendenties($auth)
112
    {
113
        $authMessage = 'Forget credential or is not an object.';
114
        $curlMessage = 'Extension CURL is not loaded or not installed.';
115
        
116
        // check if auth is null
117
        if (! is_object($auth) || null == $auth) {
118
            trigger_error($authMessage, E_USER_ERROR);
119
        }
120
        
121
        // check if extension is installed
122
        if (! extension_loaded('curl')) {
123
            trigger_error($curlMessage, E_USER_ERROR);
124
        }
125
    }
126
127
    /**
128
     * Return Integer of Timeout
129
     * default 30 setted 10
130
     *
131
     * @return integer $timeout
132
     */
133
    public function getTimeout(): int
134
    {
135
        return $this->timeout;
136
    }
137
138
    /**
139
     * Default timeout is 10 seconds
140
     * is is not set switch to 30
141
     *
142
     * @param integer $timeout
143
     */
144
    public function setTimeout($timeout)
145
    {
146
        $this->timeout = $timeout;
147
    }
148
149
    /**
150
     * Method for get array headers for Guzzle client
151
     *
152
     * @throws \Exception
153
     * @return array
154
     */
155
    private function getRequestHeaders(): array
156
    {
157
        $headers = [];
158
        $headers['stream'] = true;
159
        $headers['Accept'] = 'application/json';
160
        $headers['Content-Type'] = 'application/json';
161
        
162
        // check if header is an array
163
        if (! is_array($headers)) {
164
            $str = "The guzzle client headers must be an array.";
165
            throw new \Exception($str);
166
        }
167
        
168
        return $headers;
169
    }
170
171
    /**
172
     * Returns with the normalized JSON absolute path
173
     *
174
     * @param string $path
175
     * @param array $options
176
     * @return string $path
177
     */
178
    private function getJsonPath($path, $options = []): string
179
    {
180
        /* autentication token */
181
        $options['auth'] = $this->auth->getServertoken();
182
        /* returns the data in a human-readable format */
183
        $options['print'] = 'pretty';
184
        
185
        foreach ($options as $opt => $optVal) {
186
        
187
            if ($opt == 'orderBy') {
188
                
189
                $options['orderBy']= '"' . $optVal . '"';
190
        
191
            }
192
        }
193
           
194
        $path = ltrim($path, '/');
195
        
196
        return $path . '.json?' . http_build_query($options);
197
    }
198
199
    /**
200
     * DELETE - Removing Data FROM FIREBASE
201
     *
202
     * @param string $path
203
     * @param array $options
204
     *
205
     * {@inheritdoc}
206
     *
207
     * @see \Interfaces\FirebaseInterface::delete()
208
     */
209
    public function delete($path, $options = [])
210
    {
211
        $this->writeRequest('delete', $this->getJsonPath($path, $options), '');
212
    }
213
214
    /**
215
     * GET - Reading Data FROM FIREBASE
216
     *
217
     * @param string $path
218
     * @param array $options
219
     *
220
     * {@inheritdoc}
221
     *
222
     * @see \Interfaces\FirebaseInterface::get()
223
     */
224
    public function get($path, $options = [])
225
    {
226
        $this->writeRequest('get', $this->getJsonPath($path, $options), '');
227
    }
228
229
    /**
230
     * PATCH - Updating Data TO FIREBASE
231
     *
232
     * @param string $path
233
     * @param array $data
234
     * @param array $options
235
     *
236
     * {@inheritdoc}
237
     *
238
     * @see \Interfaces\FirebaseInterface::patch()
239
     */
240
    public function patch($path, array $data, $options = [])
241
    {
242
        $this->writeRequest('patch', $this->getJsonPath($path, $options), $data);
243
    }
244
245
    /**
246
     * POST - Pushing Data TO FIREBASE
247
     *
248
     * @param string $path
249
     * @param array $data
250
     * @param array $options
251
     *
252
     * {@inheritdoc}
253
     *
254
     * @see \Interfaces\FirebaseInterface::post()
255
     */
256
    public function post($path, array $data, $options = [])
257
    {
258
        $this->writeRequest('post', $this->getJsonPath($path, $options), $data);
259
    }
260
261
    /**
262
     * PUT - Writing Data TO FIREBASE
263
     *
264
     * @param string $path
265
     * @param array $data
266
     * @param array $options
267
     *
268
     * {@inheritdoc}
269
     *
270
     * @see \Interfaces\FirebaseInterface::put()
271
     */
272
    public function put($path, array $data, $options = [])
273
    {
274
        $this->writeRequest('put', $this->getJsonPath($path, $options), $data);
275
    }
276
277
    /**
278
     * Method to send request
279
     *
280
     * @param string $op
281
     * @param string $path
282
     * @param mixed $data
283
     */
284
    private function writeRequest($op, $path, $data)
285
    {
286
        $operation = \strtolower($op);
287
        
288
        switch ($operation) {
289
            case 'get':
290
                $response = $this->client->{$operation}($path);
291
                $this->response = $response->getBody()->getContents();
292
                
293
                $this->setDataFromOperation('get', $response->getStatusCode());
294
                break;
295
            case 'delete':
296
                $response = $this->client->{$operation}($path);
297
                $this->response = $response->getReasonPhrase(); // OK
298
                $this->setDataFromOperation('get', $response->getStatusCode());
299
                break;
300
            
301
            default:
302
                $this->response = $this->client->{$operation}($path, [
303
                    'body' => \json_encode($data)
304
                ]);
305
                
306
                $this->setDataFromOperation($op, $this->response->getStatusCode());
307
                break;
308
        }
309
    }
310
311
    /**
312
     * This function set variables after operation
313
     *
314
     * @param string $operation
315
     * @param mixed $status
316
     */
317
    private function setDataFromOperation($operation, $status)
318
    {
319
        $oP = \strtoupper($operation);
320
        
321
        $this->status = $status; // 200
322
        $this->operation = $oP;
323
    }
324
325
    /**
326
     * Start stream with server and write log in choised folder
327
     *
328
     * @param string $path
329
     * @param string $folderToStoreLog
330
     * @param integer $requestDelay
331
     * @example $requestDelay = 3000 -> 3 seconds between get request
332
     */
333
    public function startStream($path, $folderToStoreLog, $requestDelay = 5000)
334
    {
335
        $url = $this->auth->getBaseURI() . $this->getJsonPath($path);
336
        
337
        $client = new StreamClient($url, $requestDelay);
338
        
339
        // returns generator
340
        $events = $client->getEvents();
341
        
342
        // call method for create instance of logger
343
        $logger = $this->createLogger($this->formatFolderName($folderToStoreLog));
344
        
345
        // blocks until new event arrive
346
        foreach ($events as $event) {
347
            // decode json data arrived to php array
348
            $eventData = \json_decode($event->getData(), true);
349
            
350
            $this->printEventData($eventData, $event);
351
            
352
            $this->writeEventLogs($logger, $eventData, $event, $path);
353
        }
354
    }
355
356
    /**
357
     * Print on output datas
358
     *
359
     * @param mixed $eventData
360
     * @param mixed $event
361
     */
362
    private function printEventData($eventData, $event)
363
    {
364
        // pass event to callback function
365
        print_r($eventData);
366
        print_r("EVENT TYPE: " . $event->getEventType() . PHP_EOL . PHP_EOL);
367
    }
368
369
    /**
370
     * Write log of current event
371
     *
372
     * @param Logger $logger
373
     * @param array $eventData
374
     * @param mixed $event
375
     * @param string $path
376
     */
377
    private function writeEventLogs($logger, $eventData, $event, $path)
378
    {
379
        if (! empty($eventData) || null != $eventData) {
380
            $logger->addDebug("path: {$path}", [
381
                'DATA' => $eventData,
382
                'EVENT TYPE' => $event->getEventType()
383
            ]);
384
        } else {
385
            $logger->addDebug("path: {$path}", [
386
                'EVENT TYPE' => $event->getEventType()
387
            ]);
388
        }
389
    }
390
391
    /**
392
     * Format folder name
393
     *
394
     * @param string $folderToStoreLog
395
     * @return string $folderName
396
     */
397
    private function formatFolderName($folderToStoreLog): string
398
    {
399
        /* search / in string */
400
        $folderName = substr(strrchr(trim($folderToStoreLog), "/"), 1);
401
        /* if not exsits add on path+/ */
402
        $folderName = empty($folderName) ? $folderToStoreLog . '/' : $folderToStoreLog;
403
        
404
        return $folderName;
405
    }
406
407
    /**
408
     *
409
     * Create logger instance for save stream log
410
     *
411
     * @param string $folderToStoreLog
412
     * @return Logger $logger
413
     */
414
    private function createLogger($folderToStoreLog)
415
    {
416
        // the default output format is "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n"
417
        $output = "%datetime% > %level_name% > %message% %context% %extra%\n";
418
        // finally, create a formatter
419
        $formatter = new LineFormatter($output, $this->dateFormatLog);
420
        self::$dateFormatLogFilename = date("Y-m-d_H:i:s");
421
        // Create the logger
422
        $logger = new Logger('stream_logger');
423
        
424
        // Now add some handlers
425
        $stream = new StreamHandler(trim($folderToStoreLog) . self::$dateFormatLogFilename . ".log", Logger::DEBUG);
426
        
427
        $stream->setFormatter($formatter);
428
        $logger->pushHandler($stream);
429
        $logger->pushHandler(new FirePHPHandler());
430
        
431
        // You can now use your logger
432
        $logger->addInfo('Stream logger is ready...');
433
        return $logger;
434
    }
435
436
    /**
437
     * This method return the responce from firebase
438
     *
439
     * @example set and validate data passed
440
     */
441
    public function makeResponce()
442
    {
443
        $jsonData = [];
444
        if ($this->operation === 'GET') {
445
            $jsonData = json_decode($this->response, true);
446
        } else {
447
            $jsonData[] = 'success';
448
        }
449
        
450
        /* Set data after operations */
451
        $this->setOperation($this->operation);
452
        $this->setStatus($this->status);
453
        $this->setFirebaseData($jsonData);
454
        $this->validateResponce();
455
    }
456
457
    /**
458
     * Remove object from memory
459
     */
460
    public function __destruct()
461
    {}
462
}
463