public function initEC($account_id = null, $site_id = null) { // make sure the database is up to date WPLE_UpgradeHelper::maybe_upgrade_db(); // init controller $this->EC = new EbayController(); // use current default account by default (WPL1) $ebay_site_id = self::getOption('ebay_site_id'); $sandbox_enabled = self::getOption('sandbox_enabled'); $ebay_token = self::getOption('ebay_token'); // set site_id dynamically during authentication // if ( isset( $_REQUEST['site_id'] ) && isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'wplRedirectToAuthURL' ) { if (isset($_REQUEST['site_id']) && isset($_REQUEST['sandbox'])) { $ebay_site_id = $_REQUEST['site_id']; $sandbox_enabled = $_REQUEST['sandbox']; $ebay_token = ''; } // use specific account if provided in request or parameter if (!$account_id && isset($_REQUEST['account_id'])) { $account_id = $_REQUEST['account_id']; } if ($account_id) { // $account = new WPLE_eBayAccount( $account_id ); // not suitable to check if an account exists $account = WPLE_eBayAccount::getAccount($account_id); if ($account) { $ebay_site_id = $account->site_id; $sandbox_enabled = $account->sandbox_mode; $ebay_token = $account->token; } else { $msg = sprintf('<b>Warning: You are trying to use an account which does not exist in WP-Lister</b> (ID %s).', $account_id) . '<br>'; $msg .= 'This can happen when you delete an account from WP-Lister without removing all listings, profiles and orders first.' . '<br><br>'; $msg .= 'In order to solve this issue, please visit your account settings and follow the instructions to assign all listings, orders and profiles to your default account.'; wple_show_message($msg, 'warn'); } } else { $account_id = get_option('wplister_default_account_id'); } if ($site_id) { $ebay_site_id = $site_id; } $this->EC->initEbay($ebay_site_id, $sandbox_enabled, $ebay_token, $account_id); }
function add() { global $wpdb; $table = $wpdb->prefix . self::TABLENAME; $data = array(); $data['user_details'] = ''; // fix rare "Field 'user_details' doesn't have a default value" error on some MySQL servers $data['shipping_profiles'] = ''; $data['payment_profiles'] = ''; $data['return_profiles'] = ''; $data['shipping_discount_profiles'] = ''; $data['categories_map_ebay'] = ''; $data['categories_map_store'] = ''; foreach ($this->fieldnames as $key) { if (isset($this->{$key})) { $data[$key] = $this->{$key}; } } if (sizeof($data) > 0) { $result = $wpdb->insert($table, $data); if (!$wpdb->insert_id) { wple_show_message('There was a problem adding your account. MySQL said: ' . $wpdb->last_error, 'error'); } $this->id = $wpdb->insert_id; return $wpdb->insert_id; } }
static function check_max_post_vars() { // count total number of post parameters - to show warning when running into max_input_vars limit ( or close: limit - 100 ) $max_input_vars = ini_get('max_input_vars'); $post_var_count = 0; foreach ($_POST as $parameter) { $post_var_count += is_array($parameter) ? sizeof($parameter) : 1; } // show warning warning message if post count is close to limit if ($post_var_count > $max_input_vars - 100) { $estimate = intval($post_var_count / 100) * 100; $msg = '<b>Warning: Your server has a limit of ' . $max_input_vars . ' input fields set for PHP</b> (max_input_vars)'; $msg .= '<br><br>'; $msg .= 'This page submitted more than ' . $estimate . ' fields, which means that either some data is already discarded by your server when this page is updated - or it will be when you add a few more product categories to your site. '; $msg .= '<br><br>'; $msg .= 'Please contact your hosting provider and have them increase the <code>max_input_vars</code> PHP setting to at least ' . $max_input_vars * 2 . ' to prevent any issues saving your category mappings.'; wple_show_message($msg, 'warn'); } }
function insertOrUpdate($data, $Detail) { global $wpdb; // try to get existing order by order id $order = $this->getOrderByOrderID($data['order_id']); if ($order) { // update existing order WPLE()->logger->info('update order #' . $data['order_id'] . ' - LastTimeModified: ' . $data['LastTimeModified']); $result = $wpdb->update($this->tablename, $data, array('order_id' => $data['order_id'])); if ($result === false) { WPLE()->logger->error('failed to update order - MySQL said: ' . $wpdb->last_error); wple_show_message('Failed to update order #' . $data['order_id'] . ' - MySQL said: ' . $wpdb->last_error, 'error'); } $insert_id = $order['id']; $this->addToReport('updated', $data); } else { // create new order WPLE()->logger->info('insert order #' . $data['order_id'] . ' - LastTimeModified: ' . $data['LastTimeModified']); $result = $wpdb->insert($this->tablename, $data); if ($result === false) { WPLE()->logger->error('insert order failed - MySQL said: ' . $wpdb->last_error); $this->addToReport('error', $data, false, $wpdb->last_error); wple_show_message('Failed to insert order #' . $data['order_id'] . ' - MySQL said: ' . $wpdb->last_error, 'error'); return false; } $Details = maybe_unserialize($data['details']); $order_post_id = false; $insert_id = $wpdb->insert_id; // WPLE()->logger->info( 'insert_id: '.$insert_id ); // process order line items $tm = new TransactionsModel(); foreach ($Details->TransactionArray as $Transaction) { // avoid empty transaction id (auctions) $transaction_id = $Transaction->TransactionID; if (intval($transaction_id) == 0) { // use negative OrderLineItemID to separate from real TransactionIDs $transaction_id = 0 - str_replace('-', '', $Transaction->OrderLineItemID); } // check if we already processed this TransactionID if ($existing_transaction = $tm->getTransactionByTransactionID($transaction_id)) { // add history record $history_message = "Skipped already processed transaction {$transaction_id}"; $history_details = array('ebay_id' => $ebay_id); $this->addHistory($data['order_id'], 'skipped_transaction', $history_message, $history_details); // TODO: optionally update transaction to reflect correct CompleteStatus etc. - like so: // $tm->updateTransactionFromEbayOrder( $data, $Transaction ); // skip processing listing items continue; } // check if item has variation $hasVariations = false; $VariationSpecifics = array(); if (is_object(@$Transaction->Variation)) { foreach ($Transaction->Variation->VariationSpecifics as $spec) { $VariationSpecifics[$spec->Name] = $spec->Value[0]; } $hasVariations = true; } // update listing sold quantity and status $this->processListingItem($data['order_id'], $Transaction->Item->ItemID, $Transaction->QuantityPurchased, $data, $VariationSpecifics, $Transaction); // create transaction record for future reference $tm->createTransactionFromEbayOrder($data, $Transaction); } $this->addToReport('inserted', $data, $order_post_id); } }
public function checkFolders() { // WPLE()->logger->info('creating wp-content/uploads/wp-lister/templates'); // create wp-content/uploads/wp-lister/templates if not exists $uploads = wp_upload_dir(); $uploaddir = $uploads['basedir']; $wpldir = $uploaddir . '/wp-lister'; if (!is_dir($wpldir)) { $result = @mkdir($wpldir); if ($result === false) { wple_show_message("Could not create template folder: " . $wpldir, 1, 1); return false; } } $tpldir = $wpldir . '/templates'; if (!is_dir($tpldir)) { $result = @mkdir($tpldir); if ($result === false) { wple_show_message("Could not create template folder: " . $tpldir, 1, 1); return false; } } // WPLE()->logger->info('template folder: '.$tpldir); }
public function prepareProductForListing($post_id, $profile_id = false, $post_content = false, $post_title = false, $parent_id = false) { global $wpdb; // get wp post record $post = get_post($post_id); $post_title = $post_title ? $post_title : $post->post_title; $post_content = $post_content ? $post_content : $post->post_content; // skip pending products and drafts // if ( $post->post_status != 'publish' ) { if (!in_array($post->post_status, array('publish', 'private'))) { if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'wpl_prepare_single_listing') { wple_show_message(__('Skipped product with status', 'wplister') . ' <em>' . $post->post_status . '</em>: ' . $post_title, 'warn'); } $this->warnings[] = sprintf(__('Skipped product %s with status %s.', 'wpla'), $post_id, $post->post_status); return false; } // skip duplicates if ($profile_id) { // get profile $pm = new ProfilesModel(); $profile = $pm->getItem($profile_id); // check if this product already exists in profile account if (WPLE_ListingQueryHelper::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 non-existing products $product = get_product($post_id); if (!$product || !$product->exists()) { $this->errors[] = "Product {$post_id} could not be found."; return false; } // support for qTranslate if (function_exists('qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage')) { $post_title = qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage($post_title); $post_content = qtrans_useCurrentLanguageIfNotFoundUseDefaultLanguage($post_content); } // trim title to 255 characters - longer titles will break $wpdb->insert() $post_title = strlen($post_title) < 255 ? $post_title : self::mb_substr($post_title, 0, 80); // eBay titles can not be longer than 80 characters // gather product data $data = array(); $data['post_id'] = $post_id; $data['parent_id'] = $parent_id ? $parent_id : 0; $data['auction_title'] = $post_title; $data['post_content'] = ''; // not required anymore $data['price'] = ProductWrapper::getPrice($post_id); $data['locked'] = 0; $data['status'] = 'selected'; WPLE()->logger->info('insert new auction ' . $post_id . ' - title: ' . $data['auction_title']); WPLE()->logger->debug(print_r($post, 1)); // insert in auctions table $result = $wpdb->insert($this->tablename, $data); // handle unexpected SQL issues properly if (!$wpdb->insert_id) { WPLE()->logger->info('insert_id: ' . $wpdb->insert_id); WPLE()->logger->info('result: ' . print_r($result, 1)); WPLE()->logger->info('sql: ' . $wpdb->last_query); WPLE()->logger->info($wpdb->last_error); $this->errors[] = sprintf(__('Error: MySQL failed to create listing record for "%s" (%s) using profile %s. Please contact support and include this error message.', 'wpla'), get_the_title($post_id), $post_id, $profile['profile_id']); return false; } return $wpdb->insert_id; }
public function checkForDelayedProfiles() { $profile_id = get_option('wple_job_reapply_profile_id'); if (!$profile_id) { return; } $msg = '<p>'; $msg .= 'Please wait a moment while the profile is applied to all linked items.'; $msg .= ' '; $msg .= '<a id="btn_run_delayed_profile_application" class="btn_run_delayed_profile_application button wpl_job_button">' . __('Apply Profile', 'wplister') . '</a>'; $msg .= '</p>'; wple_show_message($msg, 'warn'); }
public function fixCostOfGoods() { $om = new EbayOrdersModel(); $orders = $om->getAll(); // echo "<pre>";print_r($orders);echo"</pre>";#die(); $updated_orders = 0; // loop orders foreach ($orders as $order) { $post_id = $order['post_id']; if (!$post_id) { continue; } // check if order exist - prevent fatal error in WC_COG::set_order_item_cost_meta() $_order = wc_get_order($post_id); if (!$_order) { continue; } // skip orders with existing cog data if (get_post_meta($post_id, '_wc_cog_order_total_cost', true)) { continue; } // trigger COG update do_action('wplister_after_create_order', $post_id); // WC_COG::set_order_item_cost_meta( $post_id ); // might work as well... $updated_orders++; } $msg = $updated_orders . ' orders were updated.<br><br>'; wple_show_message($msg); }
/** * If a table only contains utf8 or utf8mb4 or latin1 columns, convert it to utf8mb4. * (modified version of maybe_convert_table_to_utf8mb4() in wp core) * * @since 0.9.6.5 * * @param string $table The table to convert. * @return bool true if the table was converted, false if it wasn't. */ static function convert_custom_table_to_utf8mb4($table) { global $wpdb; global $wp_version; // do nothing before wp42 if (version_compare($wp_version, '4,2', '<')) { wple_show_message('WordPress 4.2 or better required - your version is ' . $wp_version, 'error'); return false; } // get column information $results = $wpdb->get_results("SHOW FULL COLUMNS FROM `{$table}`"); if (!$results) { wple_show_message("no columns found for {$table}", 'error'); return false; } // check charset for each column foreach ($results as $column) { if ($column->Collation) { list($charset) = explode('_', $column->Collation); $charset = strtolower($charset); if ('utf8' !== $charset && 'utf8mb4' !== $charset && 'latin1' !== $charset) { // Don't upgrade tables that have non-utf8 and non-latin1 columns. wple_show_message("skipped column {$column} in table {$table} with charset: {$charset}", 'error'); return false; } } } // convert return $wpdb->query("ALTER TABLE {$table} CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"); }
public function checkItem($item, $reviseItem = false) { $success = true; $this->VariationsHaveStock = false; // check StartPrice, Quantity and SKU if (is_object($item->Variations)) { // item has variations $VariationsHaveStock = false; $VariationsSkuArray = array(); $VariationsSkuAreUnique = true; $VariationsSkuMissing = false; // check each variation foreach ($item->Variations->Variation as $var) { // StartPrice must be greater than 0 if (self::dbSafeFloatval($var->StartPrice) == 0) { $longMessage = __('Some variations seem to have no price.', 'wplister'); $success = false; } // Quantity must be greater than 0 - at least for one variation if (intval($var->Quantity) > 0) { $VariationsHaveStock = true; } // SKUs must be unique - if present if ($var->SKU != '') { if (in_array($var->SKU, $VariationsSkuArray)) { $VariationsSkuAreUnique = false; } else { $VariationsSkuArray[] = $var->SKU; } } else { $VariationsSkuMissing = true; } // VariationSpecifics values can't be longer than 50 characters foreach ($var->VariationSpecifics->NameValueList as $spec) { if (strlen($spec->Value) > 50) { $longMessage = __('eBay does not allow attribute values longer than 50 characters.', 'wplister'); $longMessage .= '<br>'; $longMessage .= __('You need to shorten this value:', 'wplister') . ' <code>' . $spec->Value . '</code>'; $success = false; } } } if (!$VariationsSkuAreUnique) { foreach ($item->Variations->Variation as &$var) { $var->SKU = ''; } $longMessage = __('You are using the same SKU for more than one variations which is not allowed by eBay.', 'wplister'); $longMessage .= '<br>'; $longMessage .= __('To circumvent this issue, your item will be listed without SKU.', 'wplister'); // $success = false; } if ($VariationsSkuMissing) { $longMessage = __('Some variations are missing a SKU.', 'wplister'); $longMessage .= '<br>'; $longMessage .= __('It is required to assign a unique SKU to each variation to prevent issues syncing sales.', 'wplister'); // $success = false; } if (!$VariationsHaveStock && !$reviseItem && !ListingsModel::thisAccountUsesOutOfStockControl($this->account_id)) { $longMessage = __('None of these variations are in stock.', 'wplister'); $success = false; } // make this info available to reviseItem() $this->VariationsHaveStock = $VariationsHaveStock; } else { // item has no variations // StartPrice must be greater than 0 if (self::dbSafeFloatval($item->StartPrice->value) == 0) { $longMessage = __('Price can not be zero.', 'wplister'); $success = false; } // check minimum start price if found // $min_prices = get_option( 'wplister_MinListingStartPrices', array() ); $min_prices = $this->site_id ? maybe_unserialize(WPLE_eBaySite::getSiteObj($this->site_id)->MinListingStartPrices) : array(); if (!is_array($min_prices)) { $min_prices = array(); } $listing_type = $item->ListingType ? $item->ListingType : 'FixedPriceItem'; if (isset($min_prices[$listing_type])) { $min_price = $min_prices[$listing_type]; if ($item->StartPrice->value < $min_price) { $longMessage = sprintf(__('eBay requires a minimum price of %s for this listing type.', 'wplister'), $min_price); $success = false; } } } // check if any required item specifics are missing $primary_category_id = $item->PrimaryCategory->CategoryID; $specifics = EbayCategoriesModel::getItemSpecificsForCategory($primary_category_id, $this->site_id, $this->account_id); foreach ($specifics as $req_spec) { // skip non-required specs if (!$req_spec->MinValues) { continue; } // skip if Name already exists in ItemSpecifics if (self::thisNameExistsInNameValueList($req_spec->Name, $item->ItemSpecifics->NameValueList)) { continue; } // skip if Name already exists in VariationSpecificsSet if (is_object($item->Variations)) { $VariationSpecificsSet = $item->Variations->getVariationSpecificsSet(); if (self::thisNameExistsInNameValueList($req_spec->Name, $VariationSpecificsSet->NameValueList)) { continue; } } $DoesNotApplyText = WPLE_eBaySite::getSiteObj($this->site_id)->DoesNotApplyText; $DoesNotApplyText = empty($DoesNotApplyText) ? 'Does not apply' : $DoesNotApplyText; // // add missing item specifics $NameValueList = new NameValueListType(); $NameValueList->setName($req_spec->Name); $NameValueList->setValue($DoesNotApplyText); $item->ItemSpecifics->addNameValueList($NameValueList); wple_show_message('<b>Note:</b> Missing item specifics <b>' . $req_spec->Name . '</b> was set to "' . $DoesNotApplyText . '" in order to prevent listing errors.', 'warn'); } // check if any item specific have more values than allowed foreach ($specifics as $req_spec) { // skip specs without limit if (!$req_spec->MaxValues) { continue; } // count values for this item specific $number_of_values = self::countValuesForNameInNameValueList($req_spec->Name, $item->ItemSpecifics->NameValueList); if ($number_of_values <= $req_spec->MaxValues) { continue; } // remove additional values from item specific for ($i = 0; $i < sizeof($item->ItemSpecifics->NameValueList); $i++) { if ($item->ItemSpecifics->NameValueList[$i]->Name != $req_spec->Name) { continue; } $values_array = $item->ItemSpecifics->NameValueList[$i]->Value; $item->ItemSpecifics->NameValueList[$i]->Value = reset($values_array); } wple_show_message('<b>Note:</b> The item specifics <b>' . $req_spec->Name . '</b> has ' . $number_of_values . ' values, but eBay allows only ' . $req_spec->MaxValues . ' value(s).<br>In order to prevent listing errors, additional values will be omitted.', 'warn'); } // ItemSpecifics values can't be longer than 50 characters foreach ($item->ItemSpecifics->NameValueList as $spec) { $values = is_array($spec->Value) ? $spec->Value : array($spec->Value); foreach ($values as $value) { if (strlen($value) > 50) { $longMessage = __('eBay does not allow attribute values longer than 50 characters.', 'wplister'); $longMessage .= '<br>'; $longMessage .= __('You need to shorten this value:', 'wplister') . ' <code>' . $value . '</code>'; $success = false; } } } // PrimaryCategory->CategoryID must be greater than 0 if (intval(@$item->PrimaryCategory->CategoryID) == 0) { $longMessage = __('There has been no primary category assigned.', 'wplister'); $success = false; } // check for main image if (trim(@$item->PictureDetails->GalleryURL) == '') { $longMessage = __('You need to add at least one image to your product.', 'wplister'); $success = false; } // remove ReservedPrice on fixed price items if ($item->getReservePrice() && $item->getListingType() == 'FixedPriceItem') { $item->setReservePrice(null); $longMessage = __('Reserve price does not apply to fixed price listings.', 'wplister'); // $success = false; } // omit price and shipping cost when revising an item with promotional sale enabled if ($reviseItem && ListingsModel::thisListingHasPromotionalSale($this->listing_id)) { $item->setStartPrice(null); $item->setShippingDetails(null); wple_show_message(__('Price and shipping were omitted since this item has promotional sale enabled.', 'wplister'), 'info'); } if (!$success && !$this->is_ajax()) { wple_show_message($longMessage, 'error'); } elseif ($longMessage != '' && !$this->is_ajax()) { wple_show_message($longMessage, 'warn'); } $htmlMsg = '<div id="message" class="error" style="display:block !important;"><p>'; $htmlMsg .= '<b>' . 'This item did not pass the validation check' . ':</b>'; $htmlMsg .= '<br>' . $longMessage . ''; $htmlMsg .= '</p></div>'; // save error as array of objects $errorObj = new stdClass(); $errorObj->SeverityCode = 'Validation'; $errorObj->ErrorCode = '42'; $errorObj->ShortMessage = $longMessage; $errorObj->LongMessage = $longMessage; $errorObj->HtmlMessage = $htmlMsg; $errors = array($errorObj); // save results as local property $this->result = new stdClass(); $this->result->success = $success; $this->result->errors = $errors; return $success; }
function show_admin_post_vars_warning() { // check if there was a problem saving values $post_var_count = get_option('wplister_last_post_var_count'); if (!$post_var_count) { return; } // ignore if max_input_vars is not set (php52?) $max_input_vars = ini_get('max_input_vars'); if (!$max_input_vars) { return; } $estimate = intval($post_var_count / 100) * 100; $msg = '<b>Warning: Your server has a limit of ' . $max_input_vars . ' input fields set for PHP</b> (max_input_vars)'; $msg .= '<br><br>'; $msg .= 'This page submitted more than ' . $estimate . ' fields, which means that either some data is already discarded by your server when this product is updated - or it will be when you add a few more variations to your product. '; $msg .= '<br><br>'; $msg .= 'Please contact your hosting provider and have them increase the <code>max_input_vars</code> PHP setting to at least ' . $max_input_vars * 2 . ' to prevent any issues updating your products.'; wple_show_message($msg, 'warn'); // only show this warning once update_option('wplister_last_post_var_count', ''); }
function checkForInvalidData($post) { global $page; if ('product' != $post->post_type) { return; } if ('auto-draft' == $post->post_status) { return; } // if ( ! get_option( 'wple_enable_missing_details_warning' ) ) return; $product = get_product($post); $invalid_eans = array(); $invalid_upcs = array(); $var_no_stock = array(); // UPC $ebay_upc = get_post_meta($product->id, '_ebay_upc', true); if ($ebay_upc && !WPLE_ValidationHelper::isValidUPC($ebay_upc)) { $invalid_upcs[] = $ebay_upc; } // EAN $ebay_ean = get_post_meta($product->id, '_ebay_ean', true); if ($ebay_ean && !WPLE_ValidationHelper::isValidEAN($ebay_ean)) { $invalid_eans[] = $ebay_ean; } // variable product if ($product->product_type == 'variable') { // get variations $variation_ids = $product->get_children(); $parent_manage_stock = get_post_meta($product->id, '_manage_stock', true); foreach ($variation_ids as $variation_id) { $_product = get_product($variation_id); $var_info = " (#{$variation_id})"; // UPC $ebay_upc = get_post_meta($variation_id, '_ebay_upc', true); if ($ebay_upc && !WPLE_ValidationHelper::isValidUPC($ebay_upc)) { $invalid_upcs[] = $ebay_upc . $var_info; } // EAN $ebay_ean = get_post_meta($variation_id, '_ebay_ean', true); if ($ebay_ean && !WPLE_ValidationHelper::isValidEAN($ebay_ean)) { $invalid_eans[] = $ebay_ean . $var_info; } // check if stock management is enabled on variation level $variation_manage_stock = get_post_meta($variation_id, '_manage_stock', true); if ($parent_manage_stock == 'yes' && $variation_manage_stock == 'no') { $var_no_stock[] = " #{$variation_id}"; } } // foreach variation } // variable product // show warning $errors_msg = ''; if (!empty($invalid_upcs)) { $errors_msg .= __('Warning: This number does not seem to be a valid UPC:', 'wplister') . ' <b>' . join($invalid_upcs, ', ') . '</b><br>'; $errors_msg .= __('Valid UPCs must have 12 digits.', 'wplister') . '<br>'; } if (!empty($invalid_eans)) { $errors_msg .= __('Warning: This number does not seem to be a valid EAN:', 'wplister') . ' <b>' . join($invalid_eans, ', ') . '</b><br>'; $errors_msg .= __('Valid EANs must have 13 digits.', 'wplister') . '<br>'; } if (!empty($var_no_stock)) { $errors_msg .= __('Warning: Stock management is enabled for this product but is disabled for these variations:', 'wplister') . ' <b>' . join($var_no_stock, ', ') . '</b><br>'; $errors_msg .= __('eBay requires separate stock levels for each variation. So please enable stock management for each variation and set the stock level on the variation level.', 'wplister') . '<br>'; $errors_msg .= __('Disabling stock management for single variations will cause sales not to be synced properly.', 'wplister') . '<br>'; } if (!empty($errors_msg)) { wple_show_message($errors_msg, 'warn'); do_action('wple_admin_notices'); } }