?> , 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"); ?> ',
/** * 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; }
?> , 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
/** * 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); } }
/** * 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; }
/** * 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); }
/** * 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'); }
/** * 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())); }
/** * 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'); }
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'); }
/** * 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'); }
/** * 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); }
protected function returnurl() { return add_query_arg('rmtpay', $this->id(), Shopp::url(false, 'thanks')); }
/** * 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'); }
/** * 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)); }
/** * 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'))); } }
/** * 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::__('"%s" 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::__('"%s" 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::__('"%s" 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::__('"%s" 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::__('"%s" 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; }
/** * 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; }
/** * 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; }
/** * 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); }
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']); }
/** * 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; }
/** * 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; }
/** * 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); }
/** * 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'); }
/** * 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')); } }
/** * 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); }
/** * 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; }
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')); } }
/** * 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); }