Files
roi-theme/wp-content/plugins/thrive-visual-editor/admin/includes/class-tcb-symbols-rest-controller.php
root a22573bf0b 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>
2025-11-03 21:04:30 -06:00

569 lines
16 KiB
PHP
Executable File

<?php
/**
* FileName class-tcb-symbols-rest-controller.php.
*
* @project : thrive-visual-editor
* @developer: Dragos Petcu
*/
class TCB_REST_Symbols_Controller extends WP_REST_Posts_Controller {
public static $version = 1;
/**
* Constructor.
* We are overwriting the post type for this rest controller
*/
public function __construct() {
parent::__construct( TCB_Symbols_Post_Type::SYMBOL_POST_TYPE );
$this->namespace = 'tcb/v' . self::$version;
$this->rest_base = 'symbols';
$this->register_meta_fields();
$this->hooks();
}
/**
* Hooks to change the post rest api
*/
public function hooks() {
add_filter( "rest_prepare_{$this->post_type}", [ $this, 'rest_prepare_symbol' ], 10, 2 );
add_filter( "rest_insert_{$this->post_type}", [ $this, 'rest_insert_symbol' ], 10, 2 );
add_action( "rest_after_insert_{$this->post_type}", [ $this, 'rest_after_insert' ], 10, 2 );
add_action( 'rest_delete_' . TCB_Symbols_Taxonomy::SYMBOLS_TAXONOMY, [ $this, 'rest_delete_category' ], 10, 1 );
add_action( "rest_{$this->post_type}_query", [ $this, 'override_per_page' ], 10, 1 );
}
/**
* Override the per page limit for the rest api in case there are people with over 100 symbols
*
* @param $args
*
* @return mixed
*/
public function override_per_page( $params ) {
if ( isset( $params['posts_per_page'] ) ) {
$params['posts_per_page'] = '300';
}
return $params;
}
/**
* Register additional rest routes for symbols
*/
public function register_routes() {
parent::register_routes();
register_rest_route( $this->namespace, '/' . $this->rest_base . '/cloud', array(
array(
'methods' => WP_REST_Server::READABLE,
'callback' => [ $this, 'get_cloud_items' ],
'permission_callback' => [ $this, 'get_items_permissions_check' ],
),
) );
register_rest_route( $this->namespace, '/' . $this->rest_base . '/cloud/(?P<id>.+)', array(
'args' => array(
'id' => array(
'description' => __( 'Unique identifier for the object.' ),
'type' => 'string',
),
),
array(
'methods' => WP_REST_Server::READABLE,
'callback' => [ $this, 'get_cloud_item' ],
'permission_callback' => [ $this, 'get_items_permissions_check' ],
),
) );
}
/**
* Check to see if the user hase permission to view cloud items
*
* @param WP_REST_Request $request
*
* @return bool
*/
public function get_items_permissions_check( $request ) {
return TCB_Product::has_external_access();
}
/**
* @param WP_REST_Request $request
*
* @return array|WP_Error|WP_REST_Response
*/
public function get_cloud_items( $request ) {
if ( ! ( $type = $request->get_param( 'type' ) ) ) {
return new WP_Error( 'rest_invalid_element_type', __( 'Invalid element type' ), [ 'status' => 500 ] );
}
/** @var TCB_Cloud_Template_Element_Abstract $element */
if ( ! ( $element = tcb_elements()->element_factory( $type ) ) || ! is_a( $element, 'TCB_Cloud_Template_Element_Abstract' ) ) {
return new WP_Error( 'rest_invalid_element_type', __( 'Invalid element type', 'thrive-cb' ) . " ({$type})", [ 'status' => 500 ] );
}
$templates = $element->get_cloud_templates();
if ( is_wp_error( $templates ) ) {
return $templates;
}
$templates = $this->prepare_templates_for_response( $templates );
return new WP_REST_Response( $templates );
}
/**
* Transform the resulted templates array to be used in a backbone collection
*
* @param $templates
*
* @return array
*/
public function prepare_templates_for_response( $templates ) {
$results = [];
foreach ( $templates as $template ) {
$results[] = $template;
}
return $results;
}
/**
* Check to see if the user has permission to view an item from cloud
*
* @return bool
*/
public function get_cloud_item_permission_check() {
return tcb_has_external_cap();
}
/**
* Get symbol template from the cloud
*
* @param $request WP_REST_Request
*
* @return array|WP_Error|WP_REST_Response
*/
public function get_cloud_item( $request ) {
if ( ! ( $type = $request->get_param( 'type' ) ) ) {
return new WP_Error( 'rest_invalid_element_type', __( 'Invalid element type', 'thrive-cb' ), [ 'status' => 500 ] );
}
if ( ! ( $id = $request->get_param( 'id' ) ) ) {
return new WP_Error( 'invalid_id', __( 'Missing template id', 'thrive-cb' ), [ 'status' => 500 ] );
}
/** @var TCB_Cloud_Template_Element_Abstract $element */
if ( ! ( $element = tcb_elements()->element_factory( $type ) ) || ! is_a( $element, 'TCB_Cloud_Template_Element_Abstract' ) ) {
return new WP_Error( 'rest_invalid_element_type', __( 'Invalid element type', 'thrive-cb' ) . " ({$type})", [ 'status' => 500 ] );
}
$data = $element->get_cloud_template_data( $id );
if ( is_wp_error( $data ) ) {
return $data;
}
return new WP_REST_Response( $data );
}
/**
* Checks if a given request has access to create a post.
*
* @param WP_REST_Request $request Full details about the request.
*
* @return true|WP_Error True if the request has access to create items, WP_Error object otherwise.
* @since 4.7.0
*
*/
public function create_item_permissions_check( $request ) {
$parent_response = parent::create_item_permissions_check( $request );
//if we are making a duplicate symbol revert to default, do not check for duplicate titles
if ( isset( $request['old_id'] ) || is_wp_error( $parent_response ) ) {
return $parent_response;
}
return $this->check_duplicate_title( $request );
}
/**
* Checks if a given request has access to update a post.
*
* @param WP_REST_Request $request Full details about the request.
*
* @return true|WP_Error True if the request has access to update the item, WP_Error object otherwise.
* @since 4.7.0
*
*/
public function update_item_permissions_check( $request ) {
$parent_response = parent::update_item_permissions_check( $request );
if ( is_wp_error( $parent_response ) ) {
return $parent_response;
}
return $this->check_duplicate_title( $request );
}
/**
* Check if there already exists a symbol with the same title
*
* @param WP_REST_Request $request
*
* @return bool|WP_Error
*/
public function check_duplicate_title( $request ) {
$post_title = $this->get_post_title_from_request( $request );
if ( $post_title ) {
$post = tve_get_page_by_title( $post_title, TCB_Symbols_Post_Type::SYMBOL_POST_TYPE );
if ( $post && $post->post_status !== 'trash' ) {
return new WP_Error( 'rest_cannot_create_post', __( 'Sorry, you are not allowed to create global elements with the same title', 'thrive-cb' ), [ 'status' => 409 ] );
}
}
return true;
}
/**
* Get post title from request
*
* @param WP_REST_Request $request
*/
public function get_post_title_from_request( $request ) {
$post_title = '';
$schema = $this->get_item_schema();
if ( ! empty( $schema['properties']['title'] ) && isset( $request['title'] ) ) {
if ( is_string( $request['title'] ) ) {
$post_title = $request['title'];
} elseif ( ! empty( $request['title']['raw'] ) ) {
$post_title = $request['title']['raw'];
}
}
return $post_title;
}
/**
* Add the taxonomy data to the rest response
*
* @param WP_REST_Response $response
* @param WP_Post $post
*
* @return mixed
*/
public function rest_prepare_symbol( $response, $post ) {
$taxonomies = $response->data[ TCB_Symbols_Taxonomy::SYMBOLS_TAXONOMY ];
foreach ( $taxonomies as $key => $term_id ) {
$term = get_term_by( 'term_id', $term_id, TCB_Symbols_Taxonomy::SYMBOLS_TAXONOMY );
$response->data[ TCB_Symbols_Taxonomy::SYMBOLS_TAXONOMY ][ $key ] = $term;
}
/* add the thumbnail data */
$default_thumb_data = TCB_Utils::get_placeholder_data();
$response->data['thumb'] = TCB_Utils::get_thumb_data( $post->ID, TCB_Symbols_Post_Type::SYMBOL_THUMBS_FOLDER, $default_thumb_data );
$response->data['edit_url'] = tcb_get_editor_url( $post->ID );
return $response;
}
/**
* After a symbol is created generate a new thumb for it ( if we are duplicating the symbol )
*
* @param WP_Post $post Inserted or updated post object.
* @param WP_REST_Request $request Request object.
*
* @return WP_Error|bool
*/
public function rest_insert_symbol( $post, $request ) {
if ( isset( $request['old_id'] ) ) {
$this->ensure_unique_title( $request, $post );
if ( ! $this->copy_thumb( $request['old_id'], $post->ID ) ) {
return new WP_Error( 'could_not_generate_file', __( 'We were not able to copy the symbol', 'thrive-cb' ), [ 'status' => 500 ] );
};
$old_global_data = get_post_meta( $request['old_id'], 'tve_globals', true );
if ( ! empty( $old_global_data ) ) {
update_post_meta( $post->ID, 'tve_globals', $old_global_data );
}
}
update_post_meta( $post->ID, 'export_id', base_convert( time(), 10, 36 ) );
if ( isset( $request['thumb'] ) ) {
return $this->download_thumb( $request, $post->ID );
}
return true;
}
/**
* Action called after a symbol has been created
*
* @param WP_Post $post Inserted or updated post object.
*
*/
public function rest_after_insert( $post ) {
$head_css = get_post_meta( $post->ID, 'tve_custom_css', true );
/* update css specially when we get css from the cloud */
update_post_meta( $post->ID, 'tve_custom_css', str_replace( '|TEMPLATE_ID|', $post->ID, $head_css ) );
}
/**
* It handles also the case when a symbol is created starting with a template from cloud
*
* @param $request WP_REST_Request
* @param $post_id
*
* @return bool|WP_Error
*/
public function download_thumb( $request, $post_id ) {
$thumb = $request['thumb'];
$path = $thumb['url'];
$upload_dir = wp_upload_dir();
if ( strpos( $path, 'no-template-preview' ) !== false ) {
return new WP_Error( 'could_not_generate_file', __( "The inital thumbnail doesn't exists", 'thrive-cb' ), [ 'status' => 500 ] );
}
if ( strpos( $path, 'http' ) === false ) {
$path = 'http:' . $path;
} else {
$thumb_id = isset( $request['thumb_id'] ) ? $request['thumb_id'] : '';
$path = trailingslashit( $upload_dir['basedir'] ) . TCB_Symbols_Post_Type::SYMBOL_THUMBS_FOLDER . '/' . $thumb_id . '.png';
}
//check first if the directory exists. If not, create it
$dir_path = trailingslashit( $upload_dir['basedir'] ) . TCB_Symbols_Post_Type::SYMBOL_THUMBS_FOLDER;
if ( ! is_dir( $dir_path ) ) {
wp_mkdir_p( $dir_path );
}
$new_path = $dir_path . '/' . $post_id . '.png';
/* add the new thumbnail data to the post meta */
TCB_Utils::save_thumbnail_data( $post_id, $thumb );
return @copy( $path, $new_path );
}
/**
* When we duplicate a post, the duplicate will take the title_{id}, to not have symbols with the same name
*
* @param WP_REST_Request $request
* @param WP_Post $post
*/
public function ensure_unique_title( $request, $post ) {
$post_title = $this->get_post_title_from_request( $request );
$new_title = __( 'Copy of ', 'thrive-cb' ) . $post_title;
$same_title_post = tve_get_page_by_title( $new_title, TCB_Symbols_Post_Type::SYMBOL_POST_TYPE );
if ( $same_title_post && $same_title_post->post_status !== 'trash' ) {
$new_title = $new_title . '_' . $post->ID;
}
$post->post_title = $new_title;
wp_update_post( $post );
}
/**
* Get path for symbol thumbnail
*
* @param int $old_id
* @param int $new_id
*
* @return bool
*/
public function copy_thumb( $old_id, $new_id ) {
$upload_dir = wp_upload_dir();
$old_path = trailingslashit( $upload_dir['basedir'] ) . TCB_Symbols_Post_Type::SYMBOL_THUMBS_FOLDER . '/' . $old_id . '.png';
$new_path = trailingslashit( $upload_dir['basedir'] ) . TCB_Symbols_Post_Type::SYMBOL_THUMBS_FOLDER . '/' . $new_id . '.png';
if ( file_exists( $old_path ) ) {
$thumb_data = TCB_Utils::get_thumb_data( $old_id, TCB_Symbols_Post_Type::SYMBOL_THUMBS_FOLDER );
if ( ! empty( $thumb_data ) ) {
TCB_Utils::save_thumbnail_data( $new_id, $thumb_data );
}
return copy( $old_path, $new_path );
}
return true;
}
/**
* Return symbol html from meta
*
* @param array $postdata
*
* @return mixed
*/
public function get_symbol_html( $postdata ) {
$symbol_id = $postdata['id'];
return get_post_meta( $symbol_id, 'tve_updated_post', true );
}
/**
* Update symbol html from meta
*
* @param string $meta_value
* @param WP_Post $post_obj
* @param string $meta_key
*
* @return bool|int
*/
public function update_symbol_html( $meta_value, $post_obj, $meta_key ) {
/**
* Update the symbol html(form meta value) for a specific meta key
*
* @param string $meta_key
* @param string $meta_value
*/
$meta_value = apply_filters( 'tve_update_symbol_html', $meta_key, $meta_value );
return update_post_meta( $post_obj->ID, $meta_key, $meta_value );
}
/**
* Get symbol css from meta
*
* @param array $postdata
*
* @return mixed
*/
public function get_symbol_css( $postdata ) {
$symbol_id = $postdata['id'];
return get_post_meta( $symbol_id, 'tve_custom_css', true );
}
/**
* Update symbols css from meta
*
* @param string $css existing css
* @param WP_Post $post_obj
* @param string $meta_key
* @param WP_Rest_Request $request
*
* @return bool|int
*/
public function update_symbol_css( $css, $post_obj, $meta_key, $request ) {
//if old_id is sent -> we are in the duplicate cas, and we need to replace the id from the css with the new one
if ( isset( $request['old_id'] ) ) {
$css = str_replace( "_{$request['old_id']}", "_{$post_obj->ID}", $css );
}
return update_post_meta( $post_obj->ID, $meta_key, $css );
}
/**
* Move symbol from one category to another
*
* @param string $new_term_id
* @param WP_Post $post_obj
*
* @return array|bool|WP_Error
*/
public function move_symbol( $new_term_id, $post_obj ) {
if ( (int) $new_term_id === 0 ) {
//if the new category is the uncategorized one, we just have to delete the existing ones
return $this->remove_current_terms( $post_obj );
}
//get the new category and make sure that it exists
$term = get_term_by( 'term_id', $new_term_id, TCB_Symbols_Taxonomy::SYMBOLS_TAXONOMY );
if ( $term ) {
$this->remove_current_terms( $post_obj );
return wp_set_object_terms( $post_obj->ID, $term->name, TCB_Symbols_Taxonomy::SYMBOLS_TAXONOMY );
}
return false;
}
/**
* Remove the symbol from the current category( term )
*
* @param WP_Post $post_obj
*
* @return bool|WP_Error
*/
public function remove_current_terms( $post_obj ) {
$post_terms = wp_get_post_terms( $post_obj->ID, TCB_Symbols_Taxonomy::SYMBOLS_TAXONOMY );
if ( ! empty( $post_terms ) ) {
$term_name = $post_terms[0]->name;
return wp_remove_object_terms( $post_obj->ID, $term_name, TCB_Symbols_Taxonomy::SYMBOLS_TAXONOMY );
}
return true;
}
/**
* Add custom meta fields for comments to use them with the rest api
*/
public function register_meta_fields() {
register_rest_field( $this->get_object_type(), 'tve_updated_post', [
'get_callback' => [ $this, 'get_symbol_html' ],
'update_callback' => [ $this, 'update_symbol_html' ],
] );
register_rest_field( $this->get_object_type(), 'tve_custom_css', [
'get_callback' => [ $this, 'get_symbol_css' ],
'update_callback' => [ $this, 'update_symbol_css' ],
] );
register_rest_field( $this->get_object_type(), 'move_symbol', [
'update_callback' => [ $this, 'move_symbol' ],
] );
}
/**
* After a category is deleted we need to move the symbols to uncategorized
*
* @param WP_Term $term The deleted term.
*/
public function rest_delete_category( $term ) {
$posts = get_posts( array(
'post_type' => TCB_Symbols_Post_Type::SYMBOL_POST_TYPE,
'numberposts' => - 1,
'tax_query' => array(
array(
'taxonomy' => TCB_Symbols_Taxonomy::SYMBOLS_TAXONOMY,
'field' => 'id',
'terms' => $term->term_id,
),
),
) );
if ( ! empty( $posts ) ) {
foreach ( $posts as $post ) {
$this->remove_current_terms( $post );
}
}
}
}