Ejemplo n.º 1
0
 public function action()
 {
     /** @var Order $order */
     $order = $this->orderService->find((int) $this->wp->getQueryParameter('pay'));
     if ($order->getKey() !== $_GET['key']) {
         $this->messages->addError(__('Invalid security key. Unable to process order.', 'jigoshop'));
         $this->wp->redirectTo($this->options->getPageId(Pages::ACCOUNT));
     }
     if (isset($_POST['action']) && $_POST['action'] == 'purchase') {
         try {
             if ($this->options->get('advanced.pages.terms') > 0 && (!isset($_POST['terms']) || $_POST['terms'] != 'on')) {
                 throw new Exception(__('You need to accept terms & conditions!', 'jigoshop'));
             }
             if (!isset($_POST['payment_method'])) {
                 throw new Exception(__('Please select one of available payment methods.', 'jigoshop'));
             }
             $payment = $this->paymentService->get($_POST['payment_method']);
             $order->setPaymentMethod($payment);
             if (!$payment->isEnabled()) {
                 throw new Exception(__('Selected payment method is not available. Please select another one.', 'jigoshop'));
             }
             $this->orderService->save($order);
             $url = $payment->process($order);
             // Redirect to thank you page
             if (empty($url)) {
                 $url = $this->wp->getPermalink($this->wp->applyFilters('jigoshop\\checkout\\redirect_page_id', $this->options->getPageId(Pages::THANK_YOU)));
                 $url = $this->wp->getHelpers()->addQueryArg(array('order' => $order->getId(), 'key' => $order->getKey()), $url);
             }
             $this->wp->wpRedirect($url);
             exit;
         } catch (Exception $e) {
             $this->messages->addError($e->getMessage());
         }
     }
 }
Ejemplo n.º 2
0
 /**
  * Creates new product properly based on POST variable data.
  *
  * @param $id int Post ID to create object for.
  *
  * @return \Jigoshop\Entity\Product
  */
 public function create($id)
 {
     $coupon = new Entity();
     $coupon->setId($id);
     if (!empty($_POST)) {
         $helpers = $this->wp->getHelpers();
         $coupon->setTitle($helpers->sanitizeTitle($_POST['post_title']));
         $_POST['jigoshop_coupon']['individual_use'] = $_POST['jigoshop_coupon']['individual_use'] == 'on';
         $_POST['jigoshop_coupon']['free_shipping'] = $_POST['jigoshop_coupon']['free_shipping'] == 'on';
         $_POST['jigoshop_coupon']['products'] = array_filter(explode(',', $_POST['jigoshop_coupon']['products']));
         $_POST['jigoshop_coupon']['excluded_products'] = array_filter(explode(',', $_POST['jigoshop_coupon']['excluded_products']));
         $_POST['jigoshop_coupon']['categories'] = array_filter(explode(',', $_POST['jigoshop_coupon']['categories']));
         $_POST['jigoshop_coupon']['excluded_categories'] = array_filter(explode(',', $_POST['jigoshop_coupon']['excluded_categories']));
         if (!empty($_POST['jigoshop_coupon']['from'])) {
             $_POST['jigoshop_coupon']['from'] = strtotime($_POST['jigoshop_coupon']['from']);
         } else {
             $_POST['jigoshop_coupon']['from'] = false;
         }
         if (!empty($_POST['jigoshop_coupon']['to'])) {
             $_POST['jigoshop_coupon']['to'] = strtotime($_POST['jigoshop_coupon']['to']);
         } else {
             $_POST['jigoshop_coupon']['to'] = false;
         }
         $coupon->restoreState($_POST['jigoshop_coupon']);
     }
     return $coupon;
 }
Ejemplo n.º 3
0
 /**
  * Creates new product properly based on POST variable data.
  *
  * @param $id int Post ID to create object for.
  *
  * @return \Jigoshop\Entity\Product
  */
 public function create($id)
 {
     $email = new Entity();
     $email->setId($id);
     if (!empty($_POST)) {
         $helpers = $this->wp->getHelpers();
         $email->setTitle($helpers->sanitizeTitle($_POST['post_title']));
         $email->setText($helpers->parsePostBody($_POST['content']));
         $availableActions = $this->getActions();
         $_POST['jigoshop_email']['actions'] = array_intersect($_POST['jigoshop_email']['actions'], array_keys($availableActions));
         $email->restoreState($_POST['jigoshop_email']);
     }
     return $email;
 }
Ejemplo n.º 4
0
 /**
  * Save the settings
  */
 private function save()
 {
     // We need to save the options ourselves; settings api does not trigger save for the permalinks page
     if (isset($_POST['permalink_structure']) || isset($_POST['category_base']) && isset($_POST['product_permalink'])) {
         // Cat and tag bases
         $categorySlug = trim(strip_tags($_POST['jigoshop_product_category_slug']));
         $tagSlug = trim(strip_tags($_POST['jigoshop_product_tag_slug']));
         $permalinks = $this->options->get('permalinks');
         $helpers = $this->wp->getHelpers();
         $permalinks['category'] = $helpers->untrailingslashit($categorySlug);
         $permalinks['tag'] = $helpers->untrailingslashit($tagSlug);
         // Product base
         $product_permalink = trim(strip_tags($_POST['product_permalink']));
         if ($product_permalink == 'custom') {
             // Get permalink without slashes
             $product_permalink = trim(strip_tags($_POST['product_permalink_structure']), '/');
             // This is an invalid base structure and breaks pages
             if ('%' . Types::PRODUCT_CATEGORY . '%' == $product_permalink) {
                 $product_permalink = _x('product', 'slug', 'jigoshop') . '/' . $product_permalink;
             }
         } elseif (empty($product_permalink)) {
             $product_permalink = false;
         }
         $permalinks['product'] = $helpers->untrailingslashit($product_permalink);
         // Shop base may require verbose page rules if nesting pages
         $shopPageId = $this->options->getPageId(FrontendPages::SHOP);
         $shop_permalink = urldecode($shopPageId > 0 && $this->wp->getPost($shopPageId) ? $this->wp->getPageUri($shopPageId) : _x('shop', 'default-slug', 'jigoshop'));
         if ($shopPageId && trim($permalinks['product'], '/') === $shop_permalink) {
             $permalinks['verbose'] = true;
         }
         $this->options->update('permalinks', $permalinks);
         $this->options->saveOptions();
         $this->wp->getRewrite()->flush_rules();
     }
 }
Ejemplo n.º 5
0
 public function ajaxSaveAttributeOption()
 {
     $errors = array();
     if (!isset($_POST['attribute_id']) || !is_numeric($_POST['attribute_id'])) {
         $errors[] = __('Respective attribute is not set.', 'jigoshop');
     }
     if (!isset($_POST['label']) || empty($_POST['label'])) {
         $errors[] = __('Option label is not set.', 'jigoshop');
     }
     if (!empty($errors)) {
         echo json_encode(array('success' => false, 'error' => join('<br/>', $errors)));
         exit;
     }
     $attribute = $this->productService->getAttribute((int) $_POST['attribute_id']);
     if (isset($_POST['id'])) {
         $option = $attribute->removeOption($_POST['id']);
     } else {
         $option = new Attribute\Option();
     }
     $option->setLabel(trim(htmlspecialchars(strip_tags($_POST['label']))));
     if (isset($_POST['slug']) && !empty($_POST['slug'])) {
         $option->setValue(trim(htmlspecialchars(strip_tags($_POST['value']))));
     } else {
         $option->setValue($this->wp->getHelpers()->sanitizeTitle($option->getLabel()));
     }
     $attribute->addOption($option);
     $this->productService->saveAttribute($attribute);
     echo json_encode(array('success' => true, 'html' => Render::get('admin/product_attributes/option', array('id' => $attribute->getId(), 'option_id' => $option->getId(), 'option' => $option))));
     exit;
 }
Ejemplo n.º 6
0
 /**
  * Adds a note to the order.
  *
  * @param $order   Order The order.
  * @param $note    string Note text.
  * @param $private bool Is note private?
  *
  * @return int Note ID.
  */
 public function addNote($order, $note, $private = true)
 {
     $comment = array('comment_post_ID' => $order->getId(), 'comment_author' => __('Jigoshop', 'jigoshop'), 'comment_author_email' => '', 'comment_author_url' => '', 'comment_content' => $note, 'comment_type' => 'order_note', 'comment_agent' => __('Jigoshop', 'jigoshop'), 'comment_parent' => 0, 'comment_date' => $this->wp->getHelpers()->currentTime('mysql'), 'comment_date_gmt' => $this->wp->getHelpers()->currentTime('mysql', true), 'comment_approved' => true);
     $comment = $this->wp->applyFilters('jigoshop\\service\\order\\add_note', $comment, $order, $note, $private);
     $comment_id = $this->wp->wpInsertComment($comment);
     $this->wp->addCommentMeta($comment_id, 'private', $private);
     return $comment_id;
 }
Ejemplo n.º 7
0
 /**
  * @param $result string Current email message.
  * @param $item   Order\Item Item to display.
  * @param $order  Order Order being displayed.
  *
  * @return string
  */
 public function emailLink($result, $item, $order)
 {
     $product = $item->getProduct();
     if ($product instanceof Product\Downloadable && in_array($order->getStatus(), array(Order\Status::COMPLETED, Order\Status::PROCESSING))) {
         $url = $this->wp->getHelpers()->addQueryArg(array('file' => $order->getKey() . '.' . $order->getId() . '.' . $item->getKey(), Api::getUrl(DownloadFile::NAME)));
         $result .= PHP_EOL . __('Your download link for this file is:', 'jigoshop');
         $result .= PHP_EOL . ' - ' . $url;
     }
     return $result;
 }
Ejemplo n.º 8
0
 public function displayTitle($actions)
 {
     $post = $this->wp->getGlobalPost();
     // Remove "Quick edit" as we won't use it.
     unset($actions['inline hide-if-no-js']);
     if ($post->post_type == Types::ORDER) {
         $fullFormat = _x('Y/m/d g:i:s A', 'time', 'jigoshop');
         $format = _x('Y/m/d', 'time', 'jigoshop');
         $fullDate = $this->wp->getHelpers()->mysql2date($fullFormat, $post->post_date);
         $date = $this->wp->getHelpers()->mysql2date($format, $post->post_date);
         echo '<time title="' . $fullDate . '">' . $this->wp->applyFilters('post_date_column_time', $date, $post) . '</time>';
     }
     return $actions;
 }
Ejemplo n.º 9
0
 /**
  * Check PayPal IPN validity
  */
 private function isResponseValid()
 {
     $values = $this->wp->getHelpers()->stripSlashesDeep($_POST);
     $values['cmd'] = '_notify-validate';
     // Send back post vars to PayPal
     $params = array('body' => $values, 'sslverify' => false, 'timeout' => 30, 'user-agent' => 'Jigoshop/' . Core::VERSION);
     // Get url
     if ($this->settings['test_mode']) {
         $url = self::TEST_URL;
     } else {
         $url = self::LIVE_URL;
     }
     // Post back to get a response
     $response = $this->wp->wpSafeRemotePost($url, $params);
     // check to see if the request was valid
     if (!$this->wp->isWpError($response) && $response['response']['code'] >= 200 && $response['response']['code'] < 300 && strcmp($response['body'], "VERIFIED") == 0) {
         return true;
     }
     Registry::getInstance(JIGOSHOP_LOGGER)->addWarning('Received invalid response from PayPal!', array('response' => $response));
     return false;
 }
Ejemplo n.º 10
0
 /**
  * Fetches product from database.
  *
  * @param $post \WP_Post Post to fetch product for.
  *
  * @return \Jigoshop\Entity\Product
  */
 public function fetch($post)
 {
     $type = $post ? $this->wp->getPostMeta($post->ID, 'type', true) : '';
     if (empty($type)) {
         $type = Simple::TYPE;
     }
     $product = $this->get($type);
     $state = array();
     if ($post) {
         $state = array_map(function ($item) {
             return $item[0];
         }, $this->wp->getPostMeta($post->ID));
         $state['attributes'] = $this->getAttributes($post->ID);
         $state['attachments'] = $this->getAttachments($post->ID);
         $state['id'] = $post->ID;
         $state['name'] = $post->post_title;
         $state['description'] = $this->wp->getHelpers()->parsePostBody($post->post_content);
         $state['categories'] = $this->getTerms($post->ID, Types::PRODUCT_CATEGORY);
         $state['tags'] = $this->getTerms($post->ID, Types::PRODUCT_TAG);
         if (isset($state['tax_classes'])) {
             $state['tax_classes'] = unserialize($state['tax_classes']);
         }
         if (isset($state['attribute_order']) && $state['attribute_order']) {
             $state['attribute_order'] = maybe_unserialize($state['attribute_order']);
             $attributes = array();
             foreach ($state['attribute_order'] as $attributeId) {
                 $attributes[$attributeId] = $state['attributes'][$attributeId];
             }
             foreach ($state['attributes'] as $attributeId => $attribute) {
                 if (!isset($attributes[$attributeId])) {
                     $attributes[$attributeId] = $attribute;
                 }
             }
             $state['attributes'] = $attributes;
         }
         $product->restoreState($state);
     }
     return $this->wp->applyFilters('jigoshop\\find\\product', $product, $state);
 }
Ejemplo n.º 11
0
 public function action()
 {
     if (isset($_REQUEST['action'])) {
         switch ($_REQUEST['action']) {
             case 'cancel_order':
                 if ($this->wp->getHelpers()->verifyNonce($_REQUEST['nonce'], 'cancel_order')) {
                     /** @var Order $order */
                     $order = $this->orderService->find((int) $_REQUEST['id']);
                     if ($order->getKey() != $_REQUEST['key']) {
                         $this->messages->addError(__('Invalid order key.', 'jigoshop'));
                         return;
                     }
                     if ($order->getStatus() != Status::PENDING) {
                         $this->messages->addError(__('Unable to cancel order.', 'jigoshop'));
                         return;
                     }
                     $order->setStatus(Status::CANCELLED);
                     $cart = $this->cartService->createFromOrder($this->cartService->getCartIdForCurrentUser(), $order);
                     $this->orderService->save($order);
                     $this->cartService->save($cart);
                     $this->messages->addNotice(__('The order has been cancelled', 'jigoshop'));
                 }
                 break;
             case 'update-shipping':
                 $customer = $this->customerService->getCurrent();
                 $this->updateCustomer($customer);
                 break;
             case 'checkout':
                 try {
                     $cart = $this->cartService->getCurrent();
                     // Update quantities
                     $this->updateQuantities($cart);
                     // Update customer (if needed)
                     if ($this->options->get('shipping.calculator')) {
                         $customer = $this->customerService->getCurrent();
                         $this->updateCustomer($customer);
                     }
                     if (isset($_POST['jigoshop_order']['shipping_method'])) {
                         // Select shipping method
                         $method = $this->shippingService->get($_POST['jigoshop_order']['shipping_method']);
                         $cart->setShippingMethod($method);
                     }
                     if ($cart->getShippingMethod() && !$cart->getShippingMethod()->isEnabled()) {
                         $cart->removeShippingMethod();
                         $this->messages->addWarning(__('Previous shipping method is unavailable. Please select different one.', 'jigoshop'));
                     }
                     if ($this->options->get('shopping.validate_zip')) {
                         $address = $cart->getCustomer()->getShippingAddress();
                         if ($address->getPostcode() && !Validation::isPostcode($address->getPostcode(), $address->getCountry())) {
                             throw new Exception(__('Postcode is not valid!', 'jigoshop'));
                         }
                     }
                     do_action('jigoshop\\cart\\before_checkout', $cart);
                     $this->cartService->save($cart);
                     $this->messages->preserveMessages();
                     $this->wp->redirectTo($this->options->getPageId(Pages::CHECKOUT));
                 } catch (Exception $e) {
                     $this->messages->addError(sprintf(__('Error occurred while updating cart: %s', 'jigoshop'), $e->getMessage()));
                 }
                 break;
             case 'update-cart':
                 if (isset($_POST['cart']) && is_array($_POST['cart'])) {
                     try {
                         $cart = $this->cartService->getCurrent();
                         $this->updateQuantities($cart);
                         $this->cartService->save($cart);
                         $this->messages->addNotice(__('Successfully updated the cart.', 'jigoshop'));
                     } catch (Exception $e) {
                         $this->messages->addError(sprintf(__('Error occurred while updating cart: %s', 'jigoshop'), $e->getMessage()));
                     }
                 }
         }
     }
     if (isset($_GET['action']) && isset($_GET['item']) && $_GET['action'] === 'remove-item' && is_numeric($_GET['item'])) {
         $cart = $this->cartService->getCurrent();
         $cart->removeItem((int) $_GET['item']);
         $this->cartService->save($cart);
         $this->messages->addNotice(__('Successfully removed item from cart.', 'jigoshop'), false);
     }
 }
Ejemplo n.º 12
0
 /**
  * Executes actions associated with selected page.
  */
 public function action()
 {
     $cart = $this->cartService->getCurrent();
     if ($cart->isEmpty()) {
         $this->messages->addWarning(__('Your cart is empty, please add products before proceeding.', 'jigoshop'));
         $this->wp->redirectTo($this->options->getPageId(Pages::SHOP));
     }
     if (!$this->isAllowedToEnterCheckout()) {
         $this->messages->addError(__('You need to log in before processing to checkout.', 'jigoshop'));
         $this->wp->redirectTo($this->options->getPageId(Pages::CART));
     }
     if (isset($_POST['action']) && $_POST['action'] == 'purchase') {
         try {
             $allowRegistration = $this->options->get('shopping.allow_registration');
             if ($allowRegistration && !$this->wp->isUserLoggedIn()) {
                 $this->createUserAccount();
             }
             if (!$this->isAllowedToCheckout($cart)) {
                 if ($allowRegistration) {
                     throw new Exception(__('You need either to log in or create account to purchase.', 'jigoshop'));
                 }
                 throw new Exception(__('You need to log in before purchasing.', 'jigoshop'));
             }
             if ($this->options->get('advanced.pages.terms') > 0 && (!isset($_POST['terms']) || $_POST['terms'] != 'on')) {
                 throw new Exception(__('You need to accept terms &amp; conditions!', 'jigoshop'));
             }
             $this->cartService->validate($cart);
             $this->customerService->save($cart->getCustomer());
             if (!Country::isAllowed($cart->getCustomer()->getBillingAddress()->getCountry())) {
                 $locations = array_map(function ($location) {
                     return Country::getName($location);
                 }, $this->options->get('shopping.selling_locations'));
                 throw new Exception(sprintf(__('This location is not supported, we sell only to %s.'), join(', ', $locations)));
             }
             $shipping = $cart->getShippingMethod();
             if ($this->isShippingRequired($cart) && (!$shipping || !$shipping->isEnabled())) {
                 throw new Exception(__('Shipping is required for this order. Please select shipping method.', 'jigoshop'));
             }
             $payment = $cart->getPaymentMethod();
             $isPaymentRequired = $this->isPaymentRequired($cart);
             $this->wp->doAction('jigoshop\\checkout\\payment', $payment);
             if ($isPaymentRequired && (!$payment || !$payment->isEnabled())) {
                 throw new Exception(__('Payment is required for this order. Please select payment method.', 'jigoshop'));
             }
             $order = $this->orderService->createFromCart($cart);
             /** @var Order $order */
             $order = $this->wp->applyFilters('jigoshop\\checkout\\order', $order);
             $this->orderService->save($order);
             $this->cartService->remove($cart);
             $url = '';
             if ($isPaymentRequired) {
                 $url = $payment->process($order);
             } else {
                 $order->setStatus(\Jigoshop\Helper\Order::getStatusAfterCompletePayment($order));
                 $this->orderService->save($order);
             }
             // Redirect to thank you page
             if (empty($url)) {
                 $url = $this->wp->getPermalink($this->wp->applyFilters('jigoshop\\checkout\\redirect_page_id', $this->options->getPageId(Pages::THANK_YOU)));
                 $url = $this->wp->getHelpers()->addQueryArg(array('order' => $order->getId(), 'key' => $order->getKey()), $url);
             }
             $this->wp->wpRedirect($url);
             exit;
         } catch (Exception $e) {
             $this->messages->addError($e->getMessage());
         }
     }
 }
Ejemplo n.º 13
0
 /**
  * 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;
     }
 }
Ejemplo n.º 14
0
 /**
  * @param $order Order The order.
  *
  * @return array Available arguments with proper values.
  */
 private function getOrderEmailArguments($order)
 {
     $billingAddress = $order->getCustomer()->getBillingAddress();
     $shippingAddress = $order->getCustomer()->getShippingAddress();
     return $this->wp->applyFilters('jigoshop\\emails\\order_variables', array('blog_name' => $this->wp->getBloginfo('name'), 'order_number' => $order->getNumber(), 'order_date' => $this->wp->getHelpers()->dateI18n($this->wp->getOption('date_format')), 'shop_name' => $this->options->get('general.company_name'), 'shop_address_1' => $this->options->get('general.company_address_1'), 'shop_address_2' => $this->options->get('general.company_address_2'), 'shop_tax_number' => $this->options->get('general.company_tax_number'), 'shop_phone' => $this->options->get('general.company_phone'), 'shop_email' => $this->options->get('general.company_email'), 'customer_note' => $order->getCustomerNote(), 'order_items' => $this->formatItems($order), 'subtotal' => ProductHelper::formatPrice($order->getSubtotal()), 'shipping' => ProductHelper::formatPrice($order->getShippingPrice()), 'shipping_cost' => ProductHelper::formatPrice($order->getShippingPrice()), 'shipping_cost_raw' => $order->getShippingPrice(), 'shipping_method' => $order->getShippingMethod() ? $order->getShippingMethod()->getName() : '', 'discount' => ProductHelper::formatPrice($order->getDiscount()), 'total_tax' => ProductHelper::formatPrice($order->getTotalTax()), 'total' => ProductHelper::formatPrice($order->getTotal()), 'is_local_pickup' => $order->getShippingMethod() && $order->getShippingMethod()->getId() == LocalPickup::NAME ? true : null, 'checkout_url' => $order->getStatus() == Order\Status::PENDING ? OrderHelper::getPayLink($order) : null, 'payment_method' => $order->getPaymentMethod()->getName(), 'billing_first_name' => $billingAddress->getFirstName(), 'billing_last_name' => $billingAddress->getLastName(), 'billing_company' => $billingAddress instanceof CompanyAddress ? $billingAddress->getCompany() : '', 'billing_address_1' => $billingAddress->getAddress(), 'billing_address_2' => '', 'billing_postcode' => $billingAddress->getPostcode(), 'billing_city' => $billingAddress->getCity(), 'billing_country' => Country::getName($billingAddress->getCountry()), 'billing_country_raw' => $billingAddress->getCountry(), 'billing_state' => Country::hasStates($billingAddress->getCountry()) ? Country::getStateName($billingAddress->getCountry(), $billingAddress->getState()) : $billingAddress->getState(), 'billing_state_raw' => $billingAddress->getState(), 'billing_email' => $billingAddress->getEmail(), 'billing_phone' => $billingAddress->getPhone(), 'shipping_first_name' => $shippingAddress->getFirstName(), 'shipping_last_name' => $shippingAddress->getLastName(), 'shipping_company' => $shippingAddress instanceof CompanyAddress ? $shippingAddress->getCompany() : '', 'shipping_address_1' => $shippingAddress->getAddress(), 'shipping_address_2' => '', 'shipping_postcode' => $shippingAddress->getPostcode(), 'shipping_city' => $shippingAddress->getCity(), 'shipping_country' => Country::getName($shippingAddress->getCountry()), 'shipping_country_raw' => $shippingAddress->getCountry(), 'shipping_state' => Country::hasStates($shippingAddress->getCountry()) ? Country::getStateName($shippingAddress->getCountry(), $shippingAddress->getState()) : $shippingAddress->getState(), 'shipping_state_raw' => $shippingAddress->getState()), $order);
 }
Ejemplo n.º 15
0
 public function fill(OrderInterface $order, array $data)
 {
     if (!empty($data['customer']) && is_numeric($data['customer'])) {
         $data['customer'] = $this->customerService->find($data['customer']);
     }
     if (isset($data['customer'])) {
         if (!empty($data['customer'])) {
             $data['customer'] = $this->wp->getHelpers()->maybeUnserialize($data['customer']);
         } else {
             $data['customer'] = new CustomerEntity\Guest();
         }
         if (isset($data['billing_address'])) {
             $data['billing_address'] = array_merge(array_flip(array_keys(ProductHelper::getBasicBillingFields())), $data['billing_address']);
             /** @var CustomerEntity $customer */
             $customer = $data['customer'];
             $customer->setBillingAddress($this->createAddress($data['billing_address']));
         }
         if (isset($data['shipping_address'])) {
             $data['shipping_address'] = array_merge(array_flip(array_keys(ProductHelper::getBasicShippingFields())), $data['shipping_address']);
             /** @var CustomerEntity $customer */
             $customer = $data['customer'];
             $customer->setShippingAddress($this->createAddress($data['shipping_address']));
         }
         $order->setCustomer($data['customer']);
         unset($data['customer']);
     }
     /** @var OrderInterface $order */
     $order = $this->wp->applyFilters('jigoshop\\factory\\order\\fetch\\after_customer', $order);
     if (isset($data['items'])) {
         $order->removeItems();
     }
     //We do not want to add coupons and from directly, without validation.
     $coupons = null;
     if (isset($data['coupons'])) {
         $coupons = $data['coupons'];
         unset($data['coupons']);
     }
     if (isset($data['discount'])) {
         unset($data['discount']);
     }
     $order->restoreState($data);
     if ($coupons) {
         $coupons = $this->wp->getHelpers()->maybeUnserialize($coupons);
         if (isset($coupons[0]) && is_array($coupons[0])) {
             $codes = array_map(function ($coupon) {
                 return $coupon['code'];
             }, $coupons);
         } else {
             $codes = $coupons;
         }
         $coupons = $this->couponService->getByCodes($codes);
         foreach ($coupons as $coupon) {
             /** @var Coupon $coupon */
             try {
                 $order->addCoupon($coupon);
             } catch (Exception $e) {
                 $this->messages->addWarning($e->getMessage(), false);
             }
         }
     }
     return $this->wp->applyFilters('jigoshop\\factory\\order\\fill', $order);
 }
Ejemplo n.º 16
0
 public function processResponse()
 {
     if (isset($_GET['file'])) {
         try {
             $data = explode('.', $_GET['file']);
             if (count($data) != 3) {
                 throw new Exception(__('Invalid download key. Unable to download file.', 'jigoshop'));
             }
             list($key, $id, $itemKey) = $data;
             $order = $this->orderService->find((int) $id);
             /** @var $order Order */
             if ($order->getKey() !== $key) {
                 throw new Exception(__('Invalid security key. Unable to download file.', 'jigoshop'));
             }
             if (!in_array($order->getStatus(), array(Order\Status::COMPLETED, Order\Status::PROCESSING))) {
                 throw new Exception(__('Invalid order.', 'jigoshop'));
             }
             $item = $order->getItem($itemKey);
             if ($item === null) {
                 throw new Exception(__('Product not found.', 'jigoshop'));
             }
             if ($item->getType() !== Downloadable::TYPE) {
                 throw new Exception(__('Invalid file to download.', 'jigoshop'));
             }
             $downloads = $item->getMeta('downloads')->getValue();
             if (!empty($downloads) && $downloads == 0) {
                 throw new Exception(__('Sorry, you have reached your download limit for this file.', 'jigoshop'));
             }
             if ($this->options->get('shopping.login_for_downloads')) {
                 if (!$this->wp->isUserLoggedIn()) {
                     throw new Exception(__('You have to log in before you can download a file.', 'jigoshop'));
                 } else {
                     if ($order->getCustomer()->getId() != $this->wp->getCurrentUserId()) {
                         throw new Exception(__('This is not your download link.', 'jigoshop'));
                     }
                 }
             }
             $file = $item->getMeta('file')->getValue();
             if (!$file) {
                 throw new Exception(__('File not found.', 'jigoshop'));
             }
             if (!empty($downloads)) {
                 $item->getMeta('downloads')->setValue($downloads - 1);
                 $this->orderService->saveItemMeta($item, $item->getMeta('downloads'));
             }
             if (!$this->wp->isMultisite()) {
                 $site_url = $this->wp->siteUrl();
                 $site_url = str_replace('https:', 'http:', $site_url);
                 $file = str_replace($this->wp->getHelpers()->trailingslashit($site_url), ABSPATH, $file);
             } else {
                 $network_url = $this->wp->networkAdminUrl();
                 $network_url = str_replace('https:', 'http:', $network_url);
                 $upload_dir = $this->wp->wpUploadDir();
                 // Try to replace network url
                 $file = str_replace($this->wp->getHelpers()->trailingslashit($network_url), ABSPATH, $file);
                 // Now try to replace upload URL
                 $file = str_replace($upload_dir['baseurl'], $upload_dir['basedir'], $file);
             }
             $file = $this->wp->applyFilters('jigoshop\\downloadable\\file_path', $file, $itemKey, $order);
             // See if its local or remote
             if (strstr($file, 'http:') || strstr($file, 'https:') || strstr($file, 'ftp:')) {
                 $isRemote = true;
             } else {
                 $isRemote = false;
                 $file = realpath($file);
             }
             // Download the file
             $extension = strtolower(substr(strrchr($file, '.'), 1));
             switch ($extension) {
                 case 'pdf':
                     $type = 'application/pdf';
                     break;
                 case 'exe':
                     $type = 'application/octet-stream';
                     break;
                 case 'zip':
                     $type = 'application/zip';
                     break;
                 case 'doc':
                     $type = 'application/msword';
                     break;
                 case 'xls':
                     $type = 'application/vnd.ms-excel';
                     break;
                 case 'ppt':
                     $type = 'application/vnd.ms-powerpoint';
                     break;
                 case 'gif':
                     $type = 'image/gif';
                     break;
                 case 'png':
                     $type = 'image/png';
                     break;
                 case 'jpe':
                 case 'jpeg':
                 case 'jpg':
                     $type = 'image/jpg';
                     break;
                 default:
                     $type = 'application/force-download';
             }
             $this->wp->doAction('jigoshop\\downloadable\\before_download', $file, $order);
             @session_write_close();
             @set_time_limit(0);
             @ob_end_clean();
             // required for IE, otherwise Content-Disposition may be ignored
             if (ini_get('zlib.output_compression')) {
                 ini_set('zlib.output_compression', 'Off');
             }
             header('Pragma: no-cache');
             header('Expires: 0');
             header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
             header('Robots: none');
             header('Content-Type: ' . $type);
             header('Content-Description: File Transfer');
             header('Content-Transfer-Encoding: binary');
             if (strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE')) {
                 // workaround for IE filename bug with multiple periods / multiple dots in filename
                 header('Content-Disposition: attachment; filename="' . preg_replace('/\\./', '%2e', basename($file), substr_count(basename($file), '.') - 1) . '";');
             } else {
                 header('Content-Disposition: attachment; filename="' . basename($file) . '";');
             }
             if ($isRemote) {
                 header('Location: ' . $file);
             } else {
                 if (file_exists($file)) {
                     header('Content-Length: ' . filesize($file));
                     readfile($file);
                 } else {
                     throw new Exception(__('File not found.', 'jigoshop'));
                 }
             }
         } catch (Exception $e) {
             $this->messages->addError($e->getMessage());
             $this->wp->redirectTo($this->options->getPageId(Pages::SHOP));
         }
         exit;
     }
 }
Ejemplo n.º 17
0
 public function ajaxSaveAttribute()
 {
     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['attribute_id']) || empty($_POST['attribute_id'])) {
             throw new Exception(__('Attribute was not specified.', 'jigoshop'));
         }
         if (!is_numeric($_POST['attribute_id'])) {
             throw new Exception(__('Invalid attribute ID.', 'jigoshop'));
         }
         /** @var \Jigoshop\Entity\Product $product */
         $product = $this->productService->find((int) $_POST['product_id']);
         if (!$product->getId()) {
             throw new Exception(__('Product does not exists.', 'jigoshop'));
         }
         $id = (int) $_POST['attribute_id'];
         if ($product->hasAttribute($id)) {
             $attribute = $product->removeAttribute($id);
             $attributeExists = true;
         } else {
             if ($id == -1) {
                 $attribute = new Attribute\Custom();
                 $label = trim(strip_tags($_POST['attribute_label']));
                 if (empty($label)) {
                     throw new Exception(__('Custom attribute requires label to be set.', 'jigoshop'));
                 }
                 $attribute->setLabel($label);
                 $attribute->setSlug($this->wp->getHelpers()->sanitizeTitle($label));
                 $this->productService->saveAttribute($attribute);
                 $attributeExists = false;
             } else {
                 $attribute = $this->productService->getAttribute($id);
                 $attributeExists = false;
             }
         }
         if ($attribute === null) {
             throw new Exception(__('Attribute does not exists.', 'jigoshop'));
         }
         if (isset($_POST['value'])) {
             $attribute->setValue(trim(htmlspecialchars(wp_kses_post($_POST['value']))));
         } else {
             if ($attributeExists) {
                 throw new Exception(sprintf(__('Attribute "%s" already exists.', 'jigoshop'), $attribute->getLabel()));
             } else {
                 $attribute->setValue('');
             }
         }
         if (isset($_POST['options']) && isset($_POST['options']['display'])) {
             $attribute->setVisible($_POST['options']['display'] === 'true');
         }
         $this->wp->doAction('jigoshop\\admin\\product_attribute\\add', $attribute, $product);
         $product->addAttribute($attribute);
         $this->productService->save($product);
         echo json_encode(array('success' => true, 'html' => Render::get('admin/product/box/attributes/attribute', array('attribute' => $attribute))));
     } catch (Exception $e) {
         echo json_encode(array('success' => false, 'error' => $e->getMessage()));
     }
     exit;
 }