/** * Saves entity to database. * * @param $object EntityInterface Entity to save. */ public function save(EntityInterface $object) { if (!$object instanceof Entity) { throw new Exception('Trying to save not a coupon!'); } // TODO: Support for transactions! $fields = $object->getStateToSave(); if (isset($fields['id']) || isset($fields['title']) || isset($fields['code'])) { // We do not need to save ID, title and code (post name) as they are saved by WordPress itself. unset($fields['id'], $fields['title'], $fields['code']); } foreach ($fields as $field => $value) { $this->wp->updatePostMeta($object->getId(), $field, $value); } $this->wp->doAction('jigoshop\\service\\coupon\\save', $object); }
public function ajaxSaveVariation() { 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')); } if (!isset($_POST['attributes']) || !is_array($_POST['attributes'])) { throw new Exception(__('Attribute values are not specified.', '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')); } if (!$product->hasVariation((int) $_POST['variation_id'])) { throw new Exception(__('Variation does not exists.', 'jigoshop')); } $variation = $product->removeVariation((int) $_POST['variation_id']); foreach ($_POST['attributes'] as $attribute => $value) { if (!$variation->hasAttribute($attribute)) { continue; // TODO: Properly add attributes // $attr = $this->productService->getAttribute($attribute); // $variation->addAttribute(); } $variation->getAttribute($attribute)->setValue(trim(htmlspecialchars(strip_tags($value)))); } if (isset($_POST['product']) && is_array($_POST['product'])) { // For now - always manage variation product stock $_POST['product']['stock']['manage'] = 'on'; $_POST['product']['sales_enabled'] = $product->getSales()->isEnabled(); $variation->getProduct()->restoreState($_POST['product']); $variation->getProduct()->markAsDirty($_POST['product']); } $this->wp->doAction('jigoshop\\admin\\product_variation\\save', $variation); $product->addVariation($variation); $this->productService->save($product); $this->wp->updatePostMeta($variation->getProduct()->getId(), 'type', $_POST['product']['type']); $types = array(); foreach ($this->allowedSubtypes as $type) { /** @var $type Type */ $types[$type->getId()] = $type->getName(); } echo json_encode(array('success' => true, 'html' => Render::get('admin/product/box/variations/variation', array('variation' => $variation, 'attributes' => $product->getVariableAttributes(), 'allowedSubtypes' => $types)))); } catch (Exception $e) { echo json_encode(array('success' => false, 'error' => $e->getMessage())); } exit; }
/** * Saves product to database. * * @param \Jigoshop\Entity\EntityInterface $object Product to save. * * @throws Exception */ public function save(EntityInterface $object) { if (!$object instanceof \Jigoshop\Entity\Product) { throw new Exception('Trying to save not a product!'); } // TODO: Support for transactions! $fields = $object->getStateToSave(); if (isset($fields['id']) || isset($fields['name']) || isset($fields['description'])) { // We do not need to save ID, name and description (excerpt) as they are saved by WordPress itself. unset($fields['id'], $fields['name'], $fields['description']); } if (isset($fields['attributes'])) { $this->_removeAllProductAttributesExcept($object->getId(), array_map(function ($item) { /** @var $item Attribute */ return $item->getId(); }, $fields['attributes'])); foreach ($fields['attributes'] as $attribute) { $this->_saveProductAttribute($object, $attribute); } unset($fields['attributes']); } if (isset($fields['attachments'])) { $this->_removeAllProductAttachments($object->getId()); foreach ($fields['attachments'] as $attachment) { $this->_saveProductAttachment($object->getId(), $attachment); } } foreach ($fields as $field => $value) { $this->wp->updatePostMeta($object->getId(), $field, $value); } $this->wp->doAction('jigoshop\\service\\product\\save', $object); }
/** * Saves entity to database. * * @param $object EntityInterface Entity to save. */ public function save(EntityInterface $object) { if (!$object instanceof \Jigoshop\Entity\Email) { throw new Exception('Trying to save not an email!'); } // TODO: Support for transactions! $fields = $object->getStateToSave(); if (isset($fields['id']) || isset($fields['title']) || isset($fields['text'])) { // We do not need to save ID, title and text (content) as they are saved by WordPress itself. unset($fields['id'], $fields['title'], $fields['text']); } foreach ($fields as $field => $value) { $this->wp->updatePostMeta($object->getId(), $field, $value); } // //$this->addTemplate($object->getId(), $object->getActions()); $this->wp->doAction('jigoshop\\service\\email\\save', $object); }
/** * Saves order to database. * * @param $object EntityInterface Order to save. * * @throws Exception */ public function save(EntityInterface $object) { if (!$object instanceof Order) { throw new Exception('Trying to save not an order!'); } $this->wp->doAction('jigoshop\\order\\before\\' . $object->getStatus(), $object); /** @var Order $object */ $object->setUpdatedAt(new \DateTime()); if (!$object->getNumber()) { $object->setNumber($this->getNextOrderNumber()); } //Recalculate shiping $shipping = $object->getShippingMethod(); if ($shipping && $shipping instanceof Method) { $object->setShippingMethod($object->getShippingMethod()); } $fields = $object->getStateToSave(); if (isset($fields['id'])) { unset($fields['id']); } $wpdb = $this->wp->getWPDB(); if (!$object->getId()) { $date = $this->wp->getHelpers()->currentTime('mysql'); $dateGmt = $this->wp->getHelpers()->currentTime('mysql', true); $wpdb->insert($wpdb->posts, array('post_author' => $object->getCustomer()->getId() ? $object->getCustomer()->getId() : 0, 'post_date' => $date, 'post_date_gmt' => $dateGmt, 'post_modified' => $date, 'post_modified_gmt' => $dateGmt, 'post_type' => Types::ORDER, 'post_title' => $object->getTitle(), 'post_excerpt' => $object->getCustomerNote(), 'post_status' => $object->getStatus(), 'post_name' => sanitize_title($object->getTitle()), 'comment_status' => 'open', 'ping_status' => 'closed')); $id = $wpdb->insert_id; if (!is_int($id) || $id === 0) { throw new Exception(__('Unable to save order. Please try again.', 'jigoshop')); } $object->setId($id); $this->wp->doAction('jigoshop\\service\\order\\new', $id, $object); unset($fields['status'], $fields['customer_note']); } if (!$object->getKey()) { $fields['key'] = $this->generateOrderKey($object); $object->setKey($fields['key']); } if (isset($fields['status']) || isset($fields['customer_note'])) { $wpdb->update($wpdb->posts, array('post_title' => $object->getTitle(), 'post_status' => $object->getStatus(), 'post_excerpt' => $object->getCustomerNote()), array('ID' => $object->getId())); unset($fields['customer_note'], $fields['status']); } if (isset($fields['update_messages']) && !empty($fields['update_messages'])) { foreach ($fields['update_messages'] as $messages) { if ($messages['old_status'] != Order\Status::COMPLETED && $messages['new_status'] == Order\Status::COMPLETED || $messages['old_status'] != Order\Status::REFUNDED && $messages['new_status'] == Order\Status::REFUNDED) { $this->wp->doAction('jigoshop\\order\\' . $messages['new_status'], $object); } $this->wp->doAction('jigoshop\\order\\' . $messages['old_status'] . '_to_' . $messages['new_status'], $object); $this->addNote($object, sprintf(__('%sOrder status changed from %s to %s.', 'jigoshop'), $messages['message'], Order\Status::getName($messages['old_status']), Order\Status::getName($messages['new_status']))); } unset($fields['update_messages']); } if (isset($fields['items'])) { // TODO: Check again if we have enough stock $existing = array_map(function ($item) { /** @var $item Order\Item */ return $item->getId(); }, $fields['items']); $this->removeAllExcept($object->getId(), $existing); foreach ($fields['items'] as $item) { /** @var $item Order\Item */ $data = array('order_id' => $object->getId(), 'product_id' => $item->getProduct() ? $item->getProduct()->getId() : null, 'product_type' => $item->getType(), 'title' => $item->getName(), 'price' => $item->getPrice(), 'tax' => $item->getTax(), 'quantity' => $item->getQuantity(), 'cost' => $item->getCost()); if ($item->getId() !== null) { $wpdb->update($wpdb->prefix . 'jigoshop_order_item', $data, array('id' => $item->getId())); } else { $wpdb->insert($wpdb->prefix . 'jigoshop_order_item', $data); $item->setId($wpdb->insert_id); } foreach ($item->getAllMeta() as $meta) { /** @var $meta Order\Item\Meta */ $this->saveItemMeta($item, $meta); } } $reduceStatus = $this->wp->applyFilters('jigoshop\\product\\reduce_stock_status', Order\Status::PROCESSING, $object); if ($object->getStatus() == $reduceStatus) { foreach ($object->getItems() as $item) { /** @var \Jigoshop\Entity\Order\Item $item */ $product = $item->getProduct(); if ($product instanceof Variable) { $product = $product->getVariation($item->getMeta('variation_id')->getValue())->getProduct(); } if ($product->getStock()->getManage()) { $this->wp->doAction('jigoshop\\product\\sold', $product, $item->getQuantity(), $item); } } } if ($object->getStatus() == Order\Status::COMPLETED) { $object->setCompletedAt(); } unset($fields['items']); } foreach ($fields as $field => $value) { $this->wp->updatePostMeta($object->getId(), $field, $this->wp->getHelpers()->escSql($value)); } $this->wp->doAction('jigoshop\\service\\order\\save', $object); $this->wp->doAction('jigoshop\\order\\after\\' . $object->getStatus(), $object); $notifyLowStock = $this->options->get('products.notify_low_stock'); $notifyOutOfStock = $this->options->get('products.notify_out_of_stock'); if ($notifyLowStock || $notifyOutOfStock) { $threshold = $this->options->get('products.low_stock_threshold'); foreach ($object->getItems() as $item) { $stock = $this->wp->applyFilters('jigoshop\\product\\get_stock', false, $item); $product = $item->getProduct(); if ($notifyOutOfStock && $stock !== false && $stock == 0) { $this->wp->doAction('jigoshop\\product\\out_of_stock', $product); continue; } if ($notifyLowStock && $stock !== false && $stock <= $threshold) { $this->wp->doAction('jigoshop\\product\\low_stock', $product); } } } /** * TODO: If configured - send emails on backorders * $this->wp->addAction('jigoshop\product\backorders', array($this, 'productBackorders')); */ }
/** * Creates all Jigoshop e-mails. */ public function installEmails() { $default_emails = array('new_order_admin_notification', 'customer_order_status_pending_to_processing', 'customer_order_status_pending_to_on_hold', 'customer_order_status_on-hold_to_processing', 'customer_order_status_completed', 'customer_order_status_refunded', 'send_customer_invoice', 'low_stock_notification', 'no_stock_notification', 'product_on_backorders_notification'); $invoice = '==============================<wbr />============================== Order details: <span class="il">ORDER</span> [order_number] Date: [order_date] ==============================<wbr />============================== [order_items] Subtotal: [subtotal] Shipping: [shipping_cost] via [shipping_method] Total: [total] ------------------------------<wbr />------------------------------<wbr />-------------------- CUSTOMER DETAILS ------------------------------<wbr />------------------------------<wbr />-------------------- Email: <a href="mailto:[billing_email]">[billing_email]</a> Tel: [billing_phone] ------------------------------<wbr />------------------------------<wbr />-------------------- BILLING ADDRESS ------------------------------<wbr />------------------------------<wbr />-------------------- [billing_first_name] [billing_last_name] [billing_address_1], [billing_address_2], [billing_city] [billing_state], [billing_country], [billing_postcode] ------------------------------<wbr />------------------------------<wbr />-------------------- SHIPPING ADDRESS ------------------------------<wbr />------------------------------<wbr />-------------------- [shipping_first_name] [shipping_last_name] [shipping_address_1], [shipping_address_2], [shipping_city] [shipping_state], [shipping_country], [shipping_postcode]'; $title = ''; $message = ''; $post_title = ''; foreach ($default_emails as $email) { switch ($email) { case 'new_order_admin_notification': $post_title = 'New order admin notification'; $title = '[[shop_name]] New Customer Order - [order_number]'; $message = 'You have received an order from [billing_first_name] [billing_last_name]. Their order is as follows:<br/>' . $invoice; break; case 'customer_order_status_pending_to_on_hold': $post_title = 'Customer order status pending to on-hold'; $title = '[[shop_name]] Order Received'; $message = 'Thank you, we have received your order. Your order\'s details are below:<br/>' . $invoice; break; case 'customer_order_status_pending_to_processing': $post_title = 'Customer order status pending to processing'; $title = '[[shop_name]] Order Received'; $message = 'Thank you, we are now processing your order. Your order\'s details are below:<br/>' . $invoice; break; case 'customer_order_status_on-hold_to_processing': $post_title = 'Customer order status on-hold to processing'; $title = '[[shop_name]] Order Received'; $message = 'Thank you, we are now processing your order. Your order\'s details are below:<br/>' . $invoice; break; case 'customer_order_status_completed': $post_title = 'Customer order status completed'; $title = '[[shop_name]] Order Complete'; $message = 'Your order is complete. Your order\'s details are below:<br/>' . $invoice; break; case 'customer_order_status_refunded': $post_title = 'Customer order status refunded'; $title = '[[shop_name]] Order Refunded'; $message = 'Your order has been refunded. Your order\'s details are below:<br/>' . $invoice; break; case 'send_customer_invoice': $post_title = 'Send customer invoice'; $title = 'Invoice for Order: [order_number]'; $message = $invoice; break; case 'low_stock_notification': $post_title = 'Low stock notification'; $title = '[[shop_name]] Product low in stock'; $message = '#[product_id] [product_name] ([sku]) is low in stock.'; break; case 'no_stock_notification': $post_title = 'No stock notification'; $title = '[[shop_name]] Product out of stock'; $message = '#[product_id] [product_name] ([sku]) is out of stock.'; break; case 'product_on_backorders_notification': $post_title = 'Product on backorder notification'; $title = '[[shop_name]] Product Backorder on Order: [order_number].'; $message = '#[product_id] [product_name] ([sku]) was found to be on backorder.<br/>' . $invoice; break; } $post_data = array('post_content' => $message, 'post_title' => $post_title, 'post_status' => 'publish', 'post_type' => 'shop_email', 'post_author' => 1, 'ping_status' => 'closed', 'comment_status' => 'closed'); $post_id = $this->wp->wpInsertPost($post_data); $this->wp->updatePostMeta($post_id, 'subject', $title); if ($email == 'new_order_admin_notification') { // $this->emailService->addTemplate($post_id, array( // 'admin_order_status_pending_to_processing', // 'admin_order_status_pending_to_completed', // 'admin_order_status_pending_to_on_hold' // )); $this->wp->updatePostMeta($post_id, 'actions', array('admin_order_status_pending_to_processing', 'admin_order_status_pending_to_completed', 'admin_order_status_pending_to_on_hold')); } else { // $this->emailService->addTemplate($post_id, array($email)); $this->wp->updatePostMeta($post_id, 'actions', array($email)); } } }