public static function thousandsSeparator() { if (self::$thousandsSeparator === null) { self::$thousandsSeparator = self::$options->get('general.currency_thousand_separator'); } return self::$thousandsSeparator; }
public function __construct(Wordpress $wp, Options $options, CartServiceInterface $cartService) { $this->wp = $wp; $this->options = $options->get('shipping.' . self::NAME); $this->baseCountry = $options->get('general.country'); $this->cartService = $cartService; }
/** * Executes actions associated with selected page. */ public function action() { if (isset($_POST['action']) && $_POST['action'] == 'add-to-cart') { /** @var \Jigoshop\Entity\Product $product */ $product = $this->productService->find($_POST['item']); try { /** @var Item $item */ $item = $this->wp->applyFilters('jigoshop\\cart\\add', null, $product); if ($item === null) { throw new Exception(__('Unable to add product to the cart.', 'jigoshop')); } if (isset($_POST['quantity'])) { $item->setQuantity($_POST['quantity']); } /** @var Cart $cart */ $cart = $this->cartService->get($this->cartService->getCartIdForCurrentUser()); $cart->addItem($item); $this->cartService->save($cart); $url = false; $button = ''; switch ($this->options->get('shopping.redirect_add_to_cart')) { case 'cart': $url = $this->wp->getPermalink($this->options->getPageId(Pages::CART)); break; case 'checkout': $url = $this->wp->getPermalink($this->options->getPageId(Pages::CHECKOUT)); break; /** @noinspection PhpMissingBreakStatementInspection */ /** @noinspection PhpMissingBreakStatementInspection */ case 'product_list': $url = $this->wp->getPermalink($this->options->getPageId(Pages::SHOP)); case 'product': case 'same_page': default: $button = sprintf('<a href="%s" class="btn btn-warning pull-right">%s</a>', $this->wp->getPermalink($this->options->getPageId(Pages::CART)), __('View cart', 'jigoshop')); } $this->messages->addNotice(sprintf(__('%s successfully added to your cart. %s', 'jigoshop'), $product->getName(), $button)); if ($url !== false) { $this->messages->preserveMessages(); $this->wp->wpRedirect($url); } } catch (NotEnoughStockException $e) { if ($e->getStock() == 0) { $message = sprintf(__('Sorry, we do not have "%s" in stock.', 'jigoshop'), $product->getName()); } else { if ($this->options->get('products.show_stock')) { $message = sprintf(__('Sorry, we do not have enough "%s" in stock to fulfill your order. We only have %d available at this time. Please edit your cart and try again. We apologize for any inconvenience caused.', 'jigoshop'), $product->getName(), $e->getStock()); } else { $message = sprintf(__('Sorry, we do not have enough "%s" in stock to fulfill your order. Please edit your cart and try again. We apologize for any inconvenience caused.', 'jigoshop'), $product->getName()); } } $this->messages->addError($message); } catch (Exception $e) { $this->messages->addError(sprintf(__('A problem ocurred when adding to cart: %s', 'jigoshop'), $e->getMessage())); } } }
public function action() { if (isset($_POST['action']) && $_POST['action'] == 'save_address') { $customer = $this->customerService->getCurrent(); switch ($this->wp->getQueryParameter('edit-address')) { case 'shipping': $address = $customer->getShippingAddress(); break; case 'billing': default: $address = $customer->getBillingAddress(); break; } $errors = array(); if ($address instanceof CompanyAddress) { $address->setCompany(trim(htmlspecialchars(strip_tags($_POST['address']['company'])))); $address->setVatNumber(trim(htmlspecialchars(strip_tags($_POST['address']['euvatno'])))); } $address->setPhone(trim(htmlspecialchars(strip_tags($_POST['address']['phone'])))); $address->setFirstName(trim(htmlspecialchars(strip_tags($_POST['address']['first_name'])))); $address->setLastName(trim(htmlspecialchars(strip_tags($_POST['address']['last_name'])))); $address->setAddress(trim(htmlspecialchars(strip_tags($_POST['address']['address'])))); $address->setCity(trim(htmlspecialchars(strip_tags($_POST['address']['city'])))); $postcode = trim(htmlspecialchars(strip_tags($_POST['address']['postcode']))); if ($this->options->get('shopping.validate_zip') && !Validation::isPostcode($postcode, $address->getCountry())) { $errors[] = __('Postcode is not valid!', 'jigoshop'); } else { $address->setPostcode($postcode); } $country = trim(htmlspecialchars(strip_tags($_POST['address']['country']))); if (!Country::exists($country)) { $errors[] = sprintf(__('Country "%s" does not exists.', 'jigoshop'), $country); } else { $address->setCountry($country); } $state = trim(htmlspecialchars(strip_tags($_POST['address']['state']))); if (Country::hasStates($address->getCountry()) && !Country::hasState($address->getCountry(), $state)) { $errors[] = sprintf(__('Country "%s" does not have state "%s".', 'jigoshop'), Country::getName($address->getCountry()), $state); } else { $address->setState($state); } $email = trim(htmlspecialchars(strip_tags($_POST['address']['email']))); if (!Validation::isEmail($email)) { $errors[] = __('Invalid email address', 'jigoshop'); } else { $address->setEmail($email); } if (!empty($errors)) { $this->messages->addError(join('<br/>', $errors), false); } else { $this->customerService->save($customer); $this->messages->addNotice(__('Address saved.', 'jigoshop')); $this->wp->redirectTo($this->options->getPageId(Pages::ACCOUNT)); } } }
/** * @return Service Tax service. * @since 2.0 */ public function getService() { $service = new Service(); switch ($this->options->get('advanced.cache')) { // TODO: Add caching mechanisms default: $service = $this->wp->applyFilters('jigoshop\\core\\get_payment_service', $service); } return $service; }
/** * @param string $id * @return array */ public static function getOptions($id) { if (!isset(self::$loadedOptions[$id])) { $defaults = array(); if (isset(self::$defaults[$id])) { $defaults = self::$defaults[$id]; } self::$loadedOptions[$id] = array_merge($defaults, self::$options->get($id, array())); } return self::$loadedOptions[$id]; }
/** * Returns list of all allowed countries with translated names. * * Safe to use multiple times (uses cache to speed-up). * * @return array List of allowed translated countries. */ public static function getAllowed() { if (!isset(self::$cache['allowed'])) { $countries = self::getAll(); if (self::$options->get('shopping.restrict_selling_locations')) { $allowed = self::$options->get('shopping.selling_locations'); $countries = array_intersect_key($countries, array_flip($allowed)); } self::$cache['allowed'] = $countries; } return self::$cache['allowed']; }
/** * @return ProductServiceInterface Products service. * @since 2.0 */ public function getService() { $service = new Service($this->wp, $this->factory, $this->productService); switch ($this->options->get('advanced.cache')) { case 'simple': $service = new SimpleCache($service); break; default: $service = $this->wp->applyFilters('jigoshop\\core\\get_product_variable_service', $service); } return $service; }
/** * Marks old, but still in "Processing" status orders as completed. * * @internal */ public function completeProcessingOrders() { if ($this->options->get('advanced.automatic_complete')) { $orders = $this->orderService->findOldProcessing(); foreach ($orders as $order) { $this->emailService->suppressNextEmail(); /** @var $order \Jigoshop\Entity\Order */ $order->setStatus(Status::COMPLETED, __('Completed due to order being in processing state for a month or longer.', 'jigoshop')); $this->orderService->save($order); } } }
public function render() { if (!$this->wp->isUserLoggedIn()) { return Render::get('user/login', array()); } $content = $this->wp->getPostField('post_content', $this->options->getPageId(Pages::ACCOUNT)); $content = do_shortcode($content); $customer = $this->customerService->getCurrent(); $query = new \WP_Query(array('post_type' => Types::ORDER, 'post_status' => array(Status::PENDING, Status::ON_HOLD), 'posts_per_page' => $this->options->get('shopping.unpaid_orders_number'), 'meta_query' => array(array('key' => 'customer_id', 'value' => $this->wp->getCurrentUserId(), 'compare' => '=')))); $orders = $this->orderService->findByQuery($query); $permalink = get_permalink(); return Render::get('user/account', array('content' => $content, 'messages' => $this->messages, 'customer' => $customer, 'unpaidOrders' => $orders, 'editBillingAddressUrl' => Api::getEndpointUrl('edit-address', 'billing', $permalink), 'editShippingAddressUrl' => Api::getEndpointUrl('edit-address', 'shipping', $permalink), 'changePasswordUrl' => Api::getEndpointUrl('change-password', '', $permalink), 'myOrdersUrl' => Api::getEndpointUrl('orders', '', $permalink))); }
/** * @return Service Tax service. * @since 2.0 */ public function getService() { $service = new Service(); switch ($this->options->get('advanced.cache')) { // TODO: Add caching mechanisms // case 'simple': // $service = new SimpleCache($service); // break; default: $service = $this->wp->applyFilters('jigoshop\\core\\get_shipping_service', $service); } return $service; }
/** * @return SessionService */ public function getService() { switch ($this->options->get('advanced.session', 'php')) { case 'php': $service = new Service\Session\Php($this->wp, $this->options, $this->factory); break; case 'transient': $service = new Service\Session\Transient($this->wp, $this->options, $this->factory); break; default: $service = $this->wp->applyFilters('jigoshop\\core\\get_session_service', '', $this->wp, $this->options, $this->factory); break; } return $service; }
public function ajaxAddVariation() { 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')); } $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 = $this->factory->createVariation($product); $this->wp->doAction('jigoshop\\admin\\product_variation\\add', $variation); $product->addVariation($variation); $this->productService->save($product); $types = array(); foreach ($this->allowedSubtypes as $type) { /** @var $type Type */ $types[$type->getId()] = $type->getName(); } $taxClasses = array(); foreach ($this->options->get('tax.classes') as $class) { $taxClasses[$class['class']] = $class['label']; } echo json_encode(array('success' => true, 'html' => Render::get('admin/product/box/variations/variation', array('variation' => $variation, 'attributes' => $product->getVariableAttributes(), 'allowedSubtypes' => $types, 'taxClasses' => $taxClasses)))); } catch (Exception $e) { echo json_encode(array('success' => false, 'error' => $e->getMessage())); } exit; }
/** * 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(); } }
/** * Get additional information about the products of variables. * * @param \Jigoshop\Entity\Product\Variable $product - Product * @param string $type - chose to display sku or stock information * * @return string */ public function getVariableAdditionalInfo($product, $type) { if ($product->getType() == Product\Variable::TYPE && $this->options->get('advanced.products_list.variations_sku_stock')) { $additionalInfo = ''; /** @var \Jigoshop\Entity\Product\Variable\Variation $variation */ /** @var Product\Attribute $attribute */ foreach ($product->getVariations() as $variation) { if ($type == 'sku') { $additionalInfo .= $variation->getProduct()->getSku() . '<br />'; } elseif ($type == 'stock') { $variation_name = array(); $attributes = $product->getVariableAttributes(); foreach ($attributes as $attribute) { $variation_name[] = ProductHelper::getSelectOption($attribute->getOptions())[$variation->getAttribute($attribute->getId())->getValue()]; } $additionalInfo .= join(' - ', $variation_name) . ' (' . $variation->getProduct()->getStock()->getStock() . ')<br />'; } } return $additionalInfo; } else { if ($type == 'sku') { return $product->getSku(); } elseif ($type == 'stock') { return ProductHelper::getStock($product); } } }
/** * @return OrderServiceInterface Orders service. * @since 2.0 */ public function getService() { /** @var \WPAL\Wordpress $wp */ $service = new Service($this->wp, $this->options, $this->factory); switch ($this->options->get('advanced.cache')) { case 'simple': $service = new SimpleCache($service); break; case 'php_fast_cache': $service = new PhpFastCache($service); break; default: $service = $this->wp->applyFilters('jigoshop\\core\\get_order_service', $service); } return $service; }
/** * @return Service Tax service. * @since 2.0 */ public function getService() { $classes = array_map(function ($item) { return $item['class']; }, $this->options->get('tax.classes')); $service = new Service($this->wp, $classes, $this->customerService, $this->options->get('tax.included')); switch ($this->options->get('advanced.cache')) { // TODO: Add caching mechanisms // case 'simple': // $service = new SimpleCache($service); // break; default: $service = $this->wp->applyFilters('jigoshop\\core\\get_tax_service', $service); } return $service; }
public function __construct(Wordpress $wp, Options $options, TaxServiceInterface $taxService, Messages $messages) { $this->options = $options->get(self::SLUG); $this->taxService = $taxService; $options = $this->options; $wp->addAction('admin_enqueue_scripts', function () use($options) { if (!isset($_GET['tab']) || $_GET['tab'] != TaxesTab::SLUG) { return; } $classes = array(); foreach ($options['classes'] as $class) { $classes[$class['class']] = $class['label']; } $states = array(); foreach (Country::getAllStates() as $country => $stateList) { $states[$country] = array(array('id' => '', 'text' => _x('All states', 'admin_taxing', 'jigoshop'))); foreach ($stateList as $code => $state) { $states[$country][] = array('id' => $code, 'text' => $state); } } $countries = array_merge(array('' => __('All countries', 'jigoshop')), Country::getAll()); Scripts::add('jigoshop.admin.settings.taxes', \JigoshopInit::getUrl() . '/assets/js/admin/settings/taxes.js', array('jquery'), array('page' => 'jigoshop_page_jigoshop_settings')); Scripts::localize('jigoshop.admin.settings.taxes', 'jigoshop_admin_taxes', array('new_class' => Render::get('admin/settings/tax/class', array('class' => array('label' => '', 'class' => ''))), 'new_rule' => Render::get('admin/settings/tax/rule', array('rule' => array('id' => '', 'label' => '', 'class' => '', 'is_compound' => false, 'rate' => '', 'country' => '', 'states' => array(), 'postcodes' => array()), 'classes' => $classes, 'countries' => $countries)), 'states' => $states)); }); }
/** * Creates cart from order - useful for cancelling orders. * * @param $cartId string Cart ID to use. * @param $order Order Order to base cart on. * * @return \Jigoshop\Entity\Cart The cart. */ public function createFromOrder($cartId, $order) { $cart = new \Jigoshop\Entity\Cart($this->options->get('tax.classes')); $cart->setId($cartId); $cart->setCustomer($order->getCustomer()); $cart->setCustomerNote($order->getCustomerNote()); $cart->setTaxDefinitions($order->getTaxDefinitions()); foreach ($order->getItems() as $item) { /** @var $item Order\Item */ $item = clone $item; $item->setId(false); $item->setKey(false); $cart->addItem($item); } // foreach ($order->getCoupons() as $coupon) { // $cart->addCoupon() // } $shipping = $order->getShippingMethod(); if ($shipping !== null) { $cart->setShippingMethod($shipping); $cart->setShippingTax($order->getShippingTax()); } $payment = $order->getPaymentMethod(); if ($payment !== null) { $cart->setPaymentMethod($payment); } return $cart; }
public function __construct(Wordpress $wp, Options $options, Messages $messages) { $this->options = $options->get(self::SLUG); $this->messages = $messages; $this->weightUnit = array('kg' => __('Kilograms', 'jigoshop'), 'lbs' => __('Pounds', 'jigoshop')); $this->dimensionUnit = array('cm' => __('Centimeters', 'jigoshop'), 'in' => __('Inches', 'jigoshop')); $this->stockStatuses = array(StockStatus::IN_STOCK => __('In stock', 'jigoshop'), StockStatus::OUT_STOCK => __('Out of stock', 'jigoshop')); }
private function getBillingFields(Address $address) { $fields = $this->wp->applyFilters('jigoshop\\checkout\\billing_fields', $this->getDefaultBillingFields($address)); if (!Country::isEU($this->options->get('general.country'))) { unset($fields['euvatno']); } return $fields; }
/** * Get related products based on the same parent product category. * @param \Jigoshop\Entity\Product $product * * @return array */ protected function getRelated($product) { if (!$this->options->get('products.related')) { return array(); } $count = $this->wp->applyFilters('jigoshop/frontend/page/product/render/related_products_count', 3); return $this->productService->findByQuery(ProductHelper::getRelated($product, $count)); }
/** * Checks whether provided customer needs to be taxed. * * @param Entity $customer Customer to check. * * @return boolean Whether customer needs to be taxed. */ public function isTaxable(Entity $customer) { $country = $this->options->get('general.country'); $customerCountry = $customer->getTaxAddress()->getCountry(); if (Country::isEU($country)) { return Country::isEU($customerCountry); } return $country == $customerCountry; }
public function render() { if (!$this->wp->isUserLoggedIn()) { return Render::get('user/login', array()); } $order = $this->wp->getQueryParameter('orders'); $accountUrl = $this->wp->getPermalink($this->options->getPageId(Pages::ACCOUNT)); if (!empty($order) && is_numeric($order)) { $order = $this->orderService->find($order); /** @var Entity $order */ return Render::get('user/account/orders/single', array('messages' => $this->messages, 'order' => $order, 'myAccountUrl' => $accountUrl, 'listUrl' => Api::getEndpointUrl('orders', '', $accountUrl), 'showWithTax' => $this->options->get('tax.price_tax') == 'with_tax', 'getTaxLabel' => function ($taxClass) use($order) { return Tax::getLabel($taxClass, $order); })); } $customer = $this->customerService->getCurrent(); $orders = $this->orderService->findForUser($customer->getId()); return Render::get('user/account/orders', array('messages' => $this->messages, 'customer' => $customer, 'orders' => $orders, 'myAccountUrl' => $accountUrl)); }
/** * Adds a custom store banner to the site. */ public function displayCustomMessage() { if ($this->options->get('general.show_message') && Frontend\Pages::isJigoshop()) { Render::output('shop/custom_message', array('message' => $this->options->get('general.message'))); } if ($this->options->get('general.demo_store') && Frontend\Pages::isJigoshop()) { Render::output('shop/custom_message', array('message' => __('This is a demo store for testing purposes — no orders shall be fulfilled.', 'jigoshop'))); } }
public function fix($rules) { $wp_rewrite = $this->wp->getRewrite(); $permalink = $this->options->get('permalinks.product'); // Fix the rewrite rules when the product permalink have %product_category% flag if (preg_match('`/(.+)(/%' . Types::PRODUCT_CATEGORY . '%)`', $permalink, $matches)) { foreach ($rules as $rule => $rewrite) { if (preg_match('`^' . preg_quote($matches[1], '`') . '/\\(`', $rule) && preg_match('/^(index\\.php\\?' . Types::PRODUCT_CATEGORY . ')(?!(.*' . Types::PRODUCT . '))/', $rewrite)) { unset($rules[$rule]); } } } // If the shop page is used as the base, we need to enable verbose rewrite rules or sub pages will 404 if ($this->options->get('permalinks.verbose')) { $page_rewrite_rules = $wp_rewrite->page_rewrite_rules(); $rules = array_merge($page_rewrite_rules, $rules); } return $rules; }
public function render() { $cart = $this->cartService->getCurrent(); $content = $this->wp->getPostField('post_content', $this->options->getPageId(Pages::CART)); $content = do_shortcode($content); $termsUrl = ''; $termsPage = $this->options->get('advanced.pages.terms'); if ($termsPage > 0) { $termsUrl = $this->wp->getPermalink($termsPage); } return Render::get('shop/cart', array('content' => $content, 'cart' => $cart, 'messages' => $this->messages, 'productService' => $this->productService, 'customer' => $this->customerService->getCurrent(), 'shippingMethods' => $this->shippingService->getEnabled(), 'shopUrl' => $this->wp->getPermalink($this->options->getPageId(Pages::SHOP)), 'showWithTax' => $this->options->get('tax.price_tax') == 'with_tax', 'showShippingCalculator' => $this->options->get('shipping.calculator'), 'termsUrl' => $termsUrl)); }
/** * Returns empty product of selected type. * * @param $type string Type name of product. * * @throws \Jigoshop\Exception When product type does not exists. * @return \Jigoshop\Entity\Product */ public function get($type) { if (!isset($this->types[$type])) { if (WP_DEBUG) { throw new Exception(sprintf('Product type "%s" does not exists.', $type)); } Registry::getInstance(JIGOSHOP_LOGGER)->addWarning(sprintf('Product type "%s" does not exists.', $type)); $type = Simple::TYPE; } $class = $this->types[$type]; /** @var \Jigoshop\Entity\Product $instance */ $instance = new $class(); if ($instance instanceof Purchasable) { /** @var \Jigoshop\Entity\Product\Purchasable $instance */ $instance->getStock()->setManage($this->options->get('products.manage_stock')); $instance->getStock()->setStatus($this->options->get('products.stock_status')); } $instance->setTaxable($this->options->get('tax.defaults.taxable')); $instance->setTaxClasses($this->options->get('tax.defaults.classes')); return $instance; }
/** * 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)); }
public function render() { $content = $this->wp->getPostField('post_content', $this->options->getPageId(Pages::THANK_YOU)); /** @var Order $order */ $order = $this->orderService->find((int) $_REQUEST['order']); if ($order->getKey() != $_REQUEST['key']) { $this->messages->addError(__('Invalid security key. The order was processed.', 'jigoshop')); $this->wp->redirectTo($this->options->getPageId(Pages::SHOP)); } return Render::get('shop/checkout/thanks', array('content' => $content, 'messages' => $this->messages, 'order' => $order, 'showWithTax' => $this->options->get('tax.price_tax') == 'with_tax', 'shopUrl' => $this->wp->getPermalink($this->options->getPageId(Pages::SHOP)), 'cancelUrl' => \Jigoshop\Helper\Order::getCancelLink($order), 'getTaxLabel' => function ($taxClass) use($order) { return Tax::getLabel($taxClass, $order); })); }