Files
MiraviaConnector/connector-miravia/connector-miravia.php
Miravia Connector Bot 28c2d4d1f0 Fix image upload structure for Miravia API compliance
🔧 Bug Fixes:
- Fixed product image structure to match Miravia API requirements
- Updated MiraviaProduct.php getData() method to wrap images in {"Image": [...]} format
- Updated MiraviaCombination.php getData() method to wrap SKU images properly
- Resolved error "[4224] The Main image of the product is required"

📋 Changes:
- Modified getData() methods to transform flat image arrays to nested structure
- Product images: images[] → Images: {"Image": [...]}
- SKU images: images[] → Images: {"Image": [...]}
- Maintains backward compatibility for empty image arrays

🎯 Impact:
- Product uploads will now pass Miravia's image validation
- Both product-level and SKU-level images properly formatted
- Complies with official Miravia API documentation structure

🤖 Generated with Claude Code (https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-21 15:06:20 +02:00

359 lines
16 KiB
PHP

<?php
/**
* Plugin Name: Miravia Feed API Connector
* Description: Official Miravia marketplace integration using Feed API - Upload products and manage orders
* Version: 2.0.0
* Author: CloudHost.es
* Author URI: https://cloudhost.es
* Plugin URI: https://devops.cloudhost.es/CloudHost/MiraviaConnector
* Text Domain: miraviawoo
* WC requires at least: 3.0
* WC tested up to: 8.0
* Required WP: 5.0
* Tested WP: 6.4
* Network: false
* License: GPL v3 or later
* License URI: https://www.gnu.org/licenses/gpl-3.0.html
*/
if ( ! defined( 'ABSPATH' ) ) { exit; }
define('MIRAVIA_CLASSES_PATH', plugin_dir_path( __FILE__ ) . 'classes/');
define('MIRAVIA_SHARED_CLASSES_PATH', MIRAVIA_CLASSES_PATH . 'shared/');
define('MIRAVIA_VIEWS_PATH', plugin_dir_path( __FILE__ ) . 'views/');
define('MIRAVIA_ASSETS_PATH', plugin_dir_path( __FILE__ ) . 'assets/');
define('MIRAVIA_WOO_VERSION', '2.0.0');
define('MIRAVIA_BUILD_VERSION', '20');
define('MIRAVIA_DB_VERSION', 102);
define('MIRAVIA_DEBUG', get_option('miravia_debug_mode', '0'));
define('LOG_FOLDER', plugin_dir_path( __FILE__ ));
$isSetter = false;
require_once(MIRAVIA_CLASSES_PATH . 'class.log.php'); //Log CLASS
require_once(MIRAVIA_CLASSES_PATH . 'class.core.php'); //Core CLASS
require_once(MIRAVIA_CLASSES_PATH . 'class.db.php'); //DB CLASS
require_once(MIRAVIA_CLASSES_PATH . 'class.categories.php'); //Categories CLASS
require_once(MIRAVIA_CLASSES_PATH . 'class.product.php'); //Product CLASS
require_once(MIRAVIA_CLASSES_PATH . 'class.order.php'); //Order CLASS
require_once(MIRAVIA_CLASSES_PATH . 'tables/class.table.php'); //Table CLASS
require_once(MIRAVIA_CLASSES_PATH . 'class.api.php'); //API CLASS
//Miravia Shared Classes
require_once(MIRAVIA_SHARED_CLASSES_PATH . 'MiraviaFilter.php');
require_once(MIRAVIA_SHARED_CLASSES_PATH . 'MiraviaFeed.php');
require_once(MIRAVIA_SHARED_CLASSES_PATH . 'MiraviaLink.php');
require_once(MIRAVIA_SHARED_CLASSES_PATH . 'MiraviaCategory.php');
require_once(MIRAVIA_SHARED_CLASSES_PATH . 'MiraviaCombination.php');
require_once(MIRAVIA_SHARED_CLASSES_PATH . 'MiraviaProduct.php');
if(is_admin()) {
$iconUrl = plugins_url('/assets/img/icon.png', __FILE__);
}
if( !class_exists('MiraviaWOO') ) {
class MiraviaWOO {
function __construct(){
//Menu
add_action('admin_menu', array(&$this, 'admin_menu'));
add_action('admin_init', array(&$this, 'admin_init'));
add_action( 'admin_enqueue_scripts', array(&$this, 'load_style') );
add_action( 'manage_product_posts_custom_column' , array(&$this, 'colum_product'), 10, 2 );
add_filter( 'manage_product_posts_columns' , array(&$this, 'add_colum_products') );
// register_activation_hook( __FILE__, array('MIRAVIADB', 'install_db') );
add_action( 'plugins_loaded', array('MIRAVIADB', 'install') );
//Actions Table
add_filter( 'miravia_profiles_row_actions', array( &$this, 'miravia_profiles_actions' ), 10, 2 );
add_action( 'add_meta_boxes', array($this, 'create_miravia_order_metabox') );
register_deactivation_hook(
__FILE__,
array($this, 'miravia_desactivation')
);
add_action( 'manage_shop_order_posts_custom_column' , array($this, 'colum_orders'), 10, 2 );
add_action( 'woocommerce_update_product', array($this, 'miravia_update_product'), 10, 1 );
add_action('woocommerce_variation_set_stock', array($this, 'miravia_update_product'), 10, 1);
add_action('woocommerce_product_set_stock', array($this, 'miravia_update_product'), 10, 1);
add_action('woocommerce_variation_set_stock_status', array($this, 'miravia_update_product'), 10, 1);
add_action('woocommerce_product_set_stock_status', array($this, 'miravia_update_product'), 10, 1);
add_action( 'woocommerce_save_product_variation', array($this, 'miravia_update_product'), 10, 1 );
add_action( 'woocommerce_product_options_general_product_data', array($this, 'miravia_product_metabox') );
add_action( 'woocommerce_process_product_meta', array($this, 'miravia_save_metadata_product') );
add_action( 'woocommerce_variation_set_stock', array($this, 'miravia_change_stock_hook'), 15, 1);
add_action( 'woocommerce_product_set_stock', array($this, 'miravia_change_stock_hook'), 15, 1);
}
function miravia_change_stock_hook($product) {
if(get_option('miravia_only_stock', '0') == '1') {
LOG::add("Cambio de stock para el producto {$product}");
$profile = MiraviaCore::get_profile_by_product($product->sku);
$accounts = MiraviaCore::accounts_by_profile($profile);
if(count($accounts) > 0) {
MiraviaCore::request_notify($accounts[0]['token'], 'update_stock');
}
}
return true;
}
function miravia_save_metadata_product( $id ){
if(isset($_POST['miravia_brand_product'])) {
$product = wc_get_product( $id );
$product->update_meta_data( '_miravia_brand_product', sanitize_text_field( $_POST[ 'miravia_brand_product' ] ) );
$product->update_meta_data( '_miravia_unit', sanitize_text_field( $_POST[ 'miravia_unit' ] ) );
$product->update_meta_data( '_miravia_unit_value', sanitize_text_field( $_POST[ 'miravia_unit_value' ] ) );
$product->save_meta_data();
}
}
function miravia_product_metabox() {
require_once(MIRAVIA_VIEWS_PATH . "/metabox/miravia-product.php");
}
function colum_orders( $column, $post_id ) {
if ($column == 'order_status'){
$orderID = get_post_meta($post_id, '_miravia_order_id', true);
if($orderID != '' and $orderID != 0) {
echo '<span class="created_via">'.sprintf(__('Created Vía %s','aliexpress'), 'Miravia').'</span>';
}
}
}
function miravia_update_product( $product_id ) {
if(get_option('miravia_only_stock', '0') == '1') {
return;
}
global $isSetter;
if($product_id instanceof WC_Product) {
$product_id = $product_id->ID;
}elseif(isset($product_id['id'])) {
$product_id = $product_id['id'];
}
if(get_post_meta($product_id, '_miravia_need_update', true) == '1') {
LOG::add("{$product_id} no necesita notificación, ya programada.");
return;
}
LOG::add("Estableciendo notificación para el producto {$product_id}");
update_post_meta($product_id, '_miravia_need_update', '1');
if($isSetter) {
LOG::add("No es necesario establecer aviso");
return;
}
if($product_id) {
$sync = MiraviaCore::get_product_miravia($product_id);
if($sync) {
//ESTABLECER NOTIFICACIÓN
$apiKey = MiraviaCore::get_miravia_account_default();
$resultNotify = MiraviaCore::request_notify($apiKey['token'], 'update_stock');
if($resultNotify === -1) {
LOG::add("Existe una notificación pendiente");
return;
}
if($resultNotify) {
LOG::add("Seteada notificación correctamente");
$isSetter = true;
}
}
}
}
function miravia_desactivation() {
update_option('miravia_db_version', 0);
}
public function miravia_profiles_actions( $actions, $post ) {
if ( current_user_can( 'edit_posts' ) ) {
$actions['miravia'] = '<a href="'.admin_url('admin.php?page=miravia_settings&subpage=edit_profile&nonce=' . wp_create_nonce( 'miravia_edit_profile_' . $post->ID )) . '" rel="permalink">' . __('Edit') . '</a>';
}
return $actions;
}
function colum_product($column, $post_id){
if($column == 'miravia_data') {
$html = '<div class="miravia_controls" data-id="'.$post_id.'">';
$sync = MiraviaCore::get_product_miravia($post_id);
$dateUpdated = 'ND';
if($sync and count($sync) > 0) {
if($sync[0]['last_updated'] == '0000-00-00 00:00:0') {
$dateUpdated = date('d-m-Y H:i:s', strtotime($sync[0]['last_updated']));
}
//MiraviaCore::debug($sync);
if(count($sync) > 1) {
$html .= __('Uploaded with multiple accounts','miraviawoo');
}else{
if($sync[0]['id_miravia'] != '' and $sync[0]['id_miravia'] != 0) {
$html .= "<a class='button viewProduct' data-id='{$sync[0]['id_miravia']}'>View</a><span class='minidate'><br>".__('Last Update:','miraviawoo')." ".$dateUpdated."</span>";
$html .= "<p>Status: {$sync[0]['status_text']}</p>";
}
}
if(trim($sync[0]['lastError']) != '') {
$html .= '<i class="fa fa-info" style="border-radius:100px;padding:5px;background-color:#CCC;margin-left:5px" title="'.$sync[0]['lastError'].'"></i>';
}
}else{
}
$html .= '</div>';
echo wp_kses($html, array(
'a' => array(
'href' => array(),
'class' => array(),
'data-id' => array(),
),
'span' => array(
'class' => array()
),
'i' => array('class' => array(),),
'p' => array()
));
}
}
function add_colum_products( $columns ) {
return array_merge( $columns,
array( 'miravia_data' => __( 'Miravia', 'miraviawoo' ) ) );
}
function load_style() {
if(is_admin()) {
wp_enqueue_style( 'cssmiravia', plugins_url('assets/css/miravia-admin.css?v='.time(), __FILE__) );
wp_enqueue_script( 'productmiravia', plugins_url('assets/js/products.js?v='.time(), __FILE__), array( 'wp-i18n' ) );
wp_localize_script( 'productmiravia', 'MIRAVIA_DATA_JAVASCRIPT', array(
'adminAjaxURL' => admin_url('admin-ajax.php'),
));
wp_enqueue_script( 'jquery-ui-core', false, array('jquery') );
wp_enqueue_script('jquery');
wp_enqueue_script( 'filter_rules_plugin_miravia_localization', plugins_url('lib/filter_rules/localization/es.min.js', __FILE__));
wp_enqueue_script( 'filter_rules_plugin_miravia', plugins_url('lib/filter_rules/jquery.jui_filter_rules.min.js', __FILE__),array('jquery'));
wp_enqueue_script( 'filter_rules_miravia', plugins_url('lib/filter_rules_miravia.js?v='.time(), __FILE__), array('jquery'));
wp_enqueue_style( 'fontawesome_miravia_css', plugins_url('lib/fontawesome-6.1.2.all.min.css', __FILE__) );
if(isset($_GET['page']) and sanitize_text_field($_GET['page']) == 'miravia_settings') {
wp_enqueue_script( 'sweetalert_lib', plugins_url('lib/sweetalert2.min.js', __FILE__) );
wp_enqueue_script( 'select2_lib', plugins_url('lib/select2.min.js', __FILE__) );
wp_enqueue_style( 'select2_css', plugins_url('lib/select2.min.css', __FILE__) );
}
wp_enqueue_style( 'filter_rules_css', plugins_url('lib/filter_rules/jquery.jui_filter_rules.bs.min.css', __FILE__) );
wp_enqueue_script( 'fontawesome_miravia_js', plugins_url('lib/fontawesome-6.1.2.all.min.js', __FILE__) );
}
}
function admin_menu() {
global $iconUrl;
add_menu_page(
esc_html__( 'Miravia', 'miraviawoo' ),
esc_html__( 'Miravia', 'miraviawoo'),
'manage_woocommerce',
'miravia_settings',
array($this, 'settings_page'),
$iconUrl,
55.5
);
// add_submenu_page(
// 'miravia_settings',
// esc_html__( 'Brands', 'miraviawoo' ),
// esc_html__( 'Brands', 'miraviawoo'),
// 'manage_woocommerce',
// 'miravia_settings&subpage=brands',
// array($this, 'settings_page'),
// 10
// );
add_submenu_page(
'miravia_settings',
esc_html__( 'Orders', 'miraviawoo' ),
esc_html__( 'Orders', 'miraviawoo'),
'manage_woocommerce',
'miravia_settings&subpage=orders',
array($this, 'settings_page'),
10
);
add_submenu_page(
'miravia_settings',
esc_html__( 'Jobs', 'miraviawoo' ),
esc_html__( 'Jobs', 'miraviawoo'),
'manage_woocommerce',
'miravia_settings&subpage=jobs',
array($this, 'settings_page'),
10
);
add_submenu_page(
'miravia_settings',
esc_html__( 'Accounts', 'miraviawoo' ),
esc_html__( 'Accounts', 'miraviawoo'),
'manage_woocommerce',
'miravia_settings&subpage=accounts',
array($this, 'settings_page'),
10
);
add_submenu_page(
'miravia_settings',
esc_html__( 'Profiles', 'miraviawoo' ),
esc_html__( 'Profiles', 'miraviawoo'),
'manage_woocommerce',
'miravia_settings&subpage=profiles',
array($this, 'settings_page'),
10
);
add_submenu_page(
'miravia_settings',
esc_html__( 'Products', 'miraviawoo' ),
esc_html__( 'Products', 'miraviawoo'),
'manage_woocommerce',
'miravia_settings&subpage=products',
array($this, 'settings_page'),
10
);
add_submenu_page(
'miravia_settings',
esc_html__( 'Miravia Products', 'miraviawoo' ),
esc_html__( 'Miravia Products', 'miraviawoo'),
'manage_woocommerce',
'miravia_settings&subpage=products_remote',
array($this, 'settings_page'),
10
);
add_submenu_page(
'miravia_settings',
esc_html__( 'Rules', 'miraviawoo' ),
esc_html__( 'Rules', 'miraviawoo'),
'manage_woocommerce',
'miravia_settings&subpage=rules',
array($this, 'settings_page'),
10
);
}
function create_miravia_order_metabox() {
global $post;
if(get_post_meta($post->ID, '_miravia_order_id', true)){
add_meta_box( 'aew_number_shipping_metabox', __('Miravia Tracker','miraviawoo'), array($this, 'content_metabox_miravia_order'), 'shop_order', 'normal', 'high' );
}
}
function content_metabox_miravia_order($post) {
require_once(MIRAVIA_VIEWS_PATH . '/metabox/miravia-order.php');
}
public function settings_page() {
include MIRAVIA_VIEWS_PATH . 'settings.php';
}
public function brands_page() {
include MIRAVIA_VIEWS_PATH . 'brands.php';
}
function admin_init() {
}
}
}
$MIRAVIAWOO = new MIRAVIAWOO();