/** * Displays the widget in the sidebar. * * @param array $args Sidebar arguments. * @param array $instance The instance. */ public function widget($args, $instance) { // Check if session contains recently viewed products if (!isset($_SESSION[self::SESSION_KEY]) || empty($_SESSION[self::SESSION_KEY])) { return; } // Start buffering the output ob_start(); // Set the widget title $title = apply_filters('widget_title', $instance['title'] ? $instance['title'] : __('Recently Viewed Products', 'jigoshop'), $instance, $this->id_base); // Set number of products to fetch if (!($number = absint($instance['number']))) { $number = 5; } // Set up query $query_args = array('posts_per_page' => $number, 'post_type' => Core\Types::PRODUCT, 'post_status' => 'publish', 'nopaging' => true, 'post__in' => $_SESSION[self::SESSION_KEY], 'meta_query' => array(array('key' => 'visibility', 'value' => array(Product::VISIBILITY_CATALOG, Product::VISIBILITY_PUBLIC), 'compare' => 'IN'))); // Run the query $q = new \WP_Query($query_args); $products = self::$productService->findByQuery($q); $ordered = array(); foreach ($_SESSION[self::SESSION_KEY] as $key) { if (isset($products[$key])) { $ordered[$key] = $products[$key]; } } $products = $ordered; if (!empty($products)) { Render::output('widget/recently_viewed_products/widget', array_merge($args, array('title' => $title, 'products' => $products))); } }
public function __construct(Container $di, Wordpress $wp, Options $options, ProductServiceInterface $productService) { $this->wp = $wp; $this->options = $options; $types = $options->getEnabledProductTypes(); foreach ($types as $typeClass) { /** @var Types\Product\Type $type */ $type = $di->get($typeClass); if (!$type instanceof Types\Product\Type) { if (WP_DEBUG) { throw new Exception(sprintf(__('Invalid type definition! Offending class: "%s".', 'jigoshop'), $typeClass)); } Registry::getInstance(JIGOSHOP_LOGGER)->addWarning(sprintf('Invalid type definition! Offending class: "%s".', $typeClass)); continue; } $this->enabledTypes[$type->getId()] = $type; $productService->addType($type->getId(), $type->getClass()); $wp->addAction('jigoshop\\product\\type\\init', array($type, 'initialize'), 10, 2); } $wp->doAction('jigoshop\\product\\type\\init', $wp, $this->enabledTypes); // Enable comments for all orders, disable pings $wp->addFilter('wp_insert_post_data', function ($data) { if ($data['post_type'] == Product::NAME) { $data['comment_status'] = 'open'; $data['ping_status'] = 'closed'; } return $data; }); }
/** * Displays the widget in the sidebar. * * @param array $args Sidebar arguments. * @param array $instance The instance. * * @return bool|void */ public function widget($args, $instance) { // Get the best selling products from the transient $cache = get_transient(Core::WIDGET_CACHE); // If cached get from the cache if (isset($cache[$args['widget_id']])) { echo $cache[$args['widget_id']]; return; } // Start buffering ob_start(); // Set the widget title $title = apply_filters('widget_title', $instance['title'] ? $instance['title'] : __('Best Sellers', 'jigoshop'), $instance, $this->id_base); // Set number of products to fetch if (!($number = absint($instance['number']))) { $number = 5; } // Set up query $query_args = array('posts_per_page' => $number, 'post_type' => Types::PRODUCT, 'post_status' => 'publish', 'meta_key' => 'stock_sold', 'orderby' => 'meta_value_num+0', 'order' => 'desc', 'nopaging' => false, 'meta_query' => array(array('key' => 'visibility', 'value' => array(Product::VISIBILITY_CATALOG, Product::VISIBILITY_PUBLIC), 'compare' => 'IN'))); // Run the query $q = new \WP_Query($query_args); $products = self::$productService->findByQuery($q); if (!empty($products)) { Render::output('widget/best_sellers/widget', array_merge($args, array('title' => $title, 'products' => $products))); } // Flush output buffer and save to transient cache $cache[$args['widget_id']] = ob_get_flush(); set_transient(Core::WIDGET_CACHE, $cache, 3600 * 3); // 3 hours ahead }
/** * Dummy constructor. * @param Wordpress $wp * @param Options $options * @param ProductServiceInterface $productService * @param CartServiceInterface $cartService * @param Messages $messages */ public function __construct(Wordpress $wp, Options $options, ProductServiceInterface $productService, CartServiceInterface $cartService, Messages $messages) { $this->wp = $wp; $this->options = $options; $this->productService = $productService; $this->cartService = $cartService; $this->messages = $messages; $wp->addFilter('jigoshop\\cart\\add', function ($item) use($productService) { /** @var $item Item */ $item->setKey($productService->generateItemKey($item)); return $item; }); }
public function ajaxFindProduct() { try { $products = array(); if (isset($_POST['query'])) { $query = trim(htmlspecialchars(strip_tags($_POST['query']))); if (!empty($query)) { $products = $this->productService->findLike($query); } } else { if (isset($_POST['value'])) { $query = explode(',', trim(htmlspecialchars(strip_tags($_POST['value'])))); foreach ($query as $id) { $products[] = $this->productService->find($id); } } else { throw new Exception(__('Neither query nor value is provided to find products.', 'jigoshop')); } } $result = array('success' => true, 'results' => $this->prepareResults($products)); } catch (Exception $e) { $result = array('success' => false, 'error' => $e->getMessage()); } echo json_encode($result); exit; }
/** * @param $product VariableProduct Product to fetch variations for. * * @return array List of variations. */ public function getVariations($product) { $wpdb = $this->wp->getWPDB(); $query = $wpdb->prepare("\n\t\t\tSELECT pv.ID, pva.* FROM {$wpdb->posts} pv\n\t\t\t\tLEFT JOIN {$wpdb->prefix}jigoshop_product_variation_attribute pva ON pv.ID = pva.variation_id\n\t\t\t\tWHERE pv.post_parent = %d AND pv.post_type = %s\n\t\t", array($product->getId(), \Jigoshop\Core\Types\Product\Variable::TYPE)); $results = $wpdb->get_results($query, ARRAY_A); $variations = array(); $results = array_filter($results, function ($item) { return $item['attribute_id'] !== null; }); for ($i = 0, $endI = count($results); $i < $endI;) { $variation = new VariableProduct\Variation(); $variation->setId((int) $results[$i]['ID']); $variation->setParent($product); /** @var Product $variableProduct */ $variableProduct = $this->productService->find($results[$i]['ID']); $variation->setProduct($variableProduct); // TODO: Maybe some kind of fetching together? while ($i < $endI && $results[$i]['ID'] == $variation->getId()) { $attribute = new VariableProduct\Attribute(VariableProduct\Attribute::VARIATION_ATTRIBUTE_EXISTS); $attribute->setVariation($variation); $attribute->setAttribute($product->getAttribute($results[$i]['attribute_id'])); $attribute->setValue($results[$i]['value']); if ($attribute->getAttribute() !== null) { $variation->addAttribute($attribute); } $i++; } $variations[$variation->getId()] = $variation; } return $variations; }
public function render() { $query = $this->wp->getQuery(); $products = $this->productService->findByQuery($query); $content = do_shortcode($this->getContent()); return Render::get('shop', array('content' => $content, 'products' => $products, 'product_count' => $query->max_num_pages, 'messages' => $this->messages, 'title' => $this->getTitle())); }
/** * @param $id int Order ID. * * @return array List of items assigned to the order. */ private function getItems($id) { $wpdb = $this->wp->getWPDB(); $query = $wpdb->prepare("\n\t\t\tSELECT * FROM {$wpdb->prefix}jigoshop_order_item joi\n\t\t\tLEFT JOIN {$wpdb->prefix}jigoshop_order_item_meta joim ON joim.item_id = joi.id\n\t\t\tWHERE joi.order_id = %d\n\t\t\tORDER BY joi.id", array($id)); $results = $wpdb->get_results($query, ARRAY_A); $items = array(); for ($i = 0, $endI = count($results); $i < $endI;) { $id = $results[$i]['id']; $product = $this->productService->find($results[$i]['product_id']); $item = new Entity\Item(); $item->setId($results[$i]['item_id']); $item->setName($results[$i]['title']); $item->setQuantity($results[$i]['quantity']); $item->setPrice($results[$i]['price']); $item->setTax($results[$i]['tax']); while ($i < $endI && $results[$i]['id'] == $id) { // Securing against empty meta's, but still no piece of code does not add the meta. if ($results[$i]['meta_key']) { $meta = new Entity\Item\Meta(); $meta->setKey($results[$i]['meta_key']); $meta->setValue($results[$i]['meta_value']); $item->addMeta($meta); } $i++; } $product = $this->wp->applyFilters('jigoshop\\factory\\order\\find_product', $product, $item); $item->setProduct($product); $item->setKey($this->productService->generateItemKey($item)); $items[] = $item; } return $items; }
/** * Displays the form for the wordpress admin. * * @param array $instance Instance data. * * @return string|void */ public function form($instance) { $title = isset($instance['title']) ? esc_attr($instance['title']) : null; $attribute = isset($instance['attribute']) ? esc_attr($instance['attribute']) : null; $attributes = self::$productService->findAllAttributes(); Render::output('widget/layered_nav/form', array('title_id' => $this->get_field_id('title'), 'title_name' => $this->get_field_name('title'), 'title' => $title, 'attribute_id' => $this->get_field_id('attribute'), 'attribute_name' => $this->get_field_name('attribute'), 'attribute' => $attribute, 'attributes' => $attributes)); }
public function ajaxRemoveVariation() { try { if (!isset($_POST['product_id']) || empty($_POST['product_id'])) { throw new Exception(__('Product was not specified.', 'jigoshop')); } if (!is_numeric($_POST['product_id'])) { throw new Exception(__('Invalid product ID.', 'jigoshop')); } if (!isset($_POST['variation_id']) || empty($_POST['variation_id'])) { throw new Exception(__('Variation was not specified.', 'jigoshop')); } if (!is_numeric($_POST['variation_id'])) { throw new Exception(__('Invalid variation ID.', 'jigoshop')); } $product = $this->productService->find((int) $_POST['product_id']); if (!$product->getId()) { throw new Exception(__('Product does not exists.', 'jigoshop')); } if (!$product instanceof Product\Variable) { throw new Exception(__('Product is not variable - unable to add variation.', 'jigoshop')); } $variation = $product->removeVariation((int) $_POST['variation_id']); $this->service->removeVariation($variation); $this->productService->save($product); echo json_encode(array('success' => true)); } catch (Exception $e) { echo json_encode(array('success' => false, 'error' => $e->getMessage())); } exit; }
public function displayColumn($column) { $post = $this->wp->getGlobalPost(); if ($post === null) { return; } /** @var Product | Product\Variable $product */ $product = $this->productService->find($post->ID); switch ($column) { case 'thumbnail': echo ProductHelper::getFeaturedImage($product, Options::IMAGE_THUMBNAIL); break; case 'price': echo ProductHelper::getPriceHtml($product); break; case 'featured': echo ProductHelper::isFeatured($product); break; case 'type': echo $this->type->getType($product->getType())->getName(); break; case 'sku': echo $this->getVariableAdditionalInfo($product, 'sku'); break; case 'stock': echo $this->getVariableAdditionalInfo($product, 'stock'); break; case 'creation': $timestamp = strtotime($post->post_date); echo Formatter::date($timestamp); if ($product->isVisible()) { echo '<br /><strong>' . __('Visible in', 'jigoshop') . '</strong>: '; switch ($product->getVisibility()) { case ProductEntity::VISIBILITY_SEARCH: echo __('Search only', 'jigoshop'); break; case ProductEntity::VISIBILITY_CATALOG: echo __('Catalog only', 'jigoshop'); break; case ProductEntity::VISIBILITY_PUBLIC: echo __('Catalog and search', 'jigoshop'); break; } } break; } }
/** * Displays the widget in the sidebar. * * @param array $args Sidebar arguments. * @param array $instance The instance. * * @return bool|void */ public function widget($args, $instance) { ob_start(); // Set the widget title $title = apply_filters('widget_title', $instance['title'] ? $instance['title'] : __('Featured Products', 'jigoshop'), $instance, $this->id_base); // Set number of products to fetch if (!($number = absint($instance['number']))) { $number = 5; } // Set up query $query_args = array('posts_per_page' => $number, 'post_type' => Types::PRODUCT, 'post_status' => 'publish', 'meta_key' => 'featured', 'meta_value' => '1', 'meta_query' => array(array('key' => 'visibility', 'value' => array(Product::VISIBILITY_CATALOG, Product::VISIBILITY_PUBLIC), 'compare' => 'IN'))); // Run the query $q = new \WP_Query($query_args); $products = self::$productService->findByQuery($q); if (!empty($products)) { Render::output('widget/featured_products/widget', array_merge($args, array('title' => $title, 'products' => $products))); } }
/** * Finds and returns number of available attributes. * * @return int Number of available product attributes */ public function countAttributes() { if (!empty($this->attributes)) { return count($this->attributes); } if ($this->attributesCount === null) { $this->attributesCount = $this->service->countAttributes(); } return $this->attributesCount; }
/** * Displays "Stock Report" meta box. */ public function stockReport() { $lowStockThreshold = $this->options->get('advanced.low_stock_threshold', 2); $notifyOufOfStock = $this->options->get('advanced.notify_out_of_stock', true); $number = $this->options->get('advanced.dashboard_stock_number', 5); $outOfStock = array(); if ($notifyOufOfStock) { $outOfStock = $this->productService->findOutOfStock($number); } $lowStock = $this->productService->findLowStock($lowStockThreshold, $number); Render::output('admin/dashboard/stockReport', array('notifyOutOfStock' => $notifyOufOfStock, 'outOfStock' => $outOfStock, 'lowStock' => $lowStock)); }
/** * @param $variation Product\Variable\Variation * @param $product Product\Variable * * @return Product */ private function _createVariableProduct($variation, $product) { $variableId = $this->createVariablePost($variation); /** @var Product|Product\Purchasable|Product\Saleable $variableProduct */ $variableProduct = $this->productService->find($variableId); $variableProduct->setVisibility(Product::VISIBILITY_NONE); $variableProduct->setTaxable($product->isTaxable()); $variableProduct->setTaxClasses($product->getTaxClasses()); $variableProduct->getStock()->setManage(true); if ($variableProduct instanceof Product\Saleable) { $variableProduct->getSales()->unserialize($product->getSales()->serialize()); } return $variableProduct; }
protected function _fetchItemData($args) { $defaults = array('id' => 0, 'variation_id' => 0, 'variation' => array(), 'cost_inc_tax' => 0, 'name' => '', 'qty' => 1, 'cost' => 0, 'taxrate' => 0); if ($args['variation_id'] > 0) { $post = $this->wp->getPost($args['variation_id']); if ($post) { /** @var Product\Variable $product */ $product = $this->productService->find($post->post_parent); if ($product->getId() && $product instanceof Product\Variable) { $args['name'] = $product->getVariation($post->ID)->getTitle(); } } } return $this->_fetchData($defaults, $args); }
public function ajaxAddProduct() { try { /** @var \Jigoshop\Entity\Order $order */ $order = $this->orderService->find((int) $_POST['order']); if ($order->getId() === null) { throw new Exception(__('Order not found.', 'jigoshop')); } /** @var ProductEntity|ProductEntity\Purchasable $product */ $post = $this->wp->getPost((int) $_POST['product']); if ($post->post_type == 'product_variation' && $post->post_parent > 0) { $post = $this->wp->getPost($post->post_parent); //TODO: change this!!! $_POST['variation_id'] = (int) $_POST['product']; $_POST['quantity'] = 1; } /** @var Product\* $product */ $product = $this->productService->findforPost($post); if ($product->getId() === null) { throw new Exception(__('Product not found.', 'jigoshop')); } /** @var Item $item */ $item = $this->wp->applyFilters('jigoshop\\cart\\add', null, $product); if ($item === null) { throw new Exception(__('Product cannot be added to the order.', 'jigoshop')); } $key = $this->productService->generateItemKey($item); $item->setKey($key); $order->addItem($item); $this->orderService->save($order); $row = Render::get('admin/order/item/' . $item->getType(), array('item' => $item)); $result = $this->getAjaxResponse($order); $result['html']['row'] = $row; } catch (Exception $e) { $result = array('success' => false, 'error' => $e->getMessage()); } echo json_encode($result); exit; }
/** * Migrates data from old format to new one. * @param array $products * @return bool migration product status: success or not */ public function migrate($products) { $wpdb = $this->wp->getWPDB(); // Open transaction for save migration products $var_autocommit_sql = $wpdb->get_var("SELECT @@AUTOCOMMIT"); try { $this->checkSql(); $wpdb->query("SET AUTOCOMMIT=0"); $this->checkSql(); $wpdb->query("START TRANSACTION"); $this->checkSql(); // Register product type taxonomy to fetch old product types $this->wp->registerTaxonomy('product_type', array('product'), array('hierarchical' => false, 'show_ui' => false, 'query_var' => true, 'show_in_nav_menus' => false)); $this->checkSql(); if ($this->wp->getOption('jigoshop_migration_product_first', false) == false) { // Update product_cat into product_category $wpdb->query($wpdb->prepare("UPDATE {$wpdb->term_taxonomy} SET taxonomy = %s WHERE taxonomy = %s", array('product_category', 'product_cat'))); $this->checkSql(); $wpdb->query($wpdb->prepare("UPDATE {$wpdb->postmeta} SET meta_value = %s WHERE meta_key = %s AND meta_value = %s", array('product_category', '_menu_item_object', 'product_cat'))); $this->checkSql(); foreach ($wpdb->get_results("SELECT * FROM {$wpdb->prefix}jigoshop_termmeta", ARRAY_A) as $termMeta) { $wpdb->insert($wpdb->prefix . 'jigoshop_term_meta', $termMeta); } $this->wp->updateOption('jigoshop_migration_product_first', true); } $productIds = array(); $attributes = array(); $productAttributes = array(); $globalAttributes = array(); foreach ($wpdb->get_results("SELECT * FROM {$wpdb->prefix}jigoshop_attribute_taxonomies") as $attribute) { $this->checkSql(); $globalAttributes[$this->wp->getHelpers()->sanitizeTitle($attribute->attribute_name)] = $attribute; } foreach ($wpdb->get_results("SELECT id AS attribute_id, slug AS attribute_name, label AS attribute_label, type AS attribute_type FROM {$wpdb->prefix}jigoshop_attribute") as $attribute) { $this->checkSql(); $globalAttributes[$attribute->attribute_name] = $attribute; } for ($i = 0, $endI = count($products); $i < $endI;) { $product = $products[$i]; $productIds[] = $product->ID; $productAttributes[$product->ID] = array('attributes' => array(), 'variations' => array()); // Add product types $types = $this->wp->getTheTerms($product->ID, 'product_type'); $this->checkSql(); $productType = Product\Simple::TYPE; if (is_array($types)) { if (!in_array($types[0]->slug, array(Product\Simple::TYPE, Product\Virtual::TYPE, Product\Downloadable::TYPE, Product\External::TYPE, Product\Variable::TYPE))) { Migration::saveLog(sprintf(__('We detected a product <a href="%s" target="_blank">(#%d) %s </a> of type "subscription" - this type is not supported by Jigoshop without an additional plugin. We changed its type to "simple" and set it as private.', 'jigoshop'), get_permalink($product->ID), $product->ID, get_the_title($product->ID), $types[0]->slug)); $wpdb->query($wpdb->prepare("UPDATE {$wpdb->posts} SET post_status = 'private' WHERE ID = %d", $product->ID)); $types[0]->slug = 'simple'; } $productType = $types[0]->slug; $wpdb->query($wpdb->prepare("INSERT INTO {$wpdb->postmeta} VALUES (NULL, %d, %s, %s)", array($product->ID, 'type', $types[0]->slug))); $this->checkSql(); } $regularPrice = 0.0; $taxClasses = array(); // Update columns do { // Sales support if ($products[$i]->meta_key == 'sale_price' && !empty($products[$i]->meta_value)) { $wpdb->query($wpdb->prepare("INSERT INTO {$wpdb->postmeta} (post_id, meta_key, meta_value) VALUES (%d, %s, %s)", array($product->ID, 'sales_enabled', true))); $this->checkSql(); } // Product attributes support if ($products[$i]->meta_key == 'product_attributes') { $attributeData = unserialize($products[$i]->meta_value); if (is_array($attributeData)) { foreach ($attributeData as $slug => $source) { if (empty($source['value'])) { continue; } $changeLocalToGlobal = isset($source['variation']) && $source['variation'] == true && $source['is_taxonomy'] != true && $productType == Product\Variable::TYPE; $productAttributes[$product->ID]['attributes'][$slug] = array('is_visible' => $source['visible'], 'is_variable' => isset($source['variation']) && $source['variation'] == true, 'values' => $changeLocalToGlobal ? str_replace(',', '|', $source['value']) : $source['value']); if (!isset($attributes[$slug])) { $type = isset($globalAttributes[$slug]) ? $this->_getAttributeType($globalAttributes[$slug]) : Text::TYPE; if ($changeLocalToGlobal) { $type = Multiselect::TYPE; } $label = isset($globalAttributes[$slug]) ? !empty($globalAttributes[$slug]->attribute_label) ? $globalAttributes[$slug]->attribute_label : $globalAttributes[$slug]->attribute_name : $source['name']; $attribute = $this->productService->createAttribute($type); $attribute->setSlug($slug); $attribute->setLabel($label); $attribute->setLocal($source['is_taxonomy'] != true && $changeLocalToGlobal != true); if ($changeLocalToGlobal) { foreach (explode('|', $productAttributes[$product->ID]['attributes'][$slug]['values']) as $attributeOption) { $option = new Option(); $option->setLabel($attributeOption); $option->setValue(sanitize_title($attributeOption)); $attribute->addOption($option); } $productAttributes[$product->ID]['attributes'][$slug]['values'] = array_map(function ($item) { return sanitize_title($item); }, explode('|', $productAttributes[$product->ID]['attributes'][$slug]['values'])); } $attributes[$slug] = $attribute; } } } } // Product variation data if ($products[$i]->meta_key == 'variation_data') { $variations = unserialize($products[$i]->meta_value); foreach ($variations as $variation => $value) { $productAttributes[$product->ID]['variations'][str_replace('tax_', '', $variation)] = sanitize_title($value); } } $key = $this->_transformKey($products[$i]->meta_key); if ($key !== null) { $value = $this->_transform($products[$i]->meta_key, $products[$i]->meta_value); if ($key == 'regular_price') { $regularPrice = $value; } if ($key == 'tax_classes') { $taxClasses = $value; } $wpdb->query($wpdb->prepare("UPDATE {$wpdb->postmeta} SET meta_value = %s, meta_key = %s WHERE meta_id = %d", array($value, $key, $products[$i]->meta_id))); $this->checkSql(); } $i++; } while ($i < $endI && $products[$i]->ID == $product->ID); // Update regular price if it includes tax if (!empty($this->taxes)) { $taxClasses = maybe_unserialize($taxClasses); foreach ($taxClasses as $taxClass) { if (isset($this->taxes['__compound__' . $taxClass])) { $regularPrice = $regularPrice / (100 + $this->taxes['__compound__' . $taxClass]['rate']) * 100; } } foreach ($taxClasses as $taxClass) { if (isset($this->taxes[$taxClass])) { $regularPrice = $regularPrice / (100 + $this->taxes[$taxClass]['rate']) * 100; } } $wpdb->query($wpdb->prepare("UPDATE {$wpdb->postmeta} SET meta_value = %s WHERE meta_key = %s AND post_id = %d", array($regularPrice, 'regular_price', $product->ID))); $this->checkSql(); } } foreach ($globalAttributes as $slug => $attributeData) { if (isset($attributes[$slug])) { continue; } $type = $this->_getAttributeType($attributeData); $label = !empty($attributeData->attribute_label) ? $attributeData->attribute_label : $attributeData->attribute_name; $attribute = $this->productService->createAttribute($type); $attribute->setSlug($slug); $attribute->setLabel($label); $attribute->setLocal(false); $attributes[$slug] = $attribute; } foreach ($attributes as $slug => $attribute) { /** @var $attribute Product\Attribute */ $antiDuplicateAttributes = unserialize($this->wp->getOption('jigoshop_attributes_anti_duplicate', serialize(array()))); if (!isset($antiDuplicateAttributes[$attribute->getSlug()]) || $attribute->isLocal()) { if (!$attribute->isLocal()) { // Fetch options if attribute is a taxonomy $options = $wpdb->get_results("\n\t\t\t\t\t\tSELECT t.name, t.slug FROM {$wpdb->terms} t\n\t\t\t\t\t\t\tLEFT JOIN {$wpdb->term_taxonomy} tt ON tt.term_id = t.term_id\n\t\t\t\t\t\t WHERE tt.taxonomy = 'pa_{$slug}'\n\t\t\t\t \t "); $this->checkSql(); $createdOptions = array(); foreach ($options as $source) { $option = new Option(); $option->setLabel($source->name); $option->setValue($source->slug); $attribute->addOption($option); $createdOptions[] = $source->slug; } } $this->productService->saveAttribute($attribute); $this->checkSql(); if (!$attribute->isLocal()) { $antiDuplicateAttributes[$attribute->getSlug()] = $attribute->getId(); $this->wp->updateOption('jigoshop_attributes_anti_duplicate', serialize($antiDuplicateAttributes)); $this->checkSql(); } } else { //merge attributes $attribute = $this->productService->getAttribute($antiDuplicateAttributes[$attribute->getSlug()]); if ($attribute instanceof Product\Attribute) { $savedOptions = array_map(function ($item) { return $item->getValue(); }, $attribute->getOptions()); foreach ($attributes[$slug]->getOptions() as $option) { if (!in_array($option->getValue(), $savedOptions)) { $attribute->addOption($option); } } $attributes[$slug] = $attribute; $this->productService->saveAttribute($attribute); } } // Add attribute to the products if ($attribute instanceof Product\Attribute) { foreach ($productIds as $id) { if (isset($productAttributes[$id]['attributes'][$attribute->getSlug()])) { $data = $productAttributes[$id]['attributes'][$attribute->getSlug()]; $value = array(); if (is_array($data['values'])) { foreach ($attribute->getOptions() as $option) { /** @var $option Option */ if (in_array($option->getValue(), $data['values'])) { $value[] = $option->getId(); } } } if (empty($value)) { $value = $data['values']; } $wpdb->insert($wpdb->prefix . 'jigoshop_product_attribute', array('product_id' => $id, 'attribute_id' => $attribute->getId(), 'value' => is_array($value) ? join('|', $value) : $value)); $this->checkSql(); $query = array('product_id' => $id, 'attribute_id' => $attribute->getId(), 'meta_key' => 'is_visible', 'meta_value' => $data['is_visible']); $wpdb->insert($wpdb->prefix . 'jigoshop_product_attribute_meta', $query); $this->checkSql(); if ($data['is_variable']) { $query = array('product_id' => $id, 'attribute_id' => $attribute->getId(), 'meta_key' => 'is_variable', 'meta_value' => true); $wpdb->insert($wpdb->prefix . 'jigoshop_product_attribute_meta', $query); $this->checkSql(); } } } } } foreach ($productIds as $id) { foreach ($productAttributes[$id]['variations'] as $taxonomy => $value) { if (!isset($attributes[$taxonomy])) { continue; } $attribute = $attributes[$taxonomy]; $option = $this->_findOption($attribute->getOptions(), $value); $query = array('variation_id' => $id, 'attribute_id' => $attribute->getId(), 'value' => $option); $wpdb->insert($wpdb->prefix . 'jigoshop_product_variation_attribute', $query); $this->checkSql(); } } // Add found tax classes $currentTaxClasses = $this->options->get('tax.classes'); $currentTaxClassesKeys = array_map(function ($item) { return $item['class']; }, $currentTaxClasses); $this->taxClasses = array_filter(array_unique($this->taxClasses), function ($item) use($currentTaxClassesKeys) { return !in_array($item, $currentTaxClassesKeys); }); foreach ($this->taxClasses as $class) { $currentTaxClasses[] = array('label' => ucfirst($class), 'class' => $class); } $this->options->update('tax.classes', $currentTaxClasses); // commit sql transation and restore value of autocommit $wpdb->query("COMMIT"); $wpdb->query("SET AUTOCOMMIT=" . $var_autocommit_sql); return true; } catch (Exception $e) { // rollback sql transation and restore value of autocommit if (WP_DEBUG) { \Monolog\Registry::getInstance(JIGOSHOP_LOGGER)->addDebug($e); } $wpdb->query("ROLLBACK"); $wpdb->query("SET AUTOCOMMIT=" . $var_autocommit_sql); Migration::saveLog(__('Migration products end with error: ', 'jigoshop') . $e); return false; } }
/** * @param $currentTab string Current tab name. * @param $product \Jigoshop\Entity\Product Shown product. */ public function productDownloads($currentTab, $product) { Render::output('shop/product/downloads', array('product' => $product, 'currentTab' => $currentTab, 'attachments' => $this->productService->getAttachments($product)['downloads'])); }
/** * Displays the page. */ public function display() { Render::output('admin/product_attributes', array('messages' => $this->messages, 'attributes' => $this->productService->findAllAttributes(), 'types' => Attribute::getTypes())); }