Completed
Branch master (4189fe)
by Ventimiglia
02:27
created

Firebase::printEventData()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 6
rs 9.4285
cc 1
eloc 3
nc 1
nop 2
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
85
        $this->checkDipendenties($auth);
86
87
88
        // store object into variable
89
        $this->auth = $auth;
90
91
92
        $this->gulleClientInit();
93
    }
94
95
    /**
96
     * Create new guzzle client
97
     */
98
    private function gulleClientInit()
99
    {
100
101
        /* create new client */
102
        $this->client = new Client([
103
            'base_uri' => $this->auth->getBaseURI(),
104
            'timeout' => $this->getTimeout(),
105
            'headers' => $this->getRequestHeaders()
106
        ]);
107
    }
108
109
    /**
110
     * Controll of all dipendenties
111
     *
112
     * @param \ZendFirebase\Config\FirebaseAuth $auth
113
     */
114
    private function checkDipendenties($auth)
115
    {
116
        $authMessage = 'Forget credential or is not an object.';
117
        $curlMessage = 'Extension CURL is not loaded or not installed.';
118
119
        // check if auth is null
120
        if (!is_object($auth) || null == $auth) {
121
            trigger_error($authMessage, E_USER_ERROR);
122
        }
123
124
        // check if extension is installed
125
        if (!extension_loaded('curl')) {
126
            trigger_error($curlMessage, E_USER_ERROR);
127
        }
128
    }
129
130
    /**
131
     * Return Integer of Timeout
132
     * default 30 setted 10
133
     *
134
     * @return integer $timeout
135
     */
136
    public function getTimeout(): int
137
    {
138
        return $this->timeout;
139
    }
140
141
    /**
142
     * Default timeout is 10 seconds
143
     * is is not set switch to 30
144
     *
145
     * @param integer $timeout
146
     */
147
    public function setTimeout($timeout)
148
    {
149
        $this->timeout = $timeout;
150
    }
151
152
    /**
153
     * Method for get array headers for Guzzle client
154
     *
155
     * @throws \Exception
156
     * @return array
157
     */
158
    private function getRequestHeaders(): array
159
    {
160
        $headers = [];
161
        $headers['stream'] = true;
162
        $headers['Accept'] = 'application/json';
163
        $headers['Content-Type'] = 'application/json';
164
165
        // check if header is an array
166
        if (!is_array($headers)) {
167
            $str = "The guzzle client headers must be an array.";
168
            throw new \Exception($str);
169
        }
170
171
        return $headers;
172
    }
173
174
    /**
175
     * Returns with the normalized JSON absolute path
176
     *
177
     * @param string $path
178
     * @param array $options
179
     * @return string $path
180
     */
181
    private function getJsonPath($path, $options = []): string
182
    {
183
        $options['auth'] = $this->auth->getServertoken();
184
185
        $path = ltrim($path, '/');
186
        return $path . '.json?' . http_build_query($options);
187
    }
188
189
    /**
190
     * DELETE - Removing Data FROM FIREBASE
191
     *
192
     * @param string $path
193
     * @param array $options
194
     *
195
     * {@inheritdoc}
196
     *
197
     * @see \Interfaces\FirebaseInterface::delete()
198
     */
199
    public function delete($path, $options = [])
200
    {
201
        $this->writeRequest('delete', $this->getJsonPath($path), '');
202
    }
203
204
    /**
205
     * GET - Reading Data FROM FIREBASE
206
     *
207
     * @param string $path
208
     * @param array $options
209
     *
210
     * {@inheritdoc}
211
     *
212
     * @see \Interfaces\FirebaseInterface::get()
213
     */
214
    public function get($path, $options = [])
215
    {
216
        $this->writeRequest('get', $this->getJsonPath($path), '');
217
    }
218
219
    /**
220
     * PATCH - Updating Data TO FIREBASE
221
     *
222
     * @param string $path
223
     * @param array $data
224
     * @param array $options
225
     *
226
     * {@inheritdoc}
227
     *
228
     * @see \Interfaces\FirebaseInterface::patch()
229
     */
230
    public function patch($path, array $data, $options = [])
231
    {
232
        $this->writeRequest('patch', $this->getJsonPath($path), $data);
233
    }
234
235
    /**
236
     * POST - Pushing Data TO FIREBASE
237
     *
238
     * @param string $path
239
     * @param array $data
240
     * @param array $options
241
     *
242
     * {@inheritdoc}
243
     *
244
     * @see \Interfaces\FirebaseInterface::post()
245
     */
246
    public function post($path, array $data, $options = [])
247
    {
248
        $this->writeRequest('post', $this->getJsonPath($path), $data);
249
    }
250
251
    /**
252
     * PUT - Writing Data TO FIREBASE
253
     *
254
     * @param string $path
255
     * @param array $data
256
     * @param array $options
257
     *
258
     * {@inheritdoc}
259
     *
260
     * @see \Interfaces\FirebaseInterface::put()
261
     */
262
    public function put($path, array $data, $options = [])
263
    {
264
        $this->writeRequest('put', $this->getJsonPath($path), $data);
265
    }
266
267
    /**
268
     * Method to send request
269
     *
270
     * @param string $op
271
     * @param string $path
272
     * @param mixed $data
273
     */
274
    private function writeRequest($op, $path, $data)
275
    {
276
        $operation = \strtolower($op);
277
278
        switch ($operation) {
279
            case 'get':
280
                $response = $this->client->{$operation}($path);
281
                $this->response = $response->getBody()->getContents();
282
283
                $this->setDataFromOperation('get', $response->getStatusCode());
284
                break;
285
            case 'delete':
286
                $response = $this->client->{$operation}($path);
287
                $this->response = $response->getReasonPhrase(); // OK
288
                $this->setDataFromOperation('get', $response->getStatusCode());
289
                break;
290
291
            default:
292
                $this->response = $this->client->{$operation}($path, [
293
                    'body' => $data
294
                ]);
295
296
                $this->setDataFromOperation($op, $this->response->getStatusCode());
297
                break;
298
        }
299
    }
300
301
    /**
302
     * This function set variables after operation
303
     *
304
     * @param string $operation
305
     * @param mixed $status
306
     */
307
    private function setDataFromOperation($operation, $status)
308
    {
309
        $oP = \strtoupper($operation);
310
311
        $this->status = $status; // 200
312
        $this->operation = $oP;
313
    }
314
315
    /**
316
     * Start stream with server and write log in choised folder
317
     *
318
     * @param string $path
319
     * @param string $folderToStoreLog
320
     * @param integer $requestDelay
321
     * @example $requestDelay = 3000 -> 3 seconds between get request
322
     */
323
    public function startStream($path, $folderToStoreLog, $requestDelay = 5000)
324
    {
325
        $url = $this->auth->getBaseURI() . $this->getJsonPath($path);
326
327
        $client = new StreamClient($url, $requestDelay);
328
329
330
        // returns generator
331
        $events = $client->getEvents();
332
333
334
        // call method for create instance of logger
335
        $logger = $this->createLogger($this->formatFolderName($folderToStoreLog));
336
337
        // blocks until new event arrive
338
        foreach ($events as $event) {
0 ignored issues
show
Bug introduced by
The expression $events of type object<Generator>|null is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
339
            // decode json data arrived to php array
340
            $eventData = \json_decode($event->getData(), true);
341
342
            $this->printEventData($eventData, $event);
343
344
            $this->writeEventLogs($logger, $eventData, $event, $path);
345
        }
346
    }
347
348
    /**
349
     * Print on output datas
350
     *
351
     * @param unknown $eventData
352
     */
353
    private function printEventData($eventData, $event)
354
    {
355
        // pass event to callback function
356
        print_r($eventData);
357
        print_r("EVENT TYPE: " . $event->getEventType() . PHP_EOL . PHP_EOL);
358
    }
359
360
    /**
361
     * Write log of current event
362
     *
363
     * @param Logger $logger
364
     * @param array $eventData
365
     * @param mixed $event
366
     * @param string $path
367
     */
368
    private function writeEventLogs($logger, $eventData, $event, $path)
369
    {
370
        if (!empty($eventData) || null != $eventData) {
371
            $logger->addDebug("path: {$path}", [
372
                'DATA' => $eventData,
373
                'EVENT TYPE' => $event->getEventType()
374
            ]);
375
        } else {
376
            $logger->addDebug("path: {$path}", [
377
                'EVENT TYPE' => $event->getEventType()
378
            ]);
379
        }
380
    }
381
382
    /**
383
     * Format folder name
384
     *
385
     * @param string $folderToStoreLog
386
     * @return string $folderName
387
     */
388
    private function formatFolderName($folderToStoreLog): string
389
    {
390
        /* search / in string */
391
        $folderName = substr(strrchr(trim($folderToStoreLog), "/"), 1);
392
        /* if not exsits add on path+/ */
393
        $folderName = empty($folderName) ? $folderToStoreLog . '/' : $folderToStoreLog;
394
395
        return $folderName;
396
    }
397
398
    /**
399
     *
400
     * Create logger instance for save stream log
401
     *
402
     * @param string $folderToStoreLog
403
     * @return Logger $logger
404
     */
405
    private function createLogger($folderToStoreLog)
406
    {
407
        // the default output format is "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n"
408
        $output = "%datetime% > %level_name% > %message% %context% %extra%\n";
409
        // finally, create a formatter
410
        $formatter = new LineFormatter($output, $this->dateFormatLog);
411
        self::$dateFormatLogFilename = date("Y-m-d_H:i:s");
412
        // Create the logger
413
        $logger = new Logger('stream_logger');
414
415
        // Now add some handlers
416
        $stream = new StreamHandler(trim($folderToStoreLog) . self::$dateFormatLogFilename . ".log", Logger::DEBUG);
417
418
        $stream->setFormatter($formatter);
419
        $logger->pushHandler($stream);
420
        $logger->pushHandler(new FirePHPHandler());
421
422
        // You can now use your logger
423
        $logger->addInfo('Stream logger is ready...');
424
        return $logger;
425
    }
426
427
    /**
428
     * This method return the responce from firebase
429
     *
430
     * @example set and validate data passed
431
     */
432
    public function makeResponce()
433
    {
434
        $jsonData = [];
435
        if ($this->operation === 'GET') {
436
            $jsonData = json_decode($this->response, true);
437
        } else {
438
            $jsonData[] = 'success';
439
        }
440
441
        /* Set data after operations */
442
        $this->setOperation($this->operation);
443
        $this->setStatus($this->status);
444
        $this->setFirebaseData($jsonData);
445
        $this->validateResponce();
446
    }
447
448
    /**
449
     * Remove object from memory
450
     */
451
    public function __destruct()
452
    {
453
    }
454
}
455