'', 'dir' => ''] );
if ( $args['name'] ) {
$this->name = sanitize_file_name( $args['name'] );
}
if ( $args['dir'] )
$this->dir = sanitize_file_name( $args['dir'] );
$this->file_path = amem()->files->upload_basedir . 'logs' . DIRECTORY_SEPARATOR . ($this->dir ? $this->dir . DIRECTORY_SEPARATOR : '' ) . "{$this->name}.log";
if ( ! file_exists( dirname($this->file_path) ) ) {
amem()->files->filesystem()->mkdir( dirname($this->file_path), 0755 );
}
$this->search = dirname($this->file_path) . DIRECTORY_SEPARATOR . "{$this->name}*";
$this->archive();
}
/**
* Add new record to the log
*
* @param string $text
*/
public function add( $text ) {
do_action( "amem/{$this->name}/log_add", $text );
if ( !$this->enabled )
return;
if ( function_exists('is_wp_error') && is_wp_error($text) ) {
$_text = "Caught exception: ". $text->get_error_message() ." Error code: ". $text->get_code();
$text = $_text;
} elseif ( is_object($text) || is_array($text) ) {
$text = print_r($text, true);
}
$debug_string = "[".current_time('mysql');
$debug_string .= "]: {$text}\n";
if ( ! is_resource( $this->file ) ) {
$this->file = fopen( $this->file_path, 'ab+' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen -- direct file access required for logging
}
fwrite( $this->file, $debug_string ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fwrite -- direct file access required for logging
}
/**
* Archive log if it is too big
*/
public function archive() {
if ( is_file( $this->file_path ) && filesize( $this->file_path ) > $this->max_filesize ) {
$dir = dirname( $this->file_path );
$datetime = gmdate( 'YmdHi' );
$backup = "{$dir}/{$this->name}-{$datetime}.log";
if ( is_writable( $dir ) && copy( $this->file_path, $backup ) ) { // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_is_writable -- filesystem check for log archival
$this->clear();
$this->backup( $backup, true );
}
}
}
public static function backup( $file, $remove = false ) {
if ( !class_exists( 'PclZip' ) )
require_once(ABSPATH . 'wp-admin/includes/class-pclzip.php');
$archive = new \PclZip($file . '.zip');
$v_list = $archive->add($file, PCLZIP_OPT_REMOVE_ALL_PATH, PCLZIP_OPT_ADD_TEMP_FILE_ON, PCLZIP_CB_PRE_ADD, 'amem/log/pclzip/pre_add');
if ($v_list == 0) {
return false;
}
if ( $remove )
wp_delete_file( $file );
return true;
}
/**
* Delete archive files
*
* @return int The count of deleted files
*/
public function clear_archive() {
$deleted = 0;
$files = glob( $this->search );
foreach ( (array) $files as $file ) {
if ( is_file( $file ) ) {
wp_delete_file( $file );
if ( ! file_exists( $file ) ) {
$deleted ++;
}
}
}
return $deleted;
}
/**
* Clear log file
*/
public function clear() {
if ( file_exists( $this->file_path ) ) {
file_put_contents( $this->file_path, '' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents -- clearing log file
}
}
/**
* Temporary files quantity
*
* @return int
*/
public function count_files() {
$files = glob( $this->search );
return count( (array) $files );
}
/**
* Get log content
*
* @return string
*/
public function get() {
$content = (string) file_get_contents( $this->file_path );
return $content;
}
/**
* Get log content as HTML
*
* @return string
*/
public function get_html() {
if ( ! file_exists( $this->file_path ) ) {
/* translators: %s: Provider name */
return sprintf( esc_html__( 'No file "%s.log".', 'advanced-members' ), $this->name );
}
$log_arr = file( $this->file_path );
foreach ( $log_arr as $key => $value ) {
$log_arr[ $key ] = $this->format_html( trim( $value ) );
}
$content = implode( '', $log_arr );
return $content;
}
/**
* Format error as HTML text
*
* @param array|string $error An error data.
* @return string
*/
public function error_html( $error ) {
if ( is_string( $error ) ) {
return trim( $error );
}
$error_text = '';
if ( ! empty( $error['title'] ) ) {
$error_text .= '' . $error['title'] . ' ';
}
if ( ! empty( $error['title'] ) && ! empty( $error['detail'] ) ) {
$error_text .= ' - ';
}
if ( ! empty( $error['detail'] ) ) {
$error_text .= $error['detail'] . ' ';
}
if ( ! empty( $error['errors'] ) && is_array( $error['errors'] ) ) {
$error_text .= '
' . __( 'Errors', 'advanced-members' ) . ': ';
foreach ( $error['errors'] as $error ) {
if ( isset( $error['field'] ) && isset( $error['message'] ) ) {
$error_text .= sprintf( "
'%s' - %s,", $error['field'], $error['message'] );
}
}
}
return trim( $error_text, ' ,;' );
}
/**
* Format log string
*
* @param string $content A log string.
* @return string
*/
public function format_html( $content ) {
$content_b = str_replace(
apply_filters( 'amem/log/format/string', array(
'ERROR',
'SUCCESS',
'NOTICE',
'ARGS:',
'REFERER:',
'RESPONSE:',
'BACKTRACE:',
'[GET]',
'[POST]',
'[PATCH]',
'[DELETE]',
) ),
apply_filters( 'amem/log/format/replace', array(
'ERROR',
'SUCCESS',
'NOTICE',
'ARGS:',
'REFERER:',
'RESPONSE:',
'BACKTRACE:',
'[GET]',
'[POST]',
'[PATCH]',
'[DELETE]',
) ),
$content
);
return nl2br( $content_b );
}
/**
* Recursive remove links
*
* @param mixed $arr An array.
* @return mixed
*/
public function remove_links( $arr ) {
if ( is_array( $arr ) ) {
foreach ( $arr as $k => $v ) {
if ( '_links' === $k ) {
unset( $arr[ $k ] );
} else {
$arr[ $k ] = $this->remove_links( $v );
}
}
}
return $arr;
}
public function is_enabled() {
return $this->enabled;
}
public function enable() {
$this->enabled = true;
}
public function disable() {
$this->enabled = false;
}
}
// Initialize default log with amem.log
amem()->register_module( 'log', Log::getInstance() );