403Webshell
Server IP : 3.93.235.159  /  Your IP : 216.73.216.140
Web Server : Apache
System : Linux ip-172-26-0-169 5.10.0-46-cloud-amd64 #1 SMP Debian 5.10.262-1 (2026-07-31) x86_64
User : bitnami ( 1000)
PHP Version : 8.2.9
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : OFF
Directory :  /bitnami/wordpress/wp-content/plugins/yoast-test-helper/src/logger/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /bitnami/wordpress/wp-content/plugins/yoast-test-helper/src/logger/database-log-storage.php
<?php

namespace Yoast\WP\Test_Helper\Logger;

use Yoast\WP\Test_Helper\Option;

/**
 * Stores log entries in a dedicated custom table.
 */
class Database_Log_Storage implements Log_Storage {

	/**
	 * Suffix for the custom table, appended to the WordPress table prefix.
	 *
	 * @var string
	 */
	public const TABLE_SUFFIX = 'yoast_test_helper_log';

	/**
	 * Schema version, used to short-circuit dbDelta on subsequent calls.
	 *
	 * @var string
	 */
	public const SCHEMA_VERSION = '1';

	/**
	 * Default maximum number of entries kept in the table.
	 *
	 * Callers can override the effective cap via the `Yoast\WP\Test_Helper\logger_max_rows` filter.
	 *
	 * @var int
	 */
	public const DEFAULT_MAX_ROWS = 1000;

	/**
	 * Option key tracking the last applied schema version.
	 *
	 * @var string
	 */
	private const SCHEMA_OPTION = 'logger_db_version';

	/**
	 * The shared option store, used to remember the applied schema version.
	 *
	 * @var Option
	 */
	private $option;

	/**
	 * Constructs the storage.
	 *
	 * @param Option $option The shared option store.
	 */
	public function __construct( Option $option ) {
		$this->option = $option;
	}

	/**
	 * Creates or upgrades the log table when the stored schema version is out of date.
	 *
	 * @return void
	 */
	public function setup() {
		if ( $this->option->get( self::SCHEMA_OPTION ) === self::SCHEMA_VERSION ) {
			return;
		}

		require_once \ABSPATH . 'wp-admin/includes/upgrade.php';

		global $wpdb;
		$table_name      = $this->get_table_name();
		$charset_collate = $wpdb->get_charset_collate();

		$sql = "CREATE TABLE {$table_name} (
			id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
			logged_at DATETIME NOT NULL,
			level VARCHAR(16) NOT NULL,
			message TEXT NOT NULL,
			context LONGTEXT NULL,
			PRIMARY KEY  (id),
			KEY logged_at (logged_at),
			KEY level (level)
		) {$charset_collate};";

		\dbDelta( $sql );

		$this->option->set( self::SCHEMA_OPTION, self::SCHEMA_VERSION );
	}

	/**
	 * Inserts a log entry and trims the table to MAX_ROWS.
	 *
	 * @param string                                  $level     PSR-3 log level.
	 * @param string                                  $message   The interpolated message.
	 * @param array<string, scalar|array|object|null> $context   The original context array.
	 * @param int                                     $timestamp Unix timestamp at which the entry was captured.
	 *
	 * @return void
	 */
	public function write( $level, $message, array $context, $timestamp ) {
		global $wpdb;
		$table_name = $this->get_table_name();

		$wpdb->insert(
			$table_name,
			[
				'logged_at' => \gmdate( 'Y-m-d H:i:s', $timestamp ),
				'level'     => $level,
				'message'   => $message,
				// phpcs:ignore Yoast.Yoast.JsonEncodeAlternative.Found -- Compact storage; format_json_encode pretty-prints, which bloats the row.
				'context'   => \wp_json_encode( $context ),
			],
			[ '%s', '%s', '%s', '%s' ],
		);

		$max_rows = (int) \apply_filters( 'Yoast\WP\Test_Helper\logger_max_rows', self::DEFAULT_MAX_ROWS );
		if ( $max_rows < 1 ) {
			return;
		}

		// Trim using a derived subquery — MySQL cannot otherwise reference the target table in a DELETE subquery.
		$wpdb->query(
			$wpdb->prepare(
				'DELETE FROM %i WHERE id NOT IN (
					SELECT id FROM ( SELECT id FROM %i ORDER BY id DESC LIMIT %d ) AS keep_ids
				)',
				$table_name,
				$table_name,
				$max_rows,
			),
		);
	}

	/**
	 * Reads the most recent entries, newest first.
	 *
	 * @param int $limit Maximum number of entries to return.
	 *
	 * @return array<int, array{logged_at: string, level: string, message: string, context: array<string, scalar|array|object|null>}> The entries.
	 */
	public function read( $limit = 50 ) {
		global $wpdb;
		$rows = $wpdb->get_results(
			$wpdb->prepare(
				'SELECT logged_at, level, message, context FROM %i ORDER BY id DESC LIMIT %d',
				$this->get_table_name(),
				(int) $limit,
			),
			\ARRAY_A,
		);

		if ( ! \is_array( $rows ) ) {
			return [];
		}

		return \array_map( [ self::class, 'hydrate_row' ], $rows );
	}

	/**
	 * Empties the log table.
	 *
	 * @return void
	 */
	public function clear() {
		global $wpdb;
		$wpdb->query(
			$wpdb->prepare( 'TRUNCATE TABLE %i', $this->get_table_name() ),
		);
	}

	/**
	 * Converts a database row into the entry shape returned by read().
	 *
	 * @param array<string, scalar|array|object|null> $row The database row.
	 *
	 * @return array{logged_at: string, level: string, message: string, context: array<string, scalar|array|object|null>} The entry.
	 */
	private static function hydrate_row( array $row ) {
		$context = [];
		if ( isset( $row['context'] ) && $row['context'] !== '' ) {
			$decoded = \json_decode( (string) $row['context'], true );
			if ( \is_array( $decoded ) ) {
				$context = $decoded;
			}
		}

		return [
			'logged_at' => (string) $row['logged_at'],
			'level'     => (string) $row['level'],
			'message'   => (string) $row['message'],
			'context'   => $context,
		];
	}

	/**
	 * Builds the fully qualified table name.
	 *
	 * @return string The prefixed table name.
	 */
	private function get_table_name() {
		global $wpdb;
		return $wpdb->prefix . self::TABLE_SUFFIX;
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit