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,15 @@
<?php
namespace WPDRMS\ASP\Frontend\Filters;
if (!defined('ABSPATH')) die('-1');
class Button extends Filter {
protected $default = array(
'label' => '',
'type' => '',
'container_class' => '',
'button_class' => ''
);
protected $key = 'type';
protected $type = 'button';
}

View File

@@ -0,0 +1,22 @@
<?php
namespace WPDRMS\ASP\Frontend\Filters;
if (!defined('ABSPATH')) die('-1');
class ContentType extends Filter {
public $data = array(
"field" => "",
"required" => false,
"invalid_input_text" => "Please select one!"
);
protected $default = array(
'label' => '',
'selected' => false,
'value' => '',
'level' => 0,
'default' => false
);
protected $key = 'value';
protected $type = 'content_type';
}

View File

@@ -0,0 +1,116 @@
<?php
namespace WPDRMS\ASP\Frontend\Filters;
if (!defined('ABSPATH')) die('-1');
class CustomField extends Filter {
public $data = array(
"field" => "",
"source" => "postmeta",
"type" => "checkboxes",
"required" => false,
"invalid_input_text" => "Please select one!",
"logic" => 'and',
/*
* Apply the AND logic as if fields are separately stored with the same name ex.:
* field_name => value1,
* field_name => value2
* .. instead of field_name => 'value1, value2 etc..'
*/
"logic_and_separate_custom_fields" => false,
"operator" => '=',
"acf_type" => false
);
protected $default = array(
'label' => '',
'selected' => false,
'value' => '',
'level' => 0,
'default' => false,
'parent' => 0,
'option_group' => false
/**
* Other possible keys here, depending on the type:
* 'slider_from', 'slider_to', 'placeholder'
*/
);
protected $special_args = array(
"slider" => array(
'slider_prefix' => '-,',
'slider_suffix' => '.',
'slider_step' => 1,
'slider_from' => 1,
'slider_to' => 1000,
'slider_decimals' => 0,
'slider_t_separator' => ' ',
'operator' => 'let'
),
"number_range" => array(
'range_step' => 1,
'range_from' => 1,
'placeholder1' => '',
'placeholder2' => '',
'range_to' => 1000,
'range_t_separator' => ' '
),
"range" => array(
'range_prefix' => '-,',
'range_suffix' => '.',
'range_step' => 1,
'range_from' => 1,
'range_to' => 1000,
'range_decimals' => 0,
'range_t_separator' => ' '
),
"datepicker" => array(
'placeholder' => '',
'date_format' => 'dd/mm/yy',
'date_store_format' => 'datetime' // datetime, acf, timestamp
),
"dropdown" => array(
'placeholder' => '',
'multiple' => false
),
"dropdownsearch" => array(
'placeholder' => ''
),
"multisearch" => array(
'placeholder' => ''
)
);
protected $key = 'value';
protected $type = 'custom_field';
public function __construct($label = '', $display_mode = 'checkboxes', $data = array(), $position = -1) {
parent::__construct($label, $display_mode, $data, $position);
if ( isset($this->special_args[$this->display_mode]) ) {
$this->data = array_merge($this->data, $this->special_args[$this->display_mode], $data);
} else {
$this->data = array_merge($this->data, $data);
}
if ( function_exists('get_field') ) {
$this->data['acf_type'] = asp_acf_get_field_type($this->data['field']);
}
}
public function field():string {
return $this->data['field'];
}
public function getUniqueFieldName( $to_display = false ) {
if ( isset($this->data['field']) ) {
$field = $this->data['field'];
if ( $to_display ) {
$field = str_replace(
array('[', ']'),
array('!_brktl_!', '!_brktr_!'),
$field
);
}
return $field . '__' . $this->id;
} else {
return $this->id;
}
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace WPDRMS\ASP\Frontend\Filters;
if (!defined('ABSPATH')) die('-1');
class Date extends Filter {
public $data = array();
protected $default = array(
'label' => '',
'value' => '',
'name' => '',
'format' => 0,
'default' => false,
'placeholder' => ''
);
protected $key = 'value';
protected $type = 'date';
}

View File

@@ -0,0 +1,238 @@
<?php
namespace WPDRMS\ASP\Frontend\Filters;
if (!defined('ABSPATH')) die('-1');
class Filter {
private static $last_position = 0;
private static $last_id = 0;
public $label = '';
public $display_mode = 'checkboxes';
public $data = array();
public $position = 0;
public $id = 0;
public $is_api = true; // Filter added via API, set to false for parsers
protected $values = array();
// Default value for the $values array
protected $default = array(
'label' => '',
'selected' => false,
'id' => 0, // Can be numeric, as well as a field name etc..
'level' => 0,
'default' => false
);
protected $key = 'id'; // The main distinctive field
protected $type = '';
protected $option_path = array(
'taxonomy' => 'termset',
'custom_field' => 'aspf'
);
function __construct($label = '', $display_mode = 'checkboxes', $data = array(), $position = -1) {
$this->label = $label;
$this->display_mode = $display_mode;
$data = is_array($data) ? $data : (array)$data;
$this->data = array_merge($this->data, $data);
$this->id = ++self::$last_id;
if ( isset($data['is_api']) )
$this->is_api = $data['is_api'];
if ( $position > -1 ) {
$this->position = $position;
if ( $position > self::$last_position ) {
self::$last_position = $position;
}
} else {
$this->position = self::$last_position;
++self::$last_position;
}
}
public function isEmpty(): bool {
return empty($this->values);
}
public function add($filter, $position = false) {
$new = (object)array_merge($this->default, $filter);
if ( $position === false ) {
$this->values[] = $new;
} else {
$position = intval($position);
array_splice( $this->values, $position, 0, array($new) );
}
return $new;
}
public function get($ids = array()) {
$key = $this->key;
if ( is_array($ids) ) {
if (empty($ids)) {
return $this->values;
} else {
$ret = array();
foreach ($this->values as $v) {
if (in_array($v->{$key}, $ids)) {
$ret[] = $v;
}
}
return $ret;
}
} else {
foreach ($this->values as $v) {
if ($v->{$key} == $ids) {
return $v;
}
}
}
return array();
}
public function remove($ids = array(), $by_id = false) {
if ( $by_id ) {
$i = is_array($ids) ? $ids : array($ids);
foreach ( $i as $ii ) {
if (isset($this->values[$ii])) {
unset($this->values[$ii]);
}
}
} else {
$key = $this->key;
if ( is_array($ids) ) {
if (empty($ids)) {
$this->values = array();
} else {
foreach ($this->values as $k => $v) {
if (in_array($v->{$key}, $ids)) {
unset($this->values[$k]);
}
}
}
} else {
foreach ($this->values as $k => $v) {
if ($v->{$key} == $ids) {
unset($this->values[$k]);
}
}
}
}
}
public function attr($ids = array(), $att = '', $val = '', $by_id = false) {
if ( $by_id ) {
$i = is_array($ids) ? $ids : array($ids);
foreach ( $i as $ii ) {
if ( isset($this->values[$ii]) ) {
$this->values[$ii]->{$att} = $val;
}
}
} else {
$key = $this->key;
if ( is_array($ids) ) {
if (empty($ids)) {
foreach ($this->values as $k => $v) {
$this->values[$k]->{$att} = $val;
}
} else {
foreach ($this->values as $k => $v) {
if (in_array($v->{$key}, $ids)) {
$this->values[$k]->{$att} = $val;
}
}
}
} else {
foreach ($this->values as $k => $v) {
if ($v->{$key} == $ids) {
$this->values[$k]->{$att} = $val;
}
}
}
}
}
public function select($ids = array(), $unselect = false) {
if ($unselect) {
$this->unselect();
}
$this->attr($ids, 'selected', true);
}
public function unselect($ids = array(), $select = false) {
if ($select) {
$this->select();
}
$this->attr($ids, 'selected', false);
}
/** @noinspection PhpUnused */
public function selectByOptions($options ) {
if ( $this->is_api && $this->type != '' && isset($this->option_path[$this->type], $options['_fo']) ) {
$path = $this->option_path[$this->type];
$key = $this->key;
$o = $options['_fo'];
foreach( $this->values as &$value ) {
if ( $this->type == 'taxonomy' ) {
if ( isset($o[$path], $o[$path][$value->taxonomy]) ) {
$posted = $o[$path][$value->taxonomy];
if ( is_array($posted) ) {
$value->selected = in_array($value->{$key}, $posted);
} else {
$value->selected = $value->{$key} == $posted;
}
} else {
$value->selected = false;
}
} else if ( $this->type == 'custom_field' ) {
if ( method_exists($this, 'getUniqueFieldName') ) {
$unique_field_name = $this->getUniqueFieldName();
if ( isset($o[$path], $o[$path][$unique_field_name]) ) {
$posted = $o[$path][$unique_field_name];
if ( is_array($posted) ) {
if ( !is_array($value->{$key}) ) {
$value->selected = in_array($value->{$key} . '', $posted);
} else {
$value->value = array_values($posted);
}
} else {
$value->selected = $value->{$key} == $posted;
if ( $this->display_mode == 'datepicker' && isset($o[$path][$unique_field_name]) ) {
$value->value = $o[$path][$unique_field_name];
} else if ( in_array($this->display_mode, array('hidden', 'text', 'slider')) ) {
$value->value = $posted;
}
}
} else {
$value->selected = false;
}
}
}
}
}
}
public function type(): string {
return $this->type;
}
public function field(): string {
return $this->type();
}
public static function getLastId(): int {
return self::$last_id;
}
/** @noinspection PhpUnused */
public static function getLastPosition() {
return self::$last_position;
}
public static function reset() {
self::$last_id = 0;
self::$last_position = 0;
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace WPDRMS\ASP\Frontend\Filters;
if (!defined('ABSPATH')) die('-1');
class Generic extends Filter {
public $data = array(
"field" => ""
);
protected $default = array(
'label' => '',
'selected' => false,
'value' => '',
'level' => 0,
'default' => false
);
protected $key = 'value';
protected $type = 'generic';
}

View File

@@ -0,0 +1,12 @@
<?php
namespace WPDRMS\ASP\Frontend\Filters;
if (!defined('ABSPATH')) die('-1');
class PostTags extends TaxonomyTerm {
protected $type = 'post_tags';
public function field(): string {
return 'post_tag';
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace WPDRMS\ASP\Frontend\Filters;
if (!defined('ABSPATH')) die('-1');
class PostType extends Filter {
public $data = array(
'required' => false,
'invalid_input_text' => 'This is required!'
);
protected $default = array(
'label' => '',
'selected' => false,
'value' => '',
'level' => 0,
'default' => false
);
protected $key = 'value';
protected $type = 'post_type';
}

View File

@@ -0,0 +1,47 @@
<?php
namespace WPDRMS\ASP\Frontend\Filters;
if (!defined('ABSPATH')) die('-1');
class TaxonomyTerm extends Filter {
public $data = array(
"type" => "checkboxes",
"required" => false,
"invalid_input_text" => "Please select one!",
"default" => "checked",
"placeholder" => "",
"taxonomy" => "category",
"allow_empty" => '', // true or false, or '' for inherit
"logic" => '' // and, or, andex or '' for inherit
);
protected $default = array(
'label' => '',
'selected' => false,
'id' => 0,
'level' => 0,
'default' => false,
'parent' => 0,
'taxonomy' => 'category'
);
protected $type = 'taxonomy';
public function field(): string {
return $this->data['taxonomy'];
}
public function isMixed(): bool {
$taxonomies = array();
foreach ( $this->values as $value ) {
if ( $value->id != 0 && isset($value->taxonomy) ) {
$taxonomies[] = $value->taxonomy;
$taxonomies = array_unique($taxonomies);
if (count($taxonomies) > 1)
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,208 @@
<?php /** @noinspection PhpMissingParamTypeInspection */
/** @noinspection PhpMissingReturnTypeInspection */
namespace WPDRMS\ASP\Frontend;
use WPDRMS\ASP\Frontend\Filters\Filter;
use WPDRMS\ASP\Patterns\SingletonTrait;
if ( !defined('ABSPATH') ) die('-1');
class FiltersManager {
use SingletonTrait;
const NAMESPACE = "WPDRMS\\ASP\\Frontend\\Filters\\";
/**
* Filters array
*
* @var array
*/
private $filters = array();
/**
* The current search ID
*
* @var int
*/
private $search_id = 0;
/**
* Types to class names array
*
* @var array
*/
private $classes = array(
'generic' => 'Generic',
'content_type' => 'ContentType',
'post_type' => 'PostType',
'taxonomy' => 'TaxonomyTerm',
'post_tags' => 'PostTags',
'custom_field' => 'CustomField',
'date' => 'Date',
'button' => 'Button'
);
/**
* Sets the currenty search ID
*
* @param $id - search ID
*/
public function setSearchId($id) {
$this->search_id = $id + 0;
}
/**
* Creates and returns a new filter object, depending on the type
*
* @param $type - Type of the filter (generic, content_type, taxonomy, custom_field, date, search, reset)
* @param $label
* @param $display_mode - checkboxes, input, slider, range, dropdown, radio, dropdownsearch, multisearch
* @param $data - Other related information for the given filter type
* @return Filter
*/
public function create($type, $label = '', $display_mode = '', $data = array()) {
$class = !empty($type) && isset($this->classes[$type]) ? $this->classes[$type] : $this->classes['taxonomy'];
$class = self::NAMESPACE . $class;
return new $class($label, $display_mode, $data);
}
/**
* Adds an existing filter to the end of the filters list
*
* @param Filter $filter
* @return Filter mixed
*/
public function add( $filter ) {
if ( !isset($this->filters[$this->search_id]) )
$this->filters[$this->search_id] = array();
$this->filters[$this->search_id][] = $filter;
$this->organize();
return $filter;
}
/**
* Removes a filter by name or array key (id)
*
* @param int|string $key
* @return bool
*/
public function remove( $key ) {
$k = $this->find( $key, true );
if ( $k !== false ) {
unset($this->filters[$this->search_id][$k]);
$this->organize();
return true;
}
return false;
}
/**
* Clears the filters array, removing every filter, and resetting every position etc...
*
* @param int $id the search ID
*/
public function clear($id ) {
if ( isset($this->filters[$id]) )
$this->filters[$id] = array();
Filter::reset();
}
/**
* Finds a filter by array key (id) or label
*
* @param $key
* @param bool $key_only
* @return bool|int|Filter
*/
public function find($key, $key_only = false ) {
if ( is_numeric($key) ) {
if ( isset($this->filters[$this->search_id][$key]) ) {
return $key_only ? $key : $this->filters[$this->search_id][$key];
}
} else {
foreach ( $this->filters[$this->search_id] as $k => $v ) {
if ( isset($v->label) && $v->label == $key ) {
return $key_only ? $k : $this->filters[$this->search_id][$k];
}
}
}
return false;
}
/**
* Gets the filters
*
* @param string $order 'position' or 'added'
* @param bool|string $type false, or the filter type
* @return Filter[]
*/
public function get($order = 'position', $type = false ) {
if ( !isset($this->filters[$this->search_id]) )
return array();
if ( $order == 'position' ) {
$return = array();
$added = array();
while ( count($return) != count($this->filters[$this->search_id]) ) {
$key = -1;
$lowest_position = 999999999;
foreach ( $this->filters[$this->search_id] as $k => $v ) {
if ( !in_array($k, $added) ) {
if ( $v->position <= $lowest_position ) {
$lowest_position = $v->position;
$key = $k;
}
}
}
if ( $key > -1 && !in_array($key, $added) ) {
$return[] = $this->filters[$this->search_id][$key];
$added[] = $key;
}
}
} else {
$return = $this->filters[$this->search_id];
}
if ( $type !== false ) {
foreach ( $return as $k => $filter ) {
if ( $filter->type() != $type ) {
unset($return[$k]);
}
}
}
return apply_filters('asp_pre_get_front_filters', $return, $type);
}
/**
* Sets a filter attribute by array key (id) or by label
*
* @param int|string $key array key (id)
* @param $attribute
* @param $value
* @return bool
*/
public function set($key, $attribute, $value ) {
$k = $this->find( $key, true );
if ( $k !== false ) {
$this->filters[$this->search_id][$k]->{$attribute} = $value;
return true;
}
return false;
}
/**
* Reorganizes the filter IDs
*/
private function organize() {
foreach ( $this->filters as $k => $v ) {
if ( is_array($v) ) {
foreach ( $this->filters[$k] as $kk => $vv ) {
$this->filters[$k][$kk]->id = $kk + 1;
}
}
}
}
}