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,66 @@
<?php
/**
* The class is responsible to redirect ads.txt to centralized location.
*
* @package AdvancedAds
* @author Advanced Ads <info@wpadvancedads.com>
* @since 1.48.0
*/
namespace AdvancedAds\Modules\OneClick\AdsTxt;
use AdvancedAds\Utilities\WordPress;
use AdvancedAds\Framework\Interfaces\Integration_Interface;
use AdvancedAds\Framework\Utilities\Params;
use AdvancedAds\Framework\Utilities\Str;
defined( 'ABSPATH' ) || exit;
/**
* AdsTxt.
*/
class AdsTxt implements Integration_Interface {
/**
* Hook into WordPress
*
* @return void
*/
public function hooks(): void {
remove_action( 'advanced-ads-plugin-loaded', 'advanced_ads_ads_txt_init' );
add_action( 'template_redirect', [ $this, 'handle_redirect' ] );
add_filter( 'allowed_redirect_hosts', [ $this, 'allowed_redirect_hosts' ] );
}
/**
* Handle redirect
*
* @return void
*/
public function handle_redirect(): void {
if (
'ads-txt' !== get_query_var( 'name' ) ||
Str::contains( Params::server( 'REQUEST_URI' ), 'ads.txt' )
) {
return;
}
$redirect = sprintf( 'https://adstxt.pubguru.net/pg/%s/ads.txt', WordPress::get_site_domain() );
wp_safe_redirect( $redirect, 301 );
exit;
}
/**
* Allowed redirect hosts
*
* @param array $hosts Array to hold allowed hosts.
*
* @return array
*/
public function allowed_redirect_hosts( $hosts ): array {
$hosts[] = 'adstxt.pubguru.net';
return $hosts;
}
}

View File

@@ -0,0 +1,136 @@
<?php
/**
* The class is responsible to detect ads.txt.
*
* @package AdvancedAds
* @author Advanced Ads <info@wpadvancedads.com>
* @since 1.48.0
*/
namespace AdvancedAds\Modules\OneClick\AdsTxt;
use AdvancedAds\Modules\OneClick\Admin\Admin;
use AdvancedAds\Framework\Interfaces\Integration_Interface;
use AdvancedAds\Utilities\Conditional;
defined( 'ABSPATH' ) || exit;
/**
* Detector.
*/
class Detector implements Integration_Interface {
/**
* Hook into WordPress
*
* @return void
*/
public function hooks(): void {
add_action( 'current_screen', [ $this, 'conditional_loading' ] );
}
/**
* Detect ads.txt physical file
*
* @return void
*/
public function conditional_loading(): void {
if ( ! Conditional::is_screen_advanced_ads() ) {
return;
}
if ( $this->detect_files() ) {
add_action( 'all_admin_notices', [ $this, 'show_notice' ] );
}
}
/**
* Detect file exists
*
* @param string $file file name.
*
* @return bool
*/
public function detect_files( $file = 'ads.txt' ): bool {
$wp_filesystem = $this->get_filesystem();
if ( null === $wp_filesystem ) {
return false;
}
return $wp_filesystem->exists( ABSPATH . '/' . $file );
}
/**
* Backup file
*
* @return bool
*/
public function backup_file(): bool {
$source = ABSPATH . '/ads.txt';
$destination = $source . '.bak';
return $this->move_file( $source, $destination );
}
/**
* Revert file
*
* @return bool
*/
public function revert_file(): bool {
$source = ABSPATH . '/ads.txt.bak';
$destination = ABSPATH . 'ads.txt';
return $this->move_file( $source, $destination );
}
/**
* Show notice that physical file exists
*
* @return void
*/
public function show_notice(): void {
?>
<div class="notice notice-error flex items-center p-4">
<div>
<strong><?php esc_html_e( 'File alert!', 'advanced-ads' ); ?></strong> <?php esc_html_e( 'Physical ads.txt found. In order to use PubGuru service you need to delete it or back it up.', 'advanced-ads' ); ?>
</div>
<button class="!ml-auto button button-primary js-btn-backup-adstxt" data-text="<?php esc_attr_e( 'Backup the File', 'advanced-ads' ); ?>" data-loading="<?php esc_attr_e( 'Backing Up', 'advanced-ads' ); ?>" data-done="<?php esc_attr_e( 'Backed Up', 'advanced-ads' ); ?>" data-security="<?php echo wp_create_nonce( 'pubguru_oneclick_security' ); // phpcs:ignore ?>">
<?php esc_html_e( 'Backup the File', 'advanced-ads' ); ?>
</button>
</div>
<?php
}
/**
* Instantiates the WordPress filesystem for use
*
* @return object
*/
private function get_filesystem() {
global $wp_filesystem;
if ( empty( $wp_filesystem ) ) {
require_once ABSPATH . '/wp-admin/includes/file.php';
WP_Filesystem();
}
return $wp_filesystem;
}
/**
* Handle file operations (backup or revert)
*
* @param string $source Source file path.
* @param string $destination Destination file path.
*
* @return bool
*/
private function move_file( string $source, string $destination ): bool {
$wp_filesystem = $this->get_filesystem();
if ( null === $wp_filesystem || ! $wp_filesystem->is_writable( $source ) ) {
return false;
}
return $wp_filesystem->move( $source, $destination );
}
}

View File

@@ -0,0 +1,107 @@
<?php
/**
* The class is responsible to inject header bidding tags.
*
* @package AdvancedAds
* @author Advanced Ads <info@wpadvancedads.com>
* @since 1.48.0
*/
namespace AdvancedAds\Modules\OneClick;
use AdvancedAds\Framework\Utilities\Str;
use AdvancedAds\Framework\Interfaces\Integration_Interface;
defined( 'ABSPATH' ) || exit;
/**
* Header bidding tags.
*/
class Header_Bidding implements Integration_Interface {
/**
* Hook into WordPress
*
* @return void
*/
public function hooks(): void {
add_filter( 'pubguru_page_script_tag', [ $this, 'remove_tags' ] );
add_filter( 'pubguru_current_page', [ $this, 'add_tags' ] );
}
/**
* Add TrafficCop tags
*
* @param string $page Page html.
*
* @return string
*/
public function add_tags( $page ): string {
$page = $this->add_script_tag( $page );
return $page;
}
/**
* Remove script tag
*
* @param string $script Scrip tag.
*
* @return string
*/
public function remove_tags( $script ): string {
if ( Str::contains( '/gpt.js', $script ) ) {
$script = '';
}
if ( Str::contains( '//m2d.m2.ai/', $script ) || Str::contains( '//c.pubguru.net/', $script ) ) {
$script = '';
}
if ( Str::contains( 'window.pg.atq = window.pg.atq || [];', $script ) ) {
$script = '';
}
return $script;
}
/**
* Guard the page from getting JS errors
*
* @param string $page Page html.
*
* @return string
*/
private function add_script_tag( $page ): string {
$name = Helpers::get_config_file();
$at_body = Options::module( 'header_bidding_at_body' );
if ( $name ) {
$script = [];
if ( ! $at_body ) {
$script[] = '<head>';
}
$script[] = '<script src="https://securepubads.g.doubleclick.net/tag/js/gpt.js" async></script>'; // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
$script[] = '<script type="text/javascript">window.googletag=window.googletag||{};window.googletag.cmd=window.googletag.cmd||[];';
$script[] = 'window.googletag.cmd.push(function(){window.__onpageGptEmbed=(new Date()).getTime()})</script>';
$script[] = sprintf( '<script src="//c.pubguru.net/%s" async> </script>', $name ); // phpcs:ignore
if ( Options::module( 'traffic_cop' ) && Helpers::has_traffic_cop() ) {
$script[] = '<script>window.pg = window.pg || {};window.pg.atq = window.pg.atq || [];</script>';
}
if ( $at_body ) {
$page = $page . join( "\n", $script );
} else {
$page = str_replace(
'<head>',
join( "\n", $script ),
$page
);
}
}
return $page;
}
}

View File

@@ -0,0 +1,112 @@
<?php
/**
* The class is responsible to convert ad tags to pubguru tag.
*
* @package AdvancedAds
* @author Advanced Ads <info@wpadvancedads.com>
* @since 1.48.0
*/
namespace AdvancedAds\Modules\OneClick;
use AdvancedAds\Modules\OneClick\Helpers;
use AdvancedAds\Framework\Interfaces\Integration_Interface;
defined( 'ABSPATH' ) || exit;
/**
* Ad tags conversion.
*/
class Tags_Conversion implements Integration_Interface {
/**
* Hook into WordPress
*
* @return void
*/
public function hooks(): void {
add_filter( 'pubguru_current_page', [ $this, 'convert_tags' ], 20 );
}
/**
* Convert tags
*
* @param string $page Page html.
*
* @return string
*/
public function convert_tags( $page ): string {
$page = $this->convert_ad_by_config( $page );
return $page;
}
/**
* Convert ad divs to pubguru tags
*
* @param string $page Page html.
*
* @return string
*/
private function convert_ad_by_config( $page ): string {
$slots = $this->get_ad_slots();
if ( false === $slots ) {
return $page;
}
$divs = $this->get_ad_divs( $page, $slots );
foreach ( $divs as $div ) {
$replace = str_replace(
[ '<div', '</div>' ],
[ '<pubguru', '</pubguru>' ],
$div
);
$page = str_replace( $div, $replace, $page );
}
return $page;
}
/**
* Get ad divs only
*
* @param string $page Page html.
* @param array $slots Ad slots ids.
*
* @return array
*/
private function get_ad_divs( $page, $slots ): array {
$matches = [];
$slot_ids = [];
foreach ( $slots as $slot ) {
$slot_ids[] = preg_quote( $slot, '/' );
}
$slot_ids = join( '|', $slot_ids );
preg_match_all( '/<div id="(' . $slot_ids . ')"[^>]*>(.*?)<\/div>/mis', $page, $matches );
return isset( $matches[0] ) ? $matches[0] : [];
}
/**
* Get slots from config
*
* @return bool|array
*/
private function get_ad_slots() {
$ads = Helpers::get_ads_from_config();
if ( false === $ads ) {
return false;
}
$slots = [];
foreach ( $ads as $ad ) {
$slots[] = $ad['slot'];
}
return $slots;
}
}

View File

@@ -0,0 +1,49 @@
<?php
/**
* The class is responsible to wrap the google tags into traffic cop wrappers.
*
* @package AdvancedAds
* @author Advanced Ads <info@wpadvancedads.com>
* @since 1.48.0
*/
namespace AdvancedAds\Modules\OneClick;
use AdvancedAds\Framework\Utilities\Str;
use AdvancedAds\Framework\Interfaces\Integration_Interface;
defined( 'ABSPATH' ) || exit;
/**
* Traffic Cop.
*/
class Traffic_Cop implements Integration_Interface {
/**
* Hook into WordPress
*
* @return void
*/
public function hooks(): void {
add_filter( 'pubguru_page_script_tag', [ $this, 'modify_script_tag' ], 30 );
}
/**
* Modify scrip if google tag found
*
* @param mixed $content Scrip tag.
*
* @return bool|string
*/
public function modify_script_tag( $content ) {
// Early bail!!
if ( ! Str::contains( 'googletag.display', $content ) ) {
return false;
}
$content = str_replace( '<script>', '<script>pg.atq.push(function() {', $content );
$content = str_replace( '</script>', '});</script>', $content );
return $content;
}
}

View File

@@ -0,0 +1,180 @@
<?php
/**
* The class is responsible for the one-click module workflow.
*
* @package AdvancedAds
* @author Advanced Ads <info@wpadvancedads.com>
* @since 1.48.0
*/
namespace AdvancedAds\Modules\OneClick;
use AdvancedAds\Modules\OneClick\Helpers;
use AdvancedAds\Modules\OneClick\Options;
use AdvancedAds\Framework\Utilities\Params;
use AdvancedAds\Modules\OneClick\Traffic_Cop;
use AdvancedAds\Modules\OneClick\AdsTxt\AdsTxt;
use AdvancedAds\Modules\OneClick\AdsTxt\Detector;
use AdvancedAds\Framework\Interfaces\Integration_Interface;
defined( 'ABSPATH' ) || exit;
/**
* Workflow.
*/
class Workflow implements Integration_Interface {
/**
* Flush rules option key.
*
* @var string
*/
const FLUSH_KEY = 'pubguru_flush_rewrite_rules';
/**
* Hook into WordPress
*
* @return void
*/
public function hooks(): void {
add_action( 'init', [ $this, 'flush_rewrite_rules' ], 999 );
add_filter( 'pubguru_module_status_changed', [ $this, 'module_status_changed' ], 10, 3 );
if ( false !== Options::pubguru_config() && ! is_admin() ) {
add_action( 'wp', [ $this, 'init' ] );
if ( Options::module( 'ads_txt' ) ) {
( new AdsTxt() )->hooks();
}
if ( ! function_exists( 'wp_advads_pro' ) ) {
add_filter( 'advanced-ads-placement-content-offsets', [ $this, 'placement_content_offsets' ], 10, 3 );
}
}
if ( Options::module( 'ads_txt' ) ) {
if ( is_admin() ) {
( new Detector() )->hooks();
}
remove_action( 'advanced-ads-plugin-loaded', 'advanced_ads_ads_txt_init' );
}
}
/**
* Init workflow
*
* @return void
*/
public function init(): void {
// Early bail!!
$is_debugging = Params::get( 'aa-debug', false, FILTER_VALIDATE_BOOLEAN );
if ( ! $is_debugging && Helpers::is_ad_disabled() ) {
return;
}
Page_Parser::get_instance();
if ( $is_debugging || Options::module( 'header_bidding' ) ) {
$config = Options::pubguru_config();
$config['method'] = $config['method'] ?? 'page';
if ( 'page' === $config['method'] && isset( $config['page'] ) && is_page( absint( $config['page'] ) ) ) {
( new Header_Bidding() )->hooks();
}
if ( 'final' === $config['method'] ) {
( new Header_Bidding() )->hooks();
}
}
if ( $is_debugging || Options::module( 'tag_conversion' ) ) {
( new Tags_Conversion() )->hooks();
}
if ( Options::module( 'traffic_cop' ) && Helpers::has_traffic_cop() ) {
if ( ! Options::module( 'header_bidding' ) ) {
( new Header_Bidding() )->hooks();
}
( new Traffic_Cop() )->hooks();
}
}
/**
* Handle module status change
*
* @param array $data Data to send back to ajax request.
* @param string $module Module name.
* @param bool $status Module status.
*
* @return array
*/
public function module_status_changed( $data, $module, $status ): array {
if ( 'ads_txt' === $module ) {
$detector = new Detector();
if ( $status && $detector->detect_files() ) {
$data['notice'] = join(
'',
[
'<strong>' . esc_html__( 'File alert!', 'advanced-ads' ) . '</strong>',
' ',
esc_html__( 'Physical ads.txt found. In order to use PubGuru service you need to delete it or back it up.', 'advanced-ads' ),
]
);
$data['action'] = esc_html__( 'Backup the File', 'advanced-ads' );
}
if ( ! $status && $detector->detect_files( 'ads.txt.bak' ) ) {
$detector->revert_file();
}
update_option( self::FLUSH_KEY, 1 );
}
return $data;
}
/**
* Flush the rewrite rules once if the pubguru_flush_rewrite_rules option is set
*
* @return void
*/
public function flush_rewrite_rules(): void {
if ( get_option( self::FLUSH_KEY ) ) {
flush_rewrite_rules();
delete_option( self::FLUSH_KEY );
}
}
/**
* Get offsets for Content placement.
*
* @param array $offsets Existing Offsets.
* @param array $options Injection options.
* @param array $placement_opts Placement options.
*
* @return array $offsets New offsets.
*/
public function placement_content_offsets( $offsets, $options, $placement_opts ) {
if ( ! isset( $options['paragraph_count'] ) ) {
return $offsets;
}
// "Content" placement, repeat position.
if (
( ! empty( $placement_opts['repeat'] ) || ! empty( $options['repeat'] ) ) &&
isset( $options['paragraph_id'] ) &&
isset( $options['paragraph_select_from_bottom'] )
) {
$offsets = [];
for ( $i = $options['paragraph_id'] - 1; $i < $options['paragraph_count']; $i++ ) {
// Select every X number.
if ( 0 === ( $i + 1 ) % $options['paragraph_id'] ) {
$offsets[] = $options['paragraph_select_from_bottom'] ? $options['paragraph_count'] - 1 - $i : $i;
}
}
}
return $offsets;
}
}