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>
This commit is contained in:
Miravia Connector Bot
2025-07-17 08:11:23 +02:00
commit a7d7dbb164
61 changed files with 8501 additions and 0 deletions

View File

@@ -0,0 +1,495 @@
<?php
if ( ! defined( 'ABSPATH' ) ) { exit; }
if( !class_exists('APIMIRAVIA') ) {
class APIMIRAVIA {
function __construct() {
$actionsPrivate = array(
'miravia_upload_product',
'miravia_update_product',
'miravia_authorize',
'miravia_create_profile',
'miravia_download_order',
'send_products_miravia',
'miravia_check_job',
'miravia_cancel_job',
'miravia_notify',
'miravia_request_notify',
'miravia_packed_order',
'miravia_print_label',
'miravia_get_brands',
'miravia_connect_product',
'disconnect_product_miravia'
);
foreach( $actionsPrivate as $action ){
add_action( 'wp_ajax_'.$action, array( $this, $action ) );
add_action( 'wp_ajax_nopriv_'.$action, array( $this, $action ) );
}
}
function miravia_connect_product(){
global $wpdb;
if ( !current_user_can( 'manage_woocommerce' ) ) { exit; }
$res = array('ok' => false);
$sku = sanitize_text_field($_POST['sku']);
$profile_id = MiraviaCore::get_profile_by_product($sku);
LOG::add("Profile encontrado {$profile_id} -> {$sku}");
if($profile_id) {
$id_remote = sanitize_text_field($_POST['id_remote']);
$id_local = wc_get_product_id_by_sku($sku);
$existe = MiraviaCore::get_product_miravia($id_local);
if(!$existe) {
$_product = wc_get_product($id_local);
//Save product data
$wpdb->insert($wpdb->prefix.'miravia_products', array(
'id_woocommerce' => $id_local,
'sku' => $_product->get_sku() ?: $id_local,
'id_miravia' => $id_remote,
'profile_id' => $profile_id,
'stock' => $_product->get_regular_price(),
'price' => $_product->get_regular_price(),
'sale_price' => $_product->get_sale_price(),
));
LOG::add("Conectando producto ({$id_local}) remoto {$sku} con {$id_remote} con el profile {$profile_id}");
update_post_meta($id_local, '_miravia_product_id', $id_remote);
update_post_meta($id_local, '_miravia_sync_date', time());
$res['ok'] = true;
}else{
$res['alert'] = "This product exist";
}
}
wp_send_json($res);
}
function miravia_print_label() {
$id = sanitize_text_field($_POST['id']);
$package_id = sanitize_text_field($_POST['package_id']);
$account_id = get_post_meta($id, '_miravia_account_id', true);
$labelResult = false;
$account = MiraviaCore::get_accounts($account_id);
$link = new MiraviaLink($account['token']);
if($account_id) {
$labelResult = $link->getShippingLabel($package_id);
}
wp_send_json($labelResult);
}
function miravia_get_brands() {
$token = MiraviaCore::get_miravia_account_default();
if($token) {
$token = $token['token'];
$link = new MiraviaCategory($token);
$brands = $link->getBrands();
}else{
$brands = [];
}
wp_send_json($brands);
}
function miravia_packed_order(){
$id = sanitize_text_field($_POST['id']);
$account_id = get_post_meta($id, '_miravia_account_id', true);
$order_miravia_id = get_post_meta($id, '_miravia_order_id', true);
if($account_id) {
$account = MiraviaCore::get_accounts($account_id);
$link = new MiraviaLink($account['token']);
$resultPack = false;
list($order, $items) = MiraviaCore::get_order_woocommerce($id);
$resultPack = $link->orderPack($order_miravia_id, array('products' => $items));
update_post_meta($id, '_miravia_packed_result', $resultPack);
}else{
LOG::add("{$id} no ha sido importado, no tiene ID de Cuenta", false, 'pack_order');
LOG::add([$_POST, $account_id], false, 'pack_order');
}
wp_send_json($resultPack);
}
function miravia_check_job() {
$id = sanitize_text_field($_POST['id']);
if($id) {
$apiKey = sanitize_text_field($_POST['token']);
$link = new MiraviaLink($apiKey);
$result = $link->getFeedInfo($id);
// LOG::add($result, false, 'check_job');
if($result and $result['result']['processing_status'] == 'DONE') {
foreach($result['response'] as $sku => $value) {
if($value['status'] == 'FAIL') {
if($value['detail']['message']['errorDetail'] and count($value['detail']['message']['errorDetail']) > 0) {
LOG::add('SET JOB Detail' . $id . ' -> ' . $value['detail']['message']['errorDetail'][0]['message'] . ' -- ' . $sku, false, 'check_job');
MiraviaCore::set_error_product_job($sku, $id, $value['detail']['message']['errorDetail'][0]['message']);
}else{
LOG::add('SET JOB MSG' . $id . ' -> ' . $value['detail']['message']['errorMsg'] . ' -- ' . $sku, false, 'check_job');
MiraviaCore::set_error_product_job($sku, $id, $value['detail']['message']['errorMsg']);
}
}else{
//Controlar los updates
if(!isset($value['id'])) {
$value['id'] = false;
}
MiraviaCore::set_id_miravia_product_job($sku, $id, $value['id']);
}
}
}
if($result) {
// MiraviaCore::set_status_job($id, $result['result']['processing_status']);
wp_send_json(array('status' => $result['result']['processing_status']));
}else{
wp_send_json(array('status' => false));
}
}
}function miravia_cancel_job() {
$id = sanitize_text_field($_POST['id']);
if($id) {
$apiKey = sanitize_text_field($_POST['token']);
$link = new MiraviaLink($apiKey);
$result = $link->cancelFeed($id);
LOG::add($result, false, 'result_cancel_job');
if($result and $result['success']) {
MiraviaCore::clear_job($id);
wp_send_json(array('success' => true));
}else{
MiraviaCore::clear_job($id);
wp_send_json(array('error' => true, 'message' => 'You can cancel this job, products unlock locally'));
}
}
}
function miravia_request_notify() {
MiraviaCore::request_notify(sanitize_text_field($_POST['token']), sanitize_text_field($_POST['message']));
}
function miravia_download_order($id = false, $token = false) {
$id = $id ?: sanitize_text_field($_POST['id']);
$apiKey = $token ?: sanitize_text_field($_POST['token']);
$existe = MiraviaCore::order_exist($id);
if(count($existe) > 0) {
LOG::add("Order {$id} exists");
return;
}
$link = new MiraviaLink($apiKey);
$order_from_miravia = $link->getOrder($id);
$order_from_miravia['data']['account_id'] = sanitize_text_field($_POST['account_id']);
$miravia_order = new MVOrder();
$miravia_order->create($order_from_miravia['data']);
}
function miravia_notify(){
LOG::add('Datos recibidos de notificación', false, 'notify');
// LOG::add($_REQUEST, false, 'notify');
if(isset($_GET['seller'])) {
$idPedido = false;
$action = sanitize_text_field($_GET['message']);
if(sanitize_text_field($_GET['miravia_action']) == 'notify') {
if(str_contains($action, 'neworder-')) {
$idPedido = substr($action, 9);
$action = 'neworder';
}
switch($action) {
case 'update_stock':
$profiles = MiraviaCore::get_profiles_by_seller(sanitize_text_field($_GET['seller']));
foreach($profiles as $k => $p) {
$this->send_stock_price_miravia($p['id'], false);
}
//update_option('miravia_notify_' . $action . '_in', time());
break;
case 'neworder':
if($idPedido) {
if(isset($_GET['status']) and sanitize_text_field($_GET['status']) == 'pending') {
$account = MiraviaCore::get_miravia_account_default(sanitize_text_field($_GET['seller']), 'userid');
$this->miravia_download_order($idPedido, $account['token']);
}else{
LOG::add("Order status is ".sanitize_text_field($_GET['status'])." => {$idPedido}");
}
}
break;
default:
LOG::add("Action notify no recognized");
break;
}
}elseif(sanitize_text_field($_GET['miravia_action']) == 'feed') {
MiraviaCore::procesarFeed();
}elseif(sanitize_text_field($_GET['miravia_action']) == 'stock_sresync') {
$accounts = MiraviaCore::resync_stock();
if($accounts) {
foreach($accounts as $a) {
MiraviaCore::request_notify($a['token'], 'update_stock');
}
}
}
wp_send_json(array('success' => true), 200);
die();
}
wp_send_json(array('success' => false), 400);
die();
}
function send_products_miravia() {
$profile = sanitize_text_field($_POST['profile']);
LOG::add("Enviando productos del perfil {$profile}");
if ( !current_user_can( 'manage_woocommerce' ) ) { exit; }
$result = array(
'id' => 0,
'error' => false,
'message' => ''
);
$accounts = MiraviaCore::accounts_by_profile($profile);
$product = MiraviaCore::get_products_by_profile($profile);
if($product) {
foreach($accounts as $a) {
//Enviar los productos con cada una de las cuentas de usuario registrados en el profile.
//Comprobar el producto si no se ha enviado
// LOG::add("Comprobando producto en job");
// LOG::add($product);
$productsToSend = array(
'update' => array(),
'create' => array()
);
if($product){
foreach($product as $k => $p) {
if(MiraviaCore::check_product_onjob($p->id)) {
unset($product[$k]);
}else{
if($product and $product[$k]->id_miravia != 0 and $product[$k]->id_miravia != '' and $product[$k]->id_miravia != '0') {
$product[$k]->created = 1;
array_push($productsToSend['update'], $product[$k]);
}else{
array_push($productsToSend['create'], $product[$k]);
}
}
}
}
//Check after check on job
// LOG::add("PRODUCTOS DESPUES");
// LOG::add($product);
if(count($product) == 0) {
wp_send_json(array('error' => true, 'message' => 'All products is on job, please wait to complete this before send again.'));
wp_die();
}
if(count($productsToSend['create']) > 0) {
$link = new MiraviaLink($a['token']);
$feed = new MiraviaFeed();
$feed->setProducts($productsToSend['create']);
//Apply Rules
$feed = MiraviaCore::applyFilter($feed, $a['id'], $profile);
$productJson = $feed->getJsonCreate();
if(MIRAVIA_DEBUG == '0') {
$result = $link->sendFeed($productJson);
if(isset($result['feed_result']) and $result['feed_result']['success']) {
MiraviaCore::set_job_product(array_column($productsToSend['create'], 'id'), $profile, $result['feed_result']['result']);
}
}
}
if(count($productsToSend['update']) > 0) {
$link = new MiraviaLink($a['token']);
$feed = new MiraviaFeed();
$feed->setProducts($productsToSend['update']);
//Apply Rules
$feed = MiraviaCore::applyFilter($feed, $a['id'], $profile);
$productJsonUpdate = $feed->getJsonUpdate();
if(MIRAVIA_DEBUG == '0') {
$result = $link->sendFeed($productJsonUpdate, 'update');
if(isset($result['feed_result']) and $result['feed_result']['success']) {
MiraviaCore::set_job_product(array_column($productsToSend['update'], 'id'), $profile, $result['feed_result']['result']);
}
}
}
if(MIRAVIA_DEBUG == '1') {
wp_send_json(array('error' => true, 'message' => 'Debug Active', 'update' => $productJsonUpdate, 'create' => $productJson, 'initData' => $productsToSend));
die();
}
LOG::add("Enviando " . count($product) . " productos con token {$a['token']}");
LOG::add($result);
}
}
wp_send_json($product);
wp_die();
}
function send_stock_price_miravia($profile = false, $returnValue = true) {
if(!$profile) {
$profile = sanitize_text_field($_POST['profile']);
}
LOG::add("Enviando productos del perfil {$profile}");
if ($returnValue and !current_user_can( 'manage_woocommerce' ) ) { exit; }
$result = array(
'id' => 0,
'error' => false,
'message' => ''
);
$accounts = MiraviaCore::accounts_by_profile($profile);
$product = MiraviaCore::get_products_by_profile($profile, true);
$isOnlyStock = get_option('miravia_only_stock', '0') == '1';
if($product) {
foreach($accounts as $a) {
//Enviar los productos con cada una de las cuentas de usuario registrados en el profile.
//Comprobar el producto si no se ha enviado
foreach($product as $k => $p) {
if(MiraviaCore::check_product_onjob($p->id)) {
unset($product[$k]);
}
}
//Check after check on job
if(count($product) == 0) {
wp_send_json(array('error' => true, 'message' => 'All products is on job, please wait to complete this before send again.'));
wp_die();
}
$link = new MiraviaLink($a['token']);
$feed = new MiraviaFeed();
$feed->setProducts($product);
//Apply Rules
$feed = MiraviaCore::applyFilter($feed, $a['id'], $profile);
$stockJson = $feed->getJsonUpdateStock($isOnlyStock);
if(MIRAVIA_DEBUG == '1') {
wp_send_json($stockJson);
die();
}
$result = $link->updateStock($stockJson);
if(isset($result['feed_result']) and $result['feed_result']['success']) {
MiraviaCore::set_job_product(array_column($product, 'id'), $profile, $result['feed_result']['result']);
}
}
}
if($returnValue) {
wp_send_json($product);
wp_die();
}
}
function miravia_create_profile() {
$apiKey = sanitize_text_field($_REQUEST['api_key']);
$link = new MiraviaLink($apiKey);
$sellerInfo = $link->getSellerInfo(admin_url('admin-ajax.php?action=miravia_notify'));
if($sellerInfo) {
if(!MiraviaCore::get_accounts($sellerInfo['seller_id'], 'userid')) {
$profile = MiraviaCore::add_account(array(
'name' => $sellerInfo['seller_name'],
'token' => $apiKey,
'userid' => $sellerInfo['seller_id'],
'lang' => $sellerInfo['country'],
'email' => $sellerInfo['email'],
'config' => '{short_code: "'.$sellerInfo['short_code'].'"}',
));
}
}
wp_redirect( admin_url('admin.php?page=miravia_settings&subpage=accounts') );
wp_send_json(array('ok' => true));
}
function disconnect_product_miravia(){
if ( !current_user_can( 'manage_woocommerce' ) ) { exit; }
$id = $_POST['id'];
LOG::add("Desconectando producto {$id} de miravia");
update_post_meta($id, '_miravia_product_id', 0);
update_post_meta($id, '_miravia_sync_date', 0);
wp_send_json(array('ok' => true));
}
function miravia_authorize() {
LOG::add("Solicitando autorización a Miravia");
$link = new MiraviaLink();
$register_link = $link->getRegisterUrl(admin_url('admin-ajax.php?action=miravia_create_profile'));
LOG::add("Register link is " . $register_link);
wp_redirect( $register_link );
wp_send_json(array('ok' => true));
}
function miravia_upload_product() {
if ( !current_user_can( 'manage_woocommerce' ) ) { exit; }
$result = array(
'id' => 0,
'error' => false,
'message' => ''
);
$id = sanitize_text_field($_POST['id']);
$product = new MVProduct($id, 2);
wp_send_json($product);
wp_die();
$response = $product->send();
if(isset($response['item_id'])) {
//Producto subido
update_post_meta($id, '_miravia_product_id',$response['item_id']);
update_post_meta($id, '_miravia_sync_date',time());
$result['id'] = $response['item_id'];
}else{
$result['error'] = true;
$result['message'] = $response['errors'][0]['message'];
}
wp_send_json($result);
wp_die();
}
function miravia_update_product() {
if ( !current_user_can( 'manage_woocommerce' ) ) { exit; }
$result = array(
'id' => 0,
'error' => false,
'message' => ''
);
$id = sanitize_text_field($_POST['id']);
$product = new MVProduct($id);
$response = $product;
if(is_array($response) and count($response) == 0) {
//Producto subido
update_post_meta($id, '_miravia_sync_date',time());
$result['id'] = $id;
}else{
$result['error'] = true;
$result['message'] = $response['errors'][0]['message'];
}
wp_send_json($result);
wp_die();
}
}
$APIMIRAVIA = new APIMIRAVIA();
}

View File

@@ -0,0 +1,66 @@
<?php
if ( ! defined( 'ABSPATH' ) ) { exit; }
if( !class_exists('MIRAVIA_Category') ) {
class MIRAVIA_Category {
private $lang = "es_ES";
function __construct($lang = ''){
if($lang != '') {
$this->lang = $lang;
}
}
function get_category_tree() {
global $MIRAVIAWOO;
$categories = $MIRAVIAWOO->client->get('/category/tree/get', array(
'language_code' => $this->lang
));
return $categories;
}
function get_attributes($id) {
global $MIRAVIAWOO;
$attributes = $MIRAVIAWOO->client->get('/category/attributes/get', array(
'primary_category_id' => $id,
'language_code' => $this->lang
));
return $attributes;
}
function get_input_type_attr($attr, $args = array('value' => '')) {
$result = 'Esta propiedad no puede ser establecida por defecto';
if($attr['input_type'] == 'enumInput' or $attr['input_type'] == 'singleSelect' or $attr['input_type'] == 'multiSelect') {
if(isset($attr['options'])) {
$result = "<select name='attr[{$attr['name']}]'>";
$result .= "<option value=''>Seleccione</option>";
foreach($attr['options'] as $opt) {
$selected_html = '';
if($opt['name'] == $args['value']) { $selected_html = "selected='selected'"; }
$result .= "<option {$selected_html} value='{$opt['name']}'>{$opt['name']}</option>";
}
$result .= "</select>";
}else{
$result = "<input type='text' name='attr[{$attr['name']}]' value='{$args['value']}' />";
}
}elseif($attr['input_type'] == 'numeric') {
$result = "<input type='number' name='attr[{$attr['name']}]' value='{$args['value']}' />";
}elseif($attr['input_type'] == 'text') {
$result = "<input type='text' name='attr[{$attr['name']}]' value='{$args['value']}' />";
}elseif($attr['input_type'] == 'richText') {
$result = "<textarea name='attr[{$attr['name']}]'>{$args['value']}</textarea>";
}
return esc_html($result);
}
}
}

View File

@@ -0,0 +1,775 @@
<?php
if ( ! defined( 'ABSPATH' ) ) { exit; }
if( !class_exists('MiraviaCore') ) {
class MiraviaCore {
/**
* Add account miravia
*
* @param array $data
* @return bool
*
* name tinytext NOT NULL,
token varchar(200) NOT NULL,
userid varchar(30) DEFAULT '' NOT NULL,
config TEXT NOT NULL DEFAULT '{}',
lang varchar(10) NOT NULL
*/
static function add_account($args) {
global $wpdb;
$default = array(
'name' => '',
'token' => '',
'userid' => '',
'lang' => '',
'email' => '',
'config' => '{}',
);
$args = wp_parse_args( $args, $default );
if($args['token'] == '') {
return false;
}
$wpdb->insert($wpdb->prefix.'miravia_accounts',$args);
$my_id = $wpdb->insert_id;
return $my_id;
}
static function delete_account($id = false) {
global $wpdb;
if($id and current_user_can( 'manage_options' )) {
return $wpdb->delete($wpdb->prefix.'miravia_accounts', array('id' => $id));
}
return false;
}
static function delete_profile($id = false) {
global $wpdb;
if($id and current_user_can( 'manage_options' )) {
return $wpdb->delete($wpdb->prefix.'miravia_profiles', array('id' => $id));
}
return false;
}
static function delete_rule($id = false) {
global $wpdb;
if($id and current_user_can( 'manage_options' )) {
return $wpdb->delete($wpdb->prefix.'miravia_rules', array('id' => $id));
}
return false;
}
static function debug($v, $json = true) {
if($json) {
die(json_encode(($v)));
}
die("<pre>".print_r($v, true)."</pre>");
}
static function add_profile($args) {
global $wpdb;
$default = array(
'name' => '',
'accounts_id' => '',
'categories' => '',
'miravia_category' => '',
'config' => '{}',
);
$args = wp_parse_args( $args, $default );
$wpdb->insert($wpdb->prefix.'miravia_profiles',$args);
$my_id = $wpdb->insert_id;
return $my_id;
}
static function request_notify($apiKey, $message, $customSeconds = false){
$secondsNotify = !$customSeconds ? get_option('miravia_delay_time', 300) : $customSeconds;
$notify_actual = intval(get_option('miravia_notify_' . $message . '_in', 0));
$time_lost = ($notify_actual + ($secondsNotify * 1.1));
$time_now = time();
if($notify_actual >= 0 and $time_now < $time_lost ) {
LOG::add("El notify actual está establecido y es superior a {$time_now} > {$time_lost}");
return -1;
}
LOG::add("Estableciendo info notify {$secondsNotify}");
update_option('miravia_notify_' . $message . '_in', time());
$link = new MiraviaLink($apiKey);
$result = $link->subscribe($secondsNotify, $message);
if($result) {
return true;
}else{
return false;
}
}
static function add_rule($args) {
global $wpdb;
$default = array(
'name_rule' => 'No name',
'accounts' => 0,
'profile_id' => 0,
'rules_json' => '[]',
'action_json' => '[]'
);
$args = wp_parse_args( $args, $default );
$wpdb->insert($wpdb->prefix.'miravia_rules',$args);
LOG::add($wpdb->last_error);
$my_id = $wpdb->insert_id;
return $my_id;
}
static function check_product_onjob($product) {
global $wpdb;
$check = $wpdb->get_row("SELECT * FROM {$wpdb->prefix}miravia_products WHERE id_woocommerce = {$product}");
LOG::add("Comprobando si el producto {$product} esta en job {$check->status_text}");
if($check->status_text == 'IN_QUEUE') {
return true;
}
return false;
}
static function update_rule($args, $id) {
global $wpdb;
$default = array(
'name_rule' => 'No name',
'accounts' => 0,
'profile_id' => 0,
'rules_json' => '[]',
'action_json' => '[]'
);
$args = wp_parse_args( $args, $default );
if($id) {
$wpdb->update($wpdb->prefix.'miravia_rules',$args, $id);
return $id;
}
return false;
}
static function update_profile($args, $id = false) {
global $wpdb;
if($id) {
$wpdb->update($wpdb->prefix.'miravia_profiles',$args, $id);
}
return $id;
}
static function get_products_by_profile($profile = false, $need = false) {
if(!$profile) {
return false;
}
$profile = self::get_profiles($profile);
$args = array(
'posts_per_page' => -1,
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'id',
'terms' => array_map('intval', explode(',', $profile['categories'])),
'operator' => 'IN',
'include_children' => false
)
),
'post_type' => 'product',
);
if($need) {
$args['meta_query'] = array(
array(
'key' => '_miravia_need_update',
'compare' => 'EXISTS'
),
array(
'key' => '_miravia_need_update',
'compare' => '!=',
'value' => '0'
)
);
}
$saved = array();
$products = new WP_Query($args);
if($products->have_posts()) {
//Preparare products
foreach($products->posts as $p) {
$prod = new MVProduct($p->ID, $profile);
$pro = $prod->getData();
if($pro) {
$saved[] = $pro;
}
}
return $saved;
}
return false;
}
static function accounts_by_profile($profile) {
global $wpdb;
$profile = self::get_profiles($profile);
if($profile) {
return $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}miravia_accounts WHERE id IN({$profile['accounts_id']})", ARRAY_A );
}
return [];
}
static function get_local_products($page = 1, $limit = 20) {
global $wpdb;
$ofset = ($limit * $page) - $limit;
$query = "SELECT p.*,
IFNULL(COUNT(pw.ID), 0) as variationsTotal,
pp.post_title as `name`
FROM {$wpdb->prefix}miravia_products AS p
LEFT JOIN {$wpdb->prefix}posts AS pp ON pp.ID = p.id_woocommerce
LEFT JOIN {$wpdb->prefix}posts AS pw ON pw.post_parent = p.id_woocommerce AND pw.post_type = 'product_variation'
GROUP BY p.ID
LIMIT {$ofset},{$limit}";
return $wpdb->get_results( $query, ARRAY_A );
}
static function get_profiles($id = false) {
global $wpdb;
if($id) {
return $wpdb->get_row( "SELECT * FROM {$wpdb->prefix}miravia_profiles WHERE id = '{$id}'", ARRAY_A );
}
$profiles = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}miravia_profiles", ARRAY_A );
if($profiles) {
foreach($profiles as &$prof){
$prof['sync'] = self::get_products_by_profile_total($prof['categories']);
}
return $profiles;
}
return [];
}
static function get_products_by_profile_total($categories) {
global $wpdb;
if($categories == "") {
return "No categories selected";
}
$created = (array) $wpdb->get_row("SELECT COUNT(DISTINCT p.ID) AS total_created
FROM {$wpdb->prefix}posts p
INNER JOIN {$wpdb->prefix}term_relationships tr ON p.ID = tr.object_id
INNER JOIN {$wpdb->prefix}term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
INNER JOIN {$wpdb->prefix}terms t ON tt.term_id = t.term_id
WHERE tt.taxonomy = 'product_cat'
AND t.term_id IN ({$categories})");
$sync = (array) $wpdb->get_row("SELECT COUNT(DISTINCT mp.id_woocommerce) AS total_sync
FROM {$wpdb->prefix}posts p
INNER JOIN {$wpdb->prefix}term_relationships tr ON p.ID = tr.object_id
INNER JOIN {$wpdb->prefix}term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
INNER JOIN {$wpdb->prefix}terms t ON tt.term_id = t.term_id
INNER JOIN {$wpdb->prefix}miravia_products mp ON p.ID = mp.id_woocommerce AND mp.id_miravia != 0
WHERE tt.taxonomy = 'product_cat'
AND t.term_id IN ({$categories})");
// MiraviaCore::debug($created);
if($sync) {
$string = "{$sync['total_sync']} / ";
}else{
$string = "0 /";
}
if($created) {
$string .= $created['total_created'];
}else{
$string .= "0";
}
return $string;
}
static function get_profiles_by_seller($account) {
global $wpdb;
return $wpdb->get_results("SELECT
p.id
FROM
{$wpdb->prefix}miravia_profiles AS p
LEFT JOIN {$wpdb->prefix}miravia_accounts AS ma ON ma.id = p.accounts_id
WHERE
ma.userid = '{$account}'", ARRAY_A );
}
static function get_rules($id = false, $customWhere = false) {
global $wpdb;
if($id) {
return $wpdb->get_row( "SELECT * FROM {$wpdb->prefix}miravia_rules WHERE id = '{$id}'", ARRAY_A );
}else{
if($customWhere) {
return $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}miravia_rules WHERE {$customWhere}", ARRAY_A );
}
}
return $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}miravia_rules", ARRAY_A );
}
static function get_profile_by_product($sku = false) {
global $wpdb;
if($sku) {
$_product_id = wc_get_product_id_by_sku($sku);
$categories = get_the_terms( $_product_id, 'product_cat' );
foreach($categories as $c) {
$profiles = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}miravia_profiles WHERE FIND_IN_SET('{$c->term_id}', categories) > 0", ARRAY_A );
if(is_array($profiles) and count($profiles) > 0) {
return $profiles[0]['id'];
}
}
}
return false;
}
static function get_product_miravia($id = false) {
global $wpdb;
if($id) {
return $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}miravia_products WHERE id_woocommerce = '{$id}'", ARRAY_A );
}
//Is a variation...
// $parent =
return false;
}
static function get_accounts($id = false, $field = 'id') {
global $wpdb;
if($id) {
return $wpdb->get_row( "SELECT * FROM {$wpdb->prefix}miravia_accounts WHERE {$field} = '{$id}'", ARRAY_A );
}
return $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}miravia_accounts", ARRAY_A );
}
static function get_miravia_account_default($id = false, $field = 'id') {
global $wpdb;
if($id) {
return $wpdb->get_row( "SELECT * FROM {$wpdb->prefix}miravia_accounts WHERE `{$field}` = '{$id}'", ARRAY_A );
}
return $wpdb->get_row( "SELECT * FROM {$wpdb->prefix}miravia_accounts LIMIT 1", ARRAY_A );
}
static function order_exist($id) {
global $wpdb;
if($id) {
return $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}postmeta WHERE `meta_value` = '{$id}'", ARRAY_A );
}
return true;
}
static function get_product($id, $profile = 0) {
global $wpdb;
$queryProfile = "";
if($profile) {
$queryProfile = " AND profile_id = '{$profile}'";
}
return $wpdb->get_row( "SELECT * FROM {$wpdb->prefix}miravia_products WHERE id_woocommerce = '{$id}' {$queryProfile}" );
}
static function set_job_product($id, $profile, $job = 0) {
global $wpdb;
if(is_array($id)) {
$where = "id_woocommerce IN(".implode(',', $id).")";
}else{
$where = "id_woocommerce = '$id'";
}
$query = "UPDATE {$wpdb->prefix}miravia_products SET job_id='{$job}', status_text='IN_QUEUE' WHERE profile_id = {$profile} AND ". $where;
$result = $wpdb->query($query);
LOG::add("SET JOB ON PRODUCTS -> " . $query);
LOG::add($result);
}
static function set_job_product_error($id, $profile, $job = 0, $errorText = 'Generic Error') {
global $wpdb;
if(is_array($id)) {
$where = "id_woocommerce IN(".implode(',', $id).")";
}else{
$where = "id_woocommerce = '$id'";
}
$query = "UPDATE {$wpdb->prefix}miravia_products SET job_id='{$job}', lastError='{$errorText}' status_text='FAIL' WHERE profile_id = {$profile} AND ". $where;
$result = $wpdb->query($query);
LOG::add("SET JOB ON PRODUCTS -> " . $query);
LOG::add($result);
}
static function get_order_woocommerce($id) {
$order = wc_get_order($id);
$order_data = new stdClass();
$items_data = [];
$items = false;
if($order) {
$order_data->id = $id;
$order_data->total = $order->get_total();
$items = $order->get_items();
foreach($items as $item) {
array_push($items_data, wc_get_order_item_meta($item->get_id(), '_miravia_order_item_id', true));
}
}
return [$order_data, $items_data];
}
static function getCurrentRules($account_id = 0, $profile_id = 0){
$rules = self::get_rules(false, "(accounts = {$account_id} OR accounts = 0) AND (profile_id = {$profile_id} OR profile_id = '0')");
return $rules;
}
static function applyFilter($feed, $account_id, $profile_id) {
$rules = self::getCurrentRules($account_id, $profile_id);
foreach ($rules as $rule){
$jsonfilter = $rule['rules_json'];
if($jsonfilter){
if($ids = $feed->applyFilter($jsonfilter)){
switch($rule['action_type']){
case 'remove':
$feed->removeProductsById($ids);
break;
case 'only':
$feed->keepProductsById($ids);
break;
case 'price_stock':
$detail = json_decode($rule['action_json'], true);
if(is_array($detail)){
$field = $detail['field'];
$operator = $detail['operator'];
$value = $detail['value'];
$feed->applyNumericFieldAction($ids, $field, $operator, $value);
}
break;
case 'name':
$detail = json_decode($rule['action_json'], true);
if(is_array($detail)){
$field = $detail['field'];
$stringvalue = $detail['stringvalue'];
$feed->applyTextFieldAction($ids, $field, $stringvalue);
}
break;
case 'logistics':
$detail = json_decode($rule['action_json'], true);
if(is_array($detail)){
$delivery = $detail['delivery'];
$warehouse = $detail['warehouse'];
$feed->applyLogisticsAction($ids, $delivery, $warehouse);
}
break;
}
}
}
}
return $feed;
}
static function set_error_product_job($sku, $job = 0, $error = '') {
global $wpdb;
$query = "UPDATE {$wpdb->prefix}miravia_products SET lastError='{$error}', status_text='ERROR' WHERE sku = '{$sku}' AND job_id='{$job}'";
$result = $wpdb->query($query);
}
static function set_status_job($job = 0, $status = '') {
global $wpdb;
if($job) {
$query = "UPDATE {$wpdb->prefix}miravia_products SET status_text='{$status}' WHERE job_id='{$job}'";
$result = $wpdb->query($query);
}
}
static function clear_job($job = 0) {
global $wpdb;
if($job) {
$query = "UPDATE {$wpdb->prefix}miravia_products SET status_text='ND', job_id='', lastError='' WHERE job_id='{$job}'";
$result = $wpdb->query($query);
}
}
static function disconnect_product($id) {
global $wpdb;
$query = "UPDATE {$wpdb->prefix}miravia_products SET status_text='Disconected', lastError='', last_updated='NOW()', id_miravia='' WHERE id_woocommerce = '{$id}'";
$wpdb->query($query);
}
static function set_id_miravia_product_job($sku, $job = 0, $id = '') {
global $wpdb;
if($id === false) {
$query = "UPDATE {$wpdb->prefix}miravia_products SET status_text='DONE', lastError='', last_updated='NOW()' WHERE sku = '{$sku}' AND job_id='{$job}'";
}else{
$query = "UPDATE {$wpdb->prefix}miravia_products SET id_miravia='{$id}',status_text='DONE', lastError='', last_updated='NOW()' WHERE sku = '{$sku}' AND job_id='{$job}'";
}
$result = $wpdb->query($query);
}
static function get_miravia_category($product, $profile) {
$cat = $product->get_category_ids();
$category_profile_search = explode(',', $profile['categories']);
foreach($cat as $c) {
if(in_array($c, $category_profile_search)) {
return $c;
}
}
return 0;
}
static function get_attributes(WC_Product $_product, $attrs) {
$attrs = $_product->get_attributes();
// (
// [color] => WC_Product_Attribute Object
// (
// [data:protected] => Array
// (
// [id] => 0
// [name] => Color
// [options] => Array
// (
// [0] => Rojo
// )
// [position] => 0
// [visible] => 1
// [variation] =>
// )
// )
// )
// var_dump($attrs);
// die();
$attributes = [];
foreach($attrs as $key => $v) {
if(count($v['options']) == 1) {
$value = $v['options'][0];
}else{
$value = $v['options'];
}
$attributes[self::get_key_miravia_attr($key, $attrs)] = $value;
}
return $attributes;
// $map_attrs = get_term_meta($_product->get_category_ids(), "_miravia_attr", true);
}
static function get_key_miravia_attr($key, $attrs) {
if(isset($attrs->attr)) {
$attrs = $attrs->attr;
}
foreach($attrs as $k => $v) {
// MiraviaCore::debug(array($key, $attrs, $k, 'attribute_pa_'.$k == $key));
if($k == $key or 'pa_'.$k == $key or 'attribute_pa_'.$k == $key) {
return $v;
}
}
return false;
}
static function select_category($categories, $args = array('select' => '0', 'name' => 'category')) {
$html = "<select name='{$args['name']}'>";
$html .= "<option value='0'>Seleccione</option>";
foreach($categories as $c) {
// die(var_dump($c['children']));
if(isset($c['children'])) {
$html .= self::get_children_category_select($c, $args);
}else{
$selected_html = "";
if($args['select'] == $c['category_id']) { $selected_html = "selected='selected'"; }
$html .= "<option {$selected_html} value='{$c['category_id']}'>{$c['name']}</option>";
}
}
$html .= "</select>";
return esc_html($html);
}
static function get_children_category_select($categories, $args = array('select' => '0', 'name' => 'category')) {
// die(var_dump($categories));
$html = "<optgroup label='{$categories['name']}'>";
foreach($categories['children'] as $c) {
// die(var_dump($c));
if(isset($c['children'])) {
$html .= self::get_children_category_select($c, $args);
}else{
$selected_html = "";
if($args['select'] == $c['category_id']) { $selected_html = "selected='selected'"; }
$html .= "<option {$selected_html} value='{$c['category_id']}'>{$c['name']}</option>";
}
}
$html .= "</optgroup>";
return esc_html($html);
}
static function get_jobs() {
global $wpdb;
$query = "SELECT
DISTINCT(p.job_id),
COUNT(DISTINCT(p.id_woocommerce)) as total,
ac.token,
f.id,
p.updated
FROM {$wpdb->prefix}miravia_products AS p
INNER JOIN {$wpdb->prefix}miravia_profiles AS f ON p.profile_id = f.id
INNER JOIN {$wpdb->prefix}miravia_accounts AS ac ON f.accounts_id = ac.id
WHERE
p.job_id != '0' and p.job_id != ''
GROUP BY p.job_id, ac.token, f.id";
return $wpdb->get_results( $query, ARRAY_A );
}
static function get_job_detail($id = false) {
global $wpdb;
if(!$id) {
return [];
}
$query = "SELECT
p.*
FROM {$wpdb->prefix}miravia_products AS p
INNER JOIN {$wpdb->prefix}miravia_profiles AS f ON p.profile_id = f.id
INNER JOIN {$wpdb->prefix}miravia_accounts AS ac ON f.accounts_id = ac.id
WHERE
p.job_id = '{$id}'";
return $wpdb->get_results( $query, ARRAY_A );
}
static function resync_stock() {
global $wpdb;
//Actualizar todos los stocks como que necesitan actualizar y responder con un array de tokens de cuentas
$wpdb->query(
$wpdb->prepare(
"UPDATE {$wpdb->prefix}postmeta AS pm1
INNER JOIN {$wpdb->prefix}miravia_products AS pm2
ON pm1.post_id = pm2.id_woocommerce
SET pm1.meta_value = %s
WHERE pm1.meta_key = %s",
'1',
'_miravia_need_update'
)
);
return MiraviaCore::get_accounts();
}
static function procesarFeed() {
$document = sanitize_text_field($_REQUEST['document']);
$seller = sanitize_text_field($_REQUEST['seller']);
$account = MiraviaCore::get_accounts($seller,'userid');
if(!$account) {
LOG::add("Accont not found on process feed {$document}", false, 'feeds');
return false;
}
$id_seller = $account['id'];
if($id_seller) {
$link = new MiraviaLink($account['token']);
$data = $link->getFeedResult($document);
if (!empty($data)) {
$info = json_decode($data,true);
if(is_array($info) && isset($info['success']) && $info['success'] == false){
$ret['success'] = false;
$ret['error'] = $info['error'];
$txlog .= $info['error'];
}else {
$r = self::processFeedResult($seller, $data);
if ($r != 'ok') {
LOG::add("Error when process feed {$document}: {$r}", false, 'feeds');
return false;
}
}
}
}else{
LOG::add("ID Accont not found on process feed {$document}", false, 'feeds');
return false;
}
}
static public function processFeedResult($seller, $data){
if(!is_array($data)){
$data = json_decode($data, true);
}
$account = MiraviaCore::get_accounts($seller,'userid');
if(!$account){
return 'error: invalid seller';
}
if(!is_array($data)){
return 'error: invalid data';
}
foreach($data as $id => $info){
global $wpdb;
$status = isset($info['status']) ? $info['status'] : false;
$message = '?';
$item_id = '';
if($status){
$message='';
if($status=='FAIL'){
$status = 'error';
$detail = isset($info['detail']) ? $info['detail'] : false;
$message = self::getFeedDetail($detail);
}elseif($status=='SUCCESS'){
$status = 'created';
$item_id = $info['id'];
}
}else{
$status = 'error';
$message = 'Invalid response from server: ' . json_encode($info);
}
$update_fields = [
'status_text' => $status,
'lastError' => $message,
'job_id' => '',
];
if(!empty($item_id)){
$update_fields['id_miravia'] = $item_id;
}
$wpdb->update($wpdb->prefix.'miravia_products', $update_fields, array('sku' => $id,'job_id' => $_GET['feed']));
}
return 'ok';
}
static protected function getFeedDetail($tx)
{
if(is_array($tx)){
$data = $tx;
}else {
$data = json_decode($tx, true);
}
$msg = isset($data['message']) ? $data['message'] : false;
if($msg){
$data = is_array($msg) ? $msg : json_decode($msg, true);
$errorCode = isset($data['errorCode']) ? $data['errorCode'] : '0';
$errorMsg = isset($data['errorMsg']) ? $data['errorMsg'] : '0';
$errorFirst = isset($data['errors'][0]['code']) ? $data['errors'][0]['code'] : '0';
$detail = "[$errorCode] $errorMsg ($errorFirst)";
return $detail;
}
$detail = $tx;
return $detail;
}
}
}

View File

@@ -0,0 +1,77 @@
<?php
if ( ! defined( 'ABSPATH' ) ) { exit; }
class MIRAVIADB {
static function install() {
global $wpdb;
$installed_ver = get_option( "miravia_db_version", 0 );
if ($installed_ver != MIRAVIA_DB_VERSION) {
$charset_collate = $wpdb->get_charset_collate();
$sql = "CREATE TABLE {$wpdb->prefix}miravia_accounts (
id mediumint(9) NOT NULL AUTO_INCREMENT,
created datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
updated datetime DEFAULT CURRENT_TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP,
name tinytext NOT NULL,
token varchar(200) NOT NULL,
userid varchar(30) DEFAULT '' NOT NULL,
config TEXT,
lang varchar(10) NOT NULL,
email varchar(100) NOT NULL,
PRIMARY KEY (id)
) $charset_collate;";
$sql .= "CREATE TABLE {$wpdb->prefix}miravia_profiles (
id mediumint(9) NOT NULL AUTO_INCREMENT,
created datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
updated datetime DEFAULT CURRENT_TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP,
name tinytext NOT NULL,
accounts_id varchar(200) NOT NULL,
categories varchar(250) DEFAULT '' NOT NULL,
miravia_category bigint NOT NULL DEFAULT 0,
config TEXT,
PRIMARY KEY (id)
) $charset_collate;";
$sql .= "CREATE TABLE {$wpdb->prefix}miravia_products (
id mediumint(9) NOT NULL AUTO_INCREMENT,
created datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
updated datetime DEFAULT CURRENT_TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP,
last_updated datetime DEFAULT '0000-00-00 00:00:00',
id_woocommerce BIGINT NOT NULL,
sku varchar(100) NOT NULL,
id_miravia BIGINT NOT NULL,
job_id VARCHAR(100) NOT NULL DEFAULT '0',
stock INT NOT NULL DEFAULT 0,
price FLOAT(50,2) NULL DEFAULT NULL,
sale_price FLOAT(50,2) NULL DEFAULT NULL,
profile_id INT DEFAULT 0 NOT NULL,
lastError varchar(255) DEFAULT '',
status_text varchar(100) DEFAULT '',
PRIMARY KEY (id)
) $charset_collate;";
$sql .= "CREATE TABLE {$wpdb->prefix}miravia_rules (
id mediumint(9) NOT NULL AUTO_INCREMENT,
created datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
updated datetime DEFAULT CURRENT_TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP,
name_rule VARCHAR(100) NOT NULL,
accounts INT NOT NULL DEFAULT 0,
profile_id INT NOT NULL DEFAULT 0,
rules_json TEXT,
action_json TEXT,
action_type VARCHAR(100) NOT NULL,
PRIMARY KEY (id)
) $charset_collate;";
//Run SQL
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
dbDelta( $sql );
//Update bd version plugin
update_option( 'miravia_db_version', MIRAVIA_DB_VERSION );
LOG::add("La base de datos ha sido actualizada a la versión " . MIRAVIA_DB_VERSION);
}
}
}

View File

@@ -0,0 +1,11 @@
<?php
if ( ! defined( 'ABSPATH' ) ) { exit; }
if(!class_exists('MIRAVIA_LOCAL')) {
class MIRAVIA_LOCAL {
function __construct() {
}
}
}

View File

@@ -0,0 +1,60 @@
<?php
if(!class_exists('LOG')) {
class LOG {
/**
* add message to file
*
* @param string $msg String to register
* @param int|string $element Any ID or String
* @param string $type Default: user
* @return int|boolean
*/
static function add($msg, $element = false, $type = false ) {
if(!$type) {
$type = defined('LOG_DEFAULT_FILE') ? LOG_DEFAULT_FILE : 'user';
}
$root = defined('LOG_FOLDER') ? LOG_FOLDER : '/';
//If an element is defined and provided, it will be separated into files by element
$divide = defined('LOG_DIVIDE_ELEMENT');
$y = date('Y');
$m = date('m');
//Create htaccess file if no exist
if(!file_exists($root . "logs/.htaccess")) {
file_put_contents($root . "logs/.htaccess", 'Deny from all');
}
$fileDest = $root . "logs/{$y}/{$m}/";
if(!file_exists($fileDest)) {
$dir = mkdir($fileDest, 0775, true);
}
if($element && $divide) {
return file_put_contents($fileDest.$type."_{$element}.log", self::data($msg, $element, $type),FILE_APPEND);
}
return file_put_contents($fileDest.$type.".log", self::data($msg, $element, $type),FILE_APPEND);
}
/**
* Structure data
*
* @param string $msg
* @param int|string $element
* @param string $type
* @return string
*/
private static function data($msg, $element = '0', $type) {
if(is_array($msg) || is_object($msg)) {
return "[".date('Y-m-d H:i:s') . "] ". json_encode($msg, JSON_PRETTY_PRINT) . " \r\n";
}
return "[".date('Y-m-d H:i:s') . "] $msg \r\n";
}
}
}

View File

@@ -0,0 +1,120 @@
<?php
if ( ! defined( 'ABSPATH' ) ) { exit; }
if( !class_exists('MIRAVIABase') ) {
class MIRAVIABase {
private $url = "https://api.miravia.es/rest";
private $token = "50000701b37tSEfdXdiuAq0yiimwLWEyVIf3lsRgyp2yLqwX61b895957sebFoS";
private $appSecret = "8nxjS2TDTevc0AwmXh7AbKQL4XnuaE7t";
private $appKey = "500406";
private $client = false;
function __construct(){
if(!$this->client) {
$this->client = new IopClient($this->url,$this->appKey,$this->appSecret);
}
}
function secure(){
if(!$this->client) {
die(json_encode(array('error' => true, 'message' => 'No se ha establecido la conexión')));
}
}
function get($endpoint = '', $params = array()) {
$this->secure();
$request = new IopRequest($endpoint,'GET');
if($params) {
foreach($params as $k => $v) {
$request->addApiParam($k,$v);
}
}
try{
$result = $this->client->execute($request,$this->token);
}catch(Exception $e) {
return $this->error_control($e);
}
$resp = json_decode($result, true);
return $this->response($resp);
}
function post($endpoint = '', $data = array()) {
$this->secure();
$request = new IopRequest($endpoint);
if($data) {
foreach($data as $k => $v) {
$request->addApiParam($k,$v);
}
}
try{
$result = $this->client->execute($request, $this->token);
}catch(Exception $e) {
return $this->error_control($e);
}
$resp = json_decode($result, true);
return $this->response($resp);
}
function response($result) {
if(isset($result['data'])) {
return $result['data'];
}else{
//Control de errores
return $this->error_control($result);
}
}
function error_control($resp) {
// die('<pre>'.print_r($resp, true).'</pre>');
if($resp->code != '0') {
if(isset($resp->detail)) {
$errors = $resp->detail;
}else{
$errors = [$resp->message];
}
return array(
'code' => $resp->code,
'errors' => $errors
);
}else{
return array(
'code' => '-1',
'errors' => array($resp)
);
}
}
function get_images_batch($batch_id) {
return $this->get('/image/response/get', array('batch_id' => $batch_id));
}
function get_brands($page) {
$to = $page * 20;
$from = $to - 20;
return $this->get('/category/brands/query', array('start_row' => $from, "page_size" => $to));
}
function get_orders($args = array()) {
return $this->get('/orders/get', $args);
}
function get_order($args = array()) {
return $this->get('/order/get', $args);
}
function get_orders_items($args = array()) {
return $this->get('/order/items/get', $args);
}
function get_products($args = array()) {
return $this->get('/products/get', $args);
}
}
}

View File

@@ -0,0 +1,128 @@
<?php
if ( ! defined( 'ABSPATH' ) ) { exit; }
if( !class_exists('MVOrder') ) {
class MVOrder {
function __construct(){
}
function create($order_miravia = false) {
//Obtener datos del pedido
$defaultStatus = get_option('miravia_default_status', 'wc-processing');
$order = wc_create_order();
if($order_miravia['address_shipping']['customerEmail']) {
$username = $order_miravia['address_shipping']['customerEmail'];
}else{
$username = $order_miravia['order_number'];
}
$user_id = username_exists( $username );
$billing_address = array(
'first_name' => $order_miravia['address_billing']['first_name'],
'last_name' => $order_miravia['address_billing']['last_name'],
'email' => $order_miravia['address_shipping']['customerEmail'],
'phone' => $order_miravia['address_billing']['phone'],
'address_1' => "{$order_miravia['address_billing']['address1']} {$order_miravia['address_billing']['address2']} {$order_miravia['address_billing']['address3']}",
'address_2' => "{$order_miravia['address_billing']['address4']} {$order_miravia['address_billing']['address5']}",
'city' => $order_miravia['address_billing']['city'],
'state' => $order_miravia['address_billing']['country'], //Ver esto
'postcode' => $order_miravia['address_billing']['post_code'],
'country' => $order_miravia['address_billing']['country'],
);
$shipping_address = array(
'first_name' => $order_miravia['address_shipping']['firstName'],
'last_name' => $order_miravia['address_shipping']['lastName'],
'address_1' => "{$order_miravia['address_shipping']['address1']} {$order_miravia['address_shipping']['address2']} {$order_miravia['address_shipping']['address3']}",
'address_2' => "{$order_miravia['address_shipping']['address4']} {$order_miravia['address_shipping']['address5']}",
'city' => $order_miravia['address_shipping']['city'],
'state' => $order_miravia['address_shipping']['country'], //Ver esto
'postcode' => $order_miravia['address_shipping']['postCode'],
'country' => $order_miravia['address_shipping']['country'],
);
$order->set_address( $billing_address, 'billing' );
$order->set_address( $shipping_address, 'shipping' );
update_post_meta($order->ID, '_miravia_order_id', $order_miravia['order_number']);
update_post_meta($order->ID, '_miravia_account_id', $order_miravia['account_id']);
// update_post_meta($order->ID, '_miravia_order_id', $order_miravia['order_number']);
// 1. User doesn't exist - Create it - send email - set address and define
if ( ! $user_id && $user_id == false ) {
$email = $username;
$password = wp_generate_password( 12, false );
$first_name = $order_miravia['address_shipping']['firstName'];
$last_name = $order_miravia['address_shipping']['lastName'];
$user_data = array(
'user_login' => $username,
'user_pass' => $password,
'user_email' => $email,
'first_name' => $first_name,
'last_name' => $last_name,
'role' => 'customer',
);
$user_id = wp_insert_user( $user_data );
// Update Billing and shipping user data
foreach( $billing_address as $key => $value ) {
update_user_meta( $user_id, 'billing_' . $key, $value );
}
foreach( $shipping_address as $key => $value ) {
update_user_meta( $user_id, 'shipping_' . $key, $value );
}
// No send notification on create user
// WC()->mailer()->get_emails()['WC_Email_Customer_New_Account']->trigger( $user_id, $password, true );
}
// For calculating taxes on items
$calculate_taxes_for = array(
'country' => ! empty($shipping_address['country']) ? $shipping_address['country'] : $billing_address['country'],
'state' => ! empty($shipping_address['state']) ? $shipping_address['state'] : $billing_address['state'],
'postcode' => ! empty($shipping_address['postcode']) ? $shipping_address['postcode'] : $billing_address['postcode'],
'city' => ! empty($shipping_address['city']) ? $shipping_address['city'] : $billing_address['city'],
);
foreach($order_miravia['order_items'] as $k => $item) {
$this->add_product($order, $item, $calculate_taxes_for);
}
$order->set_customer_id( $user_id );
$order->set_currency( get_woocommerce_currency() );
$order->set_prices_include_tax( 'yes' === get_option( 'woocommerce_prices_include_tax' ) );
$note = 'From MIRAVIA Order';
$order->add_order_note( $note );
$order->set_customer_note( $note );
$order->set_status($defaultStatus, "Created from Miravia");
$order->calculate_totals();
$order->update_status('autoquote', true); // $order->save() is already included with update_status() method
}
function add_product($order, $product, $calculate_taxes_for) {
$product_sku = wc_get_product_id_by_sku($product['sku']);
$_product = $product_sku ? wc_get_product( $product_sku ) : false;
$cantidad = 1; //TODO ver esto
$priceWithOutTax = $product['item_price'] - (($product['item_price'] - $product['tax_amount']) / 100);
$dataLine = [
'name' => $product['name'],
'subtotal' => $priceWithOutTax,
'total' => $product['item_price']
];
$item_id = $order->add_product($_product, $cantidad, $dataLine);
wc_update_order_item_meta($item_id, '_miravia_delivery_option', $product['delivery_option_sof']);
wc_update_order_item_meta($item_id, '_miravia_order_item_id', $product['order_item_id']);
$line_item = $order->get_item( $item_id, false ); // Get the WC_Order_Item_Product Object instance from the Item Id
$line_item->calculate_taxes($calculate_taxes_for); // <== Calculating taxes
$line_item->save(); // Save data to WC_Order_Item_Product Object
}
}
}

View File

@@ -0,0 +1,125 @@
<?php
if ( ! defined( 'ABSPATH' ) ) { exit; }
if( !class_exists('ARIProduct') ) {
class ARIProduct {
private $product = false;
private $defaul_image = '';
private $category = 0;
public $ItemId = 0;
public $Images = array('Image' => array());
public $Attributes = array();
public $Skus = array('Sku' => array());
public $PrimaryCategory = 0;
function __construct($id){
$this->product = wc_get_product($id);
//Por defecto de la categoria
$terms = get_the_terms( $this->product->get_id(), 'product_cat' );
$this->category = $terms[0];
//Exist Product
$miraviaId = get_post_meta($id, '_miravia_product_id', true);
if($miraviaId) {
$this->ItemId = $miraviaId;
}
$atributos_guardados = get_term_meta($this->category->term_id, "_miravia_attr", true);
if($atributos_guardados) {
$this->Attributes = $atributos_guardados;
}
//Completar los datos básicos
$this->PrimaryCategory = get_term_meta($this->category->term_id, "_miravia_category", true);
$this->Attributes['name'] = $this->product->get_name();
$this->Attributes['description'] = $this->product->get_description();
//Cargar imagenes
$attachment_ids = $this->product->get_gallery_image_ids();
foreach( $attachment_ids as $attachment_id ) {
$this->Images['Image'][] = $this->defaul_image;
}
$this->get_skus();
}
function get_skus() {
if($this->product->is_type('simple')) {
$skus = [$this->product];
}else{
$skus = $this->product->get_available_variations();
}
foreach($skus as $index => $sku) {
$this->Skus['Sku'][$index]["SellerSku"] = $sku->get_sku();
$this->Skus['Sku'][$index]["quantity"] = $sku->get_stock_quantity();
$this->Skus['Sku'][$index]["price"] = $sku->get_regular_price();
if($sku->is_on_sale()) {
$this->Skus['Sku'][$index]["special_price"] = $sku->get_sale_price();
}
$this->Skus['Sku'][$index]["price"] = $sku->get_regular_price();
if($sku->get_manage_stock() === false) {
if($sku->get_stock_status() == "instock") {
$stock_available = intval(100); //Stock por defecto
}else{
$stock_available = 0;
}
}else{
$stock_available = $sku->get_stock_quantity();
}
$this->Skus['Sku'][$index]["quantity"] = $stock_available;
$this->Skus['Sku'][$index]["package_height"] = $sku->get_height();
$this->Skus['Sku'][$index]["package_length"] = $sku->get_length();
$this->Skus['Sku'][$index]["ean_code"] = '0'; //Implementar
$this->Skus['Sku'][$index]["package_width"] = $sku->get_width();
$this->Skus['Sku'][$index]["package_weight"] = $sku->get_weight();
$this->Skus['Sku'][$index]["package_content"] = ''; //Implementar
$attachment_ids = $sku->get_gallery_image_ids();
foreach( $attachment_ids as $attachment_id ) {
$this->Skus['Sku'][$index]["Images"]["Image"][] = $this->defaul_image;
}
}
}
function send() {
global $MIRAVIAWOO;
$send_product = json_encode(array("Request" => array("Product" => array(
'Attributes' => $this->Attributes,
'PrimaryCategory' => $this->PrimaryCategory,
'Skus' => $this->Skus,
'Images' => $this->Images
))));
$result_product = $MIRAVIAWOO->client->post('/product/create', array(
'body' => $send_product
));
return $result_product;
}
function update() {
global $MIRAVIAWOO;
$send_product = json_encode(array("Request" => array("Product" => array(
'ItemId' => $this->ItemId,
'Attributes' => $this->Attributes,
'PrimaryCategory' => $this->PrimaryCategory,
'Skus' => $this->Skus,
'Images' => $this->Images
))));
$result_product = $MIRAVIAWOO->client->post('/product/update', array(
'payload' => $send_product
));
error_log(json_encode($result_product));
return $result_product;
}
}
}

View File

@@ -0,0 +1,211 @@
<?php
if ( ! defined( 'ABSPATH' ) ) { exit; }
if( !class_exists('MVProduct') ) {
class MVProduct {
public $product = false;
public $id = 0;
public $id_woocommerce = 0;
public $id_miravia = 0;
public $profile = 0;
public $defaul_image = '';
public $last_updated = '0000-00-00 00:00:00';
function __construct($id, $profile = 0) {
global $wpdb;
$saved = MiraviaCore::get_product($id, $profile['id']);
$ean = '';
$keyEAN = get_option('miravia_ean_key', '');
if($keyEAN != '') {
$ean = get_post_meta($id, $keyEAN, true);
}
$defaultBrand = get_option('miravia_default_brand', 'No Brand');
$productBrand = get_post_meta($id, '_miravia_brand_product', true);
if($productBrand) {
$defaultBrand = $productBrand;
}
//Units
$defaultUnit = get_option('miravia_default_unit', 'units');
$defaultUnitValue = get_option('miravia_default_unit_value', '1');
$productUnit = get_post_meta($id, '_miravia_unit', true);
$productUnitValue = get_post_meta($id, '_miravia_unit_value', true);
if($productUnit) {
$defaultUnit = $productUnit;
}
if($productUnitValue) {
$defaultUnitValue = $productUnitValue;
}
// LOG::add($saved);
if($saved) {
$this->id = $saved->id;
$this->id_woocommerce = $saved->id_woocommerce;
$this->id_miravia = $saved->id_miravia;
$this->profile = $saved->profile_id;
$this->last_updated = $saved->last_updated;
$_product = wc_get_product(intval($this->id_woocommerce));
}else{
$this->id_woocommerce = $id;
//Load product
$_product = wc_get_product(intval($this->id_woocommerce));
$this->profile = $profile['id'];
$wpdb->insert($wpdb->prefix.'miravia_products', array(
'id_woocommerce' => $this->id_woocommerce,
'sku' => $_product->get_sku() ?: $id,
'id_miravia' => $this->id_miravia,
'profile_id' => $this->profile,
'stock' => $_product->get_regular_price(),
'price' => $_product->get_regular_price(),
'sale_price' => $_product->get_sale_price(),
));
$this->id = $wpdb->insert_id;
}
if($_product->get_manage_stock() === false) {
if($_product->get_stock_status() == "instock") {
$stock_available = get_option('_miravia_default_stock', 100); //Stock por defecto
}else{
$stock_available = 0;
}
}else{
$stock_available = $_product->get_stock_quantity();
}
$local_category = MiraviaCore::get_miravia_category($_product, $profile);
// $attributes_product = MiraviaCore::get_attributes($_product, $local_category);
// $attributes_product = $_product->get_attributes();
// die("<pre>".print_r($attributes_product, true)."</pre>");
$this->product = new MiraviaProduct();
$this->product->id = $this->id_woocommerce;
$this->product->id_miravia = $this->id_miravia;
$this->product->sku = $_product->get_sku() ?: $id;
$this->product->lang = 'es-ES'; // ISO lang cod
$this->product->name = $_product->get_name();
$this->product->short_description = $_product->get_short_description();
$this->product->description = $_product->get_description();
$this->product->brand = $defaultBrand;
$this->product->model = '';
$this->product->ean_code = $ean;
$this->product->warranty = '';
$this->product->id_category = $profile['miravia_category'];
$this->product->id_brand = '';
$this->product->images = []; // Se completa después
$this->product->video = '';
$this->product->price = $_product->get_regular_price();
$this->product->special_price = $_product->get_sale_price();
$this->product->width = $_product->get_width();
$this->product->height = $_product->get_height();
$this->product->length = $_product->get_length();
$this->product->weight = $_product->get_weight();
$this->product->delivery = get_option('miravia_transport_mode', 'dbm');
$this->product->info = array(
'id_category' => $local_category
);
//$this->product->extra_attributes = []; # TODO agregar caracteristicas
//Attrs
$this->product->addAttr("unit_count_type", $defaultUnit);
$this->product->addAttr("Unit_Count", $defaultUnitValue);
if($_product->is_type( 'variable' )) {
$combinations = [];
$variations = $_product->get_available_variations();
// MiraviaCore::debug($variations);
foreach($variations as $v) {
if($v['is_in_stock'] == true) {
if($v['max_qty'] == "") {
$stock_available = get_option('_miravia_default_stock', 100); //Stock por defecto
}else{
$stock_available = $v["max_qty"];
}
}else{
$stock_available = 0; //Stock por defecto
}
$ean = '';
$keyEAN = get_option('miravia_ean_key', '');
if($keyEAN != '') {
$ean = get_post_meta($v['variation_id'], $keyEAN, true);
}
$com = new MiraviaCombination();
$com->sku = $v['sku'];
$com->ean_code = $ean;
$com->price = $v['display_regular_price'];
$com->special_price = $v['display_price'];
$com->quantity = intval($stock_available);
$com->images = [];
$com->width = $v['dimensions']['width'];
$com->height = $v['dimensions']['height'];
$com->length = $v['dimensions']['length'];
$com->weight = $v['weight'];
$com->variation = [];
$encontrados = [];
$labels = [];
$lastAttribute = "";
foreach($v['attributes'] as $k => $a) {
$term_name = ( $term = get_term_by( 'slug', $a, str_replace("attribute_", "", $k) ) ) ? $term->name : $a;
$nameWithOutAttribute = str_replace("attribute_", "", $k);
if(isset($encontrados[$nameWithOutAttribute])) {
$encontrados[$nameWithOutAttribute] .= $term_name;
}else{
$encontrados[$nameWithOutAttribute] = $term_name;
}
}
foreach($encontrados as $b => $c) {
$com->addVariation($b, $c);
}
$combinations[] = $com;
}
$this->product->combinations = $combinations;
}
//Set stock
$this->product->quantity = $stock_available;
//Load images
$attachment_ids = $_product->get_gallery_image_ids();
$sizeImage = get_option('miravia_size_image', 'single-post-thumbnail');
$featured = wp_get_attachment_image_src( get_post_thumbnail_id( $this->product->id ), $sizeImage );
if($featured and is_array($featured)) {
$this->product->images[] = $featured[0];
}
foreach( $attachment_ids as $attachment_id ) {
$this->product->images[] = wp_get_attachment_image_src( $attachment_id, $sizeImage )[0];
}
}
public function getData() {
$error = false;
//Control de productos sin variaciones ni precio
if(($this->product->price == 0 or $this->product->price == "") and count($this->product->combinations) == 0) {
LOG::add("Producto {$this->product->id} no agregado por no tener precio y no tener variaciones", false, 'errors_products_send');
$error = true;
}
if(count($this->product->images) == 0) {
LOG::add("Producto {$this->product->id} no tiene imagenes, no enviado", false, 'errors_products_send');
$error = true;
}
if($error) {
return false;
}
return $this->product;
}
function send() {
return false;
}
}
}

View File

@@ -0,0 +1,11 @@
<?php
if ( ! defined( 'ABSPATH' ) ) { exit; }
if( !class_exists('ARIUi') ) {
class ARIUi {
function __construct(){
}
}
}

View File

@@ -0,0 +1,90 @@
<?php
require_once dirname(__FILE__) . '/MiraviaLink.php';
class MiraviaCategory extends MiraviaLink
{
public function getCategories($treeFormat = false)
{
$url = $this->api_url . '/category/tree';
$ret = $this->CallAPI($url);
if($ret === false){
return false;
}
$resp = json_decode($ret, true);
if(!isset($resp['success']) || !$resp['success']){
$this->last_error = $resp['error'];
return false;
}
if(isset($resp['data'])){
if($treeFormat) {
return $resp['data'];
}else{
return $this->treeToList($resp['data']);
}
}
return false;
}
public function getBrands()
{
$url = $this->api_url . '/category/brands';
$ret = $this->CallAPI($url);
if($ret === false){
return false;
}
$resp = json_decode($ret, true);
if(!isset($resp['success']) || !$resp['success']){
$this->last_error = $resp['error'];
return false;
}
if(isset($resp['data'])){
return $resp['data'];
}
return false;
}
public function getAttributes($id)
{
$url = $this->api_url . '/category/' . $id . '/attributes';
$ret = $this->CallAPI($url);
if($ret === false){
return false;
}
$resp = json_decode($ret, true);
if(!isset($resp['success']) || !$resp['success']){
$this->last_error = isset($resp['error']) ? $resp['error'] : $ret;
return false;
}
if(isset($resp['data'])){
return $resp['data'];
}
return false;
}
private function treeToList($tree = [], $prefix = '')
{
$ret = [];
$separator = $prefix=='' ? '' : ' / ';
foreach ($tree as $item) {
$name = $item['name'];
if(isset($item['children'])) {
$children = $this->treeToList($item['children'], $prefix . $separator . $name);
foreach($children as $key => $child){
$ret[] = [
'id' => $child['id'],
'name' => $child['name']
];
}
}else{
$ret[] = [
'id' => $item['category_id'],
'name' => $prefix . $separator . $name
];
}
}
return $ret;
}
}

View File

@@ -0,0 +1,59 @@
<?php
class MiraviaCombination
{
public $sku = '';
public $ean_code = '';
public $price = 0;
public $special_price = 0;
public $quantity = 0;
public $images = [];
public $width = 0;
public $height = 0;
public $length = 0;
public $weight = 0;
public $variation = [];
public function addVariation($name, $value)
{
$this->variation[$name] = $value;
}
public function getData()
{
$combination = [];
$this->weight = round((float)$this->weight, 2);
foreach ($this as $key => $value){
if($key=='ean_code' && empty($value)){
continue;
}
if($key === 'images' && is_array($value) && !empty($value)){
$combination['Images'] = ['Image' => $value];
} else if($key !== 'images') {
$combination[$key] = $value;
}
}
return $combination;
}
public function getStockData()
{
$combination = [
'sku' => $this->sku,
'price' => $this->price,
'special_price' => $this->special_price,
'quantity' => $this->quantity >= 0 ? $this->quantity : 0
];
return $combination;
}
public function getOnlyStockData()
{
$combination = [
'sku' => $this->sku,
'quantity' => $this->quantity >= 0 ? $this->quantity : 0
];
return $combination;
}
}

View File

@@ -0,0 +1,243 @@
<?php
class MiraviaFeed
{
private $products = [];
public $miravia_feed_id = '';
public $debug = false;
public $default_width = 0;
public $default_height = 0;
public $default_length = 0;
public $default_weight = 0;
public function __construct()
{
//
}
public function setProducts($products)
{
foreach($products as $p) {
$this->products[$p->id] = $p;
}
}
public function addProduct(MiraviaProduct $product)
{
$this->products[$product->id] = $product;
}
public function getProducts()
{
return $this->products;
}
public function getProductsIds()
{
return array_keys($this->products);
}
public function getJsonCreate($offset = 0, $limit = 200)
{
$ret = [];
$prods = array_slice($this->products, $offset, $limit);
foreach ($prods as $p) {
if($p->created==0){
$this->setDefaultValues($p);
$ret[] = $p->getData();
}
}
if(empty($ret)){
return false;
}
$ret = [
'products' => $ret
];
$flags = $this->debug ? JSON_PRETTY_PRINT : 0;
return json_encode($ret, $flags);
}
public function getJsonUpdate($offset = 0, $limit = 200)
{
$ret = [];
$prods = array_slice($this->products, $offset, $limit);
foreach ($prods as $p) {
if($p->created==1 && strlen($p->id_miravia)>14){
$this->setDefaultValues($p);
$ret[] = $p->getData();
}
}
if(empty($ret)){
return false;
}
$ret = [
'products' => $ret
];
$flags = $this->debug ? JSON_PRETTY_PRINT : 0;
return json_encode($ret, $flags);
}
public function setDefaultValues(MiraviaProduct &$product)
{
if((float)$product->weight == 0) $product->weight = $this->default_weight;
if((int)$product->height == 0) $product->height = $this->default_height;
if((int)$product->width == 0) $product->width = $this->default_width;
if((int)$product->length == 0) $product->length = $this->default_length;
}
public function getJsonUpdateStock($onlyStock = false, $offset = 0, $limit = 200)
{
$ret = [];
$prods = array_slice($this->products, $offset, $limit);
foreach ($prods as $p) {
if(!empty($p->id_miravia)){
if($onlyStock) {
$ret[] = $p->getOnlyStockData();
}else{
$ret[] = $p->getStockData();
}
}
}
if(empty($ret)){
return false;
}
$ret = [
'products' => $ret
];
$flags = $this->debug ? JSON_PRETTY_PRINT : 0;
return json_encode($ret, $flags);
}
public function applyFilter($jsonFilter)
{
if(empty($jsonFilter)){
return false;
}
$filter = new MiraviaFilter($jsonFilter);
if($ids = $filter->parseRecords($this->products)){
return $ids;
}
return false;
}
public function removeProductsById($ids)
{
if(!is_array($ids)){
$ids = [$ids];
}
foreach ($ids as $id){
unset($this->products[$id]);
}
}
public function keepProductsById($ids)
{
if(!is_array($ids)){
$ids = [$ids];
}
$keys = array_keys($this->products);
$ids = array_diff($keys, $ids);
foreach ($ids as $id){
unset($this->products[$id]);
}
}
public function applyNumericFieldAction($ids, $fields, $action, $value)
{
$afields = explode(',',$fields);
foreach ($afields as $field){
foreach ($ids as $id){
if(isset($this->products[$id])){
switch ($action){
case 'increment':
if($this->products[$id]->{$field}) {
$this->products[$id]->{$field} = (float)$this->products[$id]->{$field} + (float)$value;
}
foreach($this->products[$id]->combinations as &$combi){
$combi->{$field} += (float)$value;
}
break;
case 'decrement':
if($this->products[$id]->{$field}) {
$this->products[$id]->{$field} -= (float)$value;
}
foreach($this->products[$id]->combinations as &$combi){
$combi->{$field} -= (float)$value;
}
break;
case 'increment_percent':
if($this->products[$id]->{$field}) {
$this->products[$id]->{$field} += ((float)$this->products[$id]->{$field} * (float)$value / 100);
}
foreach($this->products[$id]->combinations as &$combi){
$combi->{$field} += ((float)$combi->{$field} * (float)$value / 100);
}
break;
case 'decrement_percent':
if($this->products[$id]->{$field}) {
$this->products[$id]->{$field} -= ((float)$this->products[$id]->{$field} * (float)$value / 100);
}
foreach($this->products[$id]->combinations as &$combi){
$combi->{$field} -= ((float)$combi->{$field} * (float)$value / 100);
}
break;
case 'multiply':
if($this->products[$id]->{$field}) {
$this->products[$id]->{$field} = ((float)$this->products[$id]->{$field} * (float)$value );
}
foreach($this->products[$id]->combinations as &$combi){
$combi->{$field} = ((float)$combi->{$field} * (float)$value );
}
break;
case 'set':
if($this->products[$id]->{$field}) {
$this->products[$id]->{$field} = (float)$value;
}
foreach($this->products[$id]->combinations as &$combi){
$combi->{$field} = (float)$value;
}
break;
}
}
}
}
}
public function applyTextFieldAction($ids, $field, $template)
{
foreach ($ids as $id) {
if (isset($this->products[$id])) {
$replaces = [
'name' => $this->products[$id]->name,
'description' => $this->products[$id]->description,
'short_description' => $this->products[$id]->short_description,
'manufacturer' => $this->products[$id]->getInfoValue('manufacturer'),
'supplier' => $this->products[$id]->getInfoValue('supplier'),
'category' => $this->products[$id]->getInfoValue('category'),
];
$this->products[$id]->{$field} = $template;
foreach($replaces as $search => $replace){
$this->products[$id]->{$field} = str_replace('%' . $search .'%', $replace, $this->products[$id]->{$field});
}
}
}
}
public function applyLogisticsAction($ids, $delivery, $warehouse)
{
foreach ($ids as $id) {
if (isset($this->products[$id])) {
$this->products[$id]->delivery = $delivery;
$this->products[$id]->warehouse = $warehouse;
}
}
}
public function getProductCount()
{
return sizeof($this->products);
}
}

View File

@@ -0,0 +1,134 @@
<?php
class MiraviaFilter
{
private $definition;
public function __construct($json)
{
$this->definition = json_decode($json, true);
}
/*
* Return a list of keys
*/
public function parseRecords($products)
{
if(!is_array($this->definition)){
return false;
}
$ret = [];
if(is_array($products)) {
foreach ($products as $key => $product) {
if ($this->parseGroup($this->definition, $product)) {
// condition is met
$ret[] = $product->id;
}else{
//$ret[] = "NO: " . $key;
}
}
}
return $ret;
}
private function parseGroup($condition, $product)
{
$final_result = false;
$rules_parsed = 0;
foreach ($condition as $rule){
$operator = $rule['logical_operator'];
if(!isset($rule['element_rule_id'])){
// group
$result = $this->parseGroup($rule, $product);
}else{
$result = $this->parseCondition($rule['condition'], $product);
}
if($rules_parsed==0){
$final_result = $result;
}else{
switch ($operator){
case 'OR':
$final_result = $final_result || $result;
break;
case 'AND':
$final_result = $final_result && $result;
break;
}
}
}
return $final_result;
}
private function parseCondition($condition, $product)
{
switch ($condition['field']){
case 'product_name':
$field = $product->name;
break;
case 'price':
$field = $product->price;
break;
case 'specific_price':
$field = $product->special_price;
break;
case 'stock':
$field = $product->quantity;
break;
case 'category':
$field = $product->info['id_category'];
break;
case 'supplier':
$field = $product->info['id_supplier'];
break;
case 'manufacturer':
$field = $product->info['id_manufacturer'];
break;
}
switch($condition['operator']){
case 'equal':
$value = $condition['filterValue'][0];
return $field==$value;
case 'not_equal':
$value = $condition['filterValue'][0];
return $field!=$value;
case 'less':
$value = $condition['filterValue'][0];
return $field<$value;
case 'less_or_equal':
$value = $condition['filterValue'][0];
return $field<=$value;
case 'greater':
$value = $condition['filterValue'][0];
return $field>$value;
case 'greater_or_equal':
$value = $condition['filterValue'][0];
return $field>=$value;
case 'begins_with':
$value = $condition['filterValue'][0];
return (substr($field, 0, strlen($value)) === $value);
case 'contains':
$value = $condition['filterValue'][0];
return (stripos($field, $value)!=false);
case 'ends_with':
$value = $condition['filterValue'][0];
return (substr($field, -1 * strlen($value)) === $value);
case 'not_begins_with':
$value = $condition['filterValue'][0];
return !(substr($field, 0, strlen($value)) === $value);
case 'not_contains':
$value = $condition['filterValue'][0];
return !(stripos($field, $value)!=false);
case 'not_ends_with':
$value = $condition['filterValue'][0];
return !(substr($field, -1 * strlen($value)) === $value);
case 'is_null':
case 'is_empty':
return empty($field);
case 'is_not_null':
case 'is_not_empty':
return !empty($field);
}
return false;
}
}

View File

@@ -0,0 +1,63 @@
<?php
class MiraviaLang
{
const ENGLISH = 'en';
const ARABIC = 'ar';
const GERMAN = 'de';
const SPANISH = 'es';
const FRENCH = 'fr';
const INDONESIAN = 'in';
const ITALIAN = 'it';
const HEBREW = 'iw';
const JAPANESE = 'ja';
const KOREAN = 'ko';
const DUTCH = 'nl';
const POLISH = 'pl';
const PORTUGUESE = 'pt';
const RUSSIAN = 'ru';
const THAI = 'th';
const TURKISH = 'tr';
const VIETNAMESE = 'vi';
public static $LanguagesISO = [
'ENGLISH' => 'en',
'ARABIC' => 'ar',
'GERMAN' => 'de',
'SPANISH' => 'es',
'FRENCH' => 'fr',
'INDONESIAN' => 'in',
'ITALIAN' => 'it',
'HEBREW' => 'iw',
'JAPANESE' => 'ja',
'KOREAN' => 'ko',
'DUTCH' => 'nl',
'POLISH' => 'pl',
'PORTUGUESE' => 'pt',
'RUSSIAN' => 'ru',
'THAI' => 'th',
'TURKISH' => 'tr',
'VIETNAMESE' => 'vi',
];
public static $Languages = [
'en' => 'en_US',
'ar' => 'ar_MA',
'de' => 'de_DE',
'es' => 'es_ES',
'fr' => 'fr_FR',
'in' => 'in_ID',
'it' => 'it_IT',
'iw' => 'iw_IL',
'ja' => 'ja_JP',
'ko' => 'ko_KR',
'nl' => 'nl_NL',
'pl' => 'pl_PL',
'pt' => 'pt_BR',
'ru' => 'ru_RU',
'th' => 'th_TH',
'tr' => 'tr_TR',
'vi' => 'vi_VN',
];
}

View File

@@ -0,0 +1,541 @@
<?php
class MiraviaLink
{
protected $api_url = 'https://miravia.wecomm.es';
protected $api_key = '';
public $last_error = '';
public $request_id = '';
public $insecure_mode = true;
public $sandbox_mode = false;
public function __construct($api_key = '')
{
$this->api_key = $api_key;
if( strpos($api_key, '_f6649cb881216ce050bd0e3') ){
$this->sandbox_mode = true;
$this->api_url = 'https://sandbox.miravia.wecomm.es';
}
}
public function getRegisterUrl($callback_url)
{
$url = $this->api_url . '/token';
$ret = $this->CallAPI($url, 'POST',
array('callback_url' => $callback_url));
if($ret === false){
return '';
}
$response = json_decode($ret, true);
if(!is_array($response)){
$last_error = $ret;
return '';
}
if(isset($response['error'])){
$this->last_error = $response['error'];
}
$url = isset($response['url']) ? $response['url'] : '';
$this->request_id = isset($response['request_id']) ? $response['request_id'] : '';
return $url;
}
public function getSellerInfo($notify_endpoint = '')
{
$url = $this->api_url . '/seller/info';
$ret = $this->CallAPI($url);
if($ret === false){
return false;
}
$resp = json_decode($ret, true);
if(!isset($resp['success']) || !$resp['success']){
//$this->last_error = print_r($resp,true);
return false;
}
// update data
$url = $this->api_url . '/seller/update';
if(!empty($notify_endpoint)){
$data = [ 'notification_url' => $notify_endpoint ];
}
$data = json_encode($data);
$ret = $this->CallAPI($url, 'POST', $data);
if(isset($resp['seller'])){
return $resp['seller'];
}
//$this->last_error = print_r($resp,true);
return false;
}
public function getWarehouses()
{
$url = $this->api_url . '/seller/warehouses';
$ret = $this->CallAPI($url);
if($ret === false){
return false;
}
$resp = json_decode($ret, true);
if(!isset($resp['success']) || !$resp['success']){
$this->last_error = print_r($resp,true);
return false;
}
if(isset($resp['module'])){
return $resp['module'];
}
return false;
}
public function getFeedResult($document)
{
$url = $this->api_url . '/feed/result/' . $document;
$ret = $this->CallAPI($url);
return $ret;
}
public function createProduct($json_product)
{
$url = $this->api_url . '/product/create';
$ret = $this->CallAPI($url, 'POST', $json_product);
if($ret === false){
return false;
}
$resp = json_decode($ret, true);
if(!isset($resp['success'])){
return false;
}else if(!$resp['success']){
$this->last_error = $resp['message'];
if(isset($resp['detail'])){
foreach ($resp['detail'] as $det){
$this->last_error .= "\r" . $det['field'] . ': ' . $det['message'];
}
}
}
return $resp;
}
public function updateProduct($miravia_id, $json_product)
{
$url = $this->api_url . '/product/' . $miravia_id . '/update';
$ret = $this->CallAPI($url, 'POST', $json_product);
if($ret === false){
return false;
}
$resp = json_decode($ret, true);
if(!isset($resp['success'])){
return false;
}else if(!$resp['success']){
$this->last_error = $resp['message'];
if(isset($resp['detail'])){
foreach ($resp['detail'] as $det){
$this->last_error .= "\r" . $det['field'] . ': ' . $det['message'];
}
}
}
return $resp;
}
public function getProductList($page = 1, $pagesize = 50)
{
$url = $this->api_url . '/product/list?pagesize=' . $pagesize . '&page=' . $page;
$ret = $this->CallAPI($url);
return json_decode($ret, true);
}
public function getProductBySku($sku)
{
$url = $this->api_url . '/product/' . $sku . '/find';
$ret = $this->CallAPI($url);
return json_decode($ret);
}
public function getProductById($id)
{
$url = $this->api_url . '/product/' . $id . '/get';
$ret = $this->CallAPI($url);
return json_decode($ret);
}
public function updateStock($json_stock, $use_feed = false)
{
if($use_feed){
$url = $this->api_url . '/feed/stock';
}else{
$url = $this->api_url . '/product/update_stock';
}
$ret = $this->CallAPI($url, 'POST', $json_stock);
if($ret === false){
return false;
}
$resp = json_decode($ret, true);
if(!isset($resp['success'])){
return false;
}else if(!$resp['success']){
$this->last_error = $resp['message'];
if(isset($resp['detail'])){
foreach ($resp['detail'] as $det){
$this->last_error .= "\r" . $det['field'] . ': ' . $det['message'];
}
}
}
return $resp;
}
public function disableProducts($itemids)
{
if(!is_array($itemids)){
$itemids = [$itemids];
}
$itemids = json_encode([
'item_ids' => $itemids
]);
$url = $this->api_url . '/product/disable';
$ret = $this->CallAPI($url, 'POST', $itemids);
if($ret === false){
return false;
}
$resp = json_decode($ret, true);
if(!isset($resp['success'])){
return false;
}else {
return (bool) $resp['success'];
}
}
public function enableProducts($itemids)
{
if(!is_array($itemids)){
$itemids = [$itemids];
}
$itemids = json_encode([
'item_ids' => $itemids
]);
$url = $this->api_url . '/product/enable';
$ret = $this->CallAPI($url, 'POST', $itemids);
if($ret === false){
return false;
}
$resp = json_decode($ret, true);
if(!isset($resp['success'])){
return false;
}else {
return (bool) $resp['success'];
}
}
public function deleteProduct($itemid)
{
$url = $this->api_url . '/product/' . $itemid . '/delete';
$ret = $this->CallAPI($url, 'GET');
if($ret === false){
return false;
}
$resp = json_decode($ret, true);
if(!isset($resp['success'])){
return false;
}else {
return (bool) $resp['success'];
}
}
public function getFeeds()
{
$url = $this->api_url . '/feed/list';
$ret = $this->CallAPI($url);
if($ret === false){
return false;
}
$resp = json_decode($ret, true);
if(!isset($resp['success']) || !$resp['success']){
return false;
}
if(isset($resp['feeds'])){
return $resp['feeds'];
}
//$this->last_error = print_r($resp,true);
return false;
}
public function getFeedInfo($id)
{
$url = $this->api_url . '/feed/' . $id . '/get' ;
$ret = $this->CallAPI($url);
if($ret === false){
return false;
}
$resp = json_decode($ret, true);
if(isset($resp['feed_result'])) {
$response = [];
if(isset($resp['response'])) {
$response = $resp['response'];
}
$resp = $resp['feed_result'];
$resp['response'] = $response;
}else{
if(isset($resp['code'])){
$this->last_error = $resp['code'] . ': ' .
@$resp['message'] ?: '';
}
}
if(!isset($resp['success']) || !$resp['success']){
return false;
}
return $resp;
}
public function cancelFeed($id)
{
$url = $this->api_url . '/feed/' . $id . '/cancel' ;
$ret = $this->CallAPI($url, 'POST');
if($ret === false){
return false;
}
$resp = json_decode($ret, true);
if(isset($resp['feed_result'])) {
$resp = $resp['feed_result'];
}
if(!isset($resp['success']) || !$resp['success']){
return false;
}
return $resp;
}
public function sendFeed($data, $type = 'create')
{
$url = $this->api_url . '/feed/' . $type;
$ret = $this->CallAPI($url, 'POST', $data);
if($ret === false){
return false;
}
$resp = json_decode($ret, true);
if(!isset($resp['success'])){
return false;
}else if(!$resp['success']){
// $this->last_error = $resp['message'];
if(isset($resp['detail'])){
foreach ($resp['detail'] as $det){
$this->last_error .= "\r" . $det['field'] . ': ' . $det['message'];
}
}
}
return $resp;
}
/*
* $fromDate format: YYYY-MM-DD ('Y-m-d')
*/
public function getOrders(string $fromDate)
{
if($d = date_parse_from_format('Y-m-d', $fromDate)){
$fromDate = date('Y-m-d', mktime(0, 0, 0, $d['month'], $d['day'], $d['year']));
}else{
$this->last_error= 'Invalid date';
return false;
}
$url = $this->api_url . '/order/list';
$url .= '?from_date=' . $fromDate;
$ret = $this->CallAPI($url);
if($ret === false){
return false;
}
$resp = json_decode($ret, true);
if(!isset($resp['success']) || !$resp['success']){
return false;
}
return $resp;
}
public function getOrder($order_number)
{
$url = $this->api_url . '/order/' . $order_number . '/get';
$ret = $this->CallAPI($url);
if($ret === false){
return false;
}
$resp = json_decode($ret, true);
if(!isset($resp['success']) || !$resp['success']){
return false;
}
return $resp;
}
public function orderConfirmation($order_number, $status)
{
$url = $this->api_url . '/order/confirmation/' . $order_number . '/' . $status;
$ret = $this->CallAPI($url);
if($ret === false){
return false;
}
$resp = json_decode($ret, true);
if(!isset($resp['success']) || !$resp['success']){
return false;
}
return $resp;
}
public function orderPack($id_order, $products)
{
$url = $this->api_url . '/order/' . $id_order . '/pack';
if(is_array($products)){
$data = json_encode($products);
}else{
$data = $products;
}
$ret = $this->CallAPI($url , 'POST', $data);
if($ret === false){
return false;
}
$resp = json_decode($ret, true);
if(!isset($resp['success']) || !$resp['success']){
return false;
}
return $resp;
}
public function getShippingLabel($package_id)
{
$url = $this->api_url . '/order/label/' . $package_id;
$ret = $this->CallAPI($url);
if($ret === false){
return false;
}
$resp = json_decode($ret, true);
if(!isset($resp['success']) || !$resp['success']){
return false;
}
return $resp;
}
public function getDBSCarriers()
{
$url = $this->api_url . '/order/dbs/providers';
$ret = $this->CallAPI($url);
if($ret === false){
return false;
}
$resp = json_decode($ret, true);
if(isset($resp['result'])){
$resp = $resp['result'];
}
if(!isset($resp['success']) || !$resp['success']){
return false;
}
return $resp;
}
public function setDBSTracking($packages, $tracking, $provider)
{
if(!is_array($packages)){
$packages = [$packages];
}
$payload = [];
foreach ($packages as $package){
$payload['packages'][] = [
'package_id' => $package,
'tracking_number' => $tracking,
'shipment_provider_code' => $provider
];
}
$url = $this->api_url . '/order/dbs/update_tracking';
$data = json_encode($payload);
$ret = $this->CallAPI($url, 'POST', $data);
$resp = json_decode($ret, true);
if(!isset($resp['success']) || !$resp['success']){
$this->last_error = $ret;
return false;
}
return true;
}
public function subscribe($seconds, $message='')
{
$url = $this->api_url . '/seller/notify/' . (int)$seconds;
if(!empty($message)){
$url .= '?message=' . urlencode($message);
}
$ret = $this->CallAPI($url);
if($ret === false){
return false;
}
$resp = json_decode($ret, true);
if(!isset($resp['success']) || !$resp['success']){
return false;
}
return true;
}
public function purgeImageCache()
{
$url = $this->api_url . '/image/cache/purge';
$ret = $this->CallAPI($url);
return json_decode($ret, true);
}
protected function CallAPI($url, $method='GET', $data = false)
{
$curl = curl_init();
switch ($method)
{
case "POST":
curl_setopt($curl, CURLOPT_POST, 1);
if ($data) {
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
break;
case "PUT":
curl_setopt($curl, CURLOPT_PUT, 1);
break;
default:
if ($data)
$url = sprintf("%s?%s", $url, http_build_query($data));
}
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
if($this->insecure_mode) {
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
}
if(!empty($this->api_key)){
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Api-Token: ' . $this->api_key
));
}
$result = curl_exec($curl);
if($result === false){
$this->last_error = curl_error($curl);
}
curl_close($curl);
return $result;
}
}

View File

@@ -0,0 +1,186 @@
<?php
class MiraviaProduct
{
public $id = 0;
public $id_miravia = '';
public $miravia_status = '';
public $created = 0;
public $sku = '';
public $reference_sku = '';
public $lang = 'es-ES'; // ISO lang code
public $name = '';
public $short_description = '';
public $description = '';
public $brand = 'no brand';
public $model = '';
public $ean_code = '';
public $warranty = '';
public $id_category = '';
public $id_brand = '';
public $images = []; // Public URLs
public $video = '';
public $price = 0;
public $special_price = 0;
public $quantity = 0;
public $width = 0;
public $height = 0;
public $length = 0;
public $weight = 0;
public $warehouse = '';
public $delivery = '';
public $extra_attributes = []; // [ "id_attribute" => "value", ... ]
public $combinations = []; // Array of MiraviaCombination class
public $info = []; // Internal info (for filters)
protected $private_vars = ['private_vars', 'error', 'id', 'combinations', 'info'];
public $error = '';
public function __construct()
{
//
}
public function addAttr($key = false, $value = false) {
if($key and $value) {
$this->extra_attributes[$key] = $value;
}
}
public function getData()
{
$product = [];
foreach ($this as $key => $value){
if(!in_array($key, $this->private_vars)){
if($key === 'images' && is_array($value) && !empty($value)){
$product['Images'] = ['Image' => $value];
} else if($key !== 'images') {
$product[$key] = $value;
}
}
}
$combinations = $this->getCombinations();
$product['combinations'] = $combinations;
return $product;
}
public function getStockData()
{
$combis = [];
foreach ($this->combinations as $combination){
$combis[] = $combination->getStockData();
}
if(count($combis)==0){
$combis =[[
'sku' => $this->sku,
'price' => $this->price,
'special_price' => $this->special_price,
'quantity' => $this->quantity >= 0 ? $this->quantity : 0
]];
$this->reference_sku = $this->sku;
}
$ret = [
'id' => $this->id,
'id_miravia' => $this->id_miravia,
'sku' => $this->sku,
'combinations' => $combis
];
if(!empty($this->warehouse)){
$ret['warehouse'] = $this->warehouse;
}
return $ret;
}
public function getOnlyStockData()
{
$combis = [];
foreach ($this->combinations as $combination){
$combis[] = $combination->getOnlyStockData();
}
if(count($combis)==0){
$combis =[[
'sku' => $this->sku,
'quantity' => $this->quantity >= 0 ? $this->quantity : 0
]];
$this->reference_sku = $this->sku;
}
$ret = [
'id' => $this->id,
'id_miravia' => $this->id_miravia,
'sku' => $this->sku,
'combinations' => $combis
];
if(!empty($this->warehouse)){
$ret['warehouse'] = $this->warehouse;
}
return $ret;
}
public function getJSON($pretty = false)
{
$flags = $pretty ? JSON_PRETTY_PRINT : 0;
return json_encode($this->getData(), $flags);
}
public function getCombinations()
{
$ret = [];
foreach ($this->combinations as $combination){
$ret[] = $combination->getData();
}
return $ret;
}
public function createProduct($apiKey)
{
if(!empty($this->id_miravia)){
return $this->updateProduct($apiKey);
}
$jreq = json_encode($this->getData());
$link = new MiraviaLink($apiKey);
$ret = $link->createProduct($jreq);
if($ret == false) {
$this->error = $link->last_error;
}
if(isset($ret['data'])){
if(isset($ret['data']['item_id'])){
$this->id_miravia = $ret['data']['item_id'];
}
}
return true;
}
public function updateProduct($apiKey)
{
if(empty($this->id_miravia)){
$this->error = 'Invalid Miravia Id Product';
return false;
}
$jreq = json_encode($this->getData());
$link = new MiraviaLink($apiKey);
$ret = $link->updateProduct($this->id_miravia, $jreq);
if($ret == false) {
$this->error = $link->last_error;
}
if(isset($ret['data'])){
if(isset($ret['data']['item_id'])){
$this->id_miravia = $ret['data']['item_id'];
}
return true;
}
if(isset($ret['message'])){
$this->error = $ret['message'];
}
return false;
}
public function getInfoValue($field)
{
if(isset($this->info[$field])){
return $this->info[$field];
}
return '';
}
}

View File

@@ -0,0 +1,173 @@
<?php
if ( ! defined( 'ABSPATH' ) ) { exit; }
// WP_List_Table is not loaded automatically so we need to load it in our application
if( ! class_exists( 'WP_List_Table' ) ) {
require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
}
/**
* Create a new table class that will extend the WP_List_Table
*/
class MiraviaTable extends WP_List_Table
{
/**
* Prepare the items for the table to process
*
* @return Void
*/
public $data_table = array();
public $total_elements = 0;
public $perPage = 10;
public $columns = [];
public $custom_actions = [];
public $sortable_custom_columns = [];
public $default_column_name = 'name';
function extra_tablenav( $which ) {
// if ( $which == "top" ){
// echo '<h2>Letter Templates <a href="admin.php?page=letter-template&type=new">Add New</a></h2>';
// }
}
public function prepare_items()
{
$hidden = $this->get_hidden_columns();
$sortable = $this->get_sortable_columns();
$data = $this->table_data();
usort( $data, array( &$this, 'sort_data' ) );
$perPage = $this->perPage;
$currentPage = $this->get_pagenum();
$totalItems = $this->total_elements;
$this->set_pagination_args( array(
'total_items' => $totalItems,
'per_page' => $perPage
) );
$data = array_slice($data,(($currentPage-1)*$perPage),$perPage);
$this->_column_headers = array($this->columns, $hidden, $sortable);
$this->items = $data;
}
/**
* Override the parent columns method. Defines the columns to use in your listing table
*
* @return Array
*/
public function get_columns()
{
return $this->columns;
}
/**
* Define which columns are hidden
*
* @return Array
*/
public function get_hidden_columns()
{
return array();
}
/**
* Define the sortable columns
*
* @return Array
*/
public function get_sortable_columns()
{
$sortable = array();
// if($this->total_elements and count($this->data_table) > 0) {
// foreach($this->data_table[0] as $k => $v) {
// $sortable[$k] = array($k, false);
// }
// }
return $this->sortable_custom_columns;
}
/**
* Get the table data
*
* @return Array
*/
private function table_data()
{
return $this->data_table;
}
/**
* Define what data to show on each column of the table
*
* @param Array $item Data
* @param String $column_name - Current column name
*
* @return Mixed
*/
public function column_default( $item, $column_name )
{
return $item[ $column_name ];
}
public function column_name($item){
$item_json = json_decode(json_encode($item), true);
$copy = $this->custom_actions;
foreach($this->custom_actions as $k => $action) {
foreach($item_json as $key => $d) {
$action = str_replace("[".$key."]", $item_json[$key], $action);
}
$this->custom_actions[$k] = $action;
}
$result = sprintf('%s %s', $item_json[$this->default_column_name], $this->row_actions($this->custom_actions));
$this->custom_actions = $copy;
return $result;
}
/**
* Allows you to sort the data by the variables set in the $_GET
*
* @return Mixed
*/
private function sort_data( $a, $b )
{
// Set defaults
$orderby = 'title';
$order = 'asc';
// If orderby is set, use this as the sort column
if(!empty($_GET['orderby']))
{
$orderby = sanitize_text_field($_GET['orderby']);
}
// If order is set use this as the order
if(!empty($_GET['order']))
{
$order = sanitize_text_field($_GET['order']);
}
$result = '';
if(isset($a[$orderby])) {
$result = strcmp( $a[$orderby], $b[$orderby] );
}
if($order === 'asc')
{
return $result;
}
return -$result;
}
}