PluginProbe
Code Profiler – WordPress Performance Profiling and Debugging Made Easy / 1.7.2
Code Profiler – WordPress Performance Profiling and Debugging Made Easy v1.7.2
1.9.5 1.9.4 1.9.3 trunk 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.5 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.6 1.6.1 1.6.10 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 All 40 releases
code-profiler / lib / class-stream.php

class-stream.php in Code Profiler – WordPress Performance Profiling and Debugging Made Easy 1.7.2, at lib/class-stream.php

389 lines 8.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 +=====================================================================+
4 | ____ _ ____ __ _ _ |
5 | / ___|___ __| | ___ | _ \ _ __ ___ / _(_) | ___ _ __ |
6 | | | / _ \ / _` |/ _ \ | |_) | '__/ _ \| |_| | |/ _ \ '__| |
7 | | |__| (_) | (_| | __/ | __/| | | (_) | _| | | __/ | |
8 | \____\___/ \__,_|\___| |_| |_| \___/|_| |_|_|\___|_| |
9 | |
10 | (c) Jerome Bruandet ~ https://nintechnet.com/codeprofiler/ |
11 +=====================================================================+
12 */
13
14 if (! defined( 'ABSPATH' ) ) { die( 'Forbidden' ); }
15
16 // =====================================================================
17
18 class CodeProfiler_Stream {
19
20 static $io_stats = [
21 'cast' => 0, 'chgrp' => 0,
22 'chmod' => 0, 'chown' => 0,
23 'close' => 0, 'closedir' => 0,
24 'eof' => 0, 'flush' => 0,
25 'lock' => 0, 'mkdir' => 0,
26 'open' => 0, 'opendir' => 0,
27 'readdir' => 0, 'rewinddir' => 0,
28 'read' => 0, 'rename' => 0,
29 'rmdir' => 0, 'seek' => 0,
30 'set_option'=> 0, 'stat' => 0,
31 'tell' => 0, 'truncate' => 0,
32 'write' => 0, 'touch' => 0,
33 'unlink' => 0, 'url_stat' => 0
34 ];
35 static $io_read = 0;
36 static $io_write = 0;
37 public $context;
38 public $resource;
39 protected static $protocol = 'file';
40 private $script;
41
42
43 public static function start() {
44 stream_wrapper_unregister( self::$protocol );
45 stream_wrapper_register( self::$protocol, CodeProfiler_Stream::class );
46 }
47
48
49 public static function stop() {
50 stream_wrapper_restore( self::$protocol );
51 }
52
53 /**
54 * Opens file or URL
55 */
56 public function stream_open( $path, $mode, $options, &$opened_path ) {
57 self::$io_stats['open']++;
58 self::stop();
59 if ( isset( $this->context) ) {
60 $this->resource = fopen( $path, $mode, $options, $this->context );
61 } else {
62 $this->resource = fopen( $path, $mode, $options );
63 }
64 self::start();
65
66 if ( version_compare( PHP_VERSION, '8.0', '<') ) {
67 if ( in_array( $mode, ['rb', 'rt', 'r']) &&
68 "{$path[-4]}{$path[-3]}{$path[-2]}{$path[-1]}" == '.php') {
69
70 $this->script = $this->check_exclusions( $path );
71 }
72 } else {
73 if ( str_ends_with( $path, '.php') && in_array( $mode, ['rb', 'rt', 'r']) ) {
74 $this->script = $this->check_exclusions( $path );
75 }
76 }
77
78 return $this->resource !== false;
79 }
80
81 /**
82 * Check file and folder exclusions.
83 */
84 private function check_exclusions( $path ) {
85
86 foreach( CodeProfiler_Profiler::$exclusions as $item ) {
87 if ( $item && strpos( $path, $item ) !== false ) {
88 return;
89 }
90 }
91 return 1;
92 }
93
94 /**
95 * Close a resource
96 */
97 public function stream_close() {
98 self::$io_stats['close']++;
99 return fclose( $this->resource );
100 }
101
102 /**
103 * Tests for end-of-file on a file pointer
104 */
105 public function stream_eof() {
106 self::$io_stats['eof']++;
107 return feof( $this->resource );
108 }
109
110 /**
111 * Flushes the output
112 */
113 public function stream_flush() {
114 self::$io_stats['flush']++;
115 return fflush( $this->resource );
116 }
117
118 /**
119 * Seeks to specific location in a stream
120 */
121 public function stream_seek( $offset, $whence = SEEK_SET ) {
122 self::$io_stats['seek']++;
123 return fseek( $this->resource, $offset, $whence ) === 0;
124 }
125
126 /**
127 * Delete a file
128 */
129 public function unlink( $path ) {
130 self::$io_stats['unlink']++;
131 self::stop();
132 if ( isset( $this->context ) ) {
133 $res = unlink( $path, $this->context );
134 } else {
135 $res = unlink( $path );
136 }
137 self::start();
138 return $res;
139 }
140
141 /**
142 * Renames a file or directory
143 */
144 public function rename( $path_from, $path_to ) {
145 self::$io_stats['rename']++;
146 self::stop();
147 if ( isset( $this->context ) ) {
148 $res = rename( $path_from, $path_to, $this->context );
149 } else {
150 $res = rename( $path_from, $path_to );
151 }
152 self::start();
153 return $res;
154 }
155
156 /**
157 * Removes a directory
158 */
159 public function rmdir( $path, $options ) {
160 self::$io_stats['rmdir']++;
161 self::stop();
162 if ( isset( $this->context ) ) {
163 $res = rmdir( $path, $this->context );
164 } else {
165 $res = rmdir( $path );
166 }
167 self::start();
168 return $res;
169 }
170
171 /**
172 * Retrieve the underlaying resource
173 */
174 public function stream_cast( $cast_as ) {
175 self::$io_stats['cast']++;
176 return $this->resource;
177 }
178
179 /**
180 * Advisory file locking
181 */
182 public function stream_lock( $operation ) {
183 self::$io_stats['lock']++;
184 if (! $operation ) {
185 $operation = LOCK_EX;
186 }
187 return flock( $this->resource, $operation );
188 }
189
190 /**
191 * Truncate stream
192 */
193 public function stream_truncate( $new_size ) {
194 self::$io_stats['truncate']++;
195 return ftruncate( $this->resource, $new_size );
196 }
197
198
199 public function stream_write( $data ) {
200 self::$io_stats['write']++;
201 $write = fwrite( $this->resource, $data );
202 self::$io_write += $write;
203 return $write;
204 }
205
206 /**
207 * Change stream options
208 */
209 public function stream_set_option( $option, $arg1, $arg2 ) {
210 self::$io_stats['set_option']++;
211 switch ( $option ) {
212 case STREAM_OPTION_BLOCKING:
213 return stream_set_blocking( $this->resource, $arg1 );
214 case STREAM_OPTION_READ_TIMEOUT:
215 return stream_set_timeout( $this->resource, $arg1, $arg2 );
216 case STREAM_OPTION_WRITE_BUFFER:
217 return stream_set_write_buffer( $this->resource, $arg1 );
218 case STREAM_OPTION_READ_BUFFER:
219 return stream_set_read_buffer( $this->resource, $arg1 );
220 default:
221 return false;
222 }
223 }
224
225 /**
226 * Change stream metadata
227 */
228 public function stream_metadata( $path, $option, $value ) {
229 self::stop();
230 $res = false;
231 switch ( $option ) {
232 case STREAM_META_ACCESS:
233 $res = chmod( $path, $value );
234 self::$io_stats['chmod']++;
235 break;
236 case STREAM_META_GROUP:
237 case STREAM_META_GROUP_NAME:
238 $res = chgrp( $path, $value );
239 self::$io_stats['chgrp']++;
240 break;
241 case STREAM_META_OWNER:
242 case STREAM_META_OWNER_NAME:
243 $res = chown( $path, $value );
244 self::$io_stats['chown']++;
245 break;
246 case STREAM_META_TOUCH:
247 if (! empty( $value ) ) {
248 $res = touch( $path, $value[0], $value[1] );
249 } else {
250 $res = touch( $path );
251 }
252 self::$io_stats['touch']++;
253 break;
254 }
255 self::start();
256 return $res;
257 }
258
259 /**
260 * Create a directory
261 */
262 public function mkdir( $path, $mode, $options ) {
263 self::$io_stats['mkdir']++;
264 self::stop();
265 if ( isset( $this->context ) ) {
266 $res = mkdir( $path, $mode, $options, $this->context );
267 } else {
268 $res = mkdir( $path, $mode, $options );
269 }
270 self::start();
271 return $res;
272 }
273
274 /**
275 * Open directory handle
276 */
277 public function dir_opendir( $path, $options ) {
278 self::$io_stats['opendir']++;
279 self::stop();
280 if ( isset( $this->context ) ) {
281 $this->resource = opendir( $path, $this->context );
282 } else {
283 $this->resource = opendir( $path );
284 }
285 self::start();
286 return $this->resource;
287 }
288
289 /**
290 * Close directory handle
291 */
292 public function dir_closedir() {
293 self::$io_stats['closedir']++;
294 // closedir returns no value
295 return closedir( $this->resource );
296 }
297
298 /**
299 * Read entry from directory handle
300 */
301 public function dir_readdir() {
302 self::$io_stats['readdir']++;
303 return readdir( $this->resource );
304 }
305
306 /**
307 * Rewind directory handle
308 */
309 public function dir_rewinddir() {
310 self::$io_stats['rewinddir']++;
311 return rewinddir( $this->resource );
312 }
313
314 /**
315 * Retrieve information about a file
316 */
317 public function url_stat( $path, $flags ) {
318 self::$io_stats['url_stat']++;
319 self::stop();
320 // Catch error and exception
321 set_error_handler( function() {} );
322 try {
323 $res = stat( $path );
324 } catch ( \Exception $e ) {
325 $res = null;
326 }
327 restore_error_handler();
328 self::start();
329 return $res;
330 }
331
332 /**
333 * Read from stream & enable ticks
334 */
335 public function stream_read( $count ) {
336 self::$io_stats['read']++;
337 if ( $this->script ) {
338 self::stop();
339 if ( ftell( $this->resource ) == 0 ) {
340 self::start();
341 $read = fread( $this->resource, $count - CODE_PROFILER_LENGTH );
342 self::$io_read += strlen( $read );
343 $pos = stripos( $read, '<?php' );
344 if ( $pos !== false ) {
345 return substr_replace(
346 $read,
347 '<?php declare(ticks='. CODE_PROFILER_TICKS .');',
348 $pos,
349 5
350 );
351 }
352 return $read;
353 }
354 self::start();
355 }
356 $read = fread( $this->resource, $count );
357 self::$io_read += strlen( $read );
358 return $read;
359 }
360
361 /**
362 * Retrieve information about a file resource
363 */
364 public function stream_stat() {
365 self::$io_stats['stat']++;
366 $res = fstat( $this->resource );
367 if ( $this->script ) {
368 $res['size'] += CODE_PROFILER_LENGTH;
369 $res[7] += CODE_PROFILER_LENGTH;
370 }
371 return $res;
372 }
373
374 /**
375 * Retrieve the current position of a stream
376 */
377 function stream_tell() {
378 self::$io_stats['tell']++;
379 $res = ftell( $this->resource );
380 if ( $this->script ) {
381 $res += CODE_PROFILER_LENGTH;
382 }
383 return $res;
384 }
385 }
386
387 // =====================================================================
388 // EOF
389