File: /home/d5123/myboofola_com/wp-content/plugins/code-profiler/lib/class-stream.php
<?php
/**
+=====================================================================+
| ____ _ ____ __ _ _ |
| / ___|___ __| | ___ | _ \ _ __ ___ / _(_) | ___ _ __ |
| | | / _ \ / _` |/ _ \ | |_) | '__/ _ \| |_| | |/ _ \ '__| |
| | |__| (_) | (_| | __/ | __/| | | (_) | _| | | __/ | |
| \____\___/ \__,_|\___| |_| |_| \___/|_| |_|_|\___|_| |
| |
| (c) Jerome Bruandet ~ https://nintechnet.com/codeprofiler/ |
+=====================================================================+
*/
if (! defined( 'ABSPATH' ) ) { die( 'Forbidden' ); }
// =====================================================================
class CodeProfiler_Stream {
static $io_stats = [
'cast' => 0, 'chgrp' => 0,
'chmod' => 0, 'chown' => 0,
'close' => 0, 'closedir' => 0,
'eof' => 0, 'flush' => 0,
'lock' => 0, 'mkdir' => 0,
'open' => 0, 'opendir' => 0,
'readdir' => 0, 'rewinddir' => 0,
'read' => 0, 'rename' => 0,
'rmdir' => 0, 'seek' => 0,
'set_option'=> 0, 'stat' => 0,
'tell' => 0, 'truncate' => 0,
'write' => 0, 'touch' => 0,
'unlink' => 0, 'url_stat' => 0
];
static $io_read = 0;
static $io_write = 0;
public $context;
public $resource;
protected static $protocol = 'file';
private $script;
public static function start() {
stream_wrapper_unregister( self::$protocol );
stream_wrapper_register( self::$protocol, CodeProfiler_Stream::class );
}
public static function stop() {
stream_wrapper_restore( self::$protocol );
}
/**
* Opens file or URL
*/
public function stream_open( $path, $mode, $options, &$opened_path ) {
self::$io_stats['open']++;
self::stop();
if ( isset( $this->context) ) {
$this->resource = fopen( $path, $mode, $options, $this->context );
} else {
$this->resource = fopen( $path, $mode, $options );
}
self::start();
if ( version_compare( PHP_VERSION, '8.0', '<') ) {
if ( in_array( $mode, ['rb', 'rt', 'r']) &&
"{$path[-4]}{$path[-3]}{$path[-2]}{$path[-1]}" == '.php') {
$this->script = $this->check_exclusions( $path );
}
} else {
if ( str_ends_with( $path, '.php') && in_array( $mode, ['rb', 'rt', 'r']) ) {
$this->script = $this->check_exclusions( $path );
}
}
return $this->resource !== false;
}
/**
* Check file and folder exclusions.
*/
private function check_exclusions( $path ) {
foreach( CodeProfiler_Profiler::$exclusions as $item ) {
if ( $item && strpos( $path, $item ) !== false ) {
return;
}
}
return 1;
}
/**
* Close a resource
*/
public function stream_close() {
self::$io_stats['close']++;
return fclose( $this->resource );
}
/**
* Tests for end-of-file on a file pointer
*/
public function stream_eof() {
self::$io_stats['eof']++;
return feof( $this->resource );
}
/**
* Flushes the output
*/
public function stream_flush() {
self::$io_stats['flush']++;
return fflush( $this->resource );
}
/**
* Seeks to specific location in a stream
*/
public function stream_seek( $offset, $whence = SEEK_SET ) {
self::$io_stats['seek']++;
return fseek( $this->resource, $offset, $whence ) === 0;
}
/**
* Delete a file
*/
public function unlink( $path ) {
self::$io_stats['unlink']++;
self::stop();
if ( isset( $this->context ) ) {
$res = unlink( $path, $this->context );
} else {
$res = unlink( $path );
}
self::start();
return $res;
}
/**
* Renames a file or directory
*/
public function rename( $path_from, $path_to ) {
self::$io_stats['rename']++;
self::stop();
if ( isset( $this->context ) ) {
$res = rename( $path_from, $path_to, $this->context );
} else {
$res = rename( $path_from, $path_to );
}
self::start();
return $res;
}
/**
* Removes a directory
*/
public function rmdir( $path, $options ) {
self::$io_stats['rmdir']++;
self::stop();
if ( isset( $this->context ) ) {
$res = rmdir( $path, $this->context );
} else {
$res = rmdir( $path );
}
self::start();
return $res;
}
/**
* Retrieve the underlaying resource
*/
public function stream_cast( $cast_as ) {
self::$io_stats['cast']++;
return $this->resource;
}
/**
* Advisory file locking
*/
public function stream_lock( $operation ) {
self::$io_stats['lock']++;
if (! $operation ) {
$operation = LOCK_EX;
}
return flock( $this->resource, $operation );
}
/**
* Truncate stream
*/
public function stream_truncate( $new_size ) {
self::$io_stats['truncate']++;
return ftruncate( $this->resource, $new_size );
}
public function stream_write( $data ) {
self::$io_stats['write']++;
$write = fwrite( $this->resource, $data );
self::$io_write += $write;
return $write;
}
/**
* Change stream options
*/
public function stream_set_option( $option, $arg1, $arg2 ) {
self::$io_stats['set_option']++;
switch ( $option ) {
case STREAM_OPTION_BLOCKING:
return stream_set_blocking( $this->resource, $arg1 );
case STREAM_OPTION_READ_TIMEOUT:
return stream_set_timeout( $this->resource, $arg1, $arg2 );
case STREAM_OPTION_WRITE_BUFFER:
return stream_set_write_buffer( $this->resource, $arg1 );
case STREAM_OPTION_READ_BUFFER:
return stream_set_read_buffer( $this->resource, $arg1 );
default:
return false;
}
}
/**
* Change stream metadata
*/
public function stream_metadata( $path, $option, $value ) {
self::stop();
$res = false;
switch ( $option ) {
case STREAM_META_ACCESS:
$res = chmod( $path, $value );
self::$io_stats['chmod']++;
break;
case STREAM_META_GROUP:
case STREAM_META_GROUP_NAME:
$res = chgrp( $path, $value );
self::$io_stats['chgrp']++;
break;
case STREAM_META_OWNER:
case STREAM_META_OWNER_NAME:
$res = chown( $path, $value );
self::$io_stats['chown']++;
break;
case STREAM_META_TOUCH:
if (! empty( $value ) ) {
$res = touch( $path, $value[0], $value[1] );
} else {
$res = touch( $path );
}
self::$io_stats['touch']++;
break;
}
self::start();
return $res;
}
/**
* Create a directory
*/
public function mkdir( $path, $mode, $options ) {
self::$io_stats['mkdir']++;
self::stop();
if ( isset( $this->context ) ) {
$res = mkdir( $path, $mode, $options, $this->context );
} else {
$res = mkdir( $path, $mode, $options );
}
self::start();
return $res;
}
/**
* Open directory handle
*/
public function dir_opendir( $path, $options ) {
self::$io_stats['opendir']++;
self::stop();
if ( isset( $this->context ) ) {
$this->resource = opendir( $path, $this->context );
} else {
$this->resource = opendir( $path );
}
self::start();
return $this->resource;
}
/**
* Close directory handle
*/
public function dir_closedir() {
self::$io_stats['closedir']++;
// closedir returns no value
return closedir( $this->resource );
}
/**
* Read entry from directory handle
*/
public function dir_readdir() {
self::$io_stats['readdir']++;
return readdir( $this->resource );
}
/**
* Rewind directory handle
*/
public function dir_rewinddir() {
self::$io_stats['rewinddir']++;
return rewinddir( $this->resource );
}
/**
* Retrieve information about a file
*/
public function url_stat( $path, $flags ) {
self::$io_stats['url_stat']++;
self::stop();
// Catch error and exception
set_error_handler( function() {} );
try {
$res = stat( $path );
} catch ( \Exception $e ) {
$res = null;
}
restore_error_handler();
self::start();
return $res;
}
/**
* Read from stream & enable ticks
*/
public function stream_read( $count ) {
self::$io_stats['read']++;
if ( $this->script ) {
self::stop();
if ( ftell( $this->resource ) == 0 ) {
self::start();
$read = fread( $this->resource, $count - CODE_PROFILER_LENGTH );
self::$io_read += strlen( $read );
$pos = stripos( $read, '<?php' );
if ( $pos !== false ) {
return substr_replace(
$read,
'<?php declare(ticks='. CODE_PROFILER_TICKS .');',
$pos,
5
);
}
return $read;
}
self::start();
}
$read = fread( $this->resource, $count );
self::$io_read += strlen( $read );
return $read;
}
/**
* Retrieve information about a file resource
*/
public function stream_stat() {
self::$io_stats['stat']++;
$res = fstat( $this->resource );
if ( $this->script ) {
$res['size'] += CODE_PROFILER_LENGTH;
$res[7] += CODE_PROFILER_LENGTH;
}
return $res;
}
/**
* Retrieve the current position of a stream
*/
function stream_tell() {
self::$io_stats['tell']++;
$res = ftell( $this->resource );
if ( $this->script ) {
$res += CODE_PROFILER_LENGTH;
}
return $res;
}
}
// =====================================================================
// EOF