Ejemplo n.º 1
0
 public function download($dkey = false)
 {
     $found = $this->found();
     if (!$found) {
         return shopp_add_error(Shopp::__('Download failed. "%s" could not be found.', $this->name), 'false');
     }
     add_action('shopp_download_success', array($this, 'downloaded'));
     // send immediately if the storage engine is redirecting
     if (isset($found['redirect'])) {
         $this->send();
         exit;
     }
     // Close the session in case of long download
     @session_write_close();
     // Don't want interference from the server
     if (function_exists('apache_setenv')) {
         @apache_setenv('no-gzip', 1);
     }
     @ini_set('zlib.output_compression', 0);
     set_time_limit(0);
     // Don't timeout on long downloads
     // Use HTTP/1.0 Expires to support bad browsers (trivia: timestamp used is the Shopp 1.0 release date)
     header('Expires: ' . date('D, d M Y H:i:s O', 1230648947));
     header('Cache-Control: maxage=0, no-cache, must-revalidate');
     header('Content-type: application/octet-stream');
     header("Content-Transfer-Encoding: binary");
     header('Content-Disposition: attachment; filename="' . $this->name . '"');
     header('Content-Description: Delivered by ' . ShoppVersion::agent());
     ignore_user_abort(true);
     if (ob_get_length() !== false) {
         while (@ob_end_flush()) {
         }
     }
     // Clear all open output buffers
     $this->send();
     // Send the file data using the storage engine
     flush();
     // Flush output to browser (to poll for connection)
     if (connection_aborted()) {
         return shopp_add_error(Shopp::__('Connection broken. Download attempt failed.'), SHOPP_COMM_ERR);
     }
     return true;
 }
Ejemplo n.º 2
0
/**
 * Defines the shopp() 'tag' handler for complete template customization
 *
 * Appropriately routes tag calls to the tag handler for the requested object.
 *
 * @api
 * @since 1.0
 *
 * @param mixed        $context  The object label or Object to get the tag property from
 * @param string       $property The property of the object to get/output
 * @param string|array $options  Custom options for the property result in query form
 *                               (option1=value&option2=value&...) or alternatively as an associative array
 * @return void|bool|string Boolean values or string result or nothing if the string is output
 */
function shopp($context, $property = false, $options = false)
{
    $Object = false;
    $result = false;
    $parameters = array('first', 'second', 'third');
    // Parameter prototype
    $num = func_num_args();
    // Determine number of arguments provided
    $fargs = func_get_args();
    $context = $tag = false;
    // object API to use and tag name
    $options = array();
    // options to pass to API call
    if ($num < 1) {
        // Not enough arguments to do anything, bail
        shopp_add_error(Shopp::__('shopp() theme tag syntax error: no object property specified.'), SHOPP_PHP_ERR);
        return;
    }
    // Grab the arguments (up to 3)
    $args = array_combine(array_slice($parameters, 0, $num), $fargs);
    extract($args);
    if (is_object($first)) {
        // Handle Object instances as first argument
        $Object = $first;
        $context = isset($Object->api) ? $Object->api : strtolower(get_class($Object));
        $tag = strtolower($second);
    } elseif (false !== strpos($first, '.')) {
        // Handle object.tag first argument
        list($context, $tag) = explode('.', strtolower($first));
        if ($num > 1) {
            $options = shopp_parse_options($second);
        }
    } elseif ('' == $context . $tag) {
        // Normal tag handler
        list($context, $tag) = array_map('strtolower', array($first, $second));
    }
    if ($num > 2) {
        $options = shopp_parse_options($third);
    }
    // strip hypens from tag names
    $tag = str_replace('-', '', $tag);
    // strip get prefix from requested tag
    $get = false;
    if ('get' == substr($tag, 0, 3)) {
        $tag = substr($tag, 3);
        $get = true;
    }
    $Object = apply_filters('shopp_themeapi_object', $Object, $context, $tag);
    $Object = apply_filters('shopp_tag_domain', $Object, $context);
    // @deprecated
    if ('hascontext' == $tag) {
        return $Object;
    }
    if (!$Object) {
        shopp_add_error(Shopp::__("The shopp('%s') tag cannot be used in this context because the object responsible for handling it doesn't exist.", $context), SHOPP_PHP_ERR);
    }
    $themeapi = apply_filters('shopp_themeapi_context_name', $context);
    $result = apply_filters('shopp_themeapi_' . strtolower($themeapi . '_' . $tag), $result, $options, $Object);
    // tag specific tag filter
    $result = apply_filters('shopp_tag_' . strtolower($context . '_' . $tag), $result, $options, $Object);
    // @deprecated use shopp_themeapi_{api}_{tag}
    $result = apply_filters('shopp_themeapi_' . strtolower($themeapi), $result, $options, $tag, $Object);
    // global object tag filter
    $result = apply_filters('shopp_themeapi', $result, $options, $tag, $Object);
    $result = apply_filters('shopp_ml_t', $result, $options, $tag, $Object);
    // @deprecated use shopp_themeapi
    // Force boolean result
    if (isset($options['is'])) {
        if (Shopp::str_true($options['is'])) {
            if ($result) {
                return true;
            }
        } else {
            if (false == $result) {
                return true;
            }
        }
        return false;
    }
    // Always return a boolean if the result is boolean
    if (is_bool($result)) {
        return $result;
    }
    if ($get || isset($options['return']) && Shopp::str_true($options['return']) || isset($options['echo']) && !Shopp::str_true($options['echo'])) {
        return $result;
    }
    // Output the result
    if (is_scalar($result)) {
        echo $result;
    } else {
        return $result;
    }
}
Ejemplo n.º 3
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']);
 }
Ejemplo n.º 4
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;
 }
Ejemplo n.º 5
0
 /**
  * Sets the quantity of the line item
  *
  * Sets the quantity only if stock is available or
  * the donation amount to the donation minimum.
  *
  * @author Jonathan Davis
  * @since 1.1
  *
  * @param int $qty The quantity to set the line item to
  * @return void
  **/
 public function quantity($qty = false)
 {
     $current = $this->quantity;
     if (false === $qty) {
         return $current;
     }
     if ($this->type == 'Donation' && Shopp::str_true($this->donation['var'])) {
         if (!(Shopp::str_true($this->donation['min']) && Shopp::floatval($qty) < $this->unitprice)) {
             $this->unitprice = Shopp::floatval($qty, false);
         }
         $this->quantity = 1;
         $qty = 1;
     }
     if (in_array($this->type, array('Membership', 'Subscription')) || 'Download' == $this->type && !shopp_setting_enabled('download_quantity')) {
         return $this->quantity = 1;
     }
     $qty = preg_replace('/[^\\d+]/', '', $qty);
     $this->quantity = (int) $qty;
     if (!$this->instock($qty)) {
         $levels = array($this->option->stock);
         foreach ($this->addons as $addon) {
             // Take into account stock levels of any addons
             if (Shopp::str_true($addon->inventory)) {
                 $levels[] = $addon->stock;
             }
         }
         if ($qty > ($min = min($levels))) {
             if (shopp_setting_enabled('backorders')) {
                 $this->backordered = $qty - $min;
                 shopp_add_error(Shopp::__('&quot;%s&quot; is not available in the requested quantity. %d of the items will be backordered with delayed delivery.', $this->name, $this->backordered));
             } else {
                 shopp_add_error(Shopp::__('&quot;%s&quot; is not available in the requested quantity.', $this->name));
                 if (!$min) {
                     return;
                 }
                 // don't set min to item quantity if no stock
                 $this->quantity = $min;
             }
         }
     }
     $this->qtydelta = $this->quantity - $current;
     if (0 != $this->qtydelta) {
         $this->totals();
     }
 }
Ejemplo n.º 6
0
/**
 * Add a developer debug error message to the Shopp log file
 *
 * @api
 * @since 1.3
 *
 * @param string $message The error message to add
 * @param boolean $backtrace Include the call stack in the logged message
 * @return ShoppError The ShoppError object
 **/
function shopp_debug($message, $backtrace = false)
{
    if (!SHOPP_DEBUG) {
        return false;
    }
    $callstack = false;
    if ($backtrace) {
        $callstack = ' ' . debug_caller();
    }
    return shopp_add_error($message . $callstack, SHOPP_DEBUG_ERR);
}
Ejemplo n.º 7
0
 public function returned()
 {
     if ($this->id() != $_GET['rmtpay']) {
         return;
     }
     // Not our offsite payment
     $request = array_merge(array('merchant_order_id' => false, 'key' => false, 'order_number' => false, 'total' => false, 'credit_card_processed' => false, 'invoice_id' => false, 'pay_method' => false), $_GET);
     extract($request, EXTR_SKIP);
     if (Shopp::str_true($this->settings['verify']) && !$this->verify($key)) {
         shopp_add_error(Shopp::__('The order submitted by 2Checkout could not be verified.'), SHOPP_TRXN_ERR);
         Shopp::redirect(Shopp::url(false, 'checkout'));
     }
     if (empty($merchant_order_id)) {
         shopp_add_error(Shopp::__('The order submitted by 2Checkout did not specify a transaction ID.'), SHOPP_TRXN_ERR);
         Shopp::redirect(Shopp::url(false, 'checkout'));
     }
     $Purchase = ShoppPurchase(new ShoppPurchase((int) $merchant_order_id));
     if (!$Purchase->exists()) {
         shopp_add_error(Shopp::__('The order submitted by 2Checkout did not match any submitted orders.'), SHOPP_TRXN_ERR);
         Shopp::redirect(Shopp::url(false, 'checkout'));
     }
     if ('Y' != $credit_card_processed) {
         shopp_add_order_event($Purchase->id, 'auth-fail', array('amount' => $total, 'error' => 'Declined', 'message' => Shopp::__('The payment was not completed succesfully'), 'gateway' => $this->module));
         shopp_add_error(Shopp::__('The order submitted by 2Checkout did not match any submitted orders.'), SHOPP_TRXN_ERR);
         Shopp::redirect(Shopp::url(false, 'checkout'));
     }
     $this->Order->inprogress = $Purchase->id;
     add_action('shopp_authed_order_event', array(ShoppOrder(), 'notify'));
     add_action('shopp_authed_order_event', array(ShoppOrder(), 'accounts'));
     add_action('shopp_authed_order_event', array(ShoppOrder(), 'success'));
     shopp_add_order_event($Purchase->id, 'authed', array('txnid' => $order_number, 'amount' => (double) $total, 'fees' => false, 'gateway' => $this->module, 'paymethod' => '2Checkout', 'paytype' => $pay_method, 'payid' => $invoice_id, 'capture' => true));
     Shopp::redirect(Shopp::url(false, 'thanks', false));
 }
Ejemplo n.º 8
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')));
     }
 }
Ejemplo n.º 9
0
 /**
  * Sends an email message based on a specified template file
  *
  * Sends an e-mail message in the format of a specified e-mail
  * template file using variable substitution for variables appearing in
  * the template as a bracketed [variable] with data from the
  * provided data array or the super-global $_POST array
  *
  * @author Jonathan Davis
  * @since 1.0
  *
  * @param string $template Email template file path (or a string containing the template itself)
  * @param array $data The data to populate the template with
  * @return boolean True on success, false on failure
  **/
 public static function email($template, array $data = array())
 {
     $debug = defined('SHOPP_DEBUG_EMAIL') && SHOPP_DEBUG_EMAIL;
     $headers = array();
     $to = $subject = $message = '';
     $addrs = array('from', 'sender', 'reply-to', 'to', 'cc', 'bcc');
     $protected = array_merge($addrs, array('subject'));
     if (false == strpos($template, "\n") && file_exists($template)) {
         $templatefile = $template;
         // Include to parse the PHP and Theme API tags
         ob_start();
         ShoppStorefront::intemplate($templatefile);
         include $templatefile;
         ShoppStorefront::intemplate('');
         $template = ob_get_clean();
         if (empty($template)) {
             return shopp_add_error(Shopp::__('Could not open the email template because the file does not exist or is not readable.'), SHOPP_ADMIN_ERR, array('template' => $templatefile));
         }
     }
     // Sanitize line endings
     $template = str_replace(array("\r\n", "\r"), "\n", $template);
     $lines = explode("\n", $template);
     // Collect headers
     while ($line = array_shift($lines)) {
         if (false === strpos($line, ':')) {
             continue;
         }
         // Skip invalid header lines
         list($header, $value) = explode(':', $line, 2);
         $header = strtolower($header);
         if (in_array($header, $protected)) {
             // Protect against header injection
             $value = str_replace(array("\n", "\r"), '', rawurldecode($value));
         }
         if (in_array($header, array('to', 'subject'))) {
             $headers[$header] = trim($value);
         } else {
             $headers[$header] = $line;
         }
     }
     $message = join("\n", $lines);
     // If not already in place, setup default system email filters
     ShoppEmailDefaultFilters::init();
     // Message filters first
     $message = apply_filters('shopp_email_message', $message, $headers);
     $headers = apply_filters('shopp_email_headers', $headers, $message);
     $to = $headers['to'];
     unset($headers['to']);
     $subject = $headers['subject'];
     unset($headers['subject']);
     $sent = wp_mail($to, $subject, $message, $headers);
     do_action('shopp_email_completed');
     if ($debug) {
         shopp_debug("To: " . htmlspecialchars($to) . "\n");
         shopp_debug("Subject: {$subject}\n\n");
         shopp_debug("Headers:\n");
         shopp_debug("\nMessage:\n{$message}\n");
     }
     return $sent;
 }
Ejemplo n.º 10
0
 /**
  * Detects if the maximum number of promotions have been applied
  *
  * @author Jonathan Davis
  * @since 1.3
  *
  * @param ShoppOrderPromo $Promo A promotion object
  * @return boolean True if the max was reached, false otherwise
  **/
 private function maxed(ShoppOrderPromo $Promo)
 {
     $promolimit = (int) shopp_setting('promo_limit');
     // If promotion limit has been reached and the promo has
     // not already applied as a cart discount, cancel the loop
     if ($promolimit && $this->count() + 1 > $promolimit && !$this->exists($Promo->id)) {
         if (!empty($this->request)) {
             shopp_add_error(Shopp::__('No additional codes can be applied.'));
         }
         return true;
     }
     return false;
 }
Ejemplo n.º 11
0
 public static function data($result)
 {
     if (!isset($_POST['data'])) {
         return $result;
     }
     $fields = $_POST['data'];
     if (apply_filters('shopp_clickwrap_required', isset($fields['clickwrap']) && 'agreed' !== $fields['clickwrap'])) {
         return shopp_add_error(Shopp::__('You must agree to the terms of sale.'));
     }
     return $result;
 }
Ejemplo n.º 12
0
 /**
  * Communicates with the Shopp update service server
  *
  * @author Jonathan Davis
  * @since 1.1
  *
  * @param array $request (optional) A list of request variables to send
  * @param array $data (optional) A list of data variables to send
  * @param array $options (optional)
  * @return string The response from the server
  **/
 public static function callhome($request = array(), $data = array(), $options = array())
 {
     $query = http_build_query(array_merge(array('ver' => '1.2'), $request), '', '&');
     $data = http_build_query($data, '', '&');
     $defaults = array('method' => 'POST', 'timeout' => 20, 'redirection' => 7, 'httpversion' => '1.0', 'user-agent' => SHOPP_GATEWAY_USERAGENT . '; ' . get_bloginfo('url'), 'blocking' => true, 'headers' => array(), 'cookies' => array(), 'body' => $data, 'compress' => false, 'decompress' => true, 'sslverify' => false);
     $params = array_merge($defaults, $options);
     $URL = ShoppSupport::HOMEPAGE . "?{$query}";
     // error_log('CALLHOME REQUEST ------------------');
     // error_log($URL);
     // error_log(json_encode($params));
     $connection = new WP_Http();
     $result = $connection->request($URL, $params);
     // error_log(json_encode($result));
     // error_log('-------------- END CALLHOME REQUEST');
     extract($result);
     if (isset($response['code']) && 200 != $response['code']) {
         // Fail, fallback to http instead
         $URL = str_replace('https://', 'http://', $URL);
         $connection = new WP_Http();
         $result = $connection->request($URL, $params);
         extract($result);
     }
     if (is_wp_error($result)) {
         $errors = array();
         foreach ($result->errors as $errname => $msgs) {
             $errors[] = join(' ', $msgs);
         }
         $errors = join(' ', $errors);
         shopp_add_error("Shopp: " . Lookup::errors('callhome', 'fail') . " {$errors} " . Lookup::errors('contact', 'admin') . " (WP_HTTP)", SHOPP_ADMIN_ERR);
         return false;
     } elseif (empty($result) || !isset($result['response'])) {
         shopp_add_error("Shopp: " . Lookup::errors('callhome', 'noresponse'), SHOPP_ADMIN_ERR);
         return false;
     } else {
         extract($result);
     }
     if (isset($response['code']) && 200 != $response['code']) {
         $error = Lookup::errors('callhome', 'http-' . $response['code']);
         if (empty($error)) {
             $error = Lookup::errors('callhome', 'http-unkonwn');
         }
         shopp_add_error("Shopp: {$error}", 'callhome_comm_err', SHOPP_ADMIN_ERR);
         return $body;
     }
     return $body;
 }
Ejemplo n.º 13
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');
 }
Ejemplo n.º 14
0
 /**
  * Handle Shopp login processing
  *
  * @author Jonathan Davis
  * @since 1.0
  *
  * @return void
  **/
 public function process()
 {
     if (ShoppRegistration::submitted()) {
         new ShoppRegistration();
         add_action('shopp_customer_registered', array($this, 'login'));
     }
     if (isset($_REQUEST['acct']) && 'logout' == $_REQUEST['acct'] || isset($_REQUEST['logout'])) {
         // Set the last logged out action to save the session and redirect to remove the logout request
         add_action('shopp_logged_out', array($this, 'redirect'), 100);
         // Trigger the logout
         do_action('shopp_logout');
     }
     if ('wordpress' == shopp_setting('account_system')) {
         // See if the wordpress user is already logged in
         $user = wp_get_current_user();
         // Wordpress user logged in, but Shopp customer isn't
         if (!empty($user->ID) && !$this->Customer->loggedin()) {
             if ($Account = new ShoppCustomer($user->ID, 'wpuser')) {
                 $this->login($Account);
                 $this->Customer->wpuser = $user->ID;
                 return;
             }
         }
     }
     if (!self::submitted()) {
         return false;
     }
     // Prevent checkout form from processing
     remove_all_actions('shopp_process_checkout');
     if (!isset($_POST['account-login']) || empty($_POST['account-login'])) {
         return shopp_add_error(__('You must provide a valid login name or email address to proceed.', 'Shopp'), SHOPP_AUTH_ERR);
     }
     // Add a login redirect as the very last action if a redirect parameter is provided in the request; Props @alansherwood
     if (isset($_REQUEST['redirect'])) {
         add_action('shopp_authed', array($this, 'redirect'), 100);
     }
     $mode = 'loginname';
     if (false !== strpos($_POST['account-login'], '@')) {
         $mode = 'email';
     }
     $this->auth($_POST['account-login'], $_POST['password-login'], $mode);
 }
Ejemplo n.º 15
0
 /**
  * Builds a select query from an array of query fragments
  *
  * @author Jonathan Davis
  * @since 1.2
  *
  * @param array $options The SQL fragments
  * @return string The complete SELECT SQL statement
  **/
 public static function select($options = array())
 {
     $defaults = array('columns' => '*', 'useindex' => '', 'joins' => array(), 'table' => '', 'where' => array(), 'groupby' => false, 'having' => array(), 'limit' => false, 'orderby' => false);
     $options = array_merge($defaults, $options);
     extract($options);
     if (empty($table)) {
         return shopp_add_error('No table specified for SELECT query.', SHOPP_DB_ERR);
     }
     $useindex = empty($useindex) ? '' : "FORCE INDEX({$useindex})";
     $joins = empty($joins) ? '' : "\n\t\t" . join("\n\t\t", $joins);
     $where = empty($where) ? '' : "\n\tWHERE " . join(' AND ', $where);
     $groupby = empty($groupby) ? '' : "GROUP BY {$groupby}";
     $having = empty($having) ? '' : "HAVING " . join(" AND ", $having);
     $orderby = empty($orderby) ? '' : "\n\tORDER BY {$orderby}";
     $limit = empty($limit) ? '' : "\n\tLIMIT {$limit}";
     return "SELECT {$columns}\n\tFROM {$table} {$useindex} {$joins} {$where} {$groupby} {$having} {$orderby} {$limit}";
 }
Ejemplo n.º 16
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'));
     }
 }
Ejemplo n.º 17
0
 public function email($addressee, $address, $subject, array $templates = array())
 {
     global $is_IIS;
     shopp_debug("ShoppPurchase::email(): {$addressee},{$address},{$subject}," . _object_r($templates));
     // Build the e-mail message data
     $email['from'] = Shopp::email_from(shopp_setting('merchant_email'), shopp_setting('business_name'));
     if ($is_IIS) {
         $email['to'] = Shopp::email_to($address);
     } else {
         $email['to'] = Shopp::email_to($address, $addressee);
     }
     $email['subject'] = $subject;
     $email['receipt'] = $this->receipt();
     $email['url'] = get_bloginfo('url');
     $email['sitename'] = get_bloginfo('name');
     $email['orderid'] = $this->id;
     $email = apply_filters('shopp_email_receipt_data', $email);
     $email = apply_filters('shopp_purchase_email_message', $email);
     $this->message = array_merge($this->message, $email);
     // Load and process the template file
     $defaults = array('email.php', 'order.php', 'order.html');
     $emails = array_merge((array) $templates, $defaults);
     $template = Shopp::locate_template($emails);
     if (!file_exists($template)) {
         shopp_add_error(Shopp::__('A purchase notification could not be sent because the template for it does not exist.'), SHOPP_ADMIN_ERR);
         return false;
     }
     // Send the email
     if (Shopp::email($template, $this->message)) {
         shopp_debug('A purchase notification was sent to: ' . $this->message['to']);
         return true;
     }
     shopp_debug('A purchase notification FAILED to be sent to: ' . $this->message['to']);
     return false;
 }
Ejemplo n.º 18
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;
 }
Ejemplo n.º 19
0
 /**
  * Provides a markup widget to lookup an order by order ID and customer email address
  *
  * @api `shopp('customer.order-lookup')`
  * @since 1.0
  *
  * @param string        $result  The output
  * @param array         $options The options
  * @param ShoppCustomer $O       The working object
  * @return string The widget markup
  **/
 public static function order_lookup($result, $options, $O)
 {
     if (!empty($_POST['vieworder']) && !empty($_POST['purchaseid'])) {
         ShoppPurchase(new ShoppPurchase((int) $_POST['purchaseid']));
         if (ShoppPurchase()->exists() && ShoppPurchase()->email == $_POST['email']) {
             ShoppPurchase()->load_purchased();
             ob_start();
             locate_shopp_template(array('receipt.php'), true);
             $content = ob_get_clean();
             return apply_filters('shopp_order_lookup', $content);
         } else {
             shopp_add_error(Shopp::__('No order could be found with that information.'), SHOPP_AUTH_ERR);
         }
     }
     ob_start();
     include SHOPP_ADMIN_PATH . "/orders/account.php";
     $content = ob_get_clean();
     return apply_filters('shopp_order_lookup', $content);
 }
Ejemplo n.º 20
0
 /**
  * Processes payment method selection changes by the shopper
  *
  * @author Jonathan Davis
  * @since 1.3
  *
  * @return void
  **/
 public function request()
 {
     if (!isset($_POST['paymethod'])) {
         return;
     }
     if ('freeorder' == $_POST['paymethod']) {
         return;
     }
     // Ah, ah, ah! Shoppers can't just select free order processing
     $selected = $this->selected($_POST['paymethod']);
     if (!$this->modules($selected->processor)) {
         shopp_add_error(__('The payment method you selected is no longer available. Please choose another.', 'Shopp'));
     }
     if ($selected) {
         $this->userset = true;
     }
     unset($_POST['paymethod']);
     // Prevent unnecessary reprocessing on subsequent calls
 }