require_once( get_template_directory() . '/includes/products/elastic-search-api.php' ); require_once( get_template_directory() . '/includes/user/mailchimp.php' ); require_once( get_template_directory() . '/includes/products/manual_products.php' ); function savePimImage($data) { require_once(ABSPATH . 'wp-admin/includes/media.php'); require_once(ABSPATH . 'wp-admin/includes/file.php'); require_once(ABSPATH . 'wp-admin/includes/image.php'); dump('Start to update product: ' . $data); $image = json_decode($data); if (empty($image->image_url) || empty($image->pim_id)) { error_log('Image is wrong:' . $data); } //get product by pim_id $product = getProductByPIMId((int)$image->pim_id); $id_product = $product->get_ID(); if (!$product) { error_log('PIM product not found: ' . $image->pim_id); return false; } /** * Remove old images that was related with current product */ if ((int)$image->position === 0) { removeProductImages($product); } //TODO: on prod is not working $image_id = media_sideload_image( $image->image_url, null, '', 'id'); if (!$image_id) { error_log('Image was not downloaded:' . $image->image_url); return false; } // If the image is first, set it like thumbnail. The rest of images add in gallery if (!(int)$image->position) { dump('Set thumb'); update_post_meta($id_product, '_thumbnail_id', $image_id); } else { $gallery = get_post_meta($id_product, '_product_image_gallery', true); update_post_meta($id_product, '_product_image_gallery', $gallery . (!empty($gallery) ? ',' : '') . $image_id); } dump([ 'im_id' => $image_id, 'post' => $id_product, 'thnb' => $product->get_image_id(), 'galer' => $product->get_gallery_image_ids() ]); if (class_exists('WP_Smush')) { WP_Smush::get_instance()->core()->mod->smush->wp_smush_handle_async( $image_id ); } dump('FINISH: ' . $image->image_url); } function removeProductImages($product) { $images_ids = array_merge([(int)$product->get_image_id()], $product->get_gallery_image_ids()); dump('List of old files:' . json_encode($images_ids) ) ; foreach ( $images_ids as $id_attachment ) { $id_attachment = (int)$id_attachment; if (!$id_attachment) { continue; } $file = get_attached_file( (int)$id_attachment ); //dump("File removing($id_attachment):" . json_encode($file) ) ; if ($file !== '' && file_exists($file)) { wp_delete_file( $file ); } wp_delete_attachment( $id_attachment, true ); } update_post_meta($product->get_ID(), '_thumbnail_id', ''); update_post_meta($product->get_ID(), '_product_image_gallery', ''); } add_filter( 'woocommerce_checkout_fields' , 'trigger_update_checkout_on_change' ); function trigger_update_checkout_on_change( $fields ) { $fields['billing']['billing_phone']['label'] = __t('Phone Number'); $fields['billing']['billing_first_name']['label'] = __t('First Name'); $fields['billing']['billing_last_name']['label'] = __t('Last Name'); $fields['billing']['billing_postcode']['label'] = __t('Post Code / Zip'); $fields['billing']['billing_city']['label'] = __t('City'); $fields['billing']['billing_country']['label'] = __t('Country'); $fields['billing']['billing_address_1']['label'] = __t('Street Address'); $fields['billing']['billing_address_2']['label'] = __t('This field'); $fields['billing']['billing_address_1']['placeholder'] = __t('Street and number, P.O. box, C/O'); $fields['billing']['billing_address_2']['placeholder'] = __t('Flat, Suit, Unit, Building, Floor, etc'); unset($fields['billing']['billing_company']); unset($fields['billing']['billing_state']); unset($fields['billing']['billing_email']); unset($fields['billing']['billing_phone']); $fields['billing']['billing_first_name']['priority'] = '1'; $fields['billing']['billing_last_name']['priority'] = '2'; $fields['billing']['billing_address_1']['priority'] = '3'; $fields['billing']['billing_address_2']['priority'] = '4'; $fields['billing']['billing_postcode']['priority'] = '5'; $fields['billing']['billing_city']['priority'] = '6'; $fields['billing']['billing_country']['priority'] = '7'; $fields['billing']['billing_first_name']['required'] = '1'; $fields['billing']['billing_address_1']['required'] = '1'; $fields['billing']['billing_postcode']['required'] = '1'; $fields['billing']['billing_city']['required'] = '1'; $fields['billing']['billing_country']['required'] = '1'; $fields['shipping']['shipping_first_name']['label'] = __t('First Name'); $fields['shipping']['shipping_last_name']['label'] = __t('Last Name'); $fields['shipping']['shipping_phone']['required'] = '1'; $fields['shipping']['shipping_postcode']['label'] = __t('Post Code / Zip', 'woocommerce'); $fields['shipping']['shipping_city']['label'] = __t('City', 'woocommerce'); $fields['shipping']['shipping_country']['label'] = __t('Country', 'woocommerce'); $fields['shipping']['shipping_address_1']['label'] = __t('Street Address', 'woocommerce'); $fields['shipping']['shipping_address_2']['label'] = __t('This field'); $fields['shipping']['shipping_address_1']['placeholder'] = __t('Street and number, P.O. box, C/O', 'woocommerce'); $fields['shipping']['shipping_address_2']['placeholder'] = __t('Flat, Suit, Unit, Building, Floor, etc'); unset($fields['shipping']['shipping_company']); unset($fields['shipping']['shipping_state']); unset($fields['shipping']['shipping_email']); unset($fields['shipping']['shipping_phone']); $fields['shipping']['shipping_first_name']['priority'] = '1'; $fields['shipping']['shipping_last_name']['priority'] = '2'; $fields['shipping']['shipping_address_1']['priority'] = '3'; $fields['shipping']['shipping_address_2']['priority'] = '4'; $fields['shipping']['shipping_postcode']['priority'] = '5'; $fields['shipping']['shipping_city']['priority'] = '6'; $fields['shipping']['shipping_country']['priority'] = '7'; $fields['shipping']['shipping_first_name']['required'] = '1'; $fields['shipping']['shipping_address_1']['required'] = '1'; $fields['shipping']['shipping_postcode']['required'] = '1'; $fields['shipping']['shipping_city']['required'] = '1'; $fields['shipping']['shipping_country']['required'] = '1'; return $fields; } function length_without_space($string) { $string = str_replace(' ', '', $string); return strlen($string); } add_action('woocommerce_after_checkout_validation', 'add_fake_error'); function add_fake_error($posted) { global $woocommerce; $items = $woocommerce->cart->get_cart(); $user_id = get_current_user_id(); $remove = []; foreach ($items as $item => $values) { $values['product_id'] = (int)$values['product_id']; $req_check = check_req_exists($user_id, $values['product_id']); if ($req_check!='') { continue; } if (!isInStock($values['product_id'])) { $remove[] = $values['product_id']; $cartId = WC()->cart->generate_cart_id( $values['product_id'] ); $cartItemKey = WC()->cart->find_product_in_cart( $cartId ); WC()->cart->remove_cart_item( $cartItemKey ); } } $phone = get_user_meta( $user_id, 'billing_phone', true ); if($phone == ''){ wc_add_notice( __t('orders.empty_phone', ['link' => site_url() . '/my-account' ]), 'error'); } if (count($remove) > 0) { wc_add_notice( __( "quantity_error Sorry but the selcted has been sold. You can contact our team for more options", "quantity_error Sorry but the selected has been sold. You can contact our team for more options" ), 'error'); } if ($_POST['confirm-order-flag'] == "1") { wc_add_notice( __( "custom_notice", 'fake_error' ), 'error'); } if($_POST['billing_postcode'] != "") { $billing_postcode = str_replace(' ', '', $_POST['billing_postcode']); if(strlen($billing_postcode) < 3 || strlen($billing_postcode) > 10) wc_add_notice( __( "billing_postcode", 'billing_postcode' ), 'error'); if(!preg_match('/^[a-zA-Z0-9-]+$/', $billing_postcode)) wc_add_notice( __( "billing_postcode_format", 'billing_postcode_format' ), 'error'); } if($_POST['billing_first_name'] != "") { if(length_without_space($_POST['billing_first_name']) < 3 || length_without_space($_POST['billing_first_name']) > 50) wc_add_notice( __( "billing_first_name", 'billing_first_name' ), 'error'); } if($_POST['billing_last_name'] != "") { if(length_without_space($_POST['billing_last_name']) > 50) wc_add_notice( __( "billing_last_name", 'billing_last_name' ), 'error'); } if($_POST['billing_address_1'] != "") { if(length_without_space($_POST['billing_address_1']) > 150) wc_add_notice( __( "billing_address_1", 'billing_address_1' ), 'error'); } if($_POST['billing_city'] != "") { if(length_without_space($_POST['billing_city']) > 50) wc_add_notice( __( "billing_city", 'billing_city' ), 'error'); } if ($_POST['payment_method'] === 'paypal') { wc_add_notice( __( __t('orders.paypal_not_allowed'), 'payment_method' ), 'error'); } if(isset($_POST['ship_to_different_address']) && $_POST['ship_to_different_address'] = 'on') { if($_POST['shipping_postcode'] != "") { $shipping_postcode = str_replace(' ', '', $_POST['shipping_postcode']); if(strlen($shipping_postcode) < 3 || strlen($shipping_postcode) > 10) wc_add_notice( __( "shipping_postcode", 'billing_postcode' ), 'error'); if(!preg_match('/^[a-zA-Z0-9-]+$/', $shipping_postcode)) wc_add_notice( __( "shipping_postcode_format", 'shipping_postcode_format' ), 'error'); } if($_POST['shipping_first_name'] != "") { if(length_without_space($_POST['shipping_first_name']) < 3 || length_without_space($_POST['shipping_first_name']) > 50) wc_add_notice( __( "shipping_first_name", 'shipping_first_name' ), 'error'); } if($_POST['shipping_last_name'] != "") { if(length_without_space($_POST['shipping_last_name']) > 50) wc_add_notice( __( "shipping_last_name", 'shipping_last_name' ), 'error'); } if($_POST['shipping_address_1'] != "") { if(length_without_space($_POST['shipping_address_1']) > 150) wc_add_notice( __( "shipping_address_1", 'shipping_address_1' ), 'error'); } if($_POST['shipping_city'] != "") { if(length_without_space($_POST['shipping_city']) > 50) wc_add_notice( __( "shipping_city", 'shipping_city' ), 'error'); } } } add_action('woocommerce_after_checkout_validation', 'add_fake_error'); function check_req_exists($user_id=0,$product_id=0) { $args = array( 'posts_per_page' => 1, 'post_type'=> 'order_request', 'author' => $user_id, 'post_status' => 'any', 'meta_query' => array( 'relation' => 'AND', array( 'key' => 'request_status', 'value' => 'Confirmed', 'compare' => '=' ), array( 'key' => 'requested_product', 'value' => $product_id, 'compare' => '=' ), ), ); $query = new WP_Query; $order_req = $query->query($args); return isset($order_req[0]) ? $order_req[0]->ID : null; } add_action( 'woocommerce_order_status_changed', 'woocommerce_order_status_changed_action', 10, 3 ); function woocommerce_order_status_changed_action( $order_id, $old_status, $new_status ) { saveLogInFile("Start prepare order for sending: $order_id - $old_status - $new_status"); if ($new_status === 'cancelled' || $new_status === 'failed') { return; } $order = wc_get_order( $order_id ); $user_id = $order->get_user_id(); saveLogInFile("Before sending user: " . $user_id); //Update user's data acoring added data in checkout form post_user_reg_redirect($user_id); $isSent = $order->get_meta('sent_to_erp'); saveLogInFile('Is order sent?: '. (int)$isSent); if ((int)$isSent === 1) { return false; } $data_send = prepareOrderData($order, $user_id); saveLogInFile('Send to ERP order: '. json_encode($data_send)); if (isProduction()) { $erp = new App\Services\ErpService('SYNC.ORDER'); $erp->sendMessage(null, $data_send); update_field('sent_to_erp', 1, $order_id); } //TODO: check the result and if it is an error - make something /** * Remove ordered products from stock and convert the related request to the order * According the documentation, the ERP have to remove the productuc, * But who knows when they will run this action. */ closeOrderItemsStatus($order->get_items(), $user_id, 'Converted as Order'); //Send order to the administrator if it wasn't sent before sendEmailOrderToAdmin($order_id); //Send ordere email to the customer $user_data = get_user_by('id', $user_id); order_email($order, $user_data); } function prepareOrderData($order, $user_id) { global $WOOCS; $order_data = $order->get_data(); $ccRate = getOrderCurrencyRate($order->get_id()); $countries_list = (new WC_Countries())->__get('countries'); $data_send = [ 'order_id' => $order->get_id(), 'shipping' => $order_data['shipping'], 'billing' => $order_data['billing'], 'order_payment_method_title' => $order_data['payment_method_title'], 'customer_id' => $user_id, //Phodu eto im ne nujno, jdu otvet 'invoice_link' => getInvoiceLink($order->get_id()), 'item' => [], ]; $data_send['billing']['email'] = clearUserEmail($data_send['billing']['email']); $data_send['billing']['country_code'] = $order_data['billing']['country']; $data_send['shipping']['country_code'] = $order_data['shipping']['country']; $data_send['billing']['country'] = $countries_list[$order_data['billing']['country']]; $data_send['shipping']['country'] = $countries_list[$order_data['shipping']['country']]; $data_send['shipping_cost'] = $WOOCS->back_convert($order->get_shipping_total(), $ccRate, 2); $data_send['shipping_cost'] = ceil($data_send['shipping_cost']); $user_meta = (object)getPostMeta($user_id, 'user'); $phone = getUserPhoneNumber($user_meta); $data_send['billing']['phone_code'] = $data_send['shipping']['phone_code'] = $phone->code; $data_send['billing']['phone_number'] = $data_send['shipping']['phone_number'] = $phone->number; $data_send['billing']['zip_code'] = $data_send['billing']['postcode']; $data_send['shipping']['zip_code'] = $data_send['shipping']['postcode']; $data_send['billing']['address1'] = $data_send['billing']['address_1']; $data_send['billing']['address2'] = $data_send['billing']['address_2']; $data_send['shipping']['address1'] = $data_send['shipping']['address_1']; $data_send['shipping']['address2'] = $data_send['shipping']['address_2']; unset($data_send['billing']['address_1']); unset($data_send['billing']['address_2']); unset($data_send['shipping']['address_1']); unset($data_send['shipping']['address_2']); unset($data_send['billing']['postcode']); unset($data_send['shipping']['postcode']); unset($data_send['billing']['phone']); unset($data_send['shipping']['phone']); addProductsToOrder($order, $data_send, $ccRate); return $data_send; } function getOrderCurrencyRate(int $order_id) { global $WOOCS; $currentCur = get_post_meta($order_id, '_order_currency', true); $currencies = $WOOCS->get_currencies(); return $currencies[$currentCur]['rate']; } function addProductsToOrder($order, &$data_send, $ccRate) { global $WOOCS; $user_id = $order->get_user_id(); foreach ( $order->get_items() as $item ) { $product = $item->get_product(); $item_price = ceil($WOOCS->back_convert($item->get_total(), $ccRate, 2)); $delivery_period = getProductDelivery($product); if ($item->get_quantity() > 1) { applySameSMPProduct( $data_send['item'], $product, $item_price, $delivery_period, $item->get_quantity() ); } else { $isRequested = isRequestedProduct($user_id, $product->get_id()); $data_send['item'][] = [ 'id' => $product->get_id(), 'quantity' => 1, 'requested_product' => $isRequested, 'list_id' => App\Models\Product\SmpProducts::getListId($product->get_id()), 'delivery_period' => $delivery_period, 'total' => $item_price ]; /** * If product has size, remove this size from the main product */ excludeProductSize($product->get_id()); // TODO: rewrite this function } } } function isRequestedProduct(int $user_id, int $product_id) { $result = check_req_exists($user_id, $product_id); return (int)!empty($result); } /** * Closing access to the product that has been ordered if it was in stock and had the size * * @param [type] $product_id * @return void */ function excludeProductSize($product_id) { $smp_product = new \App\Models\Product\SmpProducts(); $product = $smp_product->where('id_post', $product_id)->first(); $item_size = optional($product)->item_size; if (empty($item_size) || !$product->in_stock) { return false; } return $smp_product->where('id_post', $product_id)->update([ 'visibility' => 0, 'available' => 0, ]); } function getMainERPProduct($product_id) { $args = array( 'fields' => 'ids', 'post_type' => 'product', 'posts_per_page' => -1, 'post_status' => ['publish'], 'meta_query' => [ [ 'key' => 'all_prices', 'compare' => 'EXISTS' ], [ 'key' => 'pim_id', 'value' => get_post_meta($product_id, 'pim_id', true), 'compare' => '=' ], ] ); $query = new WP_Query; $product = $query->query($args); return isset($product[0]) ? $product[0] : null; } function applySameSMPProduct(&$products, $parent_product, $item_price, $delivery_period, $limit = -1) { $item_size = $parent_product->get_meta('item_size'); $pim_id = $parent_product->get_meta('pim_id'); if (empty($item_size) || empty($pim_id)) { return false; } $count_products = count($products); $args = array( 'fields' => 'ids', 'post_type' => 'product', 'posts_per_page' => -1, 'post_status' => ['publish', 'draft'], 'exclude' => [$parent_product->get_id()], 'meta_query' => [ [ 'key' => 'item_size', 'value' => $item_size, 'compare' => '=' ], [ 'key' => 'pim_id', 'value' => $pim_id, 'compare' => '=' ], ] ); $query = new WP_Query; $items = $query->query($args); foreach ($items as $id_product) { if (!isMainSmpProduct($id_product)) { $products[] = [ 'id' => $id_product, 'name' => $parent_product->get_name(), 'quantity' => 1, 'listid' => (int)get_post_meta($id_product, 'list_id', true), 'delivery_period' => $delivery_period, 'total' => $item_price ]; disableProduct($id_product); } else { deletePostMeta($id_product, 'products_size', $item_size, $limit); } if ($count_products >= $limit) { break; } } $id_product = $parent_product->get_id(); if (count($products) < $limit) { $products[] = [ 'id' => $id_product, 'name' => $parent_product->get_name(), 'quantity' => 1, 'listid' => (int)get_post_meta($id_product, 'list_id', true), 'delivery_period' => $delivery_period, 'total' => $item_price ]; deletePostMeta($id_product, 'products_size', $item_size, 1); } } /** * Remove the product from the stock. * It necessary for preventing double ordering the same SMP product. * * @param integer $id_product * @return void */ function disableProduct(int $id_product) { wp_update_post([ 'ID' => $id_product, 'post_status' => 'trash' ]); } function deletePostMeta($id_product, $meta_key, $meta_value, $limit) { global $wpdb; $query = $wpdb->prepare( "DELETE FROM wp_postmeta WHERE post_id = $id_product AND meta_key='$meta_key' AND meta_value='$meta_value' LIMIT $limit"); $wpdb->query( $query ); } /** * Check if selected product is one who was declared like main smp product * * @param integer $id_product * @return boolean */ function isMainSmpProduct(int $id_product) { $meta = preparePostMeta($id_product); return ( !empty($meta->all_prices) && !empty($meta->min_price) && !empty($meta->max_price) ); } function closeRequestOffer($request_id) { $room_id = get_post_meta($request_id, 'room_id', true); $offer_id = get_post_meta($request_id, 'offer_id', true); $token = generateJWTToken(); if (!$room_id || !$offer_id) { return false; } $url = ERP_API_HOST . '/client/rooms/stocks/' . $room_id . '/messages/request/' . $request_id . '/offer/pay'; $data = [ 'offerId' => $offer_id ]; $restult = wp_remote_post($url, [ 'headers' => [ 'Content-Type' => 'application/json; charset=utf-8', 'Authorization' => "Bearer " . $token, ], 'body' => json_encode($data), 'method' => 'PUT', 'data_format' => 'body', ]); if ((int)$restult['response']['code'] !== 200) { error_log('Cannot close offer: ' . json_encode($restult['body'])); } else { error_log("The offer is closed($request_id)"); } } function closeOrderItemsStatus($order_items, int $user_id, string $request_status) { $product_service = new App\Services\Products\ProductsBuyingService(); foreach ( $order_items as $item ) { $product = $item->get_product(); $product_id = $product->get_id(); $request_id = check_req_exists($user_id, $product_id); if (!empty($request_id)) { update_post_meta($request_id, 'request_status', $request_status); //closeRequestOffer($request_id); } updateProductStatus($product_id, 'draft'); $product_service->closeProduct($product_id); } } function changeRequestStatus(int $order_id, int $user_id, string $request_status) { $order = wc_get_order( $order_id ); foreach ( $order->get_items() as $item ) { $product = $item->get_product(); $requested_product_data_id = check_req_exists($user_id, $product->get_id()); if ($requested_product_data_id) { update_post_meta($requested_product_data_id, 'request_status', $request_status); } } } function updateProductStatus(int $product_id, string $status = 'draft') { global $wpdb; $query = $wpdb->prepare("UPDATE wp_posts SET post_status = '%s' WHERE ID=%s", [ $status, $product_id ]); return $wpdb->query( $query ); } function sendEmailOrderToAdmin($order_id) { //Check if email has been sent before if (isNotificationSent($order_id)) { return false; } add_filter('woocommerce_new_order_email_allows_resend', '__return_true' ); WC()->mailer()->get_emails()['WC_Email_New_Order']->trigger( $order_id ); add_filter('woocommerce_new_order_email_allows_resend', '__return_false' ); } function isNotificationSent($order_id) { global $wpdb; $admin_email = get_field("admin_email", "theme_settings"); $get_values = $wpdb->get_results( "SELECT id FROM wp_mail_catcher_logs WHERE email_to LIKE '%$admin_email%' AND subject LIKE '%[Watches World]: New order #$order_id%' LIMIT 1"); return count($get_values); } function getProductDelivery($product) { $id_request = getRequestId(get_current_user_id(), $product->get_id()); $status = !$id_request ? (int)$product->get_meta('delivery_period') : (int)get_post_meta($id_request, 'delivery_period', true); switch ($status) { case 1: $status = 1; break; case 2: $status = 4; break; default: $status = 5; } return $status; } function getRequestId(int $id_user, int $id_product) { $args = array( 'post_type' => 'order_request', 'posts_per_page' => 1, 'meta_query' => [ [ 'key' => 'order_requested_user', 'value' => $id_user, 'compare' => '=' ], [ 'key' => 'requested_product', 'value' => $id_product, 'compare' => '=' ] ] ); $query = new WP_Query; $order = $query->query($args); return $order ? $order[0]->ID : false; } /** * Custom logging system. */ function saveLogInFile($content) { $path = WP_CONTENT_DIR . '/rest-api.log'; $file = fopen($path, 'a'); fprintf($file, "%s: %s\n", date('Y-m-d H:i:s'), $content); fclose($file); } add_action( 'woocommerce_update_product', 'addProductInRedis', 10, 1 ); add_action('woocommerce_new_product', 'addProductInRedis', 10, 1); function addProductInRedis( $product_id ) { // return true; // REMOVED: was blocking ERP price sync if ( get_post_type( $product_id ) !== 'product') { error_log("Not a product:" . $product_id ); return false; } if ((int)get_field("run_redis_products", "theme_settings")) { /* if (isset($_GET['post_updating'])) { return false; }*/ $redis = new \App\Services\RedisService(); error_log('Send the product in redis:' . $product_id); $redis->send($redis::PRODUCTS_QUEUE, $product_id); } else { $pim_id = get_post_meta( $product_id, 'pim_id', true); if (!empty($pim_id) && !isset($_GET['pim_edit'])) { error_log("Start to update ERP product: $product_id, $pim_id"); updateSMPProduct($product_id, $pim_id); } else { updateReferenceCategory($product_id); $_GET['pim_edit'] = 1; updateBulkSMPProductsByPIM($product_id); } replaceTrashedLinks(); } return true; } add_action('wp_ajax_create_redis_q', 'createRedisQueue'); add_action('wp_ajax_nopriv_create_redis_q', 'createRedisQueue'); function createRedisQueue() { if (empty($_REQUEST['queue'])) { return false; } $redis = new \App\Services\RedisService(); $result = $redis->createQueue($_REQUEST['queue']); dd($result); return true; } //Take products' images from REDIS and attach them to the product add_action( 'download_products_images', 'downloadProductsImages' ); add_action('wp_ajax_download_products_images', 'downloadProductsImages'); add_action('wp_ajax_nopriv_download_products_images', 'downloadProductsImages'); function downloadProductsImages() { (new \App\Services\ProductImagesService())->run(); } //add_action( 'finish_update_products', 'finishUpdatingProducts' ); //add_action('wp_ajax_finish_update_products', 'finishUpdatingProducts'); //add_action('wp_ajax_nopriv_finish_update_products', 'finishUpdatingProducts'); function finishUpdatingProducts() { //(new \App\Services\ProductsManagementService())->run(); } function mp_sync_on_product_save( $postID ) { error_log('Start to update ERP product: ' . $postID); if (isManualAddedProduct($postID)) { completeManualAddedProduct($postID); return true; } $pim_id = get_post_meta($postID, 'pim_id', true); if (!empty($pim_id) && !isset($_GET['pim_edit'])) { updateSMPProduct($postID, $pim_id); } else { updateReferenceCategory($postID); $_GET['pim_edit'] = 1; updateBulkSMPProductsByPIM($postID); } replaceTrashedLinks(); error_log('Finish updating:' . $postID); } // rest init action hook log on init //add_action( 'rest_api_init', 'restinithook', 99, 1 ); function restinithook($wp_rest_server) { $entityBody = file_get_contents('php://input'); saveLogInFile('Rest init: ' . json_encode($entityBody)); } function sendImagesInRedis($images, $pim_id) { $redis = new \App\Services\RedisService(); foreach ($images as $index => $image) { error_log('Send image(' . $pim_id . '):' . $image->src); $redis->send( $redis::PRODUCTS_IMAGES_QUEUE, json_encode([ 'pim_id' => $pim_id, 'image_url' => $image->src, 'position' => $index ]) ); } } function getPimId($data) { foreach ($data as $meta_item) { if ($meta_item->key === 'pim_id') { return (int)$meta_item->value; } } return null; } add_filter( 'wp_insert_post_data' , 'filter_post_data' , 99, 2 ); function filter_post_data( $data , $postarr ) { //error_log('Pre save the product: ' . json_encode($data)); return $data; } /** * Update the category that is related with reference */ function updateReferenceCategory($id_post) { $reference = get_post_meta($id_post, 'org_reference', true); if (!empty($reference)) { update_post_meta($id_post, '_sku', $reference); } else { $reference = get_post_meta($id_post, '_sku', true); } if (empty($reference)) { $reference = get_post_meta($id_post, 'reference', true); update_post_meta($id_post, '_sku', $reference); //TO DO: remove this section whe issue will be fixed on PIM system $pim_id = get_post_meta($id_post, 'PIM ID', true); update_post_meta($id_post, '_saleslayerid', $pim_id); } $categories = getProductCategories($id_post); if (!isset($categories['reference'])) { return false; } //Do not rename the category if reference is same if ($reference === $categories['reference']->name) { return false; } wp_update_term( $categories['reference']->term_id, 'product_cat', [ 'name' => $reference, 'slug' => sanitize_title($reference) ]); } /** * Copy all attributes from PIM product and add them on SMP product */ function updateBulkSMPProductsByPIM($id_product) { global $wpdb; $pim_product = wc_get_product($id_product); $pim_permalink = sanitize_title($pim_product->get_name()); updatePostSlug($wpdb, $id_product, $pim_permalink . '-' . $id_product); $pim_id = $pim_product->get_meta('_saleslayerid'); if (empty($pim_id)) { return false; } //Collect all related posts $tbl = $wpdb->prefix . 'postmeta'; $products_list = getSMPProductsByPIM($wpdb, $tbl, $pim_id); $key_attributes = getPIMAttributes(); $pim_terms = wp_get_post_terms($id_product, 'product_cat', [ 'fields' => 'ids' ]); $id_main_product = null; $product_sizes = []; foreach ($products_list as $id_smp_product) { updatePostSlug($wpdb, $id_smp_product, $pim_permalink . '-' . $id_smp_product); //Hide SWATCH products if (in_array(SWATCH_CATEGORY, $pim_terms)) { update_post_meta($id_smp_product, 'visibility', 0); } $status = updateSPMProductAttributes($id_smp_product, $pim_product, $key_attributes); $item_size = get_post_meta($id_smp_product, 'item_size', true); if ($status !== 'draft' && $item_size !== '') { $product_sizes[] = $item_size; } //Update data on elastic if product is main if ( get_post_meta($id_smp_product, 'all_prices', true) !== '' && $status !== 'draft' && (int)get_post_meta($id_smp_product, 'visibility', true) == 1 && (int)get_post_meta($id_smp_product, 'is_delete', true) === 0 ) { $id_main_product = $id_smp_product; addProductInElastic((object)[ 'ID' => $id_smp_product, 'price' => get_post_meta($id_smp_product, '_price', true), 'price_on_request' => get_post_meta($id_smp_product, 'price_on_request', true), 'name' => $pim_product->get_name(), 'reference' => get_post_meta($id_smp_product, 'pim_reference', true), 'list_id' => get_post_meta($id_smp_product, 'list_id', true), 'nickname' => get_post_meta($id_smp_product, 'Nickname', true) ]); } else { deleteProductFromElastic($id_smp_product); } //Update categories wp_set_object_terms($id_smp_product, $pim_terms, 'product_cat'); } if ( count($product_sizes)) { attachAllSizes($id_main_product, $product_sizes ); } } function attachAllSizes($id_main_product, $product_sizes ) { delete_post_meta($id_main_product, 'product_sizes'); foreach ($product_sizes as $size) { add_post_meta($id_main_product, 'product_sizes', $size); } } function updatePostSlug($wpdb, $id_post, $slug) { $wpdb->query("UPDATE wp_posts SET post_name='$slug' WHERE ID = $id_post"); } function getSMPProductsByPIM($wpdb, $tbl, $pim_id) { $prepare_query = $wpdb->prepare( "SELECT post_id FROM $tbl FORCE INDEX(meta_key) where meta_key ='pim_id' and meta_value = '%s'", $pim_id); return $wpdb->get_col( $prepare_query ); } function deleteSMPOldAttributes($wpdb, $tbl, $id_smp_product, $key_attributes) { $query = $wpdb->prepare( "DELETE FROM $tbl WHERE post_id = $id_smp_product AND meta_key IN (" . implode(', ', array_fill(0, count($key_attributes), "'%s'")) . ")", $key_attributes ); $wpdb->query( $query ); } function updateSPMProductAttributes($id_smp_product, $pim_product, $key_attributes) { global $wpdb; $smp_product = wc_get_product($id_smp_product); $home_hide = get_post_meta($id_smp_product, 'home_hide', true); if (empty($home_hide)) { update_post_meta($id_smp_product, 'home_hide', 0); } update_post_meta($id_smp_product, 'pim_reference', $pim_product->get_sku()); update_post_meta($id_smp_product, 'show_list', 1); $key_attributes = array_merge($key_attributes, [ 'gender', 'Nickname' ]); foreach ($key_attributes as $name_attribute) { update_post_meta($id_smp_product, $name_attribute, $pim_product->get_meta($name_attribute)); } $status = isProductAvailable($smp_product) ? 'publish' : 'draft'; saveLogInFile("Update product($id_smp_product): $status"); $query = $wpdb->prepare("UPDATE wp_posts SET post_status = '%s', post_title='%s' WHERE ID=%s", [ $status, $pim_product->get_name(), $id_smp_product ]); $wpdb->query( $query ); return $status; } // used in ProductTranslationService class. function getPIMAttributes() { return [ 'bracelet_color', 'case_material', 'limited_edition', 'bracelet_material', 'case_diameter', 'bezel_material', 'dial_numerals', 'movement', // 'caliber', 'power_reserve', 'water_resistance', 'functions', 'glass', 'clasp_material', 'clasp_type', 'dial', 'Nickname', 'collection', 'set', 'occasion', 'style', 'metal', 'stones', 'carats', 'jewelleryType', // bags 'brand', 'model', // 'price', 'condition', 'color', 'material', 'hardware' ]; } function updateSMPProduct($postID, $pim_id) { global $wpdb; $id_parent_product = getParentProductId((int)$pim_id); if (!$id_parent_product) { error_log("The PIM $pim_id is not exists."); return false; } //Update product categories $term_list = wp_get_post_terms($id_parent_product, 'product_cat', [ 'fields' => 'ids' ]); //Hide SWATCH products if (in_array(SWATCH_CATEGORY, $term_list)) { update_post_meta($postID, 'visibility', 0); } wp_set_object_terms( $postID, $term_list, 'product_cat' ); wp_set_object_terms( $postID, $pim_id, 'product_taxonomy' ); $pim_product = wc_get_product($id_parent_product); //Update product attributes that included in parent product(PIM) updateSPMProductAttributes($postID, $pim_product, getPIMAttributes()); //TODO: make refactoring of this function. It still an old version. taxonomy_management($postID, $pim_id, $pim_product); syncCustomProductTables($postID, $id_parent_product); $permalink = get_post_field( 'post_name', $postID ); if (strpos($permalink, 'product-') !== false) { $pim_permalink = sanitize_title($pim_product->get_name()); updatePostSlug($wpdb, $postID, $pim_permalink . '-' . $postID); } } function getParentProductId(int $pim_id) { global $wpdb; $table = $wpdb->prefix . 'postmeta'; $query = $wpdb->prepare( "SELECT post_id FROM $table FORCE INDEX(meta_key) WHERE meta_key='_saleslayerid' AND meta_value='$pim_id' ORDER by post_id LIMIT 1"); $get_values = $wpdb->get_col( $query ); return isset($get_values[0]) ? $get_values[0] : null; } function getProductByPIMId(int $pim_id) { $product_id = getParentProductId($pim_id); return wc_get_product($product_id); } function isERPProductAvailable($product_id) { return ( (int)get_post_meta($product_id, 'is_delete', true) && (int)get_post_meta($product_id, 'visibility', true) === 1 ); } function taxonomy_management($id_product, $pim_id, $pim_product) { $args = array( 'posts_per_page' => -1, 'post_status' => ['publish', 'draft'], 'post_type' => 'product', 'orderby' => 'ID', 'order' => 'DESC', 'meta_query' => [ [ 'key' => 'pim_id', 'compare' => '=', 'value' => $pim_id, ] ] ); $query = new WP_Query; $posts_array = $query->query($args); $taxarrays = json_decode(json_encode($posts_array), true); saveLogInFile("Taxarrays" . json_encode($taxarrays) ); if (!count($taxarrays)) { error_log("PIM(" . $pim_id . ")No child products"); return false; } $product_prices = $product_sizes = []; $last_product = $stock_product = $requestable_product = $product_without_price = null; $requestable_min_price = $stockable_min_price = 0; foreach ($taxarrays as $taxarray) { $productid = $taxarray['ID']; $product = wc_get_product( $productid ); $deleted = (int)$product->get_meta('is_delete'); $visibility = (int)$product->get_meta('visibility'); $price_on_request = (int)$product->get_meta('price_on_request'); delete_post_meta($productid, 'min_price'); delete_post_meta($productid, 'max_price'); delete_post_meta($productid, 'all_prices'); deleteProductFromElastic($productid); wp_remove_object_terms($productid, 'enable-search', 'product_tag'); $last_product = $product; if ($deleted === 0 && $visibility === 1) { /** * Detecting the stockable & non stockable products for making one of them with priority */ if((int)$product->get_meta('in_stock') === 1) { if (!$stockable_min_price || ($product->get_price() < $stockable_min_price) ) { $stock_product = $product; $stockable_min_price = $product->get_price(); } } else if($price_on_request === 0) { if (!$requestable_min_price || ($product->get_price() < $requestable_min_price) ) { $requestable_product = $product; $requestable_min_price = $product->get_price(); } } if ($price_on_request === 0) { $product_prices[] = $product->get_price(); } else { $product_without_price = $product; } wp_set_post_terms($productid, 'enable-search', 'product_tag', true); $item_size = get_post_meta($productid, 'item_size', true); if ($item_size !== '') { $product_sizes[] = $item_size; } } } $product_prices = array_unique($product_prices); if (!count($product_prices)) { $product_prices = [0]; } $first_product = null; if (!empty($stock_product)) { $first_product = $stock_product; } else if (!empty($requestable_product)) { $first_product = $requestable_product; } else if(!empty($product_without_price)) { $first_product = $product_without_price; } else { $first_product = $last_product; } if (empty($first_product)) { return false; } $id_first_product = $first_product->get_id(); saveLogInFile("All prices: $id_first_product - (" . count($taxarrays) . ")" . json_encode($product_prices) ); if (count($product_prices)) { $min_price = min($product_prices); $max_price = max($product_prices); } else { $max_price = $min_price = $first_product->get_price(); } update_post_meta($id_first_product, 'min_price', $min_price); update_post_meta($id_first_product, 'max_price', $max_price); update_post_meta($id_first_product, 'all_prices', $min_price); updateProductStatus($id_first_product, 'publish'); if (isAvailableProduct($id_first_product)) { if (count($product_sizes)) { attachAllSizes($id_first_product, $product_sizes); } saveLogInFile("Add product in elastic: $id_first_product"); addProductInElastic((object)[ 'ID' => $id_first_product, 'price' => $first_product->get_price(), 'price_on_request' => (int)$first_product->get_meta('price_on_request'), 'name' => $pim_product->get_name(), 'reference' => $first_product->get_meta('pim_reference'), 'list_id' => $first_product->get_meta('list_id'), 'nickname' => $first_product->get_meta('Nickname') ]); if (!isProductWasAvailable($pim_product->get_ID())) { createProductNotifications($id_first_product, $pim_product->get_ID()); } } } function isProductWasAvailable($product_id) { return (int)get_post_meta($product_id, 'was_available', true); } /** * Delete pim product and related SMP products */ add_action('woocommerce_trash_product','deletePimProduct', 10, 1 ); function deletePimProduct($id_product) { $pim_id = get_post_meta($id_product ,'_saleslayerid', true); //Check if the product is PIM product if ( get_post_type($id_product) !== 'product' || empty($pim_id)) { wp_send_json([ 'status' => 'error', 'message' => "You can't delete this product." ]); die(); } global $wpdb; $tbl = $wpdb->prefix . 'postmeta'; $products_list = getSMPProductsByPIM($wpdb, $tbl, $pim_id); if (count($products_list)) { foreach ($products_list as $id_smp_product) { update_post_meta($id_smp_product, 'is_delete', 1); deleteProductFromElastic($id_smp_product); } } /** * Remove PIM product from trash and add it on draft */ $query = $wpdb->prepare("UPDATE wp_posts SET post_status = '%s' WHERE ID=%s", ['draft', $id_product]); $wpdb->query( $query ); wp_send_json([ 'status' => 'success', 'pim_id' => $pim_id, 'message' => 'The product has been deleted!' ]); die(); } add_action('user_register', 'post_user_reg_redirect', 10, 1); function post_user_reg_redirect( $userId ) { $user_meta = (object)getPostMeta($userId, 'user'); // create user object $user = get_userdata($userId); $phone = getUserPhoneNumber($user_meta); $countries_obj = new WC_Countries(); $countries = $countries_obj->__get('countries'); if (isset($_POST['billing_phone_code'])) { update_user_meta($userId, 'billing_phone_code', $phone->code); } if (isset($_POST['billing_country'])) { $user_meta->billing_country = $_POST['billing_country']; } $post_data = [ 'woo_customer_id' => $userId, 'email' => clearUserEmail($user->user_email), 'first_name' => prepareUserName($userId, $user_meta->first_name, 'billing_first_name'), 'last_name' => prepareUserName($userId, $user_meta->last_name, 'billing_last_name'), 'phone_code' => $phone->code, 'phone_number' => preparePhoneNumber($phone->number), 'address1' => $user_meta->billing_address_1 ?? '', 'address2' => $user_meta->billing_address_2 ?? '', 'zip_code' => $user_meta->billing_postcode ?? '', 'city' => $user_meta->billing_city ?? '', // 'country' => ( isset( $user_meta->billing_country ) && isset( $countries[$user_meta->billing_country] ) ) // ? $countries[$user_meta->billing_country] : '', 'country' => $user_meta->billing_country ?? '', 'created_on' => $user->user_registered, 'country_code' => $user_meta->billing_country ?? '', 'locale' => \App\Services\TranslationService::getLang() ]; if ($post_data['first_name'] !== '') { saveLogInFile('Create/Update user:' . json_encode($post_data)); // Send the user to the erp if (isProduction()) { $erp = new \App\Services\ErpService('SYNC.CLIENT'); $erp->sendMessage('insert_customer_details', $post_data); saveLogInFile("Insert new user request details:" . json_encode($post_data)); } } // sendUserToERPTrueEndpoint( true, $post_data ); subscribeUnscribeToMailchimp($userId); } function subscribeUnscribeToMailchimp($userId) { if ( isset($_REQUEST['mailchimp_woocommerce_newsletter']) && (int)$_REQUEST['mailchimp_woocommerce_newsletter'] ) { update_user_meta($userId, 'email_subscribe', 1); changeSubscriberStatus('subscribed'); } else { delete_user_meta($userId, 'email_subscribe'); changeSubscriberStatus(); } } /** * Remove country code duplications */ function preparePhoneNumber($phone) { while (substr_count($phone, '+') > 1) { $country_code = substr($phone, 0, strpos($phone, '+', 1)); $phone = str_replace($country_code.$country_code, $country_code, $phone); } return $phone; } /** * Work with PIM helper functions */ function get_pim_product_title($id) { if (!isset($id)) { return ''; } return get_the_title(get_pim_product_id($id)); } function get_pim_product_id($post_id) { if (!isset($post_id)) { return ''; } $pim_id = get_post_meta($post_id, 'pim_reference', true); if (isset($pim_id)) { global $wpdb; $tbl = $wpdb->prefix.'postmeta'; $prepare_query = $wpdb->prepare( "SELECT post_id FROM $tbl FORCE INDEX(meta_key) where meta_key ='_sku' and meta_value = '%s'", $pim_id ); $get_values = $wpdb->get_col( $prepare_query ); return isset($get_values[0]) ? $get_values[0] : null; } return $post_id; } function prepareUserName($user_id, $first_name, $key) { if (empty($first_name) && isset($_POST[$key])) { $first_name = $_POST[$key]; update_user_meta($user_id, str_replace('account_', 'billing_', $key), $first_name); } return $first_name; } function getUserPhoneNumber(object $user) { $phone_code = !empty($_REQUEST['billing_phone_code']) ? $_REQUEST['billing_phone_code'] : $user->billing_phone_code; return (object)[ 'code' => $phone_code, 'number' => !empty($user->billing_phone) ? $user->billing_phone : $_REQUEST['billing_phone'], ]; } function check_product($postID) { if ( get_post_type( $postID ) == 'product' ) { if(get_post_meta($postID,'list_id',true)!='' && get_post_meta($postID,'pim_id',true)!='') { $deleted = get_post_meta($postID,'is_delete',true); $status = get_post_meta($postID,'status',true); $visibility = get_post_meta($postID,'visibility',true); if( ($visibility == 1) && ($deleted == 0 ) && ( $status == 1 || $status == 3)) { return true; } else { return false; } } } return false; } add_action('wp', 'call_ws_for_as400'); function call_ws_for_as400() { if (is_checkout()) { global $woocommerce; global $wpdb; $user_id = get_current_user_id(); $customer_requests = $wpdb->get_results("SELECT * FROM `wp_posts` WHERE `post_author` = $user_id AND `post_type` = 'order_request' ORDER BY `wp_posts`.`post_date` DESC "); $request_approved_products = array(); foreach ($customer_requests as $key => $customer_request) { if(get_field("requested_product",$customer_request->ID)) { $requested_product_id = get_field("requested_product",$customer_request->ID); $request_status = get_field("request_status",$customer_request->ID); if($request_status == "Confirmed") { array_push($request_approved_products,$requested_product_id); } } } $items = $woocommerce->cart->get_cart(); $remove = array(); foreach($items as $item => $values) { if(!in_array($values['data']->get_id(), $request_approved_products)) if( get_post_meta($values['product_id'],'pim_id',true)!='') { if(get_post_meta($values['product_id'],'pim_id',true)!='') { if(check_product($values['product_id']) != true) { $remove[] = $values['product_id']; } } else { $remove[] = $values['product_id']; } } } if(count($remove)!=0) { foreach($remove as $item) { $product_id = $item; $product_cart_id = WC()->cart->generate_cart_id( $product_id ); $cart_item_key = WC()->cart->find_product_in_cart( $product_cart_id ); if ( $cart_item_key ) WC()->cart->remove_cart_item( $cart_item_key ); } } } } // add_action( 'woocommerce_before_checkout_form', 'check_product_before_checkout', 10, 0 ); add_action('after_setup_theme', 'remove_admin_bar'); function remove_admin_bar() { global $show_admin_bar; $show_admin_bar = false; } add_action('admin_init', 'disable_dashboard'); function disable_dashboard() { if (!is_user_logged_in()) { return null; } } function check_cats_in_cart( $product_id ) { $has_term = true; foreach( WC()->cart->get_cart() as $item ){ if ( $item['product_id'] == $product_id ) $has_term = false; if( !$has_term ) break; } return $has_term; } add_filter( 'woocommerce_add_to_cart_validation', 'sold_individually_by_cats_valid', 10, 3 ); function sold_individually_by_cats_valid( $passed, $product_id, $quantity) { $passed = check_cats_in_cart( $product_id ); if ( !$passed ) { $message = __t("This product is already in cart. Try another product"); wc_add_notice( $message, 'error' ); } return $passed; } /** * Add to cart validation. * This filter is checking if product have valid price. * If the price is ZERO - system will check if it's requested product. */ add_filter( 'woocommerce_is_purchasable', 'wpa_109409_is_purchasable', 10, 2 ); function wpa_109409_is_purchasable( $purchasable, $product ) { if ( !$product->get_price() ) { $request_data = getOrderRequest( $product->get_ID(), get_current_user_id() ); if ($request_data['request_status'][0] !== 'Confirmed' || !(int)$request_data['offer_price'][0] ) { $purchasable = false; } } return $purchasable; } add_filter( 'woocommerce_gateway_icon', 'setPaymentIcon', 10, 2); function setPaymenticon($icon, $type_payment) { $icons = getGatewaysIcons($type_payment); if (count($icons)) { $icon = ''; foreach ($icons as $icon_name) { $icon .= ""; } } return $icon; } function getGatewaysIcons($type_payment) { $icons = []; switch ($type_payment) { case 'wc_checkout_com_cards': $icons = ['visa', 'mastercard', 'amex']; break; case 'utrust_gateway': $icons = ['bitcoin']; break; case 'bacs': $icons = ['wire']; break; case 'paypal': $icons = ['paypal']; break; } return $icons; } // custom order text, custom order btn text, todo: was //add_filter( 'woocommerce_order_button_text', 'woo_custom_order_button_text' ); //function woo_custom_order_button_text() { // return __t( 'Confirm payment'); //} function get_gallery_images($product_id) { $product = new WC_product($product_id); if (!$product) { return [ wc_placeholder_img_src() ]; } $attachment_ids = $product->get_gallery_image_ids(); $image_url = []; foreach( $attachment_ids as $attachment_id ) { $image = wp_get_attachment_metadata( $attachment_id ); $image_src = getImageStorage() . $image['file']; $webp_img = getWebPImage( $image['file']); if ($webp_img) { $image_src = $webp_img; } if (!in_array($image_src, $image_url)) { $image_url[] = $image_src; } } $thumbnail = wp_get_attachment_metadata(get_post_thumbnail_id($product_id)); $thumb_url = getImageStorage() . $thumbnail['file']; if ($thumbnail && !in_array($thumb_url, $image_url)) { $webp_img = getWebPImage( $thumbnail['file'] ); if ($webp_img) { $thumb_url = $webp_img; } $image_url = array_merge([$thumb_url], $image_url); } if (!count($image_url)) { $image_url = [ wc_placeholder_img_src() ]; } return $image_url; } function get_cat_product_count($term_id) { if(!isset($term_id)) return '0'; $args = array( 'post_type' => 'product', 'post_status' => 'publish', 'posts_per_page' => -1, 'tax_query' => array( array( 'taxonomy' => 'product_cat', 'field' => 'term_id', 'terms' => $term_id, 'operator' => 'IN' ) ), 'meta_query' => array( 'query_one' => array( 'key' => 'custom_order', ), 'query_two' => array( 'key' => 'visibility', 'value' => '1', 'compare' => '=' ), ) ); $products = new WP_Query($args); return $products->post_count; } function all_product_managment() { $args = array( 'posts_per_page' => -1, 'post_type' => 'product', 'post_status' => 'any', 'meta_query' => array( 'relation' => 'AND', array( 'key' => '_saleslayerid', 'compare' => 'EXISTS', ), ), ); $query = new WP_Query; $posts = $query->query($args); $result = []; foreach ($posts as $pim) { update_post_meta($pim->ID, '_price', 0); $result[] = array($pim->ID, 0); } return $result; } add_action("wp_ajax_check_quantity", "check_quantity"); add_action("wp_ajax_nopriv_check_quantity", "check_quantity"); function check_quantity() { $list_id = get_post_meta($_POST['product_id'],'list_id',true); if ($list_id!='') { $quantity = quantity_curl($list_id); die($quantity); } else { die(false); } } function quantity_curl($list_id=0) { if ($list_id==0) { return('false'); } $result = wp_remote_post( get_field("smp_quantity_check_url", "theme_settings"), array( 'method' => 'POST', 'timeout' => 45, 'redirection' => 5, 'httpversion' => '1.0', 'blocking' => true, 'body' => ['list_id' => $list_id ], 'headers' => array('Content-Type' => 'application/x-www-form-urlencoded'), ) ); //return ('true'); $data = json_decode($result['body']); if($data->success=='true') { if($data->data->quantity!=0) { return('true'); } return('false'); } return('false'); } function update_names() { $users = get_users(); $list = array(); $i = 0; foreach($users as $user) { $first_name = get_user_meta($user->ID,'first_name',true); if($first_name!='') { $n_array = explode(' ', $first_name, 2); $list[$i]['first_name'] = $n_array[0]; $list[$i]['last_name'] = $n_array[1]; } $billing_first_name = get_user_meta($user->ID,'billing_first_name',true); if($billing_first_name!='') { $b_array = explode(' ', $billing_first_name, 2); $list[$i]['billing_first_name'] = $b_array[0]; $list[$i]['billing_last_name'] = $b_array[1]; } else { if($first_name!='') { $n_array = explode(' ', $first_name, 2); $list[$i]['billing_first_name'] = $n_array[0]; $list[$i]['billing_last_name'] = $n_array[1]; } } $shipping_first_name = get_user_meta($user->ID,'shipping_first_name',true); if($shipping_first_name!='') { $s_array = explode(' ', $shipping_first_name, 2); $list[$i]['shipping_first_name'] = $s_array[0]; $list[$i]['shipping_last_name'] = $s_array[1]; } $i++; } return $list; } function getMainSMPUrl($pim_id) { $args = array( 'fields' => 'ids', 'post_type' => 'product', 'posts_per_page' => 1, 'post_status' => ['publish', 'draft'], 'meta_query' => [ [ 'key' => 'pim_id', 'value' => $pim_id, 'compare' => '=' ], [ 'key' => 'all_prices', 'compare' => 'EXISTS' ] ] ); $query = new WP_Query; $posts = $query->query($args); return count($posts) ? getSMPProductUrlById((int)$posts[0]) : null; } /** * Return the product url not depending on post status. The link will be generated using post_name * * @param [type] $id_product * @return string */ function getSMPProductUrlById(int $id_product): string { global $wpdb; $products = $wpdb->get_results("SELECT * FROM wp_posts WHERE ID=$id_product LIMIT 1 "); if (!isset($products[0])) { return ''; } $url = site_url() . '/shop/' . $products[0]->post_name . '/'; return _langUrl($url); } add_action( 'woocommerce_email_order_details', 'actionEmailOrderMeta', 1, 4 ); // Remove item shipping cost attribute from order function actionEmailOrderMeta( $order, $sent_to_admin, $plain_text, $email ) { foreach ( $order->get_items() as &$product ) { $product->delete_meta_data('shipping_cost'); } }; Watches | Mens & Ladies Watches | Watches World
  • en
    en | EUR dropdown icon
    Select your currency and language

Watches

Discover our prestigious collections of luxury watches.
4384 results
  • All prices 0
  • Bezel material 0
  • Box 0
  • Bracelet color 0
  • Bracelet material 0
  • Case diameter 0
  • Case material 0
Sort by
Filter
Close
    Brand
    All brands
    Minimum price
    Maximum price
    Minimum price
    Maximum price
    View all
    Watches
    Jewellery
    Handbags
    Loading
    Patek Philippe Grand Complications Retrograde Perpetual Calendar 39.5mm
    Send request
    Richard Mille RM07-01 Automatic Winding

    Richard Mille RM07-01 Automatic Winding

    € 379,000
    2025
    Ref:  RM07-01 CE RG MOP
    Add to Cart
    Rolex Oyster Perpetual GMT-Master II 40mm

    Rolex Oyster Perpetual GMT-Master II 40mm

    € 84,900
    2025
    Ref:  126718GRNR-0002
    Add to Cart
    Richard Mille RM27-04 Manual Winding Tourbillon Rafael Nadal Limited Edition
    Add to Cart
    Richard Mille RM88 Automatic Winding Tourbillon Smiley Limited Edition
    Add to Cart
    Richard Mille RM17-01 Manual Winding Tourbillon
    Send request
    Rolex Oyster Perpetual Day-Date 36mm

    Rolex Oyster Perpetual Day-Date 36mm

    € 239,900
    2025
    Ref:  128238-0106
    Add to Cart
    Rolex Oyster Perpetual Day-Date 36mm

    Rolex Oyster Perpetual Day-Date 36mm

    € 245,000
    2025
    Ref:  128235-0063
    Add to Cart
    Audemars Piguet Royal Oak Selfwinding 37mm

    Audemars Piguet Royal Oak Selfwinding 37mm

    € 99,900
    2025
    Ref:  15551OR.ZS.D344CR.01
    Add to Cart
    Patek Philippe Golden Ellipse

    Patek Philippe Golden Ellipse

    € 31,900
    2025
    Ref:  5738R-001
    Add to Cart
    Patek Philippe Complications Annual Calendar Moon Phases 40mm
    Add to Cart
    Rolex Perpetual 1908 39mm

    Rolex Perpetual 1908 39mm

    € 49,900
    2025
    Ref:  52506-0002
    Add to Cart
    Richard Mille RM07-01 Automatic Winding

    Richard Mille RM07-01 Automatic Winding

    € 305,000
    2025
    Ref:  RM07-01 WG MOP
    Add to Cart
    Richard Mille RM07-01 Automatic Winding

    Richard Mille RM07-01 Automatic Winding

    € 175,000
    2025
    Ref:  RM07-01 Ti CA
    Add to Cart
    Richard Mille RM65-01 &quot;Lebron James&quot; Limited Edition

    Richard Mille RM65-01 "Lebron James" Limited Edition

    € 499,000
    2025
    Ref:  RM65-01 LEBRON
    Add to Cart
    Patek Philippe Golden Ellipse

    Patek Philippe Golden Ellipse

    € 79,900
    2025
    Ref:  5738/1R-001
    Add to Cart
    Audemars Piguet Royal Oak Selfwinding 34mm

    Audemars Piguet Royal Oak Selfwinding 34mm

    € 85,900
    2025
    Ref:  77450OR.OO.1361OR.01
    Add to Cart
    Richard Mille RM30-01 Automatic Winding with Declutchable Rotor

    Richard Mille RM30-01 Automatic Winding with Declutchable Rotor

    € 339,000
    2025
    Ref:  RM30-01 TI AT Z
    Add to Cart
    Richard Mille RM67-02 Automatic Winding Extra-Thin &quot;Italy&quot;

    Richard Mille RM67-02 Automatic Winding Extra-Thin "Italy"

    € 349,000
    2025
    Ref:  RM67-02 CA FQ Italy
    Add to Cart
    Richard Mille RM67-01 Automatic Winding Extra-Thin

    Richard Mille RM67-01 Automatic Winding Extra-Thin

    € 183,000
    2025
    Ref:  RM67-01 TI
    Add to Cart
    1 2 3 ... 220
    next
    track
    Secured and
    tracked delivery
    user
    Passionate experts
    at your service
    support
    Help and
    customer service 24/7
    guard
    All your payments
    secured

    We accept all these payment methods. ALL YoUR DATA ARE SECURED.

    Get the latest deals and more

    close subscription notification
    You have been subscribed to our newsletter and will receive the latest deals!
    If you want to unsubscribe from receiving our newsletter, then please use the ‘unsubscribe’ button on the message that you will receive and follow the instructions.

    Error

    Close