• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

snowplow / snowplow-php-tracker / 14860667206

06 May 2025 01:17PM UTC coverage: 90.143%. Remained the same
14860667206

push

github

web-flow
Release 0.9.2 (#156)

* Fix implicit nullable param to support PHP8.4 (close #154)

PR #155
Co-authored-by: Binita Rana <binitarana@Binitas-MacBook-Air.local>

* Prepare for 0.9.2 release

---------

Co-authored-by: KT <khem.thapa15@gmail.com>

567 of 629 relevant lines covered (90.14%)

64.5 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

79.12
/src/Emitter.php
1
<?php
2

3
/*
4
    Emitter.php
5

6
    Copyright (c) 2014-2022 Snowplow Analytics Ltd. All rights reserved.
7

8
    This program is licensed to you under the Apache License Version 2.0,
9
    and you may not use this file except in compliance with the Apache License
10
    Version 2.0. You may obtain a copy of the Apache License Version 2.0 at
11
    http://www.apache.org/licenses/LICENSE-2.0.
12

13
    Unless required by applicable law or agreed to in writing,
14
    software distributed under the Apache License Version 2.0 is distributed on
15
    an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
16
    express or implied. See the Apache License Version 2.0 for the specific
17
    language governing permissions and limitations there under.
18

19
    Authors: Joshua Beemster
20
    License: Apache License Version 2.0
21
*/
22

23
namespace Snowplow\Tracker;
24
use ErrorException;
25

26
class Emitter extends Constants {
27

28
    // Emitter Parameters
29

30
    private $buffer_size;
31
    private $buffer = array();
32

33
    // Debug Parameters
34

35
    private $debug_mode;
36
    private $write_perms = true;
37
    private $debug_file;
38
    private $path;
39

40
    /**
41
     * Setup emitter parameters
42
     * - Stores the emitter sub-class object
43
     * - Sets the emitter buffer size
44
     * - Sets debug mode
45
     *
46
     * @param string $type
47
     * @param bool $debug
48
     * @param int $buffer_size
49
     */
50
    public function setup($type, $debug, $buffer_size) {
51
        $this->buffer_size = $buffer_size;
260✔
52

53
        // Set error handler to catch warnings
54
        $this->warning_handler();
260✔
55

56
        if ($debug === true) {
260✔
57
            $this->debug_mode = true;
165✔
58

59
            // If physical logging is set to true
60
            if (self::DEBUG_LOG_FILES) {
165✔
61
                if ($this->initDebug($type) !== true) {
165✔
62
                    $this->write_perms = false;
×
63
                    print_r("Unable to create debug log files: invalid write permissions for ".$this->debug_file);
33✔
64
                }
65
            }
66
        }
67
        else {
68
            $this->debug_mode = false;
95✔
69
        }
70

71
        // Restore error handler back to default
72
        restore_error_handler();
260✔
73
    }
74

75
    /**
76
     * Sends the buffer to the configured emitter for sending
77
     *
78
     * @param array $buffer - The array of events that are ready for sending
79
     * @param bool $curl_send - Boolean logic needed to ascertain whether or not
80
     *                          we are going to start the curl emitter
81
     */
82
    private function flush($buffer, $curl_send = false) {
83
        if (count($buffer) > 0) {
155✔
84
            $res = $this->send($buffer, $curl_send);
155✔
85

86
            // Set error handler to catch warnings
87
            $this->warning_handler();
155✔
88

89
            if (is_bool($res) && $res) {
155✔
90
                $success_string = "Payload sent successfully\nPayload: ".json_encode($buffer)."\n\n";
105✔
91
                if ($this->debug_mode && self::DEBUG_LOG_FILES && $this->write_perms) {
105✔
92
                    if ($this->writeToFile($this->debug_file, $success_string) !== true) {
90✔
93
                        print_r($success_string);
×
94
                        $this->write_perms = false;
18✔
95
                    }
96
                }
97
                else if ($this->debug_mode) {
15✔
98
                    print_r($success_string);
21✔
99
                }
100
            }
101
            else {
102
                $error_string = $res."\nPayload: ".json_encode($buffer)."\n\n";
55✔
103
                if ($this->debug_mode && self::DEBUG_LOG_FILES && $this->write_perms) {
55✔
104
                    if ($this->writeToFile($this->debug_file, $error_string) !== true) {
55✔
105
                        print_r($error_string);
×
106
                        $this->write_perms = false;
11✔
107
                    }
108
                }
109
                else if ($this->debug_mode) {
×
110
                    print_r($error_string);
×
111
                }
112
            }
113
            $this->buffer = array();
155✔
114

115
            // Restore error handler back to default
116
            restore_error_handler();
155✔
117
        }
118
    }
119

120
    /**
121
     * Pushes the event payload into the emitter buffer
122
     * When buffer is full it flushes the buffer.
123
     *
124
     * @param array $final_payload - Takes the Trackers Payload as a parameter
125
     */
126
    public function addEvent($final_payload) {
127
        array_push($this->buffer, $final_payload);
165✔
128
        if (count($this->buffer) >= $this->buffer_size) {
165✔
129
            $this->flush($this->buffer);
10✔
130
        }
131
    }
132

133
    /**
134
     * Sends all events in the buffer to the collector
135
     */
136
    public function forceFlush() {
137
        $this->flush($this->buffer, true);
155✔
138
    }
139

140
    /**
141
     * Turns off debug_mode for the emitter
142
     * - Closes and deletes the log resource
143
     *
144
     * @param bool $deleteLocal - Delete all local information
145
     */
146
    public function debugSwitch($deleteLocal) {
147
        if ($this->debug_mode === true) {
165✔
148

149
            // Turn off debug_mode
150
            $this->debug_mode = false;
160✔
151

152
            // If log files, write permissions and closure of file resource are all true
153
            if (self::DEBUG_LOG_FILES && $this->write_perms) {
160✔
154
                $this->closeFile($this->debug_file);
160✔
155

156
                // If set to true delete the log file as well
157
                if ($deleteLocal) {
160✔
158
                    $this->deleteFile($this->path);
160✔
159
                }
160
            }
161
        }
162
    }
163

164
    /**
165
     * Returns the Collector URL
166
     *
167
     * @param string $type - The type of request we will be making to the collector
168
     * @param string $uri - Collector URI
169
     * @param string $protocol - What protocol we are using for the collector
170
     * @return string
171
     */
172
    public function getCollectorUrl($type, $uri, $protocol) {
173
        $protocol = $protocol == NULL ? self::DEFAULT_PROTOCOL : $protocol;
225✔
174
        if ($type == "POST") {
225✔
175
            return $protocol."://".$uri.self::POST_PATH;
135✔
176
        }
177
        else {
178
            return $protocol."://".$uri.self::GET_PATH;
125✔
179
        }
180
    }
181

182
    /**
183
     * Returns the request type that the emitter will use
184
     * - Makes sure that we cannot return an invalid type
185
     *   as the type determines many facets of the emitters
186
     * - If there is an invalid type OR NULL it will always
187
     *   be the default type == POST
188
     */
189
    public function getRequestType($type) {
190
        switch ($type) {
191
            case "POST" : return $type;
260✔
192
            case "GET"  : return $type;
170✔
193
            default     : return self::DEFAULT_REQ_TYPE;
15✔
194
        }
195
    }
196

197
    /**
198
     * Creates a new directory if the supplied directory path does
199
     * not exists already.
200
     *
201
     * @param string $dir - The directory we want to make
202
     * @return bool|string - Boolean describing if the creation was a success
203
     */
204
    public function makeDir($dir) {
205
        try {
206
            if (!is_dir($dir)) {
200✔
207
                mkdir($dir);
20✔
208
            }
209
            return true;
200✔
210
        } catch (ErrorException $e) {
×
211
            return $e->getMessage();
×
212
        }
213
    }
214

215
    /**
216
     * Attempts to return an opened file resource that can be written to
217
     * - If the file does not exist will attempt to make the file
218
     *
219
     * @param string $file_path - The path to the file we want to write to
220
     * @return string|resource - Either a file resource or a false boolean
221
     */
222
    public function openFile($file_path) {
223
        try {
224
            return fopen($file_path, "w");
200✔
225
        } catch (ErrorException $e) {
×
226
            return $e->getMessage();
×
227
        }
228
    }
229

230
    /**
231
     * Attempts to close an open file resource
232
     *
233
     * @param resource $file_path - The path to the file we want to close
234
     * @return bool|string - Whether or not the close was a success
235
     */
236
    public function closeFile($file_path) {
237
        try {
238
            fclose($file_path);
175✔
239
            return true;
175✔
240
        } catch (ErrorException $e) {
×
241
            return $e->getMessage();
×
242
        }
243
    }
244

245
    /**
246
     * Attempts to copy a file to a new directory
247
     *
248
     * @param string $path_from - The path to the file we want to copy
249
     * @param string $path_to - The path which we want to copt the file to
250
     * @return bool|string - Whether or not the copy was a success
251
     */
252
    public function copyFile($path_from, $path_to) {
253
        try {
254
            copy($path_from, $path_to);
15✔
255
            return true;
15✔
256
        } catch (ErrorException $e) {
×
257
            return $e->getMessage();
×
258
        }
259
    }
260

261
    /**
262
     * Attempts to delete a file
263
     *
264
     * @param string $file_path - The path of the file we want to delete
265
     * @return
266
     */
267
    public function deleteFile($file_path) {
268
        try {
269
            unlink($file_path);
160✔
270
            return true;
160✔
271
        } catch (ErrorException $e) {
×
272
            return $e->getMessage();
×
273
        }
274
    }
275

276
    /**
277
     * Attempts to write a string to a file
278
     *
279
     * @param resource $file_path - The path of the file we want to write to
280
     * @param string $content - The content we want to write into the file
281
     * @return bool|string - If the write was successful or not
282
     */
283
    public function writeToFile($file_path, $content) {
284
        try {
285
            fwrite($file_path, $content);
180✔
286
            return true;
180✔
287
        } catch (ErrorException $e) {
×
288
            return $e->getMessage();
×
289
        }
290
    }
291

292
    // Return Functions
293

294
    /**
295
     * Returns the buffer_size
296
     *
297
     * @return int
298
     */
299
    public function returnBufferSize() {
300
        return $this->buffer_size;
5✔
301
    }
302

303
    /**
304
     * Returns the events buffer
305
     *
306
     * @return array
307
     */
308
    public function returnBuffer() {
309
        return $this->buffer;
5✔
310
    }
311

312
    /**
313
     * Returns a boolean of if debug mode is on or not
314
     *
315
     * @return bool
316
     */
317
    public function returnDebugMode() {
318
        return $this->debug_mode;
5✔
319
    }
320

321
    /**
322
     * Returns the emitter debug file
323
     *
324
     * @return resource|null
325
     */
326
    public function returnDebugFile() {
327
        return $this->debug_file;
5✔
328
    }
329

330
    /**
331
     * Returns the event payload with current time as stm.
332
     *
333
     * @param array $payload
334
     * @return array - Updated event payload
335
     */
336
    public function updateStm($payload) {
337
        $payload["stm"] = strval(time() * 1000);
145✔
338
        return $payload;
145✔
339
    }
340

341
    /**
342
     * Updates all events in buffer with current time as stm.
343
     *
344
     * @param array $buffer
345
     * @return array - Buffer with updated events
346
     */
347
    public function batchUpdateStm($buffer) {
348
        return array_map(array($this, 'updateStm'), $buffer);
55✔
349
    }
350

351
    // Debug Functions
352

353
    /**
354
     * Initialize Debug Logging Paths and Files
355
     *
356
     * @param string $emitter_type - Type of emitter we are logging for
357
     */
358
    private function initDebug($emitter_type) {
359
        $this->debug_mode = true;
165✔
360
        $id = uniqid("", true);
165✔
361

362
        // If the debug files were created successfully...
363
        if ($this->initDebugLogFiles($id, $emitter_type) === true) {
165✔
364
            $debug_header = "Event Log File\nEmitter: ".$emitter_type."\nID: ".$id."\n\n";
165✔
365
            return $this->writeToFile($this->debug_file, $debug_header);
165✔
366
        }
367
        return false;
×
368
    }
369

370
    /**
371
     * Creates the debug log files
372
     *
373
     * @param string $id - Random id for the log file
374
     * @param string $type - Type of emitter we are logging for
375
     * @return bool - Whether or not debug file init was successful
376
     */
377
    private function initDebugLogFiles($id, $type) {
378
        $debug_dir = dirname(__DIR__)."/debug";
165✔
379
        $this->path = $debug_dir."/".$type."-events-log-".$id.".log";
165✔
380

381
        // Attempt to make the debug directory and open the log file
382
        if ($this->makeDir($debug_dir) === true) {
165✔
383
            $this->debug_file = $this->openFile($this->path);
165✔
384
            if ($this->debug_file !== false) {
165✔
385
                return true;
165✔
386
            }
387
        }
388
        return false;
×
389
    }
390
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc