Example #1
0
 public static function refresh($force = false)
 {
     $settings = \Shop\Models\Settings::fetch();
     if (empty($settings->{'currency.openexchangerates_api_id'})) {
         static::log('Could not refresh list of valid currencies.  Please provide an open exchange rates API ID in the Shop Configuration page', 'ERROR');
         return false;
     }
     // once a day is enough
     if (!empty($settings->currencies_last_refreshed) && $settings->currencies_last_refreshed > time() - 24 * 60 && empty($force)) {
         return false;
     }
     $oer = new \Shop\Lib\OpenExchangeRates($settings->{'currency.openexchangerates_api_id'});
     if ($response = $oer->currencies()) {
         if ($currencies = \Dsc\ArrayHelper::fromObject($response)) {
             foreach ($currencies as $code => $title) {
                 $currency = (new static())->setParam('conditions', array('code' => $code))->getItem();
                 if (empty($currency->id)) {
                     $currency = new static();
                 }
                 $currency->code = $code;
                 $currency->title = $title;
                 $currency->store();
             }
             $settings->currencies_last_refreshed = time();
             $settings->save();
         }
     }
     return true;
 }
Example #2
0
 public static function defaultList()
 {
     $conditions = array('enabled' => 1);
     $settings = \Shop\Models\Settings::fetch();
     if ($settings->countries_sort == 'name') {
         $conditions['sort'] = array('name' => 1);
     }
     $result = \Shop\Models\Countries::find($conditions);
     return $result;
 }
Example #3
0
 public static function passes(\Modules\Models\Modules $module, $route = null, $options = array())
 {
     // if this ruleset is ignored, return null
     if (!in_array($module->{'assignment.groups.method'}, array('one', 'all', 'none'))) {
         return null;
     }
     $groups_method = $module->{'assignment.groups.method'};
     $assigned_groups = $module->{'assignment.groups.list'};
     $identity_id = \Dsc\System::instance()->get('auth')->getIdentity()->id;
     if (!empty($assigned_groups)) {
         $groups = array();
         $user = (new \Users\Models\Users())->setState('filter.id', $identity_id)->getItem();
         if (empty($identity_id) || empty($user->id)) {
             // Get the default group
             $group_id = \Shop\Models\Settings::fetch()->{'users.default_group'};
             if (!empty($group_id)) {
                 $groups[] = (new \Users\Models\Groups())->setState('filter.id', (string) $group_id)->getItem();
             }
         } elseif (!empty($user->id)) {
             $groups = $user->groups();
         }
         $group_ids = array();
         foreach ($groups as $group) {
             $group_ids[] = (string) $group->id;
         }
         switch ($groups_method) {
             case "none":
                 $intersection = array_intersect($assigned_groups, $group_ids);
                 if (!empty($intersection)) {
                     return false;
                 }
                 break;
             case "all":
                 // $missing_groups == the ones from $assigned_groups that are NOT in $group_ids
                 $missing_groups = array_diff($assigned_groups, $group_ids);
                 if (!empty($missing_groups)) {
                     return false;
                 }
                 break;
             case "one":
             default:
                 $intersection = array_intersect($assigned_groups, $group_ids);
                 if (empty($intersection)) {
                     return false;
                 }
                 break;
         }
     }
     return true;
 }
Example #4
0
 /**
  * Simply formats a number according to the currency's rules
  * 
  * @param unknown $number
  * @param string $currency_code
  * @param unknown $options
  */
 public static function format($number, $currency_code = 'USD', $options = array())
 {
     $settings = \Shop\Models\Settings::fetch();
     // TODO Support custom formatting
     switch ($settings->{'currency.default'}) {
         case "INR":
             $formatted = 'Rs.' . number_format((double) $number, 0, ".", ",");
             break;
         case "USD":
         default:
             $formatted = '$' . number_format((double) $number, 2, ".", ",");
             break;
     }
     return $formatted;
 }
Example #5
0
 /**
  * Gets the customer's highest-ordered Users\Group
  * to be used for determining pricing and primary group status
  *
  * @return \Users\Models\Groups
  */
 public static function primaryGroup(\Users\Models\Users $user = null)
 {
     $group = new \Users\Models\Groups();
     if (!empty($user)) {
         if ($groups = $user->groups()) {
             $group = $groups[0];
         }
     }
     if (empty($group->id)) {
         // Set this to be a default group, as configured in the Shop config
         $group_id = \Shop\Models\Settings::fetch()->{'users.default_group'};
         if (!empty($group_id)) {
             $group = $group->setState('filter.id', (string) $group_id)->getItem();
         }
     }
     return $group;
 }
Example #6
0
 public static function diagnostics()
 {
     if (class_exists('\\Modules\\Factory')) {
         \Modules\Models\Conditions::register('\\Shop\\ModuleConditions\\Orders', array('title' => 'Orders', 'icon' => 'fa fa-shopping-cart', 'type' => 'shop', 'slug' => 'shop-orders'));
     }
     $settings = \Shop\Models\Settings::fetch();
     // TODO When did we last pull down the currency list?
     if (empty($settings->currencies_last_refreshed) || $settings->currencies_last_refreshed < time() - 24 * 60) {
         /*
         \Dsc\Queue::task('\Shop\Models\Currencies::refresh', array(), array(
             'title' => 'Refresh currencies from OpenExchangeRates.org'
         ));
         */
     }
     // TODO When did we last pull down the exchange rates?
     if (empty($settings->exchangerates_last_refreshed) || $settings->exchangerates_last_refreshed < time() - 24 * 60) {
     }
 }
Example #7
0
       	    break;
       
       } ?>
       
       <span class="label <?php echo $label_class; ?>">
       <?php echo \Dsc\ArrayHelper::get($item, 'fulfillment_status', 'n/a'); ?>
       </span>
       */
    ?>
                                                            
                            </div>                            
                        </div>        
                    <?php 
}
?>
                </div>
    
            </div>
        </div>

        <div class="order-footer">
            <?php 
echo \Shop\Models\Settings::fetch()->{'orders.printing.footer'};
?>
        </div>

    </div>

</body>

</html>
Example #8
0
 public function currencies()
 {
     $this->settings_route = '/admin/shop/settings/currencies';
     switch ($this->app->get('VERB')) {
         case "POST":
         case "post":
             // do the save and redirect to $this->settings_route
             return $this->save();
             break;
     }
     $flash = \Dsc\Flash::instance();
     $this->app->set('flash', $flash);
     $settings = \Shop\Models\Settings::fetch();
     $flash->store($settings->cast());
     $this->app->set('meta.title', 'Currencies | Shop');
     echo $this->theme->render('Shop/Admin/Views::settings/currencies.php');
 }
Example #9
0
</div> <hr/><?php 
        }
        ?>
                <?php 
    }
    ?>
                </div>
            <?php 
}
?>
            
            </div>
        </div>
    </div>

    <?php 
$settings = \Shop\Models\Settings::fetch();
?>
    <?php 
if ($settings->{'reviews.enabled'}) {
    ?>
        <?php 
    echo $this->renderView('Shop/Site/Views::product/fragment_reviews.php');
    ?>
    <?php 
}
?>
 
    
</div>
Example #10
0
 /**
  * Determines whether or not a user qualifies for this campaign
  * 
  * @param \Users\Models\Users $user
  * @throws \Exception
  * @return \Shop\Models\Campaigns
  */
 public function customerQualifies(\Shop\Models\Customers $customer)
 {
     // Set $this->__is_validated = true if YES, user qualifies for this campaign.
     // throw an Exception if NO, user does not qualify.
     /**
      * is the campaign published?
      */
     if (!$this->published()) {
         throw new \Exception('This campaign is not valid for today');
     }
     $period_start = null;
     $period_end = null;
     switch ($this->period_type) {
         case "variable":
             $period_start = date('Y-m-d', strtotime('today -' . (int) $this->variable_period_days . ' days'));
             $period_end = date('Y-m-d', strtotime('tomorrow'));
             break;
         case "fixed":
             $period_start = $this->fixed_period_start;
             $period_end = $this->fixed_period_end;
             break;
         default:
             throw new \Exception('Invalid period type');
             break;
     }
     // has the minimum spend amount for the qualification period been met?
     if (!empty($this->rule_min_spent)) {
         // Get the total amount spent by the customer during the qualification period
         $total = $customer->fetchTotalSpent($period_start, $period_end);
         if ($total < $this->rule_min_spent) {
             throw new \Exception('Customer has not spent enough during the qualification period');
         }
     }
     /**
      * evaluate shopper groups against $this->groups
      */
     if (!empty($this->groups)) {
         $groups = array();
         if (empty($customer->id)) {
             // Get the default group
             $group_id = \Shop\Models\Settings::fetch()->{'users.default_group'};
             if (!empty($group_id)) {
                 $groups[] = (new \Users\Models\Groups())->setState('filter.id', (string) $group_id)->getItem();
             }
         } elseif (!empty($customer->id)) {
             $groups = $customer->groups();
         }
         $group_ids = array();
         foreach ($groups as $group) {
             $group_ids[] = (string) $group->id;
         }
         switch ($this->groups_method) {
             case "none":
                 $intersection = array_intersect($this->groups, $group_ids);
                 if (!empty($intersection)) {
                     // TODO Chagne the error messages!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                     throw new \Exception('You do not qualify for this campaign.');
                 }
                 break;
             case "all":
                 // $missing_groups == the ones from $this->groups that are NOT in $group_ids
                 $missing_groups = array_diff($this->groups, $group_ids);
                 if (!empty($missing_groups)) {
                     throw new \Exception('You do not qualify for this campaign.');
                 }
                 break;
             case "one":
             default:
                 $intersection = array_intersect($this->groups, $group_ids);
                 if (empty($intersection)) {
                     throw new \Exception('You do not qualify for this campaign.');
                 }
                 break;
         }
     }
     /**
      * if we made it this far, the user qualifies
      */
     $this->__is_validated = true;
     return $this;
 }
Example #11
0
 /**
  * Gets the billing country, default one if not set
  *
  * @param string $default
  * @return string
  */
 public function billingCountry($default = null)
 {
     if ($this->{'checkout.billing_address.country'}) {
         return $this->{'checkout.billing_address.country'};
     }
     return $default ? $default : \Shop\Models\Settings::fetch()->{'country'};
 }
Example #12
0
 public static function sendEmailForOrder($order_id)
 {
     $settings = \Shop\Models\Settings::fetch();
     if (empty($settings->{'reviews.enabled'})) {
         return;
     }
     $days_from_now = $settings->{'reviews.email_days'};
     if (empty($days_from_now)) {
         return;
     }
     // load the order
     $order = (new \Shop\Models\Orders())->setState('filter.id', $order_id)->getItem();
     if (empty($order->id)) {
         return;
     }
     // check which products from the order have not been reviewed.
     // If all have been reviewed, don't send the email.
     $product_ids = array();
     foreach ($order->items as $item) {
         $key = (string) $item['product_id'];
         $product_ids[$key] = $item['product_id'];
     }
     $products = array_values($product_ids);
     $product_reviews = static::collection()->find(array('product_id' => array('$in' => $products), 'user_id' => $order->user_id));
     foreach ($product_reviews as $doc) {
         $key = (string) $doc['product_id'];
         unset($product_ids[$key]);
     }
     // at this point, $product_ids should have the list of unreviewed products from this order
     if (empty($product_ids)) {
         return;
     }
     // so get an array of actual products
     $products = array();
     foreach ($product_ids as $product_id) {
         foreach ($order->items as $item) {
             if ($item['product_id'] == $product_id) {
                 $products[] = $item;
             }
         }
     }
     if (empty($products)) {
         return;
     }
     // get the recipient's email and send the email
     $recipients = array($order->user_email);
     if (empty($recipients)) {
         return;
     }
     $subject = $settings->get('reviews.email_subject');
     if (empty($subject)) {
         $subject = "Please review your recent purchases!";
     }
     $user = $order->user();
     \Base::instance()->set('user', $user);
     \Base::instance()->set('products', $products);
     $html = \Dsc\System::instance()->get('theme')->renderView('Shop/Views::emails_html/review_products.php');
     $text = \Dsc\System::instance()->get('theme')->renderView('Shop/Views::emails_text/review_products.php');
     foreach ($recipients as $recipient) {
         \Dsc\System::instance()->get('mailer')->send($recipient, $subject, array($html, $text));
     }
 }
Example #13
0
 /**
  * Send out new order emails to admins
  *
  * @param array $recipients
  */
 public function sendEmailNewOrderNotifications(array $recipients = array())
 {
     if (empty($recipients)) {
         $recipients = (array) \Shop\Models\Settings::fetch()->{'notifications.orders.emails'};
     }
     \Base::instance()->set('order', $this);
     \Base::instance()->set('settings', \Shop\Models\Settings::fetch());
     $html = \Dsc\System::instance()->get('theme')->renderView('Shop/Views::emails_html/new_order_notification.php');
     $text = \Dsc\System::instance()->get('theme')->renderView('Shop/Views::emails_text/new_order_notification.php');
     $order_number = $this->number;
     $subject = 'New Order #' . $order_number;
     foreach ($recipients as $recipient) {
         $this->__sendEmailNewOrder = \Dsc\System::instance()->get('mailer')->send($recipient, $subject, array($html, $text));
     }
     return $this;
 }
Example #14
0
 /**
  * 
  * @param unknown $cart_id
  * @param unknown $notification_idx
  */
 public static function sendAbandonedEmailNotification($cart_id, $notification_idx)
 {
     $settings = \Shop\Models\Settings::fetch();
     if (empty($settings->abandoned_cart_emails_enabled)) {
         return;
     }
     $cart = (new static())->setState('filter.id', $cart_id)->getItem();
     // cart was deleted so dont do anything
     if (empty($cart->id)) {
         return;
     }
     // Has the cart been updated recently?  if so, don't send this email
     $abandoned_time = $settings->get('abandoned_cart_time') * 60;
     $abandoned_time = time() - $abandoned_time;
     if ($cart->{'metadata.last_modified.time'} > $abandoned_time) {
         return;
     }
     if ($cart->quantity() == 0) {
         return;
     }
     $user = $cart->user();
     if (empty($user->id) || $user->id != $cart->user_id || $user->guest) {
         return;
     }
     // get correct user email
     $recipients = array();
     if (empty($cart->{'user_email'})) {
         if (!empty($user->email)) {
             $recipients = array($user->email);
         }
     } else {
         $recipients = array($cart->{'user_email'});
     }
     if (empty($recipients)) {
         return;
     }
     $token = \Dsc\System::instance()->get('auth')->getAutoLoginToken($user, true);
     \Base::instance()->set('cart', $cart);
     \Base::instance()->set('user', $user);
     \Base::instance()->set('idx', $notification_idx);
     \Base::instance()->set('token', $token);
     $subject = $settings->get('abandoned_cart_emails.' . $notification_idx . '.subject');
     if (empty($subject)) {
         $subject = $settings->get('abandoned_cart_subject');
         if (empty($subject)) {
             $subject = "Complete your purchase";
         }
     }
     $notification = $settings->get('abandoned_cart_emails.' . $notification_idx);
     if (empty($notification)) {
         $notification = array('text' => array('html' => '', 'plain' => ''));
     }
     \Base::instance()->set('notification', $notification);
     $html = \Dsc\System::instance()->get('theme')->renderView('Shop/Views::emails_html/abandoned_cart.php');
     $text = \Dsc\System::instance()->get('theme')->renderView('Shop/Views::emails_text/abandoned_cart.php');
     foreach ($recipients as $recipient) {
         \Dsc\System::instance()->get('mailer')->send($recipient, $subject, array($html, $text));
     }
     $num = $notification_idx + 1;
     \Dsc\Activities::trackActor($user->email, 'Received abandoned cart email notification #' . $num, array('cart_value' => (string) $cart->total(), 'cart_items_count' => (string) $cart->quantity()));
 }
Example #15
0
 /**
  * Determines if this coupon is valid for a cart
  * 
  * @param \Shop\Models\Carts $cart
  * @throws \Exception
  */
 public function cartValid(\Shop\Models\Carts $cart)
 {
     // Set $this->__is_validated = true if YES, cart can use this coupon
     // throw an Exception if NO, cart cannot use this coupon
     /**
      * is the coupon published?
      */
     if (!$this->published()) {
         throw new \Exception('This coupon is expired.');
     }
     /**
      * Only 1 user-submitted coupon per cart,
      * and if the auto-coupon is exclusive, it can't be added with others
      */
     // If this is a user-submitted coupon && there are other user-submitted coupons in the cart, fail
     if (empty($this->usage_automatic) && $cart->userCoupons() && $cart->userCoupons()[0]['code'] != $this->code) {
         throw new \Exception('Only one coupon allowed per cart');
     }
     // if this is an automatic coupon && usage_with_others == 0 && there are other automatic coupons in the cart
     if ($this->usage_automatic && empty($this->usage_with_others) && $cart->autoCoupons()) {
         throw new \Exception('This coupon cannot be combined with others');
     }
     // TODO take min_subtotal_amount_currency into account once we have currencies sorted
     if (!empty($this->min_subtotal_amount) && $cart->subtotal() < $this->min_subtotal_amount) {
         throw new \Exception('Cart has not met the minimum required subtotal');
     }
     // TODO take min_order_amount_currency into account once we have currencies sorted
     $total = $cart->subtotal() - $cart->giftCardTotal() - $cart->discountTotal() - $cart->creditTotal();
     // Add back the value of this coupon in case it is already applied
     foreach ($cart->allCoupons() as $coupon) {
         if ((string) $coupon['_id'] == (string) $this->id) {
             $total = $total + $coupon['amount'];
             break;
         }
     }
     if (!empty($this->min_order_amount) && $total < $this->min_order_amount) {
         throw new \Exception('Cart has not met the minimum required amount');
     }
     /**
      * check that at least one of the $this->required_products is in the cart
      */
     if (!empty($this->required_products)) {
         // get the IDs of all products in this cart
         $product_ids = array();
         foreach ($cart->items as $cartitem) {
             $product_ids[] = (string) \Dsc\ArrayHelper::get($cartitem, 'product_id');
         }
         $intersection = array_intersect($this->required_products, $product_ids);
         if (empty($intersection)) {
             throw new \Exception('Coupon does not apply to any products in your cart.');
         }
     }
     /**
      * check that at least one of the $this->required_coupons is in the cart
      */
     if (!empty($this->required_coupons)) {
         // get the IDs of all coupons in this cart
         $coupon_ids = array();
         foreach ($cart->userCoupons() as $coupon) {
             $coupon_ids[] = (string) $coupon['_id'];
         }
         foreach ($cart->autoCoupons() as $coupon) {
             $coupon_ids[] = (string) $coupon['_id'];
         }
         $intersection = array_intersect($this->required_coupons, $coupon_ids);
         if (empty($intersection)) {
             throw new \Exception('Cart does not have any of the required coupons');
         }
     }
     /**
      * check that at least one of the products from $this->required_collections is in the cart
      */
     if (!empty($this->required_collections)) {
         // get the IDs of all products in this cart
         $product_ids = array();
         foreach ($cart->items as $cartitem) {
             $product_ids[] = (string) \Dsc\ArrayHelper::get($cartitem, 'product_id');
         }
         $found = false;
         foreach ($this->required_collections as $collection_id) {
             $collection_product_ids = \Shop\Models\Collections::productIds($collection_id);
             $intersection = array_intersect($collection_product_ids, $product_ids);
             if (!empty($intersection)) {
                 $found = true;
                 break;
                 // if its found, break the foreach loop
             }
         }
         if (!$found) {
             throw new \Exception('Coupon does not apply to any products in your cart.');
         }
     }
     /**
      * evaluate shopper groups against $this->groups
      */
     if (!empty($this->groups)) {
         $groups = array();
         $user = (new \Users\Models\Users())->setState('filter.id', $cart->user_id)->getItem();
         if (empty($cart->user_id) || empty($user->id)) {
             // Get the default group
             $group_id = \Shop\Models\Settings::fetch()->{'users.default_group'};
             if (!empty($group_id)) {
                 $groups[] = (new \Users\Models\Groups())->setState('filter.id', (string) $group_id)->getItem();
             }
         } elseif (!empty($user->id)) {
             $groups = $user->groups();
         }
         $group_ids = array();
         foreach ($groups as $group) {
             $group_ids[] = (string) $group->id;
         }
         switch ($this->groups_method) {
             case "none":
                 $intersection = array_intersect($this->groups, $group_ids);
                 if (!empty($intersection)) {
                     throw new \Exception('Your order does not qualify for this discount.');
                 }
                 break;
             case "all":
                 // $missing_groups == the ones from $this->groups that are NOT in $group_ids
                 $missing_groups = array_diff($this->groups, $group_ids);
                 if (!empty($missing_groups)) {
                     throw new \Exception('Your order does not qualify for this discount.');
                 }
                 break;
             case "one":
             default:
                 $intersection = array_intersect($this->groups, $group_ids);
                 if (empty($intersection)) {
                     throw new \Exception('Your order does not qualify for this discount.');
                 }
                 break;
         }
     }
     /**
      * using geo_address_type (shipping/billing) from the cart, check that it is in geo_countries | geo_regions (if either is set)
      */
     if (!empty($this->geo_countries) || !empty($this->geo_regions)) {
         // ok, so which of the addresses should we evaluate?
         switch ($this->geo_address_type) {
             case "billing":
                 $region = $cart->billingRegion();
                 $country = $cart->billingCountry();
                 break;
             case "shipping":
             default:
                 $region = $cart->shippingRegion();
                 $country = $cart->shippingCountry();
                 break;
         }
         if (is_null($region) && !empty($this->geo_regions) || is_null($country) && !empty($this->geo_countries)) {
             throw new \Exception('Customer cannot use this coupon until we know your address');
         }
         if (!empty($this->geo_countries)) {
             // eval the country
             if (!in_array($country, $this->geo_countries)) {
                 throw new \Exception('Shipping address is invalid');
             }
         }
         if (!empty($this->geo_regions)) {
             // eval the region
             if (!in_array($region, $this->geo_regions)) {
                 throw new \Exception('Shipping address is invalid');
             }
         }
     }
     /**
      * Check the usage of the coupon
      */
     if (strlen($this->usage_max)) {
         // usage_max = number of times TOTAL that the coupon may be used
         // count the orders with coupon.code
         $total_count = (new \Shop\Models\Orders())->collection()->count(array('coupons.code' => $this->code));
         if ((int) $this->usage_max <= (int) $total_count) {
             throw new \Exception('Coupon cannot be used any more');
         }
     }
     if (strlen($this->usage_max_per_customer)) {
         // usage_max_per_customer = number of times this customer may use this coupon
         // count the orders with coupon.code for user.id
         $user_count = (new \Shop\Models\Orders())->collection()->count(array('coupons.code' => $this->code, 'user_id' => $cart->user_id));
         if ((int) $this->usage_max_per_customer <= (int) $user_count) {
             throw new \Exception('You cannot use this coupon any more');
         }
     }
     /**
      * Check, if this isn't generated code
      */
     if (!empty($this->generated_code)) {
         $key = new \MongoRegex('/' . $this->generated_code . '/i');
         $result = \Shop\Models\Coupons::collection()->aggregate(array('$match' => array('_id' => new \MongoId((string) $this->id))), array('$unwind' => '$codes.list'), array('$match' => array("codes.list.code" => $key)), array('$group' => array('_id' => '$title', 'used_code' => array('$sum' => '$codes.list.used'))));
         if (count($result['result'])) {
             if ($result['result'][0]['used_code']) {
                 throw new \Exception('You cannot use this coupon any more');
             }
         } else {
             throw new \Exception('Coupon "' . $this->generated_code . '" is no longer available.');
         }
     }
     /**
      * if we made it this far, the cart is valid for this coupon
      */
     $this->__is_validated = true;
     return $this;
 }
Example #16
0
 public function productsXml()
 {
     $settings = \Shop\Models\Settings::fetch();
     if (!$settings->{'feeds.gm_products.enabled'}) {
         return;
     }
     $this->app->set('CACHE', true);
     $cache = \Cache::instance();
     $cache_period = 3600 * 24;
     if ($cache->exists('googlemerchant.products_xml', $string)) {
         header('Content-Type: application/xml; charset=utf-8');
         echo $string;
         exit;
     }
     $base = \Dsc\Url::base();
     $model = (new \Shop\Models\Products())->setState('filter.published_today', true)->setState('filter.inventory_status', 'in_stock')->setState('filter.publication_status', 'published');
     $conditions = $model->conditions();
     $conditions['product_type'] = array('$nin' => array('giftcard', 'giftcards'));
     $cursor = \Shop\Models\Products::collection()->find($conditions)->sort(array('title' => 1));
     //->limit(10);
     /**
      * Generate XML
      */
     $x = new \XMLWriter();
     $x->openMemory();
     $x->setIndent(true);
     $x->setIndentString(" ");
     $x->startDocument('1.0', 'UTF-8');
     $x->startElement('rss');
     $x->writeAttribute('version', '2.0');
     $x->writeAttribute('xmlns:g', 'http://base.google.com/ns/1.0');
     $x->startElement('channel');
     $title = $settings->{'feeds.gm_products.title'} ? $settings->{'feeds.gm_products.title'} : 'Product Feed';
     $x->startElement('title');
     $x->text($title);
     $x->endElement();
     // title
     $link = $base;
     $x->startElement('link');
     $x->text($link);
     $x->endElement();
     // link
     if ($description = $settings->{'feeds.gm_products.description'}) {
         $x->startElement('description');
         $x->text($description);
         $x->endElement();
         // description
     }
     foreach ($cursor as $product_doc) {
         $product = new \Shop\Models\Products($product_doc);
         foreach ($product->variantsInStock() as $variant) {
             $price = $product->price($variant['id']);
             // Skip products where price == 0.00
             if (empty($price)) {
                 continue;
             }
             $x->startElement('item');
             $x->startElement('title');
             $x->text($product->title);
             $x->endElement();
             // title
             $x->startElement('description');
             $x->text(strip_tags($product->getAbstract()));
             $x->endElement();
             // description
             $x->startElement('g:link');
             $x->text($base . 'shop/product/' . $product->slug);
             $x->endElement();
             // g:link
             // image_link
             if ($image = $variant['image'] ? $variant['image'] : $product->{'featured_image.slug'}) {
                 $x->startElement('g:image_link');
                 $x->text($base . 'asset/' . $image);
                 $x->endElement();
                 // g:image_link
             }
             // google_product_category
             if ($product->{'gm_product_category'}) {
                 $x->startElement('g:google_product_category');
                 $x->text($product->{'gm_product_category'});
                 $x->endElement();
                 // g:google_product_category
             }
             // TODO product_type
             // gender = female (or male, unisex)
             $gender = $settings->{'feeds.gm_products.gender'};
             if ($product->{'gm_products.gender'}) {
                 $gender = $product->{'gm_products.gender'};
             }
             if ($gender) {
                 $x->startElement('g:gender');
                 $x->text($gender);
                 $x->endElement();
                 // g:gender
             }
             // age_group = adult (or newborn, infanct, toddler, kids)
             $age_group = $settings->{'feeds.gm_products.age_group'};
             if ($product->{'gm_products.age_group'}) {
                 $age_group = $product->{'gm_products.age_group'};
             }
             if ($age_group) {
                 $x->startElement('g:age_group');
                 $x->text($age_group);
                 $x->endElement();
                 // g:age_group
             }
             // following handles color, size, pattern, material (if they are set as attributes)
             foreach ($product->attributes as $attribute) {
                 $att_title = strtolower($attribute['title']);
                 if (in_array($att_title, array('color', 'material', 'pattern', 'size'))) {
                     $att_id = $attribute['id'];
                     // get the attribute options
                     $options = array();
                     foreach ($attribute['options'] as $option) {
                         $options[] = $option['id'];
                     }
                     if ($found = array_intersect($options, $variant['attributes'])) {
                         $key = array_search($found, $variant['attributes']);
                         if (!empty($variant['attribute_titles'][$key])) {
                             $x->startElement('g:' . $att_title);
                             $x->text($variant['attribute_titles'][$key]);
                             $x->endElement();
                             // g:$att_title
                         }
                     }
                 }
             }
             // since we do variants: item_group_id
             $x->startElement('g:item_group_id');
             $x->text($product->{'tracking.sku'});
             $x->endElement();
             // g:item_group_id
             $sku = $variant['sku'] ? $variant['sku'] : $product->{'tracking.sku'};
             if (!$sku) {
                 $sku = $variant['id'];
             }
             $x->startElement('g:id');
             $x->text($sku);
             $x->endElement();
             // g:id
             if ($brand = $settings->{'feeds.gm_products.brand'}) {
                 $x->startElement('g:brand');
                 $x->text($brand);
                 $x->endElement();
                 // g:brand
             }
             $x->startElement('g:mpn');
             $x->text($sku);
             $x->endElement();
             // g:mpn
             $x->startElement('g:price');
             $x->text($price . ' USD');
             $x->endElement();
             // g:price
             $x->startElement('g:condition');
             $x->text('new');
             $x->endElement();
             // g:condition
             $x->startElement('g:availability');
             $x->text('in stock');
             $x->endElement();
             // g:availability
             $x->endElement();
             // item
         }
     }
     $x->endElement();
     // channel
     $x->endElement();
     // rss
     $x->endDocument();
     $string = $x->outputMemory();
     $cache->set('googlemerchant.products_xml', $string, $cache_period);
     header('Content-Type: application/xml; charset=utf-8');
     echo $string;
 }
Example #17
0
 /**
  * \T (tab) delimited feed of products
  * 
  * http://www.pepperjamnetwork.com/doc/product_feed_advanced.html
  * 
  */
 public function productsTxt()
 {
     $settings = \Shop\Models\Settings::fetch();
     if (!$settings->{'feeds.pepperjam_products.enabled'}) {
         return;
     }
     $this->app->set('CACHE', true);
     $cache = \Cache::instance();
     $cache_period = 3600 * 24;
     if ($cache->exists('pepperjam.products_text', $string)) {
         header('Content-Type: text/plain; charset=utf-8');
         echo $string;
         exit;
     }
     $base = \Dsc\Url::base();
     $model = (new \Shop\Models\Products())->setState('filter.published_today', true)->setState('filter.inventory_status', 'in_stock')->setState('filter.publication_status', 'published');
     $conditions = $model->conditions();
     $conditions['product_type'] = array('$nin' => array('giftcard', 'giftcards'));
     $cursor = \Shop\Models\Products::collection()->find($conditions)->sort(array('title' => 1));
     //->limit(10);
     /**
      * name	sku	buy_url	image_url	description_short	description_long	price	manufacturer
      */
     $column_headers = array('name', 'sku', 'buy_url', 'image_url', 'description_short', 'description_long', 'price', 'manufacturer');
     $string = implode("\t", $column_headers) . "\r\n";
     foreach ($cursor as $product_doc) {
         $product = new \Shop\Models\Products($product_doc);
         foreach ($product->variantsInStock() as $variant) {
             $valid = true;
             $price = $product->price($variant['id']);
             // Skip products where price == 0.00
             if (empty($price)) {
                 continue;
             }
             $pieces = array('name' => null, 'sku' => null, 'buy_url' => null, 'image_url' => null, 'description_short' => null, 'description_long' => null, 'price' => null, 'manufacturer' => null);
             $pieces['name'] = $product->title;
             $sku = $variant['sku'] ? $variant['sku'] : $product->{'tracking.sku'};
             if (!$sku) {
                 $sku = $variant['id'];
             }
             $pieces['sku'] = $sku;
             $pieces['buy_url'] = $base . 'shop/product/' . $product->slug . '?variant_id=' . $variant['id'];
             // image_link
             if ($image = $variant['image'] ? $variant['image'] : $product->{'featured_image.slug'}) {
                 $pieces['image_url'] = $base . 'asset/' . $image;
             }
             $pieces['description_short'] = $product->title . ' ';
             if ($attribute_title = \Dsc\ArrayHelper::get($variant, 'attribute_title')) {
                 $pieces['description_short'] .= $attribute_title;
             }
             $pieces['description_short'] = trim($pieces['description_short']);
             $pieces['description_long'] = strip_tags($product->getAbstract());
             $pieces['price'] = $price;
             if ($brand = $settings->{'feeds.pepperjam_products.brand'}) {
                 $pieces['manufacturer'] = $brand;
             }
             global $product;
             //walk peices logging empty values and omiting them
             array_walk($pieces, function (&$value, $key) {
                 global $product;
                 if (empty($value)) {
                     \Dsc\Mongo\Collections\Logs::add($product->title . ' | ID: ' . $product->id . ' is missing ' . $key, 'WARNING', 'PepperJam');
                     $valid = false;
                 }
             });
             if ($valid) {
                 $string .= implode("\t", $pieces) . "\r\n";
             }
         }
     }
     $cache->set('pepperjam.products_text', $string, $cache_period);
     header('Content-Type: text/plain; charset=utf-8');
     echo $string;
     exit;
 }
Example #18
0
 /**
  * User-aware price of the product,
  * accounting for user group, date, specials, etc.
  * Defaults to the product's default price.
  * 
  * @param \Users\Models\Users $user
  * @return unknown
  */
 public function price($variant_id = null, \Users\Models\Users $user = null)
 {
     $price = $this->get('prices.default');
     if (empty($user)) {
         $identity = \Dsc\System::instance()->get('auth')->getIdentity();
         if (!empty($identity->id)) {
             $user = $identity;
         }
     }
     $settings = \Shop\Models\Settings::fetch();
     // find the first user group that has special price override in settings and use it
     $settings_price_override = null;
     $settings_override = false;
     if (!empty($user)) {
         foreach ($user->groups() as $group) {
             $settings_override = $settings->exists('special_group_default_prices.' . $group['slug']);
             if ($settings_override) {
                 // found it, so get the correct number and leave
                 $type_price = 'regular';
                 if (!empty($this->{'prices.list'})) {
                     $type_price = 'sale';
                 }
                 $settings_price_override = 'special_group_default_prices.' . $group['slug'] . '.' . $type_price;
                 break;
             }
         }
     }
     // Get the product price for the user's primary group
     // primaryGroup defaults to the site-wide default user group
     $primaryGroup = \Shop\Models\Customers::primaryGroup($user);
     if ($group_slug = $primaryGroup->{'slug'}) {
         if (!$settings_override && $this->exists('prices.' . $group_slug)) {
             $price = $this->get('prices.' . $group_slug);
         }
     }
     if (!empty($variant_id) && $this->{'policies.variant_pricing.enabled'} && ($variant = $this->variant($variant_id))) {
         $price = $variant['price'];
     }
     // adjust price based on date ranges too
     $using_special_price = false;
     $now = strtotime('now');
     $today = date('Y-m-d', $now);
     foreach ((array) $this->{'prices.special'} as $special_price) {
         if (empty($special_price['group_id']) || $special_price['group_id'] == (string) $primaryGroup->id) {
             if (!empty($special_price['start']['time']) && $special_price['start']['time'] <= $now && (empty($special_price['end']['time']) || $special_price['end']['time'] > $now)) {
                 $price = $special_price['price'];
                 $using_special_price = true;
                 break;
             }
         }
     }
     // don't discount special prices
     if (!$using_special_price && $settings_override) {
         $ratio = 1.0 - (double) $settings->{$settings_price_override} / 100.0;
         $price = $price * $ratio;
     }
     return $price;
 }
Example #19
0
<?php

$selected_country = $flash->old('country') ? $flash->old('country') : \Shop\Models\Settings::fetch()->{'store_address.country'};
?>

<div id="address" class="well well-sm">
    <div class="form-group">
        <input type="text" class="form-control name" data-required="true" name="name" value="<?php 
echo $flash->old('name');
?>
" placeholder="Full Name" autocomplete="name">
    </div>
    <div class="form-group">
        <input type="text" class="form-control address" data-required="true" name="line_1" value="<?php 
echo $flash->old('line_1');
?>
" placeholder="Address Line 1" autocomplete="address-line1">
    </div>
    <div class="form-group">
        <input type="text" class="form-control address" name="line_2" value="<?php 
echo $flash->old('line_2');
?>
" placeholder="Address Line 2" autocomplete="address-line2">
    </div>
    <div class="form-group">
        <input type="text" class="form-control city" data-required="true" name="city" value="<?php 
echo $flash->old('city');
?>
" placeholder="City" autocomplete="locality">
    </div>
    <div class="row">
Example #20
0
 public function sendEmailShareGiftCard($data)
 {
     \Base::instance()->set('data', $data);
     \Base::instance()->set('giftcard', $this);
     \Base::instance()->set('settings', \Shop\Models\Settings::fetch());
     $html = \Dsc\System::instance()->get('theme')->renderView('Shop/Views::emails_html/share_gift_card.php');
     $text = \Dsc\System::instance()->get('theme')->renderView('Shop/Views::emails_text/share_gift_card.php');
     $subject = 'A gift card from ' . $data['sender_name'];
     $this->__sendEmailShareGiftCard = \Dsc\System::instance()->get('mailer')->send($data['recipient_email'], $subject, array($html, $text));
     // Add the entry to the gift card's internal history log
     $this->history[] = array('created' => \Dsc\Mongo\Metastamp::getDate('now'), 'subject' => $data['sender_name'] . ' (' . $data['sender_email'] . ')', 'verb' => 'shared', 'object' => $data['recipient_name'] . ' (' . $data['recipient_email'] . ')');
     return $this->save();
 }