Пример #1
0
?>
,
	uidir = '<?php 
echo SHOPP_ADMIN_URI;
?>
',
	siteurl = '<?php 
bloginfo('url');
?>
',
	adminurl = '<?php 
echo admin_url();
?>
',
	canonurl = '<?php 
echo trailingslashit(Shopp::url('' != get_option('permalink_structure') ? get_class_property('ProductCategory', 'namespace') : $Category->taxonomy . '='));
?>
',
	ajaxurl = adminurl+'admin-ajax.php',
	addcategory_url = '<?php 
echo wp_nonce_url(admin_url() . "admin-ajax.php", "shopp-ajax_add_category");
?>
',
	editslug_url = '<?php 
echo wp_nonce_url(admin_url() . "admin-ajax.php", "wp_ajax_shopp_edit_slug");
?>
',
	fileverify_url = '<?php 
echo wp_nonce_url(admin_url() . "admin-ajax.php", "shopp-ajax_verify_file");
?>
',
Пример #2
0
 /**
  * Handles shopping cart requests
  *
  * @author Jonathan Davis
  * @since 1.1
  *
  * @return void
  **/
 public function cart()
 {
     if (isset($_REQUEST['shopping']) && 'reset' == strtolower($_REQUEST['shopping'])) {
         ShoppShopping()->reset();
         Shopp::redirect(Shopp::url());
     }
     if (empty($_REQUEST['cart'])) {
         return true;
     }
     do_action('shopp_cart_request');
     if (isset($_REQUEST['checkout'])) {
         Shopp::redirect(Shopp::url(false, 'checkout', $this->security()));
     }
     if (isset($_REQUEST['ajax'])) {
         $Cart = ShoppOrder()->Cart;
         $Cart->totals();
         $Cart->ajax();
     }
     $redirect = false;
     if (isset($_REQUEST['redirect'])) {
         $redirect = $_REQUEST['redirect'];
     }
     switch ($redirect) {
         case 'checkout':
             Shopp::redirect(Shopp::url(false, $redirect, ShoppOrder()->security()));
             break;
         default:
             if (!empty($_REQUEST['redirect'])) {
                 Shopp::safe_redirect($_REQUEST['redirect']);
             } else {
                 Shopp::redirect(Shopp::url(false, 'cart'));
             }
     }
     exit;
 }
Пример #3
0
?>
,
	uidir = '<?php 
echo SHOPP_ADMIN_URI;
?>
',
	siteurl = '<?php 
bloginfo('url');
?>
',
	screenid = '<?php 
echo get_current_screen()->id;
?>
',
	canonurl = '<?php 
echo trailingslashit(Shopp::url());
?>
',
	adminurl = '<?php 
echo admin_url();
?>
',
	sugg_url = '<?php 
echo wp_nonce_url(admin_url('admin-ajax.php'), "wp_ajax_shopp_storage_suggestions");
?>
',
	tagsugg_url = '<?php 
echo wp_nonce_url(admin_url('admin-ajax.php'), "wp_ajax_shopp_suggestions");
?>
',
	spectemp_url = '<?php 
Пример #4
0
 /**
  * Returns a URL for a resized image.
  *
  * If direct mode is enabled (which it is by
  * default) and the image is already cached to the file system then a URL for that
  * file will be returned.
  *
  * In all other cases a Shopp Image Server URL will be returned.
  *
  * @param $width
  * @param $height
  * @param $scale
  * @param $sharpen
  * @param $quality
  * @param $fill
  * @return string
  */
 public function url($width = null, $height = null, $scale = null, $sharpen = null, $quality = null, $fill = null)
 {
     $request = array();
     $url = Shopp::url('' != get_option('permalink_structure') ? trailingslashit($this->id) . $this->filename : $this->id, 'images');
     // Get the current URI
     $uri = $this->uri;
     // Handle resize requests
     $params = func_get_args();
     if (count($params) > 0) {
         list($width, $height, $scale, $sharpen, $quality, $fill) = $params;
         $request = $this->resizing($width, $height, $scale, $sharpen, $quality, $fill);
         // Build the path to the cached copy of the file (if it exists)
         $size = $this->cachefile($request);
         $uri = "cache_{$size}_{$this->filename}";
         // Override the URI for the request
     }
     // Ask the engine if we have a direct URL
     $direct_url = $this->engine()->direct($uri);
     if (false !== $direct_url) {
         return $direct_url;
     }
     if (empty($request)) {
         return $url;
     } else {
         return Shopp::add_query_string($request, $url);
     }
 }
Пример #5
0
 /**
  * Provides the checkout page URL
  *
  * @api `shopp('checkout.url')`
  * @since 1.0
  *
  * @param string     $result  The output
  * @param array      $options The options
  * @param ShoppOrder $O       The working object
  * @return string The checkout page URL
  **/
 public static function url($result, $options, $O)
 {
     $link = Shopp::url(false, 'checkout', $O->security());
     $Storefront = ShoppStorefront();
     // Pass any arguments along
     $args = $_GET;
     unset($args['shopp_page'], $args['acct']);
     $link = esc_url(add_query_arg($args, $link));
     if (isset($Storefront->_confirm_page_content)) {
         $link = apply_filters('shopp_confirm_url', $link);
     } else {
         $link = apply_filters('shopp_checkout_url', $link);
     }
     return $link;
 }
Пример #6
0
 /**
  * Iterates loaded products in buffered batches and generates a feed-friendly item record
  *
  * NOTE: To modify the output of the RSS generator, use
  * the filter hooks provided in a separate plugin or
  * in the theme functions.php file.
  *
  * @author Jonathan Davis
  * @since 1.0
  * @version 1.1
  *
  * @return string A feed item record
  **/
 public function feed()
 {
     $paged = 100;
     // Buffer 100 products at a time.
     $loop = false;
     $product = ShoppProduct();
     if ($product) {
         $loop = shopp($this, 'products');
         if (!$loop) {
             $product = false;
         } else {
             $product = ShoppProduct();
         }
     }
     if (!($product || $loop)) {
         if (!$this->products) {
             $page = 1;
         } else {
             $page = $this->page + 1;
         }
         if ($this->pages > 0 && $page > $this->pages) {
             return false;
         }
         $this->load(array('load' => array('prices', 'specs', 'categories', 'coverimages'), 'paged' => $paged, 'page' => $page));
         $loop = shopp($this, 'products');
         if (!$loop) {
             return false;
         }
         // Loop ended, bail out
         $product = ShoppProduct();
         if (!$product) {
             return false;
         }
         // No products, bail
     }
     $item = array();
     $item['guid'] = shopp($product, 'get-id');
     $item['title'] = $product->name;
     $item['link'] = shopp($product, 'get-url');
     $item['pubDate'] = date('D, d M Y H:i O', $product->publish);
     // Item Description
     $item['description'] = '';
     $item['description'] .= '<table><tr>';
     $Image = current($product->images);
     if (!empty($Image)) {
         $item['description'] .= '<td><a href="' . $item['link'] . '" title="' . $product->name . '">';
         $item['description'] .= '<img src="' . esc_attr(add_query_string($Image->resizing(75, 75, 0), Shopp::url($Image->id, 'images'))) . '" alt="' . $product->name . '" width="75" height="75" />';
         $item['description'] .= '</a></td>';
     }
     $pricing = "";
     $priceindex = 'price';
     if (Shopp::str_true($product->sale)) {
         $priceindex = 'saleprice';
     }
     if ($product->min[$priceindex] != $product->max[$priceindex]) {
         $pricing .= Shopp::__('from') . ' ';
     }
     $pricing .= money($product->min[$priceindex]);
     $item['description'] .= "<td><p><big>{$pricing}</big></p>";
     $item['description'] .= apply_filters('shopp_rss_description', $product->summary, $product) . '</td></tr></table>';
     $item['description'] = '<![CDATA[' . $item['description'] . ']]>';
     // Google Base Namespace
     // http://www.google.com/support/merchants/bin/answer.py?hl=en&answer=188494
     // Below are Google Base specific attributes
     // You can use the shopp_rss_item filter hook to add new item attributes or change the existing attributes
     if ($Image) {
         $item['g:image_link'] = add_query_string($Image->resizing(400, 400, 0), Shopp::url($Image->id, 'images'));
     }
     $item['g:condition'] = 'new';
     $item['g:availability'] = shopp_setting_enabled('inventory') && $product->outofstock ? 'out of stock' : 'in stock';
     $price = Shopp::floatval(Shopp::str_true($product->sale) ? $product->min['saleprice'] : $product->min['price']);
     if (!empty($price)) {
         $item['g:price'] = $price;
         $item['g:price_type'] = "starting";
     }
     // Include product_type using Shopp category taxonomies
     foreach ($product->categories as $category) {
         $ancestry = array($category->name);
         $ancestors = get_ancestors($category->term_id, $category->taxonomy);
         foreach ((array) $ancestors as $ancestor) {
             $term = get_term($ancestor, $category->taxonomy);
             if ($term) {
                 array_unshift($ancestry, $term->name);
             }
         }
         $item['g:product_type[' . $category->term_id . ']'] = join(' > ', $ancestry);
     }
     $brand = shopp($product, 'get-spec', 'name=Brand');
     if (!empty($brand)) {
         $item['g:brand'] = $brand;
     }
     $gtins = array('UPC', 'EAN', 'JAN', 'ISBN-13', 'ISBN-10', 'ISBN');
     foreach ($gtins as $id) {
         $gtin = shopp($product, 'get-spec', 'name=' . $id);
         if (!empty($gtin)) {
             $item['g:gtin'] = $gtin;
             break;
         }
     }
     $mpn = shopp($product, 'get-spec', 'name=MPN');
     if (!empty($mpn)) {
         $item['g:mpn'] = $mpn;
     }
     // Check the product specs for matching Google Base information
     $g_props = array('MPN' => 'mpn', 'Color' => 'color', 'Material' => 'material', 'Pattern' => 'pattern', 'Size' => 'size', 'Gender' => 'gender', 'Age Group' => 'age_group', 'Google Product Category' => 'google_product_category');
     foreach (apply_filters('shopp_googlebase_spec_map', $g_props) as $name => $key) {
         $value = shopp($product, 'get-spec', 'name=' . $name);
         if (!empty($value)) {
             $item["g:{$key}"] = $value;
         }
     }
     return apply_filters('shopp_rss_item', $item, $product);
 }
Пример #7
0
 /**
  * Interface processor for the product editor
  *
  * @author Jonathan Davis
  * @return void
  **/
 public function editor()
 {
     $Shopp = Shopp::object();
     if (!current_user_can('shopp_products')) {
         wp_die(__('You do not have sufficient permissions to access this page.'));
     }
     if (empty($Shopp->Product)) {
         $Product = new ShoppProduct();
         $Product->status = "publish";
     } else {
         $Product = $Shopp->Product;
     }
     $Product->slug = apply_filters('editable_slug', $Product->slug);
     $permalink = trailingslashit(Shopp::url());
     $Price = new ShoppPrice();
     $priceTypes = ShoppPrice::types();
     $billPeriods = ShoppPrice::periods();
     $workflows = array('continue' => Shopp::__('Continue Editing'), 'close' => Shopp::__('Products Manager'), 'new' => Shopp::__('New Product'), 'next' => Shopp::__('Edit Next'), 'previous' => Shopp::__('Edit Previous'));
     $taglist = array();
     foreach ($Product->tags as $tag) {
         $taglist[] = $tag->name;
     }
     if ($Product->id && !empty($Product->images)) {
         $ids = join(',', array_keys($Product->images));
         $CoverImage = reset($Product->images);
         $image_table = $CoverImage->_table;
         $Product->cropped = sDB::query("SELECT * FROM {$image_table} WHERE context='image' AND type='image' AND '2'=SUBSTRING_INDEX(SUBSTRING_INDEX(name,'_',4),'_',-1) AND parent IN ({$ids})", 'array', 'index', 'parent');
     }
     $shiprates = shopp_setting('shipping_rates');
     if (!empty($shiprates)) {
         ksort($shiprates);
     }
     $uploader = shopp_setting('uploader_pref');
     if (!$uploader) {
         $uploader = 'flash';
     }
     $process = empty($Product->id) ? 'new' : $Product->id;
     $_POST['action'] = add_query_arg(array_merge($_GET, array('page' => $this->Admin->pagename('products'))), admin_url('admin.php'));
     $post_type = ShoppProduct::posttype();
     // Re-index menu options to maintain order in JS #2930
     if (isset($Product->options['v']) || isset($Product->options['a'])) {
         $options = array_keys($Product->options);
         foreach ($options as $type) {
             foreach ($Product->options[$type] as $id => $menu) {
                 $Product->options[$type][$type . $id] = $menu;
                 $Product->options[$type][$type . $id]['options'] = array_values($menu['options']);
                 unset($Product->options[$type][$id]);
             }
         }
     } else {
         foreach ($Product->options as &$menu) {
             $menu['options'] = array_values($menu['options']);
         }
     }
     do_action('add_meta_boxes', ShoppProduct::$posttype, $Product);
     do_action('add_meta_boxes_' . ShoppProduct::$posttype, $Product);
     do_action('do_meta_boxes', ShoppProduct::$posttype, 'normal', $Product);
     do_action('do_meta_boxes', ShoppProduct::$posttype, 'advanced', $Product);
     do_action('do_meta_boxes', ShoppProduct::$posttype, 'side', $Product);
     include $this->ui('editor.php');
 }
Пример #8
0
 /**
  * Create a lock for transaction processing
  *
  * @author Jonathan Davis
  * @since 1.2.1
  *
  * @return boolean
  **/
 public function lock($data)
 {
     if (!isset($data['order'])) {
         return false;
     }
     $order = $data['order'];
     $locked = 0;
     for ($attempts = 0; $attempts < 3 && $locked == 0; $attempts++) {
         $locked = sDB::query("SELECT GET_LOCK('{$order}'," . SHOPP_TXNLOCK_TIMEOUT . ") AS locked", 'auto', 'col', 'locked');
         if (0 == $locked) {
             sleep(1);
         }
         // Wait a sec before trying again
     }
     if (1 == $locked) {
         return true;
     }
     shopp_debug("Purchase authed lock for order #{$order} failed. Could not achieve a lock.");
     Shopp::redirect(Shopp::url(false, 'thanks', ShoppOrder()->security()));
 }
Пример #9
0
 /**
  * Provides the context appropriate URL for selecting shipping options
  *
  * @api `shopp('context.property')`
  * @since 1.0
  *
  * @param string         $result  The output
  * @param array          $options The options
  * @param ShoppShiprates $O       The working object
  * @return void
  **/
 public static function url($result, $options, $O)
 {
     return is_shopp_page('checkout') ? Shopp::url(false, 'confirm-order') : Shopp::url(false, 'cart');
 }
Пример #10
0
 public function process()
 {
     $action = $this->form('checkout');
     if ('process' != $action) {
         return;
     }
     $Payments = ShoppOrder()->Payments;
     $Cart = ShoppOrder()->Cart;
     $forcedconfirm = 'always' == shopp_setting('order_confirmation');
     $wasfree = $Cart->orderisfree();
     // Get current free status
     $estimated = $Cart->total();
     // Get current total
     $Cart->totals();
     // Retotal after checkout to capture order total changes
     // We have to avoid truthiness, hence the strange logic expression
     if (true !== apply_filters('shopp_validate_checkout', true)) {
         return;
     } else {
         $this->customer();
     }
     // Catch changes from validation
     // Catch originally free orders that get extra (shipping) costs added to them
     if ($wasfree && $Payments->count() > 1 && !$Cart->orderisfree() && empty($Payments->selected()->cards)) {
         shopp_add_error(Shopp::__('The order amount changed and requires that you select a payment method.'));
         Shopp::redirect(Shopp::url(false, 'checkout', ShoppOrder()->security()));
     }
     // Do not use shopp_checkout_processed for payment gateway redirect actions
     // Free order processing doesn't take over until the order is submitted for processing in `shopp_process_order`
     do_action('shopp_checkout_processed');
     // If the cart's total changes at all, confirm the order
     if (apply_filters('shopp_order_confirm_needed', $estimated != $Cart->total() || $forcedconfirm)) {
         Shopp::redirect(Shopp::url(false, 'confirm', ShoppOrder()->security()));
         return;
     }
     do_action('shopp_process_order');
 }
Пример #11
0
 /**
  * Interface processor for the category editor
  *
  * @author Jonathan Davis
  * @since 1.0
  * @return void
  **/
 public function screen()
 {
     global $CategoryImages;
     $Shopp = Shopp::object();
     if (!current_user_can('shopp_categories')) {
         wp_die(__('You do not have sufficient permissions to access this page.'));
     }
     $Category = $this->Model;
     $Price = new ShoppPrice();
     $priceTypes = ShoppPrice::types();
     $billPeriods = ShoppPrice::periods();
     // Build permalink for slug editor
     $permalink = trailingslashit(Shopp::url()) . "category/";
     $Category->slug = apply_filters('editable_slug', $Category->slug);
     $pricerange_menu = array("disabled" => __('Price ranges disabled', 'Shopp'), "auto" => __('Build price ranges automatically', 'Shopp'), "custom" => __('Use custom price ranges', 'Shopp'));
     $uploader = shopp_setting('uploader_pref');
     if (!$uploader) {
         $uploader = 'flash';
     }
     $workflows = array("continue" => __('Continue Editing', 'Shopp'), "close" => __('Categories Manager', 'Shopp'), "new" => __('New Category', 'Shopp'), "next" => __('Edit Next', 'Shopp'), "previous" => __('Edit Previous', 'Shopp'));
     do_action('add_meta_boxes', ProductCategory::$taxon, $Category);
     do_action('add_meta_boxes_' . ProductCategory::$taxon, $Category);
     do_action('do_meta_boxes', ProductCategory::$taxon, 'normal', $Category);
     do_action('do_meta_boxes', ProductCategory::$taxon, 'advanced', $Category);
     do_action('do_meta_boxes', ProductCategory::$taxon, 'side', $Category);
     include $this->ui('category.php');
 }
Пример #12
0
 /**
  * Handle login redirects
  *
  * @author Jonathan Davis
  * @since 1.2
  *
  * @return void
  **/
 public function redirect()
 {
     $redirect = false;
     $secure = ShoppOrder()->security();
     if (isset($_REQUEST['redirect']) && !empty($_REQUEST['redirect'])) {
         if (ShoppPages()->exists($_REQUEST['redirect'])) {
             $redirect = Shopp::url(false, $_REQUEST['redirect'], $secure);
         } else {
             $redirect = $_REQUEST['redirect'];
         }
     }
     if (!$redirect) {
         $redirect = apply_filters('shopp_login_redirect', Shopp::url(false, 'account', $secure));
     }
     Shopp::safe_redirect($redirect);
 }
Пример #13
0
 protected function returnurl()
 {
     return add_query_arg('rmtpay', $this->id(), Shopp::url(false, 'thanks'));
 }
Пример #14
0
 /**
  * Provides the URL of for the order
  *
  * @api `shopp('context.property')`
  * @since 1.0
  *
  * @param string        $result  The output
  * @param array         $options The options
  * @param ShoppPurchase $O       The working object
  * @return void
  **/
 public static function url($result, $options, $O)
 {
     return Shopp::url(array('order' => $Purchase->id), 'account');
 }
Пример #15
0
 /**
  * Handle the synchronous return from PPS (PDT and default return)
  *
  * @author Jonathan Davis
  * @since 1.2
  **/
 public function pdt()
 {
     $Order = ShoppOrder();
     if (!$this->pdtvalid()) {
         return;
     }
     $Message = $this->Message;
     $id = $Message->order();
     $event = $Message->event();
     $Purchase = new ShoppPurchase($id);
     if (empty($Purchase->id)) {
         shopp_debug('PDT processing could not load the in progress order from the database.');
         return Shopp::redirect(Shopp::url(false, 'thanks', false));
     }
     $Order->inprogress = $Purchase->id;
     $this->process($event, $Purchase);
     Shopp::redirect(Shopp::url(false, 'thanks', false));
 }
Пример #16
0
 /**
  * Resets a customer/user password with a valid activation key
  *
  * @since 1.0
  *
  * @param string $activation The activation key
  * @return void
  **/
 static function resetpassword($activation)
 {
     if ('none' == shopp_setting('account_system') || ShoppCustomer()->loggedin()) {
         return;
     }
     $user_data = false;
     $activation = preg_replace('/[^a-z0-9]/i', '', $activation);
     $errors = array();
     if (empty($activation) || !is_string($activation)) {
         $errors[] = shopp_add_error(Shopp::__("Invalid password reset key. Try copy/pasting the url in password reset email into your web browser's address bar."));
     } else {
         $RecoveryCustomer = new ShoppCustomer($activation, 'activation');
         if (empty($RecoveryCustomer->id)) {
             $errors[] = shopp_add_error(Shopp::__("Invalid password reset key. Try copy/pasting the url in password reset email into your web browser's address bar."));
         }
     }
     if (!empty($errors)) {
         return false;
     }
     // Generate a new random password
     $password = wp_generate_password(12, false);
     do_action_ref_array('password_reset', array($RecoveryCustomer, $password));
     $RecoveryCustomer->password = wp_hash_password($password);
     if ('wordpress' == shopp_setting('account_system')) {
         $user_data = get_userdata($RecoveryCustomer->wpuser);
         wp_set_password($password, $user_data->ID);
     }
     $RecoveryCustomer->activation = '';
     $RecoveryCustomer->save();
     $subject = apply_filters('shopp_reset_password_subject', Shopp::__('[%s] New Password', get_option('blogname')));
     $_ = array();
     $_[] = 'From: ' . Shopp::email_from(shopp_setting('merchant_email'), shopp_setting('business_name'));
     $_[] = 'To: ' . $RecoveryCustomer->email;
     $_[] = 'Subject: ' . $subject;
     $_[] = 'Content-type: text/html';
     $_[] = '';
     $_[] = '<p>' . Shopp::__('Your new password for %s:', get_bloginfo('url')) . '</p>';
     $_[] = '';
     $_[] = '<ul>';
     if (apply_filters('shopp_reset_password_wpuser', true) && !empty($user_data->user_login)) {
         $_[] = '<li>' . Shopp::__('Login: %s', $user_data->user_login) . '</li>';
     } elseif (!empty($RecoveryCustomer->email)) {
         $_[] = '<li>' . Shopp::__('Login: %s', $RecoveryCustomer->email) . '</li>';
     }
     $_[] = '<li>' . Shopp::__('Password: %s', $password) . '</li>';
     $_[] = '</ul>';
     $_[] = '';
     $_[] = '<p>' . Shopp::__('Click here to login: %s', Shopp::url(false, 'account')) . '</p>';
     $message = apply_filters('shopp_reset_password_message', $_);
     if (!Shopp::email(join("\n", $message))) {
         shopp_add_notice(Shopp::__('Your password was reset to: ' . $password));
     } else {
         shopp_add_notice(Shopp::__('Your new password has been emailed to you for your records. Your password was reset to: ' . $password));
     }
     unset($_GET['acct']);
     // Auto-login
     $RecoveryCustomer->login();
     // Login the customer
     if (!empty($user_data)) {
         // Log the WordPress user in
         ShoppLogin::wpuser($user_data);
     }
     // Show notice after login in case of failures during login
     shopp_add_notice(Shopp::__('You are now logged into your account.'));
     if (apply_filters('shopp_reset_password_redirect', true)) {
         shopp_add_notice(Shopp::__('If you wish, please use the form below to change your password to one of your choosing.'));
         Shopp::redirect(add_query_arg('profile', '', Shopp::url(false, 'account')));
     }
 }
Пример #17
0
 /**
  * Handles product file download requests
  *
  * @author Jonathan Davis
  * @since 1.1
  *
  * @return void
  **/
 public function download()
 {
     $Shopp = Shopp::object();
     $download = $this->request['shopp_download'];
     $Purchase = false;
     $Purchased = false;
     if (defined('WP_ADMIN')) {
         $forbidden = false;
         $Download = new ProductDownload($download);
     } else {
         $Order = ShoppOrder();
         $accounts = 'none' != shopp_setting('account_system');
         $Download = new ProductDownload();
         $Download->loadby_dkey($download);
         $Purchased = $Download->purchased();
         $Purchase = new ShoppPurchase($Purchased->purchase);
         $Purchase->load_events();
         $name = $Purchased->name . (!empty($Purchased->optionlabel) ? ' (' . $Purchased->optionlabel . ')' : '');
         $forbidden = false;
         // Voided orders
         if ($Purchase->isvoid()) {
             shopp_add_error(Shopp::__('&quot;%s&quot; cannot be downloaded because the order has been cancelled.', $name));
             $forbidden = true;
         }
         // Purchase Completion check
         if (!$Purchase->ispaid() && !SHOPP_PREPAYMENT_DOWNLOADS) {
             shopp_add_error(Shopp::__('&quot;%s&quot; cannot be downloaded because payment has not been received yet.', $name));
             $forbidden = true;
         }
         // If accounts are used and this is not a guest account
         if ($accounts && Shopp::__('Guest') != ShoppCustomer()->type) {
             // User must be logged in when accounts are being used
             if (!ShoppCustomer()->loggedin()) {
                 shopp_add_error(Shopp::__('You must login to download purchases.'));
                 $forbidden = true;
             }
             // Logged in account must be the owner of the purchase
             if (ShoppCustomer()->id != $Purchase->customer) {
                 shopp_add_error(Shopp::__('You are not authorized to download the requested file.'));
                 $forbidden = true;
             }
         }
         // Download limit checking
         if (shopp_setting('download_limit') && $Purchased->downloads + 1 > shopp_setting('download_limit')) {
             shopp_add_error(Shopp::__('&quot;%s&quot; is no longer available for download because the download limit has been reached.', $name));
             $forbidden = true;
         }
         // Download expiration checking
         if (shopp_setting('download_timelimit') && $Purchased->created + shopp_setting('download_timelimit') < current_time('timestamp')) {
             shopp_add_error(Shopp::__('&quot;%s&quot; is no longer available for download because it has expired.', 'Shopp', $name));
             $forbidden = true;
         }
         // IP restriction checks
         if ('ip' == shopp_setting('download_restriction') && !empty($Purchase->ip) && $Purchase->ip != $_SERVER['REMOTE_ADDR']) {
             shopp_add_error(Shopp::__('&quot;%s&quot; cannot be downloaded because your computer could not be verified as the system the file was purchased from.', $name));
             $forbidden = true;
         }
         do_action_ref_array('shopp_download_request', array($Purchased));
     }
     if (apply_filters('shopp_download_forbidden', $forbidden, $Purchased)) {
         Shopp::redirect(add_query_arg('downloads', '', Shopp::url(false, 'account')), true, 303);
     }
     // Send the download
     $download = $Download->download();
     if (is_a($download, 'ShoppError')) {
         // If the result is an error redirect to the account downloads page
         Shopp::redirect(add_query_arg('downloads', '', Shopp::url(false, 'account')), true, 303);
     } else {
         do_action_ref_array('shopp_download_success', array($Purchased, $Purchase, $Download));
         // @deprecated use shopp_download_order_event instead
         shopp_add_order_event($Purchase->id, 'download', array('purchased' => $Purchased->id, 'download' => $Download->id, 'ip' => ShoppShopping()->ip, 'customer' => ShoppCustomer()->id));
     }
     exit;
 }
Пример #18
0
 /**
  * Provides the current account menu item from the account-menu loop
  *
  * @api `shopp('storefront.account-menuitem')`
  * @since 1.2
  *
  * @param string          $result  The output
  * @param array           $options The options
  * @param ShoppStorefront $O       The working object
  * @return string The account menu item entry
  **/
 public static function account_menuitem($result, $options, $O)
 {
     $Storefront = ShoppStorefront();
     $page = current($Storefront->menus);
     if (array_key_exists('url', $options)) {
         return add_query_arg($page->request, '', Shopp::url(false, 'account'));
     }
     if (array_key_exists('action', $options)) {
         return $page->request;
     }
     if (array_key_exists('classes', $options)) {
         $classes = array($page->request);
         if ($Storefront->account['request'] == $page->request) {
             $classes[] = 'current';
         }
         return join(' ', $classes);
     }
     if (array_key_exists('current', $options) && $Storefront->account['request'] == $page->request) {
         return true;
     }
     return $page->label;
 }
Пример #19
0
 /**
  * Responds to AJAX-based cart requests
  *
  * @author Jonathan Davis
  * @since 1.0
  *
  * @return void
  **/
 public function ajax()
 {
     if ('html' == strtolower($_REQUEST['response'])) {
         shopp('cart.sidecart');
         exit;
     }
     $AjaxCart = new StdClass();
     $AjaxCart->url = Shopp::url(false, 'cart');
     $AjaxCart->label = __('Edit shopping cart', 'Shopp');
     $AjaxCart->checkouturl = Shopp::url(false, 'checkout', ShoppOrder()->security());
     $AjaxCart->checkoutLabel = __('Proceed to Checkout', 'Shopp');
     $AjaxCart->imguri = '' != get_option('permalink_structure') ? trailingslashit(Shopp::url('images')) : Shopp::url() . '&siid=';
     $AjaxCart->Totals = json_decode((string) $this->Totals);
     $AjaxCart->Contents = array();
     foreach ($this as $Item) {
         $CartItem = clone $Item;
         unset($CartItem->options);
         $AjaxCart->Contents[] = $CartItem;
     }
     if (isset($this->added)) {
         $AjaxCart->Item = clone $this->added();
     } else {
         $AjaxCart->Item = new ShoppCartItem();
     }
     unset($AjaxCart->Item->options);
     echo json_encode($AjaxCart);
     exit;
 }
Пример #20
0
 /**
  * Safely handles redirect requests to ensure they remain onsite
  *
  * Derived from WP 2.8 wp_safe_redirect
  *
  * @author Mark Jaquith, Ryan Boren
  * @since 1.1
  *
  * @param string $location The URL to redirect to
  * @param int $status (optional) The HTTP status to send to the browser
  * @return void
  **/
 public static function safe_redirect($location, $status = 302)
 {
     // Need to look at the URL the way it will end up in wp_redirect()
     $location = wp_sanitize_redirect($location);
     // browsers will assume 'http' is your protocol, and will obey a redirect to a URL starting with '//'
     if (substr($location, 0, 2) == '//') {
         $location = 'http:' . $location;
     }
     // In php 5 parse_url may fail if the URL query part contains http://, bug #38143
     $test = ($cut = strpos($location, '?')) ? substr($location, 0, $cut) : $location;
     $lp = parse_url($test);
     $wpp = parse_url(get_option('home'));
     $allowed_hosts = (array) apply_filters('allowed_redirect_hosts', array($wpp['host']), isset($lp['host']) ? $lp['host'] : '');
     if (isset($lp['host']) && (!in_array($lp['host'], $allowed_hosts) && $lp['host'] != strtolower($wpp['host']))) {
         $location = Shopp::url(false, 'account');
     }
     self::redirect($location, true, $status);
 }
Пример #21
0
 static function resetpassword($activation)
 {
     if ('none' == shopp_setting('account_system')) {
         return;
     }
     $user_data = false;
     $activation = preg_replace('/[^a-z0-9]/i', '', $activation);
     $errors = array();
     if (empty($activation) || !is_string($activation)) {
         $errors[] = new ShoppError(Shopp::__('Invalid key'));
     }
     $RecoveryCustomer = new ShoppCustomer($activation, 'activation');
     if (empty($RecoveryCustomer->id)) {
         $errors[] = new ShoppError(Shopp::__('Invalid key'));
     }
     if (!empty($errors)) {
         return false;
     }
     // Generate a new random password
     $password = wp_generate_password();
     do_action_ref_array('password_reset', array($RecoveryCustomer, $password));
     $RecoveryCustomer->password = wp_hash_password($password);
     if ('wordpress' == shopp_setting('account_system')) {
         $user_data = get_userdata($RecoveryCustomer->wpuser);
         wp_set_password($password, $user_data->ID);
     }
     $RecoveryCustomer->activation = '';
     $RecoveryCustomer->save();
     $subject = apply_filters('shopp_reset_password_subject', Shopp::__('[%s] New Password', get_option('blogname')));
     $_ = array();
     $_[] = 'From: ' . Shopp::email_from(shopp_setting('merchant_email'), shopp_setting('business_name'));
     $_[] = 'To: ' . $RecoveryCustomer->email;
     $_[] = 'Subject: ' . $subject;
     $_[] = 'Content-type: text/html';
     $_[] = '';
     $_[] = '<p>' . Shopp::__('Your new password for %s:', get_bloginfo('url')) . '</p>';
     $_[] = '';
     $_[] = '<ul>';
     if ($user_data) {
         $_[] = '<li>' . Shopp::__('Login name: %s', $user_data->user_login) . '</li>';
     }
     $_[] = '<li>' . Shopp::__('Password: %s', $password) . '</li>';
     $_[] = '</ul>';
     $_[] = '';
     $_[] = '<p>' . Shopp::__('Click here to login: %s', Shopp::url(false, 'account')) . '</p>';
     $message = apply_filters('shopp_reset_password_message', $_);
     if (!Shopp::email(join("\n", $message))) {
         shopp_add_error(Shopp::__('The e-mail could not be sent.'));
         Shopp::redirect(add_query_arg('acct', 'recover', Shopp::url(false, 'account')));
     } else {
         shopp_add_error(Shopp::__('Check your email address for your new password.'));
     }
     unset($_GET['acct']);
 }
Пример #22
0
 /**
  * Provides markup for a slideshow of cover images for products in the collection
  *
  * @api `shopp('collection.slideshow')`
  * @since 1.1
  *
  * @param string           $result  The output
  * @param array            $options The options
  * @param ShoppCollection $O       The working object
  * @return string The slideshow markup
  **/
 public static function slideshow($result, $options, $O)
 {
     $options['load'] = array('images');
     if (!$O->loaded) {
         $O->load($options);
     }
     if (count($O->products) == 0) {
         return false;
     }
     $defaults = array('fx' => 'fade', 'duration' => 1000, 'delay' => 7000, 'order' => 'normal');
     $imgdefaults = array('setting' => false, 'width' => '580', 'height' => '200', 'size' => false, 'fit' => 'crop', 'sharpen' => false, 'quality' => false, 'bg' => false);
     $options = array_merge($defaults, $imgdefaults, $options);
     extract($options, EXTR_SKIP);
     $href = Shopp::url('' != get_option('permalink_structure') ? trailingslashit('000') : '000', 'images');
     $imgsrc = add_query_string("{$width},{$height}", $href);
     $string = '<ul class="slideshow ' . $fx . '-fx ' . $order . '-order duration-' . $duration . ' delay-' . $delay . '">';
     $string .= '<li class="clear"><img src="' . $imgsrc . '" width="' . $width . '" height="' . $height . '" /></li>';
     foreach ($O->products as $Product) {
         if (empty($Product->images)) {
             continue;
         }
         $string .= '<li><a href="' . $Product->tag('url') . '">';
         $imgoptions = array_filter(array_intersect_key($options, $imgdefaults));
         $string .= shopp($Product, 'get-image', $imgoptions);
         $string .= '</a></li>';
     }
     $string .= '</ul>';
     return $string;
 }
Пример #23
0
 /**
  * Generates markup for an element to remove a cart item
  *
  * By default, the remove element is a plain text link.
  *
  * @api `shopp('cartitem.remove')`
  * @since 1.0
  *
  * @param string        $result  The output
  * @param array         $options The options
  * - **label**: `Remove` The text label shown
  * - **class**: The class attribute specifies one or more class-names for an element
  * - **input**: (button, checkbox) Display the remove element as an input instead of a link.
  * @param ShoppCartItem $O       The working object
  * @return string The remove button markup
  **/
 public static function remove($result, $options, $O)
 {
     $label = __('Remove', 'Shopp');
     if (isset($options['label'])) {
         $label = $options['label'];
     }
     if (isset($options['class'])) {
         $class = ' class="' . $options['class'] . '"';
     } else {
         $class = ' class="remove"';
     }
     if (isset($options['input'])) {
         switch ($options['input']) {
             case "button":
                 $result = '<button type="submit" name="remove[' . $O->_id . ']" value="' . $O->_id . '"' . $class . ' tabindex="">' . $label . '</button>';
                 break;
             case "checkbox":
                 $result = '<input type="checkbox" name="remove[' . $O->_id . ']" value="' . $O->_id . '"' . $class . ' tabindex="" title="' . $label . '"/>';
                 break;
         }
     } else {
         $result = '<a href="' . href_add_query_arg(array('cart' => 'update', 'item' => $O->_id, 'quantity' => 0), Shopp::url(false, 'cart')) . '"' . $class . '>' . $label . '</a>';
     }
     return $result;
 }
Пример #24
0
 /**
  * Provides the product permalink URL
  *
  * @api `shopp('product.url')`
  * @since 1.0
  *
  * @param string       $result  The output
  * @param array        $options The options
  * @param ShoppProduct $O       The working object
  * @return string The URL
  **/
 public static function url($result, $options, $O)
 {
     global $wp_rewrite;
     return Shopp::url($wp_rewrite->using_permalinks() ? $O->slug : array(ShoppProduct::$posttype => $O->slug), false);
 }
Пример #25
0
 /**
  * Provides the full URL for the shopping cart page
  *
  * @api `shopp('cart.url')`
  * @since 1.1
  *
  * @param string    $result  The output
  * @param array     $options The options
  * @param ShoppCart $O       The working object
  * @return string The cart page URL
  */
 public static function url($result, $options, $O)
 {
     return Shopp::url(false, 'cart');
 }
Пример #26
0
 /**
  * Handler for profile updates in the account dashboard
  *
  * @author Jonathan Davis
  * @since 1.1
  *
  * @return boolean|string output based on the account menu request
  **/
 public function profile()
 {
     if (empty($_POST['customer'])) {
         return;
     }
     // Not a valid customer profile update request
     check_admin_referer('shopp_profile_update');
     $defaults = array('phone' => '', 'password' => null, 'confirm-password' => null, 'info' => null, 'billing' => array(), 'shipping' => array());
     $updates = array_merge($defaults, $_POST);
     extract($updates, EXTR_SKIP);
     $phone = preg_replace('/[^\\d\\(\\)\\-+\\. (ext|x)]/', '', $phone);
     // Update this ShoppCustomer model
     $this->updates($updates);
     if (is_array($info)) {
         $this->info = $info;
     }
     // Add info fields
     if ('' != $password . $updates['confirm-password'] && $password == $updates['confirm-password']) {
         $this->password = wp_hash_password($password);
         if ('wordpress' == shopp_setting('account_system') && !empty($this->wpuser)) {
             wp_set_password($password, $this->wpuser);
         }
         $this->_password_change = true;
     } else {
         if (!empty($password)) {
             shopp_add_error(Shopp::__('The passwords you entered do not match. Please re-enter your passwords.'));
         }
         $this->_password_change = false;
     }
     do_action('shopp_customer_update', $this);
     $this->save();
     $this->load_info();
     $addresses = array('billing' => 'Billing', 'shipping' => 'Shipping');
     foreach ($addresses as $type => $Address) {
         if (empty($updates[$type])) {
             continue;
         }
         $Updated = ShoppOrder()->{$Address};
         $Updated->customer = $this->id;
         $Updated->updates($updates[$type]);
         $Updated->save();
     }
     $this->updated(self::PROFILE, true);
     if ($this->_password_change) {
         Shopp::redirect(Shopp::url(false, 'account'));
     }
 }
Пример #27
0
 /**
  * Provide the customer account page URL
  *
  * @api `shopp('customer.url')`
  * @since 1.0
  *
  * @param string        $result  The output
  * @param array         $options The options
  * @param ShoppCustomer $O       The working object
  * @return string The page URL
  **/
 public static function url($result, $options, $O)
 {
     $Shopp = Shopp::object();
     return Shopp::url(array('acct' => null), 'account', $Shopp->Gateways->secure);
 }
Пример #28
0
 /**
  * Validate order data before transaction processing
  *
  * @author Jonathan Davis
  * @since 1.1
  *
  * @return boolean Validity of the order
  **/
 public function isvalid($report = true)
 {
     $Customer = $this->Customer;
     $Shipping = $this->Shipping;
     $Shiprates = $this->Shiprates;
     $Payments = $this->Payments;
     $Cart = $this->Cart;
     $valid = true;
     $errlevel = $report ? SHOPP_TRXN_ERR : SHOPP_DEBUG_ERR;
     shopp_debug('Validating order data for processing');
     if (0 == $Cart->count()) {
         $valid = apply_filters('shopp_ordering_empty_cart', false);
         shopp_add_error(__('There are no items in the cart.', 'Shopp'), $errlevel);
     }
     $stock = true;
     foreach ($Cart as $item) {
         if (!$item->instock()) {
             $valid = apply_filters('shopp_ordering_items_outofstock', false);
             shopp_add_error(sprintf(__('%s does not have sufficient stock to process order.', 'Shopp'), $item->name . (empty($item->option->label) ? '' : '(' . $item->option->label . ')')), $errlevel);
             $stock = false;
         }
     }
     $valid_customer = true;
     if (!$Customer) {
         $valid_customer = apply_filters('shopp_ordering_empty_customer', false);
     }
     // No Customer
     // Always require name and email
     if (empty($Customer->firstname)) {
         $valid_customer = apply_filters('shopp_ordering_empty_firstname', false);
     }
     if (empty($Customer->lastname)) {
         $valid_customer = apply_filters('shopp_ordering_empty_lastname', false);
     }
     if (empty($Customer->email)) {
         $valid_customer = apply_filters('shopp_ordering_empty_email', false);
     }
     if (!$valid_customer) {
         $valid = false;
         shopp_add_error(__('There is not enough customer information to process the order.', 'Shopp'), $errlevel);
     }
     // Check for shipped items but no Shipping information
     $valid_shipping = true;
     if ($Cart->shipped() && shopp_setting_enabled('shipping')) {
         if (empty($Shipping->address)) {
             $valid_shipping = apply_filters('shopp_ordering_empty_shipping_address', false);
         }
         if (empty($Shipping->country)) {
             $valid_shipping = apply_filters('shopp_ordering_empty_shipping_country', false);
         }
         if (empty($Shipping->postcode)) {
             $valid_shipping = apply_filters('shopp_ordering_empty_shipping_postcode', false);
         }
         if ($Shiprates->count() == 0 && !$Shiprates->free()) {
             $valid = apply_filters('shopp_ordering_no_shipping_costs', false);
             $message = __('The order cannot be processed. No shipping is available to the address you provided. Please return to %scheckout%s and try again.', 'Shopp');
             if ($Shiprates->realtime()) {
                 $message = __('The order cannot be processed. The shipping rate service did not provide rates because of a problem and no other shipping is available to the address you provided. Please return to %scheckout%s and try again or contact the store administrator.', 'Shopp');
             }
             if (!$valid) {
                 shopp_add_error(sprintf($message, '<a href="' . Shopp::url(false, 'checkout', $this->security()) . '">', '</a>'), $errlevel);
             }
         }
     }
     if (!$valid_shipping) {
         $valid = false;
         shopp_add_error(__('The shipping address information is incomplete. The order cannot be processed.', 'Shopp'), $errlevel);
     }
     // Alert when no gateway is configured (and the order is not free)
     if ($Payments->count() == 0 && $Cart->total() > 0) {
         $valid = false;
         shopp_add_error(Lookup::errors('gateway', 'nogateways'), $errlevel);
     }
     return $valid;
 }
Пример #29
0
 public static function process()
 {
     // We have to avoid truthiness, hence the strange logic expression
     if (true !== apply_filters('shopp_validate_registration', true)) {
         return;
     }
     $Customer = ShoppOrder()->Customer;
     do_action('shopp_customer_registration', $Customer);
     if ($Customer->session(ShoppCustomer::GUEST)) {
         $Customer->type = __('Guest', 'Shopp');
         // No cuts
         $Customer->wpuser = 0;
         // No buts
         unset($Customer->password);
         // No coconuts
     } else {
         // WordPress account integration used, customer has no wp user
         if ('wordpress' == shopp_setting('account_system') && empty($Customer->wpuser)) {
             if ($wpuser = get_current_user_id()) {
                 $Customer->wpuser = $wpuser;
             } else {
                 $Customer->create_wpuser();
             }
             // not logged in, create new account
         }
         if (!$Customer->exists(true)) {
             $Customer->id = false;
             shopp_debug('Creating new Shopp customer record');
             if (empty($Customer->password)) {
                 $Customer->password = wp_generate_password(12, true);
             }
             if ('shopp' == shopp_setting('account_system')) {
                 $Customer->notification();
             }
             $Customer->password = wp_hash_password($Customer->password);
             if (isset($Customer->passhash)) {
                 $Customer->password = $Customer->passhash;
             }
         } else {
             unset($Customer->password);
         }
         // Existing customer, do not overwrite password field!
     }
     // New customer, save hashed password
     $Customer->save();
     $Customer->password = '';
     // Update billing and shipping addresses
     $addresses = array('Billing', 'Shipping');
     foreach ($addresses as $Address) {
         if (empty(ShoppOrder()->{$Address}->address)) {
             continue;
         }
         $Address = ShoppOrder()->{$Address};
         $Address->customer = $Customer->id;
         $Address->save();
     }
     do_action('shopp_customer_registered', $Customer);
     // Auto-login
     $Customer->login();
     // Login the customer
     if (!empty($Customer->wpuser)) {
         // Log the WordPress user in
         ShoppLogin::wpuser(get_user_by('id', $Customer->wpuser));
     }
     if (apply_filters('shopp_registration_redirect', false)) {
         Shopp::redirect(Shopp::url(false, 'account'));
     }
 }
Пример #30
0
 /**
  * Bounce the browser to the secure unlock request
  *
  * The redirect uses HTTP 307 to encourage browsers to resubmit
  * their POST data to the redirected URL.
  *
  * @since 1.3.6
  *
  * @return void
  */
 public function bouncer()
 {
     $this->data = false;
     // Prevent saving the session
     $https = Shopp::url(array('unlock' => Shopp::raw_request_url()), 'checkout', true);
     Shopp::redirect($https, true, 307);
 }