'', '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("
".print_r($v, true).""); } 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}"); if($check) { LOG::add("DEBUG: Product {$product} found in DB - Status: {$check->status_text}, Job ID: {$check->job_id}, Last Error: {$check->lastError}"); if($check->status_text == 'IN_QUEUE') { LOG::add("DEBUG: Product {$product} is IN_QUEUE - blocking new submission"); return true; } LOG::add("DEBUG: Product {$product} not in queue (status: {$check->status_text}) - allowing submission"); } else { LOG::add("DEBUG: Product {$product} not found in miravia_products table - allowing submission"); } 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).")"; LOG::add("DEBUG: Setting job for multiple products: " . implode(',', $id)); }else{ $where = "id_woocommerce = '$id'"; LOG::add("DEBUG: Setting job for single product: {$id}"); } LOG::add("DEBUG: Setting job ID {$job} for profile {$profile}"); $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("DEBUG: Set job query executed: " . $query); LOG::add("DEBUG: Set job query affected {$result} rows"); if($result === false) { LOG::add("DEBUG: Set job query FAILED - SQL Error: " . $wpdb->last_error); } elseif($result == 0) { LOG::add("DEBUG: Set job query affected 0 rows - products may not exist or already have this status"); } } 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 = ""; return esc_html($html); } static function get_children_category_select($categories, $args = array('select' => '0', 'name' => 'category')) { // die(var_dump($categories)); $html = ""; 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; } } }