Commit inicial - WordPress Análisis de Precios Unitarios

- WordPress core y plugins
- Tema Twenty Twenty-Four configurado
- Plugin allow-unfiltered-html.php simplificado
- .gitignore configurado para excluir wp-config.php y uploads

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2025-11-03 21:04:30 -06:00
commit a22573bf0b
24068 changed files with 4993111 additions and 0 deletions

View File

@@ -0,0 +1,153 @@
<?php declare(strict_types = 1);
/**
* Ajax request dispatcher.
*
* @package query-monitor
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
class QM_Dispatcher_AJAX extends QM_Dispatcher {
public $id = 'ajax';
public function __construct( QM_Plugin $qm ) {
parent::__construct( $qm );
// This dispatcher needs to run on a priority lower than 1 so it can output
// its headers before wp_ob_end_flush_all() flushes all the output buffers:
// https://github.com/WordPress/wordpress-develop/blob/0a3a3c5119897c6d551a42ae9b5dbfa4f576f2c9/src/wp-includes/default-filters.php#L382
add_action( 'shutdown', array( $this, 'dispatch' ), 0 );
}
/**
* @return void
*/
public function init() {
if ( ! self::user_can_view() ) {
return;
}
if ( QM_Util::is_ajax() ) {
// Start an output buffer for Ajax requests so headers can be output at the end:
ob_start();
}
parent::init();
}
/**
* @return void
*/
public function dispatch() {
if ( ! $this->should_dispatch() ) {
return;
}
$this->before_output();
foreach ( $this->get_outputters( 'headers' ) as $id => $output ) {
$output->output();
}
$this->after_output();
}
/**
* @return void
*/
protected function before_output() {
foreach ( (array) glob( $this->qm->plugin_path( 'output/headers/*.php' ) ) as $file ) {
require_once $file;
}
}
/**
* @return void
*/
protected function after_output() {
# flush once, because we're nice
if ( ob_get_length() ) {
ob_flush();
}
}
/**
* @return bool
*/
public function is_active() {
if ( ! QM_Util::is_ajax() ) {
return false;
}
if ( ! self::user_can_view() ) {
return false;
}
# If the headers have already been sent then we can't do anything about it
if ( headers_sent() ) {
return false;
}
# Don't process if the minimum required actions haven't fired:
if ( is_admin() ) {
if ( ! did_action( 'admin_init' ) ) {
return false;
}
} else {
if ( ! did_action( 'wp' ) ) {
return false;
}
}
return true;
}
/**
* @param string $message
* @param mixed[] $e
* @phpstan-param array{
* message: string,
* file: string,
* line: int,
* type?: int,
* trace?: mixed|null,
* } $e
*/
public function output_fatal( $message, array $e ): void {
if ( ! headers_sent() ) {
header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
}
// @TODO
echo wp_json_encode(
array(
'code' => 'qm_fatal',
'message' => $message,
'data' => $e,
),
JSON_UNESCAPED_SLASHES
);
}
}
/**
* @param array<string, QM_Dispatcher> $dispatchers
* @param QM_Plugin $qm
* @return array<string, QM_Dispatcher>
*/
function register_qm_dispatcher_ajax( array $dispatchers, QM_Plugin $qm ) {
$dispatchers['ajax'] = new QM_Dispatcher_AJAX( $qm );
return $dispatchers;
}
add_filter( 'qm/dispatchers', 'register_qm_dispatcher_ajax', 10, 2 );

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,118 @@
<?php declare(strict_types = 1);
/**
* REST API request dispatcher.
*
* @package query-monitor
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
class QM_Dispatcher_REST extends QM_Dispatcher {
public $id = 'rest';
public function __construct( QM_Plugin $qm ) {
parent::__construct( $qm );
add_filter( 'rest_post_dispatch', array( $this, 'filter_rest_post_dispatch' ), 1 );
}
/**
* Filters a REST API response in order to add QM's headers.
*
* @param WP_HTTP_Response $result Result to send to the client. Usually a WP_REST_Response.
* @return WP_HTTP_Response Result to send to the client.
*/
public function filter_rest_post_dispatch( WP_HTTP_Response $result ) {
if ( ! $this->should_dispatch() ) {
return $result;
}
$this->before_output();
/** @var array<string, QM_Output_Headers> $outputters */
$outputters = $this->get_outputters( 'headers' );
foreach ( $outputters as $output ) {
$output->output();
}
$this->after_output();
return $result;
}
/**
* @return void
*/
protected function before_output() {
foreach ( (array) glob( $this->qm->plugin_path( 'output/headers/*.php' ) ) as $file ) {
include_once $file;
}
}
/**
* @return bool
*/
public function is_active() {
# If the headers have already been sent then we can't do anything about it
if ( headers_sent() ) {
return false;
}
if ( ! defined( 'REST_REQUEST' ) || ! REST_REQUEST ) {
return false;
}
if ( ! self::user_can_view() ) {
return false;
}
return true;
}
/**
* @param string $message
* @param mixed[] $e
* @phpstan-param array{
* message: string,
* file: string,
* line: int,
* type?: int,
* trace?: mixed|null,
* } $e
*/
public function output_fatal( $message, array $e ): void {
if ( ! headers_sent() ) {
header( 'Content-Type: application/json; charset=' . get_option( 'blog_charset' ) );
}
echo wp_json_encode(
array(
'code' => 'qm_fatal',
'message' => $message,
'data' => $e,
),
JSON_UNESCAPED_SLASHES
);
}
}
/**
* @param array<string, QM_Dispatcher> $dispatchers
* @param QM_Plugin $qm
* @return array<string, QM_Dispatcher>
*/
function register_qm_dispatcher_rest( array $dispatchers, QM_Plugin $qm ) {
$dispatchers['rest'] = new QM_Dispatcher_REST( $qm );
return $dispatchers;
}
add_filter( 'qm/dispatchers', 'register_qm_dispatcher_rest', 10, 2 );

View File

@@ -0,0 +1,80 @@
<?php declare(strict_types = 1);
/**
* REST API enveloped request dispatcher.
*
* @package query-monitor
*/
class QM_Dispatcher_REST_Envelope extends QM_Dispatcher {
public $id = 'rest_envelope';
public function __construct( QM_Plugin $qm ) {
parent::__construct( $qm );
add_filter( 'rest_envelope_response', array( $this, 'filter_rest_envelope_response' ), 999, 2 );
}
/**
* Filters the enveloped form of a REST API response to add QM's data.
*
* @param array<string, mixed> $envelope Envelope data.
* @param WP_REST_Response $response Original response data.
* @return array<string, mixed> Envelope data.
*/
public function filter_rest_envelope_response( array $envelope, WP_REST_Response $response ) {
if ( ! $this->should_dispatch() ) {
return $envelope;
}
$data = array();
$this->before_output();
/** @var array<string, QM_Output_Raw> $outputters */
$outputters = $this->get_outputters( 'raw' );
foreach ( $outputters as $id => $output ) {
$data[ $id ] = $output->get_output();
}
$this->after_output();
$envelope['qm'] = $data;
return $envelope;
}
/**
* @return void
*/
protected function before_output() {
foreach ( (array) glob( $this->qm->plugin_path( 'output/raw/*.php' ) ) as $file ) {
include_once $file;
}
}
/**
* @return bool
*/
public function is_active() {
if ( ! self::user_can_view() ) {
return false;
}
return true;
}
}
/**
* @param array<string, QM_Dispatcher> $dispatchers
* @param QM_Plugin $qm
* @return array<string, QM_Dispatcher>
*/
function register_qm_dispatcher_rest_envelope( array $dispatchers, QM_Plugin $qm ) {
$dispatchers['rest_envelope'] = new QM_Dispatcher_REST_Envelope( $qm );
return $dispatchers;
}
add_filter( 'qm/dispatchers', 'register_qm_dispatcher_rest_envelope', 10, 2 );

View File

@@ -0,0 +1,101 @@
<?php declare(strict_types = 1);
/**
* HTTP redirect dispatcher.
*
* @package query-monitor
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
class QM_Dispatcher_Redirect extends QM_Dispatcher {
public $id = 'redirect';
public function __construct( QM_Plugin $qm ) {
parent::__construct( $qm );
add_filter( 'wp_redirect', array( $this, 'filter_wp_redirect' ), 9999, 2 );
}
/**
* Filters a redirect location in order to output QM's headers.
*
* @param string $location The path to redirect to.
* @param int $status Status code to use.
* @return string
*/
public function filter_wp_redirect( $location, $status ) {
if ( ! $this->should_dispatch() ) {
return $location;
}
$this->before_output();
/** @var array<string, QM_Output_Headers> $outputters */
$outputters = $this->get_outputters( 'headers' );
foreach ( $outputters as $output ) {
$output->output();
}
$this->after_output();
return $location;
}
/**
* @return void
*/
protected function before_output() {
foreach ( (array) glob( $this->qm->plugin_path( 'output/headers/*.php' ) ) as $file ) {
require_once $file;
}
}
/**
* @return bool
*/
public function is_active() {
if ( ! self::user_can_view() ) {
return false;
}
# If the headers have already been sent then we can't do anything about it
if ( headers_sent() ) {
return false;
}
# Don't process if the minimum required actions haven't fired:
if ( is_admin() ) {
if ( ! did_action( 'admin_init' ) ) {
return false;
}
} else {
if ( ! ( did_action( 'wp' ) || did_action( 'login_init' ) ) ) {
return false;
}
}
return true;
}
}
/**
* @param array<string, QM_Dispatcher> $dispatchers
* @param QM_Plugin $qm
* @return array<string, QM_Dispatcher>
*/
function register_qm_dispatcher_redirect( array $dispatchers, QM_Plugin $qm ) {
$dispatchers['redirect'] = new QM_Dispatcher_Redirect( $qm );
return $dispatchers;
}
add_filter( 'qm/dispatchers', 'register_qm_dispatcher_redirect', 10, 2 );

View File

@@ -0,0 +1,168 @@
<?php declare(strict_types = 1);
/**
* Dispatcher for output that gets added to `wp_die()` calls.
*
* @package query-monitor
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
class QM_Dispatcher_WP_Die extends QM_Dispatcher {
/**
* @var string
*/
public $id = 'wp_die';
/**
* @var QM_Backtrace|null
*/
public $trace = null;
public function __construct( QM_Plugin $qm ) {
add_action( 'shutdown', array( $this, 'dispatch' ), 0 );
add_filter( 'wp_die_handler', array( $this, 'filter_wp_die_handler' ) );
parent::__construct( $qm );
}
/**
* @param callable $handler
* @return callable
*/
public function filter_wp_die_handler( $handler ) {
$this->trace = new QM_Backtrace( array(
'ignore_hook' => array(
current_filter() => true,
),
) );
return $handler;
}
/**
* @return void
*/
public function dispatch() {
if ( ! $this->should_dispatch() ) {
return;
}
$switched_locale = self::switch_to_locale( get_user_locale() );
$stack = array();
$filtered_trace = $this->trace->get_filtered_trace();
$component = $this->trace->get_component();
foreach ( $filtered_trace as $i => $item ) {
$stack[] = QM_Output_Html::output_filename( $item['display'], $item['file'], $item['line'] );
}
?>
<style>
#query-monitor {
position: absolute;
margin: 4em 0 1em -2em;
border: 1px solid #ccd0d4;
box-shadow: 0 1px 1px rgb( 0 0 0 / 4% );
background: #fff;
padding-top: 1em;
max-width: 700px;
z-index: -1;
}
#query-monitor h2 {
font-size: 12px;
font-weight: normal;
padding: 7px;
background: #f3f3f3;
margin: 0;
border-top: 1px solid #ddd;
}
#query-monitor ol,
#query-monitor p {
font-size: 12px;
padding: 0;
margin: 1em 2.5em;
}
#query-monitor ol {
padding: 0 0 1em 0;
}
#query-monitor li {
margin: 0 0 0.7em;
list-style: none;
}
#query-monitor .qm-info {
color: #666;
}
#query-monitor a.qm-edit-link svg {
display: none !important;
}
</style>
<?php
echo '<div id="query-monitor">';
echo '<p>';
if ( 'unknown' !== $component->type ) {
$name = ( 'plugin' === $component->type ) ? $component->context : $component->name;
printf(
/* translators: %s: Plugin or theme name */
esc_html__( 'This message was triggered by %s.', 'query-monitor' ),
'<b>' . esc_html( $name ) . '</b>'
);
}
echo '</p>';
echo '<p>' . esc_html__( 'Call stack:', 'query-monitor' ) . '</p>';
echo '<ol>';
echo '<li>' . implode( '</li><li>', $stack ) . '</li>'; // WPCS: XSS ok.
echo '</ol>';
echo '<h2>' . esc_html__( 'Query Monitor', 'query-monitor' ) . '</h2>';
echo '</div>';
if ( $switched_locale ) {
self::restore_previous_locale();
}
}
/**
* @return bool
*/
public function is_active() {
if ( ! $this->trace ) {
return false;
}
if ( ! self::user_can_view() ) {
return false;
}
return true;
}
}
/**
* @param array<string, QM_Dispatcher> $dispatchers
* @param QM_Plugin $qm
* @return array<string, QM_Dispatcher>
*/
function register_qm_dispatcher_wp_die( array $dispatchers, QM_Plugin $qm ) {
$dispatchers['wp_die'] = new QM_Dispatcher_WP_Die( $qm );
return $dispatchers;
}
add_filter( 'qm/dispatchers', 'register_qm_dispatcher_wp_die', 10, 2 );