public function ajax_wpla_view_pnq_log()
 {
     $sku = $_REQUEST['sku'];
     if (!$sku) {
         return;
     }
     // get all feed IDs:
     $feed_ids = WPLA_AmazonFeed::getAllPnqFeedsForSKU($sku);
     $log_rows = array();
     $feed_currency_format = get_option('wpla_feed_currency_format');
     // fetch all data rows for this SKU
     foreach ($feed_ids as $feed_id) {
         $feed = new WPLA_AmazonFeed($feed_id);
         $data_row = $feed->getDataRowForSKU($sku);
         // add details for template view
         $data_row['feed_id'] = $feed->id;
         $data_row['FeedSubmissionId'] = $feed->FeedSubmissionId;
         $data_row['SubmittedDate'] = $feed->SubmittedDate;
         $data_row['CompletedProcessingDate'] = $feed->CompletedProcessingDate;
         $data_row['FeedProcessingStatus'] = $feed->FeedProcessingStatus;
         // maybe convert decimal comma to decimal point
         if ($feed_currency_format == 'force_comma') {
             $data_row['price'] = str_replace(',', '.', $data_row['price']);
             $data_row['minimum-seller-allowed-price'] = str_replace(',', '.', $data_row['minimum-seller-allowed-price']);
             $data_row['maximum-seller-allowed-price'] = str_replace(',', '.', $data_row['maximum-seller-allowed-price']);
         }
         $log_rows[] = $data_row;
     }
     // echo "<pre>";print_r($log_rows);echo"</pre>";#die();
     // load template
     $tpldata = array('sku' => $sku, 'log_rows' => $log_rows);
     @WPLA_Page::display('ajax/pnq_log', $tpldata);
     exit;
 }
 public static function submitOrderToFBA($post_id)
 {
     // make sure we don't submit the same order twice (just a precaution)
     $status = get_post_meta($post_id, '_wpla_fba_submission_status', true);
     if ($status && $status != 'failed') {
         return false;
     }
     // should never happen - it might as well read: die('you are doing it wrong');
     // create FBA feed
     $feed = new WPLA_AmazonFeed();
     $feed->updateFbaSubmissionFeed($post_id);
     // mark order as submitted (pending)
     update_post_meta($post_id, '_wpla_fba_submission_status', 'pending');
     $response = new stdClass();
     $response->success = true;
     return $response;
 }
 /** ************************************************************************
  * REQUIRED! This is where you prepare your data for display. This method will
  * usually be used to query the database, sort and filter the data, and generally
  * get it ready to be displayed. At a minimum, we should set $this->items and
  * $this->set_pagination_args(), although the following properties and methods
  * are frequently interacted with here...
  * 
  * @uses $this->_column_headers
  * @uses $this->items
  * @uses $this->get_columns()
  * @uses $this->get_sortable_columns()
  * @uses $this->get_pagenum()
  * @uses $this->set_pagination_args()
  **************************************************************************/
 function prepare_items()
 {
     // process bulk actions
     $this->process_bulk_action();
     // get pagination state
     $current_page = $this->get_pagenum();
     $per_page = $this->get_items_per_page('feeds_per_page', 20);
     // define columns
     $this->_column_headers = $this->get_column_info();
     // fetch profiles from model
     $feedsModel = new WPLA_AmazonFeed();
     $this->items = $feedsModel->getPageItems($current_page, $per_page);
     $total_items = $feedsModel->total_items;
     // register our pagination options & calculations.
     $this->set_pagination_args(array('total_items' => $total_items, 'per_page' => $per_page, 'total_pages' => ceil($total_items / $per_page)));
 }
 public function action_submit_pending_feeds()
 {
     WPLA()->logger->info("do_action: wpla_submit_pending_feeds");
     $accounts = WPLA_AmazonAccount::getAll();
     foreach ($accounts as $account) {
         // refresh feeds
         WPLA_AmazonFeed::updatePendingFeedForAccount($account);
         // get pending feeds for account
         $feeds = WPLA_AmazonFeed::getAllPendingFeedsForAccount($account->id);
         WPLA()->logger->info("found " . sizeof($feeds) . " pending feeds for account {$account->id}");
         foreach ($feeds as $feed) {
             $autosubmit_feeds = array('_POST_FLAT_FILE_PRICEANDQUANTITYONLY_UPDATE_DATA_', '_POST_FLAT_FILE_LISTINGS_DATA_', '_POST_FLAT_FILE_FULFILLMENT_DATA_', '_POST_FLAT_FILE_FULFILLMENT_ORDER_REQUEST_DATA_', '_POST_FLAT_FILE_INVLOADER_DATA_');
             if (!in_array($feed->FeedType, $autosubmit_feeds)) {
                 WPLA()->logger->info("skipped pending feed {$feed->id} ({$feed->FeedType}) for account {$account->id} - autosubmit disabled for feed type");
                 continue;
             }
             // submit feed
             $feed->submit();
             WPLA()->logger->info("submitted pending feed {$feed->id} ({$feed->FeedType}) for account {$account->id}");
         }
     }
 }
 static function buildFeed($feed_type, $items, $account, $profile = false, $append_feed = false)
 {
     WPLA()->logger->info('buildFeed() ' . $feed_type . ' - account id: ' . $account->id);
     WPLA()->logger->info('items count: ' . sizeof($items));
     // WPLA()->logger->info('items: '.print_r($items,1));
     // limit feed size to prevent timeout
     $max_feed_size = get_option('wpla_max_feed_size', 1000);
     if (sizeof($items) > $max_feed_size) {
         $items = array_slice($items, 0, $max_feed_size);
     }
     // generate CSV data
     switch ($feed_type) {
         case '_POST_FLAT_FILE_PRICEANDQUANTITYONLY_UPDATE_DATA_':
             # price and quantity feed
             WPLA()->logger->info('building price and quantity feed...');
             WPLA()->logger->start('buildPriceAndQuantityFeedData');
             $csv_object = WPLA_FeedDataBuilder::buildPriceAndQuantityFeedData($items, $account->id);
             WPLA()->logger->logTime('buildPriceAndQuantityFeedData');
             break;
         case '_POST_FLAT_FILE_LISTINGS_DATA_':
             # new products feed
             WPLA()->logger->info('building new products feed...');
             WPLA()->logger->start('buildNewProductsFeedData');
             $csv_object = WPLA_FeedDataBuilder::buildNewProductsFeedData($items, $account->id, $profile, $append_feed);
             WPLA()->logger->logTime('buildNewProductsFeedData');
             break;
         case '_POST_FLAT_FILE_INVLOADER_DATA_':
             # delete products feed (Inventory Loader)
             WPLA()->logger->info('building delete products feed...');
             WPLA()->logger->start('buildInventoryLoaderFeedData');
             $csv_object = WPLA_FeedDataBuilder::buildInventoryLoaderFeedData($items, $account->id, $profile);
             WPLA()->logger->logTime('buildInventoryLoaderFeedData');
             break;
         default:
             # default
             WPLA()->logger->error('unsupported feed type ' . $feed_type);
             $csv_object = false;
             break;
     }
     if (!$csv_object || empty($csv_object->data)) {
         WPLA()->logger->warn('no feed data - not creating feed');
         return false;
     }
     // WPLA()->logger->info('CSV: '.$csv_object->data);
     // // extract TemplateType from listing data feed
     // $template_name = '';
     // if ( preg_match('/TemplateType=(.*)\t/U', $csv_object->data, $matches) ) {
     // 	$template_name = $matches[1];
     // 	WPLA()->logger->info('TemplateType: '.$template_name);
     // }
     // get template name / type from CSV object
     $template_name = '';
     if ('_POST_FLAT_FILE_LISTINGS_DATA_' == $feed_type) {
         $template_name = $csv_object->template_type;
         WPLA()->logger->info('TemplateType: ' . $template_name);
     }
     if ('_POST_FLAT_FILE_INVLOADER_DATA_' == $feed_type) {
         $template_name = 'Product Removal';
     }
     // set feed properties (required since $this is recycled here...)
     $new_feed = new WPLA_AmazonFeed();
     $new_feed->data = $csv_object->data;
     // $new_feed->line_count           = sizeof( $items );
     $new_feed->line_count = $csv_object->line_count;
     $new_feed->FeedType = $feed_type;
     $new_feed->template_name = $template_name;
     $new_feed->FeedProcessingStatus = 'pending';
     $new_feed->status = 'pending';
     $new_feed->account_id = $account->id;
     $new_feed->date_created = date('Y-m-d H:i:s');
     // check if a pending feed of this type already exists
     $existing_feed_id = self::getPendingFeedId($feed_type, $template_name, $account->id);
     // echo "<pre>template name: ";print_r($template_name);echo"</pre>";
     // echo "<pre>existing feed: ";print_r($existing_feed_id);echo"</pre>";
     if ($existing_feed_id && $append_feed) {
         // update existing feed (append)
         $existing_feed = self::getFeed($existing_feed_id);
         $new_feed->data = $existing_feed->data . "\n" . $csv_object->data;
         $new_feed->id = $existing_feed_id;
         $new_feed->template_name = $existing_feed->template_name;
         $new_feed->line_count += $existing_feed->line_count;
         $new_feed->update();
         WPLA()->logger->info('appended content to existing feed ' . $new_feed->id);
     } elseif ($existing_feed_id && !$append_feed) {
         // update existing feed (replace)
         $new_feed->id = $existing_feed_id;
         $new_feed->update();
         WPLA()->logger->info('updated existing feed ' . $new_feed->id);
     } else {
         // add new feed
         $new_feed->id = null;
         $new_feed->add();
         WPLA()->logger->info('added NEW feed - id ' . $new_feed->id);
     }
     WPLA()->logger->info('feed was built - ' . $new_feed->id);
     WPLA()->logger->info('------');
     return true;
 }
 public function prepareProductForListing($post_id, $profile_id)
 {
     global $wpdb;
     // get wp post and profile
     $post = get_post($post_id);
     $profile = new WPLA_AmazonProfile($profile_id);
     // if ( ! $profile ) return false;
     // skip duplicates
     // $product = get_product( $post_id );
     if ($item = $this->productExistsInAccount($post_id, $profile->account_id)) {
         $this->warnings[] = sprintf(__('"%s" already exists in account %s and has been skipped.', 'wpla'), get_the_title($post_id), $profile->account_id);
         return false;
     }
     // skip drafts
     // if ( $post->post_status != 'published' ) return;
     // support for qTranslate
     // if ( function_exists('qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage') ) {
     // 	$post_title   = qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage( $post_title );
     // 	$post_content = qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage( $post_content );
     // }
     // gather product data
     $product = get_product($post_id);
     if (!$product || !$product->exists()) {
         $this->errors[] = "Product {$post_id} could not be found.";
         return false;
     }
     // handle custom listing title
     $listing_title = $post->post_title;
     if ($product_value = get_post_meta($post_id, '_amazon_title', true)) {
         $listing_title = $product_value;
     }
     // trim title to 500 characters - longer titles will break $wpdb->insert() on varchar(500) column
     $listing_title = strlen($listing_title) < 500 ? $listing_title : $this->mb_substr($listing_title, 0, 500);
     // Amazon titles can not be longer than 500 characters
     // build listing item
     $data = array();
     $data['post_id'] = $post_id;
     $data['listing_title'] = $listing_title;
     // $data['post_content']  = $post->post_content;
     $data['price'] = WPLA_ProductWrapper::getPrice($post_id);
     $data['quantity'] = WPLA_ProductWrapper::getStock($post_id);
     $data['sku'] = WPLA_ProductWrapper::getSKU($post_id);
     $data['date_created'] = date('Y-m-d H:i:s', time());
     $data['status'] = 'prepared';
     $data['source'] = 'woo';
     $data['profile_id'] = $profile->profile_id;
     $data['account_id'] = $profile->account_id;
     $data['product_type'] = $product->product_type;
     // handle variable products
     if ($product->product_type == 'variable') {
         $last_variation_data = $this->prepareVariations($post_id, $profile, $post, $data);
         $data['vtheme'] = $last_variation_data['vtheme'];
     }
     WPLA()->logger->info('insert new listing ' . $post_id . ' - title: ' . $data['listing_title']);
     // WPLA()->logger->debug( print_r($post,1) );
     WPLA()->logger->debug(print_r($data, 1));
     // insert in listings table
     $wpdb->insert($this->tablename, $data);
     echo $wpdb->last_error;
     WPLA()->logger->debug('insert_id: ' . $wpdb->insert_id);
     WPLA()->logger->debug('sql: ' . $wpdb->last_query);
     WPLA()->logger->debug($wpdb->last_error);
     // apply profile (price)
     $listing_id = $wpdb->insert_id;
     $this->applyProfileToItem($profile, $listing_id);
     // update / create pending feed
     WPLA_AmazonFeed::updatePendingFeeds();
     return $listing_id;
 }
 public function showFeedDetails($id)
 {
     // get amazon_feed record
     $feed = new WPLA_AmazonFeed($id);
     // prepare feed content
     // $rows = $this->csv_to_array( $feed_data );
     $rows = $feed->getDataArray();
     // prepare feed result
     $result_header = implode("\n", array_slice(explode("\n", $feed->results), 0, 4));
     $result_content = implode("\n", array_slice(explode("\n", $feed->results), 4));
     $result_content = str_replace('original-record-number', '#', $result_content);
     $result_content = str_replace('error-code', 'code', $result_content);
     $result_content = str_replace('error-type', 'type', $result_content);
     $result_rows = $this->csv_to_array($result_content);
     // send log entry to support
     if (isset($_REQUEST['send_to_support']) && $_REQUEST['send_to_support'] == 'yes') {
         $this->sendRecordToSupport($id, $row);
     }
     unset($feed->data);
     unset($feed->results);
     $aData = array('feed' => $feed, 'rows' => $rows, 'result_rows' => $result_rows, 'result_header' => $result_header);
     $this->display('feed_details', $aData);
 }
 function customize_toolbar($wp_admin_bar)
 {
     // check if current user can manage listings
     if (!current_user_can('manage_amazon_listings')) {
         return;
     }
     // get stats about active and scheduled jobs
     $feeds_in_progress = get_option('wpla_feeds_in_progress', 0);
     $reports_in_progress = get_option('wpla_reports_in_progress', 0);
     $pending_feeds = get_option('wpla_db_version') > 0 ? WPLA_AmazonFeed::getAllPendingFeeds() : array();
     $total_active_jobs = $feeds_in_progress + $reports_in_progress + sizeof($pending_feeds);
     if ($total_active_jobs) {
         add_action('admin_footer', array(&$this, 'print_admin_toolbar_styles'));
     }
     // top level 'Amazon'
     $extra_class = $total_active_jobs ? '-spinner' : '';
     $args = array('id' => 'wpla_top', 'title' => __('Amazon', 'wpla'), 'href' => admin_url('admin.php?page=wpla'), 'meta' => array('class' => 'wpla-toolbar-top' . $extra_class));
     $wp_admin_bar->add_node($args);
     // Activity Monitor
     $activity_title = sprintf(__('%s active tasks', 'wpla'), $total_active_jobs);
     $activity_title = $total_active_jobs ? $activity_title : __('No active tasks', 'wpla');
     $args = array('id' => 'wpla_current_activity', 'title' => $activity_title, 'href' => '#', 'parent' => 'wpla_top', 'meta' => array('class' => 'wpla-toolbar-page wpla-activity-monitor'));
     $wp_admin_bar->add_node($args);
     // Activity: Reports
     $args = array('id' => 'wpla_current_reports', 'title' => __('Reports in progress', 'wpla') . ': ' . $reports_in_progress, 'href' => admin_url('admin.php?page=wpla-reports'), 'parent' => 'wpla_current_activity', 'meta' => array('class' => 'wpla-toolbar-page wpla-activity-monitor'));
     if ($reports_in_progress) {
         $wp_admin_bar->add_node($args);
     }
     // Activity: Feeds (submitted)
     $args = array('id' => 'wpla_current_feeds_submitted', 'title' => __('Feeds in progress', 'wpla') . ': ' . $feeds_in_progress, 'href' => admin_url('admin.php?page=wpla-feeds&feed_status=submitted'), 'parent' => 'wpla_current_activity', 'meta' => array('class' => 'wpla-toolbar-page wpla-activity-monitor'));
     if ($feeds_in_progress) {
         $wp_admin_bar->add_node($args);
     }
     // Activity: Feeds (pending)
     $args = array('id' => 'wpla_current_feeds_pending', 'title' => __('Scheduled feeds', 'wpla') . ': ' . sizeof($pending_feeds), 'href' => admin_url('admin.php?page=wpla-feeds&feed_status=pending'), 'parent' => 'wpla_current_activity', 'meta' => array('class' => 'wpla-toolbar-page wpla-activity-monitor'));
     if (!empty($pending_feeds)) {
         $wp_admin_bar->add_node($args);
     }
     // Listings page
     $args = array('id' => 'wpla_listings', 'title' => __('Listings', 'wpla'), 'href' => admin_url('admin.php?page=wpla'), 'parent' => 'wpla_top', 'meta' => array('class' => 'wpla-toolbar-page'));
     $wp_admin_bar->add_node($args);
     // Orders page
     $args = array('id' => 'wpla_orders', 'title' => __('Orders', 'wpla'), 'href' => admin_url('admin.php?page=wpla-orders'), 'parent' => 'wpla_top', 'meta' => array('class' => 'wpla-toolbar-page'));
     $wp_admin_bar->add_node($args);
     // Reports page
     $args = array('id' => 'wpla_reports', 'title' => __('Reports', 'wpla'), 'href' => admin_url('admin.php?page=wpla-reports'), 'parent' => 'wpla_top', 'meta' => array('class' => 'wpla-toolbar-page'));
     $wp_admin_bar->add_node($args);
     // Feeds page
     $args = array('id' => 'wpla_feeds', 'title' => __('Feeds', 'wpla'), 'href' => admin_url('admin.php?page=wpla-feeds'), 'parent' => 'wpla_top', 'meta' => array('class' => 'wpla-toolbar-page'));
     $wp_admin_bar->add_node($args);
     // Profiles page
     $args = array('id' => 'wpla_profiles', 'title' => __('Profiles', 'wpla'), 'href' => admin_url('admin.php?page=wpla-profiles'), 'parent' => 'wpla_top', 'meta' => array('class' => 'wpla-toolbar-page'));
     $wp_admin_bar->add_node($args);
     // Import page
     $args = array('id' => 'wpla_import', 'title' => __('Import', 'wpla'), 'href' => admin_url('admin.php?page=wpla-import'), 'parent' => 'wpla_top', 'meta' => array('class' => 'wpla-toolbar-page'));
     $wp_admin_bar->add_node($args);
     // Tools page
     $args = array('id' => 'wpla_tools', 'title' => __('Tools', 'wpla'), 'href' => admin_url('admin.php?page=wpla-tools'), 'parent' => 'wpla_top', 'meta' => array('class' => 'wpla-toolbar-page'));
     $wp_admin_bar->add_node($args);
     // Repricing Tool
     $args = array('id' => 'wpla_tools_repricing', 'title' => __('Repricing Tool', 'wpla'), 'href' => admin_url('admin.php?page=wpla-tools&tab=repricing'), 'parent' => 'wpla_tools', 'meta' => array('class' => 'wpla-toolbar-page'));
     $wp_admin_bar->add_node($args);
     // Inventory Check
     $args = array('id' => 'wpla_tools_inventory', 'title' => __('Inventory Check', 'wpla'), 'href' => admin_url('admin.php?page=wpla-tools&tab=inventory'), 'parent' => 'wpla_tools', 'meta' => array('class' => 'wpla-toolbar-page'));
     $wp_admin_bar->add_node($args);
     // SKU Generator
     $args = array('id' => 'wpla_tools_skugen', 'title' => __('SKU Generator', 'wpla'), 'href' => admin_url('admin.php?page=wpla-tools&tab=skugen'), 'parent' => 'wpla_tools', 'meta' => array('class' => 'wpla-toolbar-page'));
     $wp_admin_bar->add_node($args);
     // Developer Tools
     $args = array('id' => 'wpla_tools_developer', 'title' => __('Developer', 'wpla'), 'href' => admin_url('admin.php?page=wpla-tools&tab=developer'), 'parent' => 'wpla_tools', 'meta' => array('class' => 'wpla-toolbar-page'));
     $wp_admin_bar->add_node($args);
     if (current_user_can('manage_amazon_options')) {
         // Settings page
         $args = array('id' => 'wpla_settings', 'title' => __('Settings', 'wpla'), 'href' => admin_url('admin.php?page=wpla-settings'), 'parent' => 'wpla_top', 'meta' => array('class' => 'wpla-toolbar-page'));
         $wp_admin_bar->add_node($args);
         // Settings - General tab
         $args = array('id' => 'wpla_settings_general', 'title' => __('General Settings', 'wpla'), 'href' => admin_url('admin.php?page=wpla-settings&tab=settings'), 'parent' => 'wpla_settings', 'meta' => array('class' => 'wpla-toolbar-page'));
         $wp_admin_bar->add_node($args);
         // Settings - Accounts tab
         $args = array('id' => 'wpla_settings_accounts', 'title' => __('Accounts', 'wpla'), 'href' => admin_url('admin.php?page=wpla-settings&tab=accounts'), 'parent' => 'wpla_settings', 'meta' => array('class' => 'wpla-toolbar-page'));
         $wp_admin_bar->add_node($args);
         // Settings - Categories tab
         $args = array('id' => 'wpla_settings_categories', 'title' => __('Categories', 'wpla'), 'href' => admin_url('admin.php?page=wpla-settings&tab=categories'), 'parent' => 'wpla_settings', 'meta' => array('class' => 'wpla-toolbar-page'));
         $wp_admin_bar->add_node($args);
         // Settings - Advanced tab
         $args = array('id' => 'wpla_settings_advanced', 'title' => __('Advanced', 'wpla'), 'href' => admin_url('admin.php?page=wpla-settings&tab=advanced'), 'parent' => 'wpla_settings', 'meta' => array('class' => 'wpla-toolbar-page'));
         $wp_admin_bar->add_node($args);
         // Settings - Developer tab
         $args = array('id' => 'wpla_settings_developer', 'title' => __('Developer', 'wpla'), 'href' => admin_url('admin.php?page=wpla-settings&tab=developer'), 'parent' => 'wpla_settings', 'meta' => array('class' => 'wpla-toolbar-page'));
         $wp_admin_bar->add_node($args);
     }
     // if current_user_can('manage_amazon_options')
     if (current_user_can('manage_amazon_options') && get_option('wpla_log_to_db') == '1') {
         // Logs page
         $args = array('id' => 'wpla_log', 'title' => __('Logs', 'wpla'), 'href' => admin_url('admin.php?page=wpla-log'), 'parent' => 'wpla_top', 'meta' => array('class' => 'wpla-toolbar-page'));
         $wp_admin_bar->add_node($args);
     }
     // product page
     global $post;
     global $wp_query;
     global $pagenow;
     $post_id = false;
     if ($wp_query->in_the_loop && isset($wp_query->post->post_type) && $wp_query->post->post_type == 'product') {
         $post_id = $wp_query->post->ID;
     } elseif (is_object($post) && isset($post->post_type) && $post->post_type == 'product') {
         $post_id = $post->ID;
     }
     // skip product links on the main products page
     if ($pagenow == 'edit.php') {
         return;
     }
     // do we have a single product page?
     if (empty($post_id)) {
         return;
     }
     // enqueue ProductMatcher.js
     wp_register_script('wpla_product_matcher', WPLA_URL . '/js/classes/ProductMatcher.js?ver=' . time(), array('jquery'));
     wp_enqueue_script('wpla_product_matcher');
     wp_localize_script('wpla_product_matcher', 'wpla_ProductMatcher_i18n', array('WPLA_URL' => WPLA_URL));
     // get all items
     $lm = new WPLA_ListingsModel();
     $listings = $lm->getAllItemsByPostOrParentID($post_id);
     if (sizeof($listings) > 0) {
         $asin = $lm->getASINFromPostID($post_id);
         // $url = $lm->getViewItemURLFromPostID( $post_id );
         // View on Amazon link
         $args = array('id' => 'wpla_view_on_amazon', 'title' => __('View item on Amazon', 'wpla'), 'parent' => 'wpla_top', 'meta' => array('target' => '_blank', 'class' => 'wpla-toolbar-link'));
         if ($asin) {
             $wp_admin_bar->add_node($args);
         }
         foreach ($listings as $listing) {
             $listing_url = 'http://www.amazon.com/dp/' . $listing->asin . '/';
             if ($listing->account_id) {
                 $account = new WPLA_AmazonAccount($listing->account_id);
                 $market = new WPLA_AmazonMarket($account->market_id);
                 $listing_url = 'http://www.' . $market->url . '/dp/' . $listing->asin . '/';
             }
             $args = array('id' => 'wpla_view_on_amazon_' . $listing->id, 'title' => '#' . $listing->asin . ': ' . $listing->listing_title, 'href' => $listing_url, 'parent' => 'wpla_view_on_amazon', 'meta' => array('target' => '_blank', 'class' => 'wpla-toolbar-link'));
             if ($listing_url) {
                 $wp_admin_bar->add_node($args);
             }
         }
         // View in WP-Lister
         $url = admin_url('admin.php?page=wpla&s=' . $post_id);
         $args = array('id' => 'wpla_view_on_listings_page', 'title' => __('View item in WP-Lister', 'wpla'), 'href' => $url, 'parent' => 'wpla_top', 'meta' => array('target' => '_blank', 'class' => 'wpla-toolbar-link'));
         $wp_admin_bar->add_node($args);
     } else {
         // no listings
         // match product option
         $tb_url = admin_url('admin-ajax.php?action=wpla_show_product_matches&id=' . $post_id . '&width=640&height=420');
         // echo '<a href="'.$tb_url.'" class="thickbox" title="Match product on Amazon"><img src="'.WPLA_URL.'/img/search3.png" alt="match" /></a>';
         $onclick = 'tb_show("' . __('Match on Amazon', 'wpla') . '", "' . $tb_url . '");return false;';
         $args = array('id' => 'wpla_match_on_amazon', 'title' => __('Match on Amazon', 'wpla'), 'href' => $tb_url, 'parent' => 'wpla_top', 'meta' => array('onclick' => $onclick, 'class' => 'wpla-toolbar-link'));
         $wp_admin_bar->add_node($args);
         // $args = $this->addPrepareActions( $args );
     }
     // if ( current_user_can('prepare_amazon_listings') )
     $this->addPrepareActions($wp_admin_bar, $post_id);
 }
 function update_products_on_shutdown()
 {
     // get queue
     $collected_products = get_option('wpla_updated_products_queue', array());
     if (!is_array($collected_products)) {
         $collected_products = array();
     }
     // DEBUG
     WPLA()->logger->info("CSV: update_products_on_shutdown() - collected_products: " . print_r($collected_products, 1));
     // mark each queued product as modified
     $lm = new WPLA_ListingsModel();
     foreach ($collected_products as $post_id) {
         // do_action( 'wpla_product_has_changed', $post_id );
         $lm->markItemAsModified($post_id, true);
         // set $skip_updating_feeds = true
     }
     // clear queue
     delete_option('wpla_updated_products_queue');
     // update pending feeds - after all items have been updated
     if (!empty($collected_products)) {
         WPLA_AmazonFeed::updatePendingFeeds();
     }
 }