public function getProductVariations($post_id) { // update cache if required if (!array_key_exists($post_id, $this->product_variations)) { $this->product_variations[$post_id] = WPLA_ProductWrapper::getVariations($post_id); } return $this->product_variations[$post_id]; }
public function displayAdvancedSettingsPage() { $wp_roles = new WP_Roles(); // check import folder $upload_dir = wp_upload_dir(); $basedir_name = self::getOption('import_images_basedir_name', 'imported/'); $images_dir = $upload_dir['basedir'] . '/' . $basedir_name; if (!is_dir($images_dir)) { mkdir($images_dir); } if (!is_dir($images_dir)) { wpla_show_message('The folder for imported images <code>' . $images_dir . '</code> could not be created. Please check your folder permissions.', 'error'); } $aData = array('plugin_url' => self::$PLUGIN_URL, 'message' => $this->message, 'dismiss_imported_products_notice' => self::getOption('dismiss_imported_products_notice'), 'enable_missing_details_warning' => self::getOption('enable_missing_details_warning'), 'enable_custom_product_prices' => self::getOption('enable_custom_product_prices', 1), 'enable_minmax_product_prices' => self::getOption('enable_minmax_product_prices', 0), 'enable_item_condition_fields' => self::getOption('enable_item_condition_fields', 2), 'enable_thumbs_column' => self::getOption('enable_thumbs_column'), 'autofetch_listing_quality_feeds' => self::getOption('autofetch_listing_quality_feeds', 1), 'autofetch_inventory_report' => self::getOption('autofetch_inventory_report', 0), 'product_gallery_first_image' => self::getOption('product_gallery_first_image'), 'product_gallery_fallback' => self::getOption('product_gallery_fallback', 'none'), 'pricing_info_expiry_time' => self::getOption('pricing_info_expiry_time', 24), 'repricing_use_lowest_offer' => self::getOption('repricing_use_lowest_offer', 0), 'repricing_margin' => self::getOption('repricing_margin', ''), 'import_parent_category_id' => self::getOption('import_parent_category_id', ''), 'enable_variation_image_import' => self::getOption('enable_variation_image_import', 1), 'enable_gallery_images_import' => self::getOption('enable_gallery_images_import', 1), 'import_images_subfolder_level' => self::getOption('import_images_subfolder_level', 0), 'import_images_basedir_name' => self::getOption('import_images_basedir_name', 'imported/'), 'default_matcher_selection' => self::getOption('default_matcher_selection', 'title'), 'available_attributes' => WPLA_ProductWrapper::getAttributeTaxonomies(), 'variation_attribute_map' => self::getOption('variation_attribute_map', array()), 'variation_merger_map' => self::getOption('variation_merger_map', array()), 'custom_shortcodes' => self::getOption('custom_shortcodes', array()), 'variation_meta_fields' => self::getOption('variation_meta_fields', array()), 'allowed_html_tags' => self::getOption('allowed_html_tags', '<b><i>'), 'process_shortcodes' => self::getOption('process_shortcodes', 'off'), 'remove_links' => self::getOption('remove_links', 'default'), 'variation_title_mode' => self::getOption('variation_title_mode', 'default'), 'profile_editor_mode' => self::getOption('profile_editor_mode', 'default'), 'option_uninstall' => self::getOption('uninstall'), 'available_roles' => $wp_roles->role_names, 'wp_roles' => $wp_roles->roles, 'settings_url' => 'admin.php?page=' . self::ParentMenuId . '-settings', 'form_action' => 'admin.php?page=' . self::ParentMenuId . '-settings' . '&tab=advanced'); $this->display('settings_advanced', $aData); }
public static function updateMinMaxPrices($item_ids) { // echo "<pre>";print_r($item_ids);echo"</pre>"; // TODO: sanitize values $min_base_price = trim($_REQUEST['min_base_price']); $min_price_percentage = trim($_REQUEST['min_price_percentage']); $min_price_amount = trim($_REQUEST['min_price_amount']); $max_base_price = trim($_REQUEST['max_base_price']); $max_price_percentage = trim($_REQUEST['max_price_percentage']); $max_price_amount = trim($_REQUEST['max_price_amount']); $min_price_amount = str_replace(',', '.', $min_price_amount); // convert decimal comma $max_price_amount = str_replace(',', '.', $max_price_amount); // remember last used options $options = array('min_base_price' => $min_base_price, 'max_base_price' => $max_base_price, 'min_price_amount' => $min_price_amount, 'max_price_amount' => $max_price_amount, 'min_price_percentage' => $min_price_percentage, 'max_price_percentage' => $max_price_percentage); update_option('wpla_price_wizard_options', $options); $lm = new WPLA_ListingsModel(); foreach ($item_ids as $listing_id) { // load listing item $item = $lm->getItem($listing_id, OBJECT); if (!$item) { continue; } if ($item->product_type == 'variable') { continue; } $post_id = $item->post_id; // get base price (min) $base_price = 0; if ($min_base_price == 'price') { $base_price = WPLA_ProductWrapper::getPrice($post_id); } if ($min_base_price == 'sale_price') { $base_price = WPLA_ProductWrapper::getSalePrice($post_id); } if ($min_base_price == 'msrp') { $base_price = get_post_meta($post_id, '_msrp', true) ? get_post_meta($post_id, '_msrp', true) : get_post_meta($post_id, '_msrp_price', true); } // calculate new min price if ($min_price_percentage) { $base_price = $base_price + $base_price * floatval($min_price_percentage) / 100; } if ($min_price_amount) { $base_price = $base_price + floatval($min_price_amount); } if ($min_base_price == 'no_change') { $base_price = $item->min_price; } $new_min_price = round($base_price, 2); // get base price (max) $base_price = 0; if ($max_base_price == 'price') { $base_price = WPLA_ProductWrapper::getPrice($post_id); } if ($max_base_price == 'sale_price') { $base_price = WPLA_ProductWrapper::getSalePrice($post_id); } if ($max_base_price == 'msrp') { $base_price = get_post_meta($post_id, '_msrp', true) ? get_post_meta($post_id, '_msrp', true) : get_post_meta($post_id, '_msrp_price', true); } // calculate new max price if ($max_price_percentage) { $base_price = $base_price + $base_price * floatval($max_price_percentage) / 100; } if ($max_price_amount) { $base_price = $base_price + floatval($max_price_amount); } if ($max_base_price == 'no_change') { $base_price = $item->max_price; } $new_max_price = round($base_price, 2); // update listing table $data = array('min_price' => $new_min_price, 'max_price' => $new_max_price, 'pnq_status' => 1); $lm->updateWhere(array('id' => $listing_id), $data); // update product update_post_meta($item->post_id, '_amazon_minimum_price', $new_min_price); update_post_meta($item->post_id, '_amazon_maximum_price', $new_max_price); } // foreach item }
public static function processAttributeShortcodes($product, $field_value, $max_length = false) { // child variations: check variation attributes first if ($product->product_type == 'variation') { // match shortcodes - exit if none are found if (!preg_match_all("/\\[attribute_(.*)\\]/uUsm", $field_value, $matches)) { return $field_value; } // get variation attributes $variation_attributes = $product->get_variation_attributes(); foreach ($matches[1] as $attribute) { $taxonomy_name = 'attribute_pa_' . $attribute; if (isset($variation_attributes[$taxonomy_name]) && $variation_attributes[$taxonomy_name] !== '') { $attribute_slug = $variation_attributes[$taxonomy_name]; $attribute_value = WPLA_ProductWrapper::getAttributeValueFromSlug($taxonomy_name, $attribute_slug); $field_value = str_replace('[attribute_' . $attribute . ']', $attribute_value, $field_value); } } } // if child variation $post_id = $product->id; // match shortcodes (again, because they may already been processed) if (preg_match_all("/\\[attribute_(.*)\\]/uUsm", $field_value, $matches)) { // $product_attributes = WPLA_ProductWrapper::getAttributes( $post_id ); // WPLA()->logger->debug('processAttributeShortcodes() - product_attributes: '.print_r($product_attributes,1)); // WPLA()->logger->debug('called getAttributes() for post_id '.$post_id.' - field: '.$field_value); // process attribute shortcodes i.e. [attribute_Brand] $product_attributes = WPLA()->memcache->getProductAttributes($post_id); foreach ($matches[1] as $attribute) { if (isset($product_attributes['pa_' . $attribute])) { $attribute_value = $product_attributes['pa_' . $attribute]; } else { $attribute_value = ''; } $processed_html = str_replace('[attribute_' . $attribute . ']', $attribute_value, $field_value); // check if string exceeds max_length after processing shortcode // if ( $max_length && ( $this->mb_strlen( $processed_html ) > $max_length ) ) { // $attribute_value = ''; // $processed_html = str_replace( '[attribute_'.$attribute.']', $attribute_value, $field_value ); // } $field_value = $processed_html; } } // WPLA()->logger->info('processAttributeShortcodes() - return value: '.print_r($field_value,1)); return $field_value; }
public function checkFBAStock($mode = 'in_stock_only') { // get all published listings $lm = new WPLA_ListingsModel(); $out_of_sync_products = array(); if ($mode == 'all_stock') { $listings = $lm->getAllItemsUsingFBA(); } else { $listings = $lm->getAllItemsWithStockInFBA(); } // process FBA listings foreach ($listings as $item) { // get wc product $item = (array) $item; $_product = $this->getProduct($item['post_id']); if (!$_product) { continue; } // checking parent variations makes no sense in WPLA, so skip them if ($_product->product_type == 'variable') { continue; } // check stock level $stock = WPLA_ProductWrapper::getStock($item['post_id']); if ($stock == $item['fba_quantity']) { continue; } // copy FBA qty to Woo if (isset($_REQUEST['wpla_copy_fba_qty_to_woo'])) { update_post_meta($item['post_id'], '_stock', $item['fba_quantity']); continue; } // add to list of out of stock products $item['stock'] = $stock; $item['parent_id'] = $_product->product_type == 'variation' ? $_product->parent->id : false; $out_of_sync_products[] = $item; } // return if empty if (empty($out_of_sync_products)) { WPLA()->showMessage('All FBA products are in sync with WooCommerce.', 0, 1); return; } $msg = '<p>'; $msg .= sprintf('There are %s FBA products have a different stock level in WooCommerce.', sizeof($out_of_sync_products)); $msg .= '</p>'; // table header $msg .= '<table style="width:100%">'; $msg .= "<tr>"; $msg .= "<th style='text-align:left'>SKU</th>"; $msg .= "<th style='text-align:left'>Product</th>"; $msg .= "<th style='text-align:left'>FBA</th>"; $msg .= "<th style='text-align:left'>WooCommerce</th>"; $msg .= "<th style='text-align:left'>ASIN</th>"; $msg .= "<th style='text-align:left'>Status</th>"; $msg .= "</tr>"; // table rows foreach ($out_of_sync_products as $item) { // get column data $sku = $item['sku']; $qty = $item['quantity']; $fba_qty = $item['fba_quantity']; $stock = $item['stock']; $title = $item['listing_title']; $post_id = $item['post_id']; $asin = $item['asin']; $status = $item['status']; // build links // $amazon_url = $item['ViewItemURL'] ? $item['ViewItemURL'] : $amazon_url = 'http://www.amazon.com/itm/'.$asin; $amazon_url = 'admin.php?page=wpla&s=' . $asin; $amazon_link = '<a href="' . $amazon_url . '" target="_blank">' . $asin . '</a>'; $edit_link = '<a href="post.php?action=edit&post=' . ($item['parent_id'] ? $item['parent_id'] : $post_id) . '" target="_blank">' . $title . '</a>'; // build table row $msg .= "<tr>"; $msg .= "<td>{$sku}</td>"; $msg .= "<td>{$edit_link}</td>"; $msg .= "<td>{$fba_qty}</td>"; $msg .= "<td>{$stock}</td>"; $msg .= "<td>{$amazon_link}</td>"; $msg .= "<td>{$status}</td>"; $msg .= "</tr>"; } $msg .= '</table>'; $msg .= '<p>'; $url = 'admin.php?page=wpla-tools&tab=inventory&action=check_wc_fba_stock&wpla_copy_fba_qty_to_woo=yes&mode=' . $mode . '&_wpnonce=' . wp_create_nonce('wpla_tools_page'); $msg .= '<a href="' . $url . '" class="button">' . __('Copy FBA quantity to WooCommerce', 'wpla') . '</a> '; $msg .= 'Click this button set the stock level in WooCommerce to the current FBA quantity for each found product.'; $msg .= '</p>'; WPLA()->showMessage($msg, 1, 1); }
public function applyProfileToItem($profile, $item) { global $wpdb; // allow to pass a listing_id instead of item object if (!is_object($item)) { $item = $this->getItem($item, OBJECT); } // echo "<pre>";print_r($item);echo"</pre>";#die(); // get item data $id = $item->id; $post_id = $item->post_id; $status = $item->status; $asin = $item->asin; // gather profile data $data = array(); $data['profile_id'] = $profile->id; $data['account_id'] = $profile->account_id; // apply profile price $data['price'] = WPLA_ProductWrapper::getPrice($post_id); $data['price'] = $profile->processProfilePrice($data['price']); // update vtheme for child and parent variations if (in_array($item->product_type, array('variation', 'variable'))) { // $data['vtheme'] == $item->vtheme; ? // check for actual change // check profile for variation_theme $profile_fields = maybe_unserialize($profile->fields); if (is_array($profile_fields) && isset($profile_fields['variation_theme']) && !empty($profile_fields['variation_theme'])) { // use variation theme from profile $data['vtheme'] = $profile_fields['variation_theme']; } else { // update variation theme from product (parent variation) $parent_id = $item->parent_id ? $item->parent_id : $item->post_id; $data['vtheme'] = self::getVariationThemeForPostID($parent_id); } } // if variable product // default new status is 'changed' $data['status'] = 'changed'; if ($status == 'failed') { $data['status'] = 'changed'; } if ($status == 'online') { $data['status'] = 'changed'; } // except for matched or imported products if ($status == 'matched') { $data['status'] = $status; } if ($status == 'imported') { $data['status'] = $status; } if ($status == 'prepared') { $data['status'] = $status; } // submitted items stay 'submitted' and archived items stay archived if ($status == 'submitted') { $data['status'] = $status; } if ($status == 'archived') { $data['status'] = $status; } if ($status == 'trash') { $data['status'] = $status; } if ($status == 'trashed') { $data['status'] = $status; } // debug if ($status != $data['status']) { WPLA()->logger->info('applyProfileToItem(' . $id . ') old status: ' . $status); WPLA()->logger->info('applyProfileToItem(' . $id . ') new status: ' . $data['status']); } // update auctions table $wpdb->update($this->tablename, $data, array('id' => $id)); // WPLA()->logger->info('updating listing ID '.$id); // WPLA()->logger->info('data: '.print_r($data,1)); // WPLA()->logger->info('sql: '.$wpdb->last_query); // WPLA()->logger->info('error: '.$wpdb->last_error); }
function meta_box_images() { global $post; $this->add_inline_js(); ?> <style type="text/css"> #wpla-amazon-images .wpla_gallery_thumb_link { float: left; margin-right: 1em; border: 1px solid #ccc; } #wpla-amazon-images .wpla_gallery_thumb_link:hover, #wpla-amazon-images .wpla_gallery_thumb_link.disabled:hover { border: 1px solid #555; } #wpla-amazon-images .wpla_gallery_thumb_link.disabled { border: 1px solid #eee; } #wpla-amazon-images .wpla_gallery_thumb_link.disabled img { opacity: 0.33; } #wpla-amazon-images .wpla_gallery_thumb_img { width:79px; } </style> <?php // get disabled images as array of attachment_ids $disabled_images = get_post_meta($post->ID, '_wpla_disabled_gallery_images', true); $disabled_images = explode(',', $disabled_images); // get featured image $featured_image_id = get_post_thumbnail_id($post->ID); // get gallery images $product = get_product($post->ID); $attachment_ids = WPLA_ProductWrapper::getGalleryAttachmentIDs($product); // use featured image first, and merge gallery images $attachment_ids = array_unique(array_merge(array($featured_image_id), $attachment_ids)); // process gallery images $gallery_images = array(); foreach ($attachment_ids as $attachment_id) { $src = wp_get_attachment_image_src($attachment_id, 'thumbnail'); //getting image source $image = new stdClass(); $image->id = $attachment_id; $image->src = $src[0]; $gallery_images[] = $image; } // output thumbnails foreach ($gallery_images as $image) { $css_class = in_array($image->id, $disabled_images) ? 'disabled' : ''; echo '<a href="#" class="wpla_gallery_thumb_link ' . $css_class . '" data-attachment_id="' . $image->id . '" title="' . basename($image->src) . '"/>'; echo '<img src="' . $image->src . '" class="wpla_gallery_thumb_img" data-attachment_id="' . $image->id . '"/>'; echo '</a>'; } echo '<p style="clear:both;">'; echo '<small>'; echo __('Click an image to disable / enable it to be used on Amazon.', 'wpla'); echo '</small></p>'; echo '<div id="amazon_result_info" class="updated" style="display:none"><p></p></div>'; // echo "<pre>";print_r($disabled_images);echo"</pre>";#die(); // echo "<pre>";print_r($gallery_images);echo"</pre>";#die(); }
public function ajax_wpla_load_template_data_for_product() { // TODO: check nonce if (isset($_REQUEST['tpl_id'])) { $template = new WPLA_AmazonFeedTemplate($_REQUEST['tpl_id']); $post_id = $_REQUEST['post_id']; $field_data = get_post_meta($post_id, '_wpla_custom_feed_columns', true); if ($template) { // build settings form $data = array(); $data['fields'] = $template->getFieldData(); $data['values'] = $template->getFieldValues(); $data['profile_field_data'] = is_array($field_data) ? $field_data : array(); $data['product_attributes'] = WPLA_ProductWrapper::getAttributeTaxonomies(); @WPLA_Page::display('profile/edit_field_data', $data); exit; } else { echo "invalid template id"; } } }
function collect_updated_products($post_id, $post) { WPLA()->logger->info("CSV: collect_updated_products( {$post_id} )"); if (!$_POST) { return $post_id; } // if ( is_int( wp_is_post_revision( $post_id ) ) ) return; // if( is_int( wp_is_post_autosave( $post_id ) ) ) return; // if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return $post_id; if (!current_user_can('edit_post', $post_id)) { return $post_id; } if (!in_array($post->post_type, array('product', 'product_variation'))) { return $post_id; } // if this is a single variation use parent_id // if ( $parent_id = WPLA_ProductWrapper::getVariationParent( $post_id ) ) { if ($post->post_type == 'product_variation') { $parent_id = WPLA_ProductWrapper::getVariationParent($post_id); // WPLA()->logger->info("single variation found - use parent $parent_id for $post_id"); $post_id = $parent_id; } // get queue $collected_products = get_option('wpla_updated_products_queue', array()); if (!is_array($collected_products)) { $collected_products = array(); } // add product_id to queue - if it doesn't exist if (!in_array($post_id, $collected_products)) { $collected_products[] = $post_id; } // WPLA()->logger->info("collected products: ".print_r($collected_products,1)); // update queue update_option('wpla_updated_products_queue', $collected_products); }
function revertStockReduction($wpla_order) { global $wpdb; if (!is_array($wpla_order['history'])) { return; } foreach ($wpla_order['history'] as $history_record) { // filter reduce_stock actions if ($history_record->action != 'reduce_stock') { continue; } // make sure purchased qty was recorded (since 0.9.2.8) $details = $history_record->details; if (!isset($details['qty_purchased'])) { continue; } $quantity_purchased = $details['qty_purchased']; // handle non-FBA quantity if (isset($details['quantity']) && isset($details['sku'])) { // get listing item $lm = new WPLA_ListingsModel(); $listing = $lm->getItemBySKU($details['sku']); // update quantity for FBA orders $quantity = $listing->quantity + $quantity_purchased; $quantity_sold = $listing->quantity_sold - $quantity_purchased; $wpdb->update($wpdb->prefix . 'amazon_listings', array('quantity' => $quantity, 'quantity_sold' => $quantity_sold), array('sku' => $details['sku'])); } // handle FBA quantity if (isset($details['fba_quantity']) && isset($details['sku'])) { // get listing item $lm = new WPLA_ListingsModel(); $listing = $lm->getItemBySKU($details['sku']); // update quantity for FBA orders $fba_quantity = $listing->fba_quantity + $quantity_purchased; $quantity_sold = $listing->quantity_sold - $quantity_purchased; $wpdb->update($wpdb->prefix . 'amazon_listings', array('fba_quantity' => $fba_quantity, 'quantity_sold' => $quantity_sold), array('sku' => $details['sku'])); } // handle WooCommerce quantity if (isset($details['product_id'])) { // increase product stock $post_id = $details['product_id']; $newstock = WPLA_ProductWrapper::increaseStockBy($post_id, $quantity_purchased, $wpla_order['order_id']); WPLA()->logger->info('increased product stock for #' . $post_id . ' by ' . $quantity_purchased . ' - new qty: ' . $newstock); // notify WP-Lister for eBay (and other plugins) do_action('wpla_inventory_status_changed', $post_id); } } // each history record }
function getProductVariations($post_id) { // update cache if required if ($this->last_product_var_id != $post_id) { $this->last_product_variations = WPLA_ProductWrapper::getVariations($post_id); $this->last_product_var_id = $post_id; } return $this->last_product_variations; }