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,312 @@
<?php
/**
* Thrive Themes - https://thrivethemes.com
*
* @package thrive-dashboard
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Silence is golden
}
class TD_DB_Manager {
/**
* Array of instances for each products
*
* @var TD_DB_Manager[]
*/
protected static $_instances = array();
/**
* Path to migrations folder
*
* @var string path
*/
protected $_migrations_path;
/**
* Version to which this class should run the migrations
*
* @var string
*/
protected $_required_version;
/**
* Current version of DB; stored in wp_option
*
* @var string
*/
protected $_current_version;
/**
* Option name which holds the version of DB
*
* @var string
*/
protected $_option_name;
/**
* Product name to be included in the error message
*
* @var string
*/
protected $_product_name;
/**
* Prefix to be used for tables
*
* @var string
*/
protected $_table_prefix;
/**
* Reset option parameter name
*
* @var string
*/
protected $_reset_option_param = '';
/**
* Holder for DB error
*
* @var string
*/
protected $_last_db_error;
/**
* TD_DB_Manager constructor.
*
* @param string $path
* @param string $option_name
* @param string $required_version
* @param string $product_name
* @param string $table_prefix
* @param string $reset_option_param
*
* @throws Exception
*/
public function __construct( $path, $option_name, $required_version, $product_name = '', $table_prefix = '', $reset_option_param = '' ) {
if ( is_dir( $path ) === false ) {
throw new Exception( 'Path to migrations is invalid' );
}
if ( strpos( $option_name, '_db' ) !== false ) {
$this->_option_name = $option_name;
} else {
throw new Exception( 'Unknown option name' );
}
$this->_migrations_path = trailingslashit( $path );
$this->_required_version = $required_version;
$this->_current_version = $this->_get_current_version();
$this->_product_name = $product_name;
$this->_table_prefix = $table_prefix;
$this->_reset_option_param = $reset_option_param ? $reset_option_param : ( $this->_option_name . '_reset' );
}
protected function _get_current_version( $default = '0.0' ) {
$this->_current_version = get_option( $this->_option_name, $default );
return $this->_current_version;
}
/**
* Reset the wp_option so that all the migrations will run again at next check()
*
* @return bool
*/
protected function _reset() {
$this->_current_version = '0.0';
return delete_option( $this->_option_name );
}
protected function _update( $value ) {
$this->_current_version = $value;
return update_option( $this->_option_name, $value );
}
/**
* Compare the current db version with the required version and
* Runs all the scrips from current version until the required version
*/
public function check() {
if ( is_admin() && ! empty( $_REQUEST[ $this->_reset_option_param ] ) ) {
$this->_reset();
}
if ( version_compare( $this->_current_version, $this->_required_version, '<' ) ) {
$scripts = $this->_get_scripts( $this->_current_version, $this->_required_version );
if ( ! empty( $scripts ) ) {
! defined( 'THRIVE_DB_UPGRADING' ) ? define( 'THRIVE_DB_UPGRADING', true ) : null;
}
/** @var $wpdb wpdb */
global $wpdb;
/**
* We only want to hide the errors not suppress them
* in case we need to log them somewhere
*/
$wpdb->hide_errors();
$has_error = false;
foreach ( $scripts as $file_path ) {
$migration = new TD_DB_Migration( $this->_table_prefix, $file_path );
$has_error = $migration->run() === false;
if ( $has_error ) {
/* ERROR: we don't change the DB version option and notify the user about the last error */
break;
}
}
if ( $has_error ) {
$this->_last_db_error = $wpdb->last_error;
add_action( 'admin_notices', array( $this, 'display_admin_error' ) );
} else {
$this->_update( $this->_required_version );
}
do_action( 'tve_after_db_migration', $this->_option_name );
}
}
/**
* Get all DB update scripts from $from_version to $to_version.
*
* @param string $from_version from version.
* @param string $to_version to version.
*
* @return array
*/
protected function _get_scripts( $from_version, $to_version ) {
$scripts = array();
$dir = new DirectoryIterator( $this->_migrations_path );
foreach ( $dir as $file ) {
/**
* DirectoryIterator
*
* @var $file
*/
if ( $file->isDot() ) {
continue;
}
$script_version = $this->_get_script_version( $file->getFilename() );
if ( empty( $script_version ) ) {
continue;
}
if ( version_compare( $script_version, $from_version, '>' ) && version_compare(
$script_version, $to_version, '<=' ) ) {
$script_key = $this->_generate_script_key( $script_version, $scripts );
$scripts[ $script_key ] = $file->getPathname();
}
}
/**
* Sort the scripts in the correct version order
*/
uksort( $scripts, 'version_compare' );
return $scripts;
}
/**
* Generate a key for script if there is multiple migration file name with same version.
*
* @param string $script_version migration file name's version.
* @param array $scripts list of scripts.
*
* @return string
*/
protected function _generate_script_key( $script_version, $scripts ) {
if ( ! isset( $scripts[ $script_version ] ) ) {
return $script_version;
}
return $script_version . '.0';
}
/**
* Parse the script_ame and returns its version
*
* @param string $script_name in the following format {name}-{[\d+].[\d+]}.php.
*
* @return string
*/
protected function _get_script_version( $script_name ) {
if ( ! preg_match( '/(.+?)-(\d+)\.(\d+)(.\d+)?\.php/', $script_name, $m ) ) {
return false;
}
return $m[2] . '.' . $m[3] . ( ! empty( $m[4] ) ? $m[4] : '' );
}
/**
* Display a WP Notification with last db error
*/
public function display_admin_error() {
if ( ! $this->_last_db_error ) {
return;
}
// @codingStandardsIgnoreStart
echo '<div class="notice notice-error is-dismissible"><p>' .
sprintf(
__( 'There was an error while updating the database tables%s. Detailed error message: %s. If you continue seeing this message, please contact %s', 'thrive-dash' ),
$this->_product_name ? " ({$this->_product_name})" : '',
'<strong>' . $this->_last_db_error . '</strong>',
'<a target="_blank" href="https://thrivethemes.com/forums/">' . __( 'Thrive Themes Support', 'thrive-dash' ) . '</a>'
) .
'</p></div>';
// @codingStandardsIgnoreEnd
}
/**
* Collect all thrive db managers
* Each plugin should hook into the 'thrive_prepare_migrations' hook
*/
public static function collect_migration_managers() {
/**
* Action hook.
* Executed during the WP 'init' hook
*
* @since 2.0.49
*/
try {
do_action( 'thrive_prepare_migrations' );
} catch ( Exception $exception ) {
/* do nothing for now. better safe than sorry. each plugin should catch errors */
}
foreach ( static::$_instances as $instance ) {
$instance->check();
}
}
/**
* @param string $path Path to the migrations folder
* @param string $option_name db wp_options table option name
* @param string $required_version version to check against
* @param string $product_name optional, a string used to display a nice product name to the user in case of errors
* @param string $table_prefix optional, table prefix - can be used inside the migration file to automatically prepend it to table names
* @param string $reset_option_param query parameter name for resetting the option holding the version
*
* @throws Exception
*/
public static function add_manager( $path, $option_name, $required_version, $product_name = '', $table_prefix = '', $reset_option_param = '' ) {
static::$_instances [] = new static( $path, $option_name, $required_version, $product_name, $table_prefix, $reset_option_param );
}
}

View File

@@ -0,0 +1,258 @@
<?php
/**
* Thrive Themes - https://thrivethemes.com
*
* @package thrive-dashboard
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Silence is golden
}
class TD_DB_Migration {
/**
* @var array
*/
protected $_queries = array();
/**
* @var string
*/
protected $_table_prefix;
/**
* @var wpdb
*/
protected $_wpdb;
/**
* Full path to the migration file
*
* @var string
*/
protected $_file_path;
/**
* TD_DB_Migration constructor.
*
* Each migration works with prefixed tables
*
* @param string $table_prefix plugin's table prefix
* @param string $file_path full absolute path to the migration file
*/
public function __construct( $table_prefix, $file_path = '' ) {
global $wpdb;
$this->_wpdb = $wpdb;
$this->_file_path = $file_path;
$this->_table_prefix = $this->_wpdb->prefix . ( empty( $table_prefix ) ? '' : rtrim( $table_prefix, '_ ' ) . '_' );
}
/**
* Based on the prefix sent on initialization returns the name of the table
* with {wp_prefix}_{plugin_prefix}_{name}
*
* @param $name
*
* @return string
*/
public function get_table_name( $name ) {
$name = preg_replace( '#^' . $this->_table_prefix . '#', '', $name );
return $this->_table_prefix . $name;
}
/**
* Adds and sql query to the queue for later execution
*
* @param string $sql
* @param bool $collate whether or not to add COLLATE specification to the query
*
* @return TD_DB_Migration allows fluent interface
*/
public function add( $sql, $collate = true ) {
return $this->add_query( trim( $sql ) . ( $collate ? ' ' . $this->_wpdb->get_charset_collate() : '' ) );
}
/**
* Adds a raw query to the queue
*
* @param string $query
*
* @return TD_DB_Migration allows fluent interface
*/
public function add_query( $query ) {
$query = preg_replace_callback( '#\{(.+?)\}#', array( $this, 'preg_replace_table_name' ), $query );
$this->_queries [] = $query;
return $this;
}
/**
* Adds a CREATE TABLE query to the queue
*
* @param string $table_name
* @param string $spec full table spec, excluding brackets
* @param bool $add_collate_spec whether to add collate specification
*
* @return TD_DB_Migration allows fluent interface$this
*/
public function create_table( $table_name, $spec, $add_collate_spec = false ) {
$table_name = $this->_prepare_table_name( $table_name );
$this->add_query( "CREATE TABLE IF NOT EXISTS `{$table_name}` ({$spec})" . ( $add_collate_spec ? ( ' ' . $this->_wpdb->get_charset_collate() ) : '' ) );
return $this;
}
/**
* Adds or modifies a column from a table. First, it checks if the column exists
*
* @param string $table_name
* @param string $column_name
* @param string $spec
*
* @return TD_DB_Migration allows fluent interface
*/
public function add_or_modify_column( $table_name, $column_name, $spec ) {
$table_name = $this->_prepare_table_name( $table_name );
$sql = "ALTER TABLE `{$table_name}` ";
$exists = $this->column_exists( $table_name, $column_name ) ? "CHANGE `{$column_name}` " : 'ADD COLUMN ';
$this->add_query( $sql . $exists . "`{$column_name}` {$spec}" );
return $this;
}
/**
* Drops column from table if exists
*
* @param $table_name
* @param $column_name
*
* @return TD_DB_Migration allows fluent interface
*/
public function drop_column( $table_name, $column_name ) {
if ( $this->column_exists( $table_name, $column_name ) ) {
$table_name = $this->_prepare_table_name( $table_name );
$this->add_query( "ALTER TABLE `{$table_name}` DROP COLUMN `{$column_name}`;" );
}
return $this;
}
/**
* Checks if a column exists
*
* @param string $table_name
* @param string $column_name
*
* @return bool
*/
public function column_exists( $table_name, $column_name ) {
$results = $this->_wpdb->get_results( "SHOW FULL COLUMNS FROM `{$this->_prepare_table_name($table_name)}` LIKE '$column_name'" );
return ! empty( $results );
}
/**
* Creates an index on table
*
* @param string $index_name
* @param string $table_name
* @param array|string $columns
*
* @return TD_DB_Migration allows fluent interface
*/
public function create_index( $index_name, $table_name, $columns ) {
$table_name = $this->_prepare_table_name( $table_name );
if ( ! is_array( $columns ) ) {
$columns = array( $columns );
}
$str_columns = implode( ',', $columns );
if ( false === $this->index_exists( $index_name, $table_name ) ) {
$this->add_query( "CREATE INDEX `{$index_name}` ON `{$table_name}` ({$str_columns})" );
}
return $this;
}
/**
* Checks if an index with name exists on the table
*
* @param string $index_name
* @param string $table_name
*
* @return bool
*/
public function index_exists( $index_name, $table_name ) {
$table_name = $this->_prepare_table_name( $table_name );
$index = $this->_wpdb->get_row( "SHOW INDEX FROM `{$table_name}` WHERE Key_name = '{$index_name}'" );
return (bool) $index;
}
/**
* Loops through the queries and executes them
*
* @return bool
*/
public function run() {
$success = true;
if ( defined( 'THRIVE_DB_UPGRADING' ) === false ) {
$this->_wpdb->last_error = 'Cannot run migrations outside of Database Manager';
$success = false;
}
if ( $this->_file_path ) {
$result = require_once $this->_file_path;
/* backwards compat support */
if ( $result instanceof TD_DB_Migration ) {
return $result->run();
}
}
foreach ( $this->_queries as $query ) {
if ( $success && $this->_wpdb->query( $query ) === false ) {
$success = false;
break;
}
}
return $success;
}
/**
* Prepares a table name for using it in queries
*
* @param string $table_name
*
* @return mixed|string
*/
protected function _prepare_table_name( $table_name ) {
return $this->get_table_name( str_replace( '`', '', $table_name ) );
}
/**
* Replaces {table_name} instances with prefixed_table_name
*
* @param array $matches
*
* @return string
*/
protected function preg_replace_table_name( $matches ) {
return $this->get_table_name( $matches[1] );
}
}

View File

@@ -0,0 +1,2 @@
<?php
// silence is golden

View File

@@ -0,0 +1,31 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit( 1 );
}
/**
* The version is 1.0.3 instead of 1.0.2 because a fix was applied directly to the 1.0.2 file (this), making it 1.0.3.
*/
/** @var TD_DB_Migration $installer */
$installer = $this;
$installer->create_table( 'thrive_reporting_logs', '
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`event_type` VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
`created` DATETIME NULL DEFAULT NULL,
`item_id` BIGINT(20) NULL DEFAULT 0,
`user_id` BIGINT(20) NULL DEFAULT 0,
`post_id` BIGINT(20) NULL DEFAULT 0,
`int_field_1` BIGINT(20) NULL DEFAULT NULL,
`int_field_2` BIGINT(20) NULL DEFAULT NULL,
`float_field` DOUBLE NULL DEFAULT NULL,
`varchar_field_1` VARCHAR(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`varchar_field_2` VARCHAR(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`text_field_1` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX (`event_type`),
INDEX (`user_id`),
INDEX (`item_id`),
INDEX (`created`),
INDEX (`post_id`)'
);

View File

@@ -0,0 +1,13 @@
<?php
/**
* Thrive Themes - https://thrivethemes.com
*
* @package thrive-dashboard
*/
/** @var $this TD_DB_Migration */
if ( ! defined( 'ABSPATH' ) ) {
exit; // Silence is golden!
}
$this->add_or_modify_column( 'td_fields', 'identifier', 'VARCHAR(32) NULL DEFAULT NULL AFTER `id`' );

View File

@@ -0,0 +1,32 @@
<?php
/**
* Thrive Themes - https://thrivethemes.com
*
* @package thrive-dashboard
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Silence is golden
}
global $wpdb;
/** @var $this TD_DB_Migration */
$this->create_table( 'td_groups', '
`id` INT( 11 ) AUTO_INCREMENT,
`name` TEXT NOT NULL,
`is_default` INT NOT NULL DEFAULT 0,
`created_at` DATETIME NULL,
`updated_at` DATETIME NULL,
PRIMARY KEY( `id` )' );
$this->create_table( 'td_fields', '
`id` INT( 11 ) AUTO_INCREMENT,
`group_id` INT( 11 ) NOT NULL,
`name` TEXT NOT NULL,
`type` INT NOT NULL,
`data` TEXT NULL,
`is_default` INT NOT NULL DEFAULT 0,
`created_at` DATETIME NULL,
`updated_at` DATETIME NULL,
PRIMARY KEY( `id` )' );