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,434 @@
<?php
/**
* Created by PhpStorm.
* User: Ovidiu
* Date: 5/29/2017
* Time: 9:39 AM
*/
class TCB_Post_Grid {
private $_template = 'sc-post-grid.php';
private $_cfg_code = '__CONFIG_post_grid__';
/**
* Defines rules that remove from Post Grid content specific elements
*
* @var array
*/
private $_content_to_remove = array(
'#<a href="javascript:(.+?)</a>#',
'#<span class="tve_s_cnt">(.+?)</span> shares#',
'#__CONFIG_group_edit__(.+?)__CONFIG_group_edit__#',
'#__CONFIG_local_colors__(.+?)__CONFIG_local_colors__#',
/* some "custom" custom menus are saved without the __CONFIG_widget_menu key (in symbols, this is a problem) - we need to get rid of all json-encoded string from the content */
'#{"menu_id"(.+)(true|false|null|"|\'|\d|]|})}#',
/* Custom menu - encoded json version */
'@{&#8220;menu_id&#8221;(.+)(true|false|null|&#8221;|\d|]|})}@',
);
/**
* When set to false, the shortcode config DIV wont be rendered
*
* @var bool
*/
public $output_shortcode_config = true;
/**
* PostGrid constructor.
*
* @param $config
*/
public function __construct( $config = [] ) {
$config = stripslashes_deep( $config );
$defaults = array(
'display' => 'grid',
'grid_layout' => 'horizontal',
'columns' => '3',
'text_type' => 'summary',
'read-more-text' => __( 'Read More', 'thrive-cb' ),
'image-height' => '',
'font-size' => '', //Backwards Compatibility: Title Font Size
'text-line-height' => '', //Backwards Compatibility: Title Line Height
'teaser_layout' => [
'featured_image' => 'true',
'title' => 'true',
'text' => 'true',
'read_more' => 'true',
],
'layout' => [
'featured_image',
'title',
'text',
'read_more',
],
'orderby' => 'date',
'order' => 'DESC',
'recent_days' => '0',
'posts_start' => '0',
'posts_per_page' => '6',
'content_types' => [ 'post' ],
'filters' => [
'category' => [],
'tag' => [],
'tax' => [],
'author' => [],
'posts' => [],
],
);
/**
* Backwards compatible $config['post_types'].
* This can be removed after users update a while when users update their post grids and the post_types variable is removed from the config array
*/
if ( ! empty( $config['post_types'] ) && is_array( $config['post_types'] ) && empty( $config['content_types'] ) ) {
$config['content_types'] = [];
foreach ( $config['post_types'] as $type => $checked ) {
if ( $checked === 'true' ) {
$config['content_types'][] = $type;
}
}
}
$this->_config = array_merge( $defaults, $config );
}
/**
* Render Functions
* Goes through all posts and builds the HTML code
*
* @return string
*/
public function render() {
$posts = $this->_get_post_grid_posts();
$count = count( $posts );
$index = 1;
$extra_classes = 'tve_post_grid_' . $this->_config['display'];
if ( $this->_config['grid_layout'] === 'vertical' ) {
$extra_classes .= ' tve_post_grid_vertical';
}
$html = '';
if ( $this->output_shortcode_config ) {
$html .= $this->_get_shortcode_config();
}
$html .= '<div class="tve_post_grid_wrapper tve_clearfix thrive-shortcode-html ' . $extra_classes . '">';
if ( $count === 0 ) {
$html .= __( 'No results have been returned for your Query. Please edit the query for content to display.', 'thrive-cb' );
}
foreach ( $posts as $key => $post ) {
$html .= tcb_template( $this->_template, [ 'cls' => $this, 'index' => $index, 'post' => $post, 'count' => $count ], true );
$index ++;
}
$html .= '</div>';
return $html;
}
/**
* Outputs the config shortcode.
*
* @return string
*/
private function _get_shortcode_config() {
$encoded_config = tve_json_utf8_unslashit( json_encode( $this->_config ) );
return '<div class="thrive-shortcode-config" style="display: none !important">' . $this->_cfg_code . $encoded_config . $this->_cfg_code . '</div>';
}
/**
* Applies the settings and returns an array with all posts with the corresponding settings
*
* @return array
*/
private function _get_post_grid_posts() {
if ( empty( $this->_config['exclude'] ) ) {
$this->_config['exclude'] = 0;
}
$types = empty( $this->_config['content_types'] ) ? 'any' : $this->_config['content_types'];
$args = array(
'post_type' => $types,
'offset' => $this->_config['posts_start'],
'posts_per_page' => intval( $this->_config['posts_per_page'] ) == 0 ? - 1 : $this->_config['posts_per_page'],
'order' => $this->_config['order'],
'orderby' => $this->_config['orderby'],
'post_status' => 'publish',
'post__not_in' => [ $this->_config['exclude'] ],
);
if ( ! empty( $this->_config['filters']['category'] ) ) {
//Backwards compatibility:
if ( is_string( $this->_config['filters']['category'] ) ) {
$this->_config['filters']['category'] = explode( ',', $this->_config['filters']['category'] );
}
$args['tax_query'] = array(
'relation' => 'AND',
array(
'relation' => 'OR',
array(
'taxonomy' => 'category',
'field' => 'name',
'terms' => $this->_config['filters']['category'],
'operator' => 'IN',
),
array(
'taxonomy' => 'apprentice',
'field' => 'name',
'terms' => $this->_config['filters']['category'],
'operator' => 'IN',
),
),
);
}
if ( ! empty( $this->_config['filters']['tag'] ) ) {
//Backwards compatibility:
if ( is_string( $this->_config['filters']['tag'] ) ) {
$tags = explode( ',', trim( $this->_config['filters']['tag'], ',' ) );
$tags = empty( $tags ) ? [] : $tags;
$this->_config['filters']['tag'] = array_unique( $tags );
}
$query_tags = array(
'relation' => 'OR',
array(
'taxonomy' => 'post_tag',
'field' => 'name',
'terms' => $this->_config['filters']['tag'],
'operator' => 'IN',
),
array(
'taxonomy' => 'apprentice-tag',
'field' => 'name',
'terms' => $this->_config['filters']['tag'],
'operator' => 'IN',
),
);
if ( ! empty( $this->_config['filters']['category'] ) ) {
$args['tax_query'][] = $query_tags;
} else {
$args['tax_query'] = [
'relation' => 'AND',
$query_tags,
];
}
}
if ( ! empty( $this->_config['filters']['tax'] ) ) {
//Backwards compatibility:
if ( is_string( $this->_config['filters']['tax'] ) ) {
$tax_parts = explode( ',', trim( $this->_config['filters']['tax'], ',' ) );
$tax_parts = empty( $tax_parts ) ? [] : $tax_parts;
$this->_config['filters']['tax'] = array_unique( $tax_parts );
}
$tax_names = $this->_config['filters']['tax']; //array_unique( $tax_names );
$tax_query = [];
//foreach taxonomy name get all its terms and build tax_query for it
foreach ( $tax_names as $tax_name ) {
$terms_obj = get_terms( $tax_name );
if ( empty( $terms_obj ) || $terms_obj instanceof WP_Error ) {
continue;
}
$tax_terms = [];
foreach ( $terms_obj as $term ) {
$tax_terms[] = $term->slug;
}
$tax_query[] = [
'taxonomy' => $tax_name,
'field' => 'slug',
'terms' => $tax_terms,
];
}
if ( ! empty( $tax_query ) ) {
$tax_query['relation'] = 'OR';
$args['tax_query'] = $tax_query;
}
}
if ( ! empty( $this->_config['filters']['author'] ) ) {
//Backwards compatibility:
if ( is_string( $this->_config['filters']['author'] ) ) {
$this->_config['filters']['author'] = array_unique( explode( ',', trim( $this->_config['filters']['author'], ',' ) ) );
}
$author_names = $this->_config['filters']['author']; //array_unique( $author_names );
$author_ids = [];
foreach ( $author_names as $name ) {
$author = get_user_by( 'slug', $name );
if ( $author ) {
$author_ids[] = $author->ID;
}
}
if ( ! empty( $author_ids ) ) {
$args['author'] = implode( ',', $author_ids );
}
}
if ( ! empty( $this->_config['filters']['posts'] ) ) {
if ( is_string( $this->_config['filters']['posts'] ) ) { //Backwards Compatibility
$post_ids = array_unique( explode( ',', $this->_config['filters']['posts'] ) );
} else {
$post_ids = wp_list_pluck( array_filter( $this->_config['filters']['posts'] ), 'id' ); //array_unique( $post_ids );
}
$args['post__in'] = $post_ids;
}
if ( ! empty( $this->_config['recent_days'] ) ) {
$args['date_query'] = array(
'after' => date( 'Y-m-d', strtotime( '-' . intval( $this->_config['recent_days'] ) . ' days', strtotime( date( 'Y-m-d' ) ) ) ),
);
}
$args['ignore_sticky_posts'] = 1;
remove_filter( 'pre_get_posts', 'thrive_exclude_category' );
$results = new WP_Query( $args );
return $results->posts;
}
/**
* Returns the post content by checking if post option to be displayed exists: featured image, text, read more, title
*
* @param $post
*
* @return string
*/
public function get_post_content( $post ) {
$html = '';
if ( ! in_array( 'read_more', $this->_config['layout'] ) ) {
$this->_config['layout'][] = 'read_more';
}
foreach ( $this->_config['layout'] as $layout ) {
if ( ! empty( $this->_config['teaser_layout'][ $layout ] ) && $this->_config['teaser_layout'][ $layout ] === 'true' ) {
$function_name = '_display_post_' . $layout;
$html .= call_user_func( [ $this, $function_name ], $post );
}
}
return $html;
}
/**
* Displays the post featured image
* Used in get_post_content method
*
* @param $post
*
* @return string
*/
private function _display_post_featured_image( $post ) {
if ( ! has_post_thumbnail( $post->ID ) ) {
return '';
}
$src = wp_get_attachment_url( get_post_thumbnail_id( $post->ID ) );
$height = ! empty( $this->_config['image-height'] ) ? "height: {$this->_config['image-height']}px" : '';
return '<a href="' . get_permalink( $post ) . '"><div class="tve_post_grid_image_wrapper" style="background-image: url(' . $src . ' ); ' . $height . '"><div class="tve_pg_img_overlay"><span class="thrv-icon thrv-icon-forward"></span></div></div></a>';
}
/**
* Display the post text
* Used in get_post_content method
*
* @param $post
*
* @return string
*/
private function _display_post_text( $post ) {
//get whole the content
$content = empty( $post->post_content ) ? $post->tve_updated_post : $post->post_content;
//strip all the shortcodes from the content
$content = strip_shortcodes( $content );
if ( $this->_config['text_type'] === 'summary' ) {
$content = $this->_get_summary_text( $content );
} elseif ( $this->_config['text_type'] === 'excerpt' ) {
$content = empty( $post->post_excerpt ) ? $this->_get_summary_text( $content ) : $post->post_excerpt;
} elseif ( $this->_config['text_type'] === 'fulltext' ) {
$content = $this->_filter_content( $content );
$content = strip_tags( $content, '<p><h1><h2><h3><h4><h5><h6><a><strong><b>' );
// Remove breaks (new line characters)
$content = trim( preg_replace( '/[\r\n\t ]+/', ' ', $content ) );
}
if ( empty( $content ) ) {
return '';
}
return '<div class="tve-post-grid-text">' . $content . '</div>';
}
/**
* Displays post title
* Used in get_post_content method
*
* @param $post
*
* @return string
*/
private function _display_post_title( $post ) {
$title_font_size = ! empty( $this->_config['font-size'] ) ? 'font-size: ' . $this->_config['font-size'] . 'px;' : '';
$title_line_height = ! empty( $this->_config['text-line-height'] ) ? 'line-height: ' . $this->_config['text-line-height'] . ';' : '';
$title_style = '';
if ( ! empty( $title_font_size ) || ! empty( $title_line_height ) ) {
$title_style = 'style="' . $title_font_size . $title_line_height . '"';
}
return '<span class="tve-post-grid-title" ' . $title_style . '><a href="' . get_permalink( $post ) . '" aria-label="' . get_the_title( $post->ID ) . '" >' . get_the_title( $post->ID ) . '</a></span>';
}
/**
* Displays post read more text
* Used in get_post_content method
*
* @param $post
*
* @return string
*/
private function _display_post_read_more( $post ) {
return '<div class="tve_pg_more"><a href="' . get_permalink( $post ) . '" aria-label="' . $this->_config['read-more-text'] . '">' . $this->_config['read-more-text'] . '</a>&nbsp;<span class="thrv-icon thrv-icon-uniE602"></span></div>';
}
private function _get_summary_text( $text ) {
$text = $this->_filter_content( $text );
$text = wp_strip_all_tags( $text, true );
$text = wp_trim_words( $text, 20, '&#91;...&#93;' );
return $text;
}
/**
* Filters the content by removing specific elements
*
* @param string $content
*
* @return string
*/
private function _filter_content( $content = '' ) {
foreach ( $this->_content_to_remove as $pattern ) {
$content = preg_replace( $pattern, '', $content );
}
return $content;
}
}