updated ubercart, faq

This commit is contained in:
Bachir Soussi Chiadmi 2016-11-05 16:50:18 +01:00
parent 3413d81bb8
commit 0bb339fc99
110 changed files with 1382 additions and 641 deletions

View File

@ -4,9 +4,9 @@ dependencies[] = uc_payment
package = Ubercart - payment
core = 7.x
; Information added by Drupal.org packaging script on 2014-10-22
version = "7.x-3.8"
; Information added by Drupal.org packaging script on 2016-07-16
version = "7.x-3.10"
core = "7.x"
project = "ubercart"
datestamp = "1413965350"
datestamp = "1468644909"

View File

@ -9,9 +9,18 @@
* Implements hook_uninstall().
*/
function uc_2checkout_uninstall() {
db_delete('variable')
->condition('name', 'uc_2checkout_%', 'LIKE')
->execute();
// Remove all module variables from the database.
variable_del('uc_2checkout_check');
variable_del('uc_2checkout_checkout_type');
variable_del('uc_2checkout_currency_code');
variable_del('uc_2checkout_demo');
variable_del('uc_2checkout_language');
variable_del('uc_2checkout_notification_url');
variable_del('uc_2checkout_method_title');
variable_del('uc_2checkout_secret_word');
variable_del('uc_2checkout_server_url');
variable_del('uc_2checkout_sid');
}
/**

View File

@ -31,6 +31,11 @@ function uc_2checkout_menu() {
'type' => MENU_CALLBACK,
'file' => 'uc_2checkout.pages.inc',
);
$items['cart/2checkout/notification'] = array(
'page callback' => 'uc_2checkout_process_notification',
'access callback' => TRUE,
'file' => 'uc_2checkout.pages.inc',
);
return $items;
}
@ -143,6 +148,15 @@ function uc_payment_method_2checkout($op, &$order, $form = NULL, &$form_state =
),
'#default_value' => variable_get('uc_2checkout_language', 'en'),
);
$form['uc_2checkout_currency_code'] = array(
'#type' => 'select',
'#title' => t('Currency for the sale'),
'#options' => array(
'' => t('Auto detected by 2CO'),
'USD', 'EUR', 'ARS', 'AUD', 'BRL', 'GBP', 'CAD', 'DKK', 'HKD', 'INR', 'ILS', 'JPY', 'LTL', 'MYR', 'MXN', 'NZD', 'NOK', 'PHP', 'RON', 'RUB', 'SGD', 'ZAR', 'SEK', 'CHF', 'TRY', 'AED'
),
'#default_value' => variable_get('uc_2checkout_currency_code', ''),
);
$form['uc_2checkout_check'] = array(
'#type' => 'checkbox',
'#title' => t('Allow customers to choose to pay by credit card or online check.'),
@ -154,14 +168,20 @@ function uc_payment_method_2checkout($op, &$order, $form = NULL, &$form_state =
'#default_value' => variable_get('uc_2checkout_method_title', t('Credit card on a secure server:')),
);
$form['uc_2checkout_checkout_type'] = array(
'#type' => 'select',
'#title' => t('2Checkout.com checkout type'),
'#description' => t('Single page checkout only works for stores selling intangible products using credit card payments.'),
'#type' => 'radios',
'#title' => t('Checkout type'),
'#options' => array(
'multi' => t('Multi-page checkout'),
'single' => t('Single page checkout'),
'dynamic' => t('Dynamic checkout (user is redirected to 2CO)'),
'direct' => t('Direct checkout (payment page opens in iframe popup)'),
),
'#default_value' => variable_get('uc_2checkout_checkout_type', 'multi'),
'#default_value' => variable_get('uc_2checkout_checkout_type', 'dynamic'),
);
$form['uc_2checkout_notification_url'] = array(
'#type' => 'textfield',
'#title' => t('Instant notification settings URL'),
'#description' => t('Pass this URL to the <a href="@help_url">instant notification settings</a> parameter in your 2Checkout account. This way, any refunds or failed fraud reviews will automatically cancel the Ubercart order.', array('@help_url' => 'https://www.2checkout.com/static/va/documentation/INS/index.html')),
'#default_value' => url('cart/2checkout/notification', array('absolute' => TRUE)),
'#attributes' => array('readonly' => 'readonly'),
);
return $form;
}
@ -178,14 +198,7 @@ function uc_2checkout_form($form, &$form_state, $order) {
$data = array(
'sid' => variable_get('uc_2checkout_sid', ''),
'total' => uc_currency_format($order->order_total, FALSE, FALSE, '.'),
'cart_order_id' => $order->order_id,
'demo' => variable_get('uc_2checkout_demo', TRUE) ? 'Y' : 'N',
'fixed' => 'Y',
'lang' => variable_get('uc_2checkout_language', 'en'),
'x_receipt_link_url' => url('cart/2checkout/complete/' . uc_cart_get_id(), array('absolute' => TRUE)),
'merchant_order_id' => $order->order_id,
'pay_method' => isset($_SESSION['pay_method']) ? $_SESSION['pay_method'] : 'CC',
'mode' => '2CO',
'card_holder_name' => drupal_substr($order->billing_first_name . ' ' . $order->billing_last_name, 0, 128),
'street_address' => drupal_substr($order->billing_street1, 0, 64),
'street_address2' => drupal_substr($order->billing_street2, 0, 64),
@ -195,19 +208,34 @@ function uc_2checkout_form($form, &$form_state, $order) {
'country' => $country[0]['country_iso_code_3'],
'email' => drupal_substr($order->primary_email, 0, 64),
'phone' => drupal_substr($order->billing_phone, 0, 16),
'id_type' => 1,
'purchase_step' => 'payment-method',
'demo' => variable_get('uc_2checkout_demo', TRUE) ? 'Y' : 'N',
'lang' => variable_get('uc_2checkout_language', 'en'),
'merchant_order_id' => $order->order_id,
'pay_method' => 'CC',
'x_receipt_link_url' => url('cart/2checkout/complete/' . uc_cart_get_id(), array('absolute' => TRUE)),
'total' => uc_currency_format($order->order_total, FALSE, FALSE, '.'),
'cart_order_id' => $order->order_id,
);
if ($currency_code = variable_get('uc_2checkout_currency_code', '')) {
$data['currency_code'] = $currency_code;
}
$i = 0;
foreach ($order->products as $product) {
$i++;
$data['c_prod_' . $i] = $product->model . ',' . $product->qty;
$data['c_name_' . $i] = $product->title;
$data['c_description_' . $i] = '';
$data['c_price_' . $i] = uc_currency_format($product->price, FALSE, FALSE, '.');
$data['li_' . $i . '_name'] = $product->title;
$data['li_' . $i . '_price'] = uc_currency_format($product->price, FALSE, FALSE, '.');
}
$form['#action'] = _uc_2checkout_post_url(variable_get('uc_2checkout_checkout_type', 'multi'));
if (variable_get('uc_2checkout_checkout_type', 'dynamic') == 'direct') {
$form['#suffix'] = '<script src="https://www.2checkout.com/static/checkout/javascript/direct.min.js"></script>';
}
$form['#action'] = variable_get('uc_2checkout_server_url', 'https://www.2checkout.com/checkout/purchase');
foreach ($data as $name => $value) {
$form[$name] = array('#type' => 'hidden', '#value' => $value);
@ -221,16 +249,3 @@ function uc_2checkout_form($form, &$form_state, $order) {
return $form;
}
/**
* Helper function to obtain 2Checkout URL for a transaction.
*/
function _uc_2checkout_post_url($type) {
switch ($type) {
case 'single':
return 'https://www.2checkout.com/checkout/spurchase';
case 'multi':
default:
return 'https://www.2checkout.com/2co/buyer/purchase';
}
}

View File

@ -2,21 +2,20 @@
/**
* @file
* 2checkout menu items.
* 2Checkout menu items.
*/
/**
* Finalizes 2checkout transaction.
* Finalizes 2Checkout transaction.
*/
function uc_2checkout_complete($cart_id = 0) {
watchdog('2Checkout', 'Receiving new order notification for order !order_id.', array('!order_id' => check_plain($_REQUEST['merchant_order_id'])));
watchdog('uc_2checkout', 'Receiving new order notification for order !order_id.', array('!order_id' => check_plain($_REQUEST['merchant_order_id'])));
$order = uc_order_load($_REQUEST['merchant_order_id']);
if ($order === FALSE || uc_order_status_data($order->order_status, 'state') != 'in_checkout') {
if ($order === FALSE) {
return t('An error has occurred during payment. Please contact us to ensure your order has submitted.');
}
$key = $_REQUEST['key'];
$order_number = variable_get('uc_2checkout_demo', TRUE) ? 1 : $_REQUEST['order_number'];
$valid = md5(variable_get('uc_2checkout_secret_word', 'tango') . $_REQUEST['sid'] . $order_number . $_REQUEST['total']);
@ -26,7 +25,7 @@ function uc_2checkout_complete($cart_id = 0) {
}
if ($_REQUEST['demo'] == 'Y' xor variable_get('uc_2checkout_demo', TRUE)) {
watchdog('uc_2checkout', 'The 2checkout payment for order <a href="@order_url">@order_id</a> demo flag was set to %flag, but the module is set to %mode mode.', array(
watchdog('uc_2checkout', 'The 2Checkout payment for order <a href="@order_url">@order_id</a> demo flag was set to %flag, but the module is set to %mode mode.', array(
'@order_url' => url('admin/store/orders/' . $order->order_id),
'@order_id' => $order->order_id,
'%flag' => $_REQUEST['demo'] == 'Y' ? 'Y' : 'N',
@ -63,7 +62,7 @@ function uc_2checkout_complete($cart_id = 0) {
if ($_REQUEST['credit_card_processed'] == 'Y' && is_numeric($_REQUEST['total'])) {
$comment = t('Paid by !type, 2Checkout.com order #!order.', array('!type' => $_REQUEST['pay_method'] == 'CC' ? t('credit card') : t('echeck'), '!order' => check_plain($_REQUEST['order_number'])));
uc_payment_enter($order->order_id, '2checkout', $_REQUEST['total'], 0, NULL, $comment);
uc_payment_enter($order->order_id, '2Checkout', $_REQUEST['total'], 0, NULL, $comment);
}
else {
drupal_set_message(t('Your order will be processed as soon as your payment clears at 2Checkout.com.'));
@ -86,3 +85,42 @@ function uc_2checkout_complete($cart_id = 0) {
return $build;
}
/**
* React on status changes from 2CO.
*/
function uc_2checkout_process_notification() {
$values = $_POST;
watchdog('uc_2checkout', 'Received 2Checkout notification with following data: !data', array('!data' => print_r($values, TRUE)));
if (!empty($values['message_type']) && !empty($values['md5_hash']) && !empty($values['message_id'])) {
// Validate the hash.
$secret_word = variable_get('uc_2checkout_secret_word', 'tango');
$sid = variable_get('uc_2checkout_sid', '');
$twocheckout_order_id = $values['sale_id'];
$twocheckout_invoice_id = $values['invoice_id'];
$hash = strtoupper(md5($twocheckout_order_id . $sid . $twocheckout_invoice_id . $secret_word));
if ($hash != $values['md5_hash']) {
watchdog('uc_2checkout', '2CO notification #@num had a wrong hash.', array('@num' => $values['message_id']));
die('Hash Incorrect');
}
$order_id = $values['vendor_order_id'];
if ($values['message_type'] == 'FRAUD_STATUS_CHANGED') {
switch ($values['fraud_status']) {
case 'fail':
uc_order_update_status($order_id, uc_order_state_default('canceled'));
uc_order_comment_save($order_id, 0, t('Order have not passed 2Checkout fraud review.'));
die('fraud');
break;
}
}
elseif ($values['message_type'] == 'REFUND_ISSUED') {
uc_order_update_status($order_id, uc_order_state_default('canceled'));
uc_order_comment_save($order_id, 0, t('Order have been refunded through 2Checkout.'));
die('refund');
}
}
die('ok');
}

View File

@ -5,9 +5,9 @@ dependencies[] = uc_credit
package = Ubercart - payment
core = 7.x
; Information added by Drupal.org packaging script on 2014-10-22
version = "7.x-3.8"
; Information added by Drupal.org packaging script on 2016-07-16
version = "7.x-3.10"
core = "7.x"
project = "ubercart"
datestamp = "1413965350"
datestamp = "1468644909"

View File

@ -5,9 +5,9 @@ dependencies[] = uc_credit
package = Ubercart - payment
core = 7.x
; Information added by Drupal.org packaging script on 2014-10-22
version = "7.x-3.8"
; Information added by Drupal.org packaging script on 2016-07-16
version = "7.x-3.10"
core = "7.x"
project = "ubercart"
datestamp = "1413965350"
datestamp = "1468644909"

View File

@ -62,7 +62,7 @@ class UbercartCreditCardTestCase extends UbercartTestHelper {
/**
* Implements DrupalWebTestCase::setUp().
*/
public function setUp(array $modules = array()) {
protected function setUp($modules = array(), $permissions = array()) {
$modules += array('uc_payment', 'uc_credit', 'test_gateway');
$permissions = array('administer credit cards', 'process credit cards');
parent::setUp($modules, $permissions);

View File

@ -8,9 +8,9 @@ core = 7.x
; Test cases
files[] = tests/uc_credit.test
; Information added by Drupal.org packaging script on 2014-10-22
version = "7.x-3.8"
; Information added by Drupal.org packaging script on 2016-07-16
version = "7.x-3.10"
core = "7.x"
project = "ubercart"
datestamp = "1413965350"
datestamp = "1468644909"

View File

@ -7,9 +7,9 @@ core = 7.x
; Class definitions
files[] = uc_cybersource.soap.inc
; Information added by Drupal.org packaging script on 2014-10-22
version = "7.x-3.8"
; Information added by Drupal.org packaging script on 2016-07-16
version = "7.x-3.10"
core = "7.x"
project = "ubercart"
datestamp = "1413965350"
datestamp = "1468644909"

View File

@ -6,9 +6,9 @@ dependencies[] = uc_quote
package = Ubercart - payment
core = 7.x
; Information added by Drupal.org packaging script on 2014-10-22
version = "7.x-3.8"
; Information added by Drupal.org packaging script on 2016-07-16
version = "7.x-3.10"
core = "7.x"
project = "ubercart"
datestamp = "1413965350"
datestamp = "1468644909"

View File

@ -18,7 +18,7 @@ class UbercartPaymentPaneTestCase extends UbercartTestHelper {
/**
* Overrides DrupalWebTestCase::setUp().
*/
public function setUp() {
protected function setUp($modules = array(), $permissions = array()) {
parent::setUp(array('uc_payment', 'uc_payment_pack'));
$this->drupalLogin($this->adminUser);
$this->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));

View File

@ -0,0 +1,42 @@
/**
* @file
* Styles for uc_payment module.
*/
.payment-details-cod .form-item {
float: right;
padding-right: inherit;
padding-left: 5px;
}
.payment-details-credit label {
clear: right;
float: right;
}
.payment-details-credit input,
.payment-details-credit select {
float: right;
}
.payment-details-credit .field-suffix {
float: right;
}
img.uc-2checkout-logo {
left: auto;
right: 2.2em;
}
#line-items-div {
float: left;
margin: 0 1em 1em 0;
}
#uc-payment-by-order-form .form-type-item {
float: right;
}
#uc-payment-by-order-form table {
clear: right;
}

View File

@ -107,7 +107,13 @@ function theme_uc_payment_method_table($variables) {
function uc_payment_method_settings_form($form, &$form_state, $method_id) {
$callback = _uc_payment_method_data($method_id, 'callback');
$null = NULL;
$form = $callback('settings', $null, array(), $form_state);
if (function_exists($callback)) {
$form = $callback('settings', $null, array(), $form_state);
}
else {
drupal_not_found();
drupal_exit();
}
return system_settings_form($form);
}

View File

@ -21,8 +21,8 @@
.payment-details-cod .form-item {
display: block;
float: left;
padding-right: 5px;
float: left; /* LTR */
padding-right: 5px; /* LTR */
}
.payment-details-credit .form-item {
@ -30,8 +30,8 @@
}
.payment-details-credit label {
clear: left;
float: left;
clear: left; /* LTR */
float: left; /* LTR */
margin: 2px 0;
padding-top: 5px;
width: 10em;
@ -39,7 +39,7 @@
.payment-details-credit input,
.payment-details-credit select {
float: left;
float: left; /* LTR */
margin: 2px;
}
@ -51,20 +51,20 @@
}
.payment-details-credit .field-suffix {
float: left;
float: left; /* LTR */
margin: 2px;
padding-top: 5px;
}
img.uc-2checkout-logo {
position: relative;
left: 2.2em;
left: 2.2em; /* LTR */
}
#line-items-div {
border: 1px solid #bbb;
float: right;
margin: 0 0 1em 1em;
float: right; /* LTR */
margin: 0 0 1em 1em; /* LTR */
}
#line-items-div table {
@ -81,10 +81,10 @@ img.uc-2checkout-logo {
}
#uc-payment-by-order-form .form-type-item {
float: left;
float: left; /* LTR */
width: 10em;
}
#uc-payment-by-order-form table {
clear: left;
clear: left; /* LTR */
}

View File

@ -10,9 +10,9 @@ files[] = tests/uc_payment.test
configure = admin/store/settings/payment
; Information added by Drupal.org packaging script on 2014-10-22
version = "7.x-3.8"
; Information added by Drupal.org packaging script on 2016-07-16
version = "7.x-3.10"
core = "7.x"
project = "ubercart"
datestamp = "1413965350"
datestamp = "1468644909"

View File

@ -86,14 +86,19 @@ function uc_payment_schema() {
function uc_payment_install() {
$t = get_t();
db_insert('uc_order_statuses')
->fields(array(
db_merge('uc_order_statuses')
->key(array('order_status_id' => 'payment_received'))
->insertFields(array(
'order_status_id' => 'payment_received',
'title' => $t('Payment received'),
'state' => 'payment_received',
'weight' => 10,
'locked' => 1,
))
->updateFields(array(
'state' => 'payment_received',
'locked' => 1,
))
->execute();
}

View File

@ -5,9 +5,9 @@ dependencies[] = uc_payment
package = Ubercart - payment
core = 7.x
; Information added by Drupal.org packaging script on 2014-10-22
version = "7.x-3.8"
; Information added by Drupal.org packaging script on 2016-07-16
version = "7.x-3.10"
core = "7.x"
project = "ubercart"
datestamp = "1413965350"
datestamp = "1468644909"

View File

@ -4,9 +4,9 @@ dependencies[] = uc_payment
package = Ubercart - payment
core = 7.x
; Information added by Drupal.org packaging script on 2014-10-22
version = "7.x-3.8"
; Information added by Drupal.org packaging script on 2016-07-16
version = "7.x-3.10"
core = "7.x"
project = "ubercart"
datestamp = "1413965350"
datestamp = "1468644909"

View File

@ -530,7 +530,7 @@ function uc_payment_method_paypal_ec($op, &$order) {
$form['api'] = array(
'#type' => 'fieldset',
'#title' => t('API credentials'),
'#description' => t('!link for information on obtaining credentials. You need to acquire an API Signature. If you have already requested API credentials, you can review your settings under the API Access section of your PayPal profile.', array('!link' => l(t('Click here'), 'https://www.paypal.com/IntegrationCenter/ic_certificate.html'))),
'#description' => t('!link for information on obtaining credentials. You need to acquire an API Signature. If you have already requested API credentials, you can review your settings under the API Access section of your PayPal profile.', array('!link' => l(t('Click here'), 'https://developer.paypal.com/docs/classic/api/apiCredentials/'))),
'#collapsible' => TRUE,
'#collapsed' => variable_get('uc_paypal_api_username', '') != '',
);

View File

@ -6,9 +6,9 @@ core = 7.x
configure = admin/store/settings/quotes/methods
; Information added by Drupal.org packaging script on 2014-10-22
version = "7.x-3.8"
; Information added by Drupal.org packaging script on 2016-07-16
version = "7.x-3.10"
core = "7.x"
project = "ubercart"
datestamp = "1413965350"
datestamp = "1468644909"

View File

@ -21,7 +21,7 @@ class UbercartQuoteTestCase extends UbercartTestHelper {
/**
* Overrides DrupalWebTestCase::setUp().
*/
function setUp() {
protected function setUp($modules = array(), $permissions = array()) {
$modules = array('rules_admin', 'uc_payment', 'uc_payment_pack', 'uc_quote', 'uc_flatrate');
$permissions = array('administer rules', 'bypass rules access');
parent::setUp($modules, $permissions);

View File

@ -0,0 +1,14 @@
/**
* @file
* Styles for shipping quote cart and checkout panes.
*/
#uc-cart-pane-quotes .form-submit {
margin-left: auto;
margin-right: 16em;
}
.quote-notes {
margin-left: auto;
margin-right: 25px;
}

View File

@ -17,7 +17,7 @@
}
#uc-cart-pane-quotes .form-submit {
margin-left: 16em;
margin-left: 16em; /* LTR */
}
#quote {
@ -36,7 +36,7 @@
}
.quote-notes {
margin-left: 25px;
margin-left: 25px; /* LTR */
}
/**

View File

@ -9,9 +9,9 @@ configure = admin/store/settings/quotes
; Test cases
files[] = tests/uc_quote.test
; Information added by Drupal.org packaging script on 2014-10-22
version = "7.x-3.8"
; Information added by Drupal.org packaging script on 2016-07-16
version = "7.x-3.10"
core = "7.x"
project = "ubercart"
datestamp = "1413965350"
datestamp = "1468644909"

View File

@ -58,15 +58,6 @@ function uc_quote_menu() {
return $items;
}
/**
* Implements hook_init().
*/
function uc_quote_init() {
global $conf;
$conf['i18n_variables'][] = 'uc_quote_err_msg';
$conf['i18n_variables'][] = 'uc_quote_pane_description';
}
/**
* Implements hook_theme().
*/

View File

@ -0,0 +1,40 @@
<?php
/**
* @file
* Variable module hook implementations.
*/
/**
* Implements hook_variable_group_info().
*/
function uc_quote_variable_group_info() {
$groups['uc_quote'] = array(
'title' => t('Ubercart shipping quote settings'),
'access' => 'administer store',
'path' => array('admin/store/settings/quotes'),
);
return $groups;
}
/**
* Implements hook_variable_info().
*/
function uc_quote_variable_info($options) {
$variables['uc_quote_err_msg'] = array(
'type' => 'text',
'title' => t('Shipping quote error message', array(), $options),
'description' => t('The error message shown to a user when a problem is encountered while generating a shipping quote.', array(), $options),
'group' => 'uc_quote',
'default' => t("There were problems getting a shipping quote. Please verify the delivery and product information and try again.\nIf this does not resolve the issue, please call in to complete your order.", array(), $options),
);
$variables['uc_quote_pane_description'] = array(
'type' => 'text',
'title' => t('Shipping quote pane description', array(), $options),
'description' => t('Message to indicate to users that a shipping quote can be updated automatically on address change, or manually by pressing a button.', array(), $options),
'group' => 'uc_quote',
'default' => t('Shipping quotes are generated automatically when you enter your address and may be updated manually with the button below.', array(), $options),
);
return $variables;
}

View File

@ -1096,7 +1096,7 @@ function theme_uc_shipping_shipment_print($variables) {
file_exists($package->label_image->uri)) {
// TODO: Find a way to store these magic numbers specifically for UPS.
list($width, $height) = array(672, 392);
$output .= '<br class="page-break" />' . "\n";;
$output .= '<br class="page-break" />' . "\n";
$output .= theme('image', array(
'path' => $package->label_image->uri,
'attributes' => array('width' => $width, 'height' => $height),

View File

@ -8,9 +8,9 @@ core = 7.x
files[] = views/uc_shipping_handler_field_shipment_id.inc
files[] = views/uc_shipping_handler_field_package_weight.inc
; Information added by Drupal.org packaging script on 2014-10-22
version = "7.x-3.8"
; Information added by Drupal.org packaging script on 2016-07-16
version = "7.x-3.10"
core = "7.x"
project = "ubercart"
datestamp = "1413965350"
datestamp = "1468644909"

View File

@ -6,9 +6,9 @@ core = 7.x
configure = admin/store/settings/quotes/settings/ups
; Information added by Drupal.org packaging script on 2014-10-22
version = "7.x-3.8"
; Information added by Drupal.org packaging script on 2016-07-16
version = "7.x-3.10"
core = "7.x"
project = "ubercart"
datestamp = "1413965350"
datestamp = "1468644909"

View File

@ -54,7 +54,7 @@ function uc_usps_admin_settings($form, &$form_state) {
'#type' => 'checkbox',
'#title' => t('Display USPS "online" rates'),
'#default_value' => variable_get('uc_usps_online_rates', FALSE),
'#description' => t('Show your customer standard USPS rates (default) or discounted "online" rates. Online rates apply only if you, the merchant, pay for and print out postage from the USPS <a href="https://sss-web.usps.com/cns/landing.do">Click-N-Ship</a> web site.'),
'#description' => t('Show your customer standard USPS rates (default) or discounted "online" rates. Online rates apply only if you, the merchant, pay for and print out postage from the USPS <a href="https://cns.usps.com/labelInformation.shtml">Click-N-Ship</a> web site.'),
);
$form['domestic']['uc_usps_env_services'] = array(

View File

@ -6,9 +6,9 @@ core = 7.x
configure = admin/store/settings/quotes/settings/usps
; Information added by Drupal.org packaging script on 2014-10-22
version = "7.x-3.8"
; Information added by Drupal.org packaging script on 2016-07-16
version = "7.x-3.10"
core = "7.x"
project = "ubercart"
datestamp = "1413965350"
datestamp = "1468644909"

View File

@ -6,9 +6,9 @@ core = 7.x
configure = admin/store/settings/quotes/methods
; Information added by Drupal.org packaging script on 2014-10-22
version = "7.x-3.8"
; Information added by Drupal.org packaging script on 2016-07-16
version = "7.x-3.10"
core = "7.x"
project = "ubercart"
datestamp = "1413965350"
datestamp = "1468644909"

View File

@ -4,9 +4,9 @@ dependencies[] = uc_cart
package = Ubercart - extra
core = 7.x
; Information added by Drupal.org packaging script on 2014-10-22
version = "7.x-3.8"
; Information added by Drupal.org packaging script on 2016-07-16
version = "7.x-3.10"
core = "7.x"
project = "ubercart"
datestamp = "1413965350"
datestamp = "1468644909"

View File

@ -21,7 +21,7 @@ class UbercartAttributeTestCase extends UbercartTestHelper {
/**
* Overrides DrupalWebTestCase::setUp().
*/
function setUp() {
protected function setUp($modules = array(), $permissions = array()) {
parent::setUp(array('uc_attribute'), array('administer attributes', 'administer product attributes', 'administer product options'));
$this->drupalLogin($this->adminUser);
}
@ -316,8 +316,14 @@ class UbercartAttributeTestCase extends UbercartTestHelper {
$edit = (array) self::createAttribute(array(), FALSE);
$this->drupalPost('admin/store/products/attributes/add', $edit, t('Submit'));
$this->assertText('Options for ' . $edit['name']);
$this->assertText('No options for this attribute have been added yet.');
if ($edit['display'] !=0) {
// We redirect to add options page ONLY for non-textfield attributes.
$this->assertText('Options for ' . $edit['name']);
$this->assertText('No options for this attribute have been added yet.');
}
else {
// For textfield attributes we redirect to attribute list.
}
$this->drupalGet('admin/store/products/attributes');
$this->assertRaw('<td class="active">' . $edit['name'] . '</td>', t('Verify name field.'));
@ -325,7 +331,7 @@ class UbercartAttributeTestCase extends UbercartTestHelper {
$this->assertRaw('<td>' . ($edit['required'] ? t('Yes') : t('No')) . '</td>', t('Verify required field.'));
$this->assertRaw('<td>' . $edit['ordering'] . '</td>', t('Verify ordering field.'));
$types = _uc_attribute_display_types();
$this->assertRaw('<td>' . $types[$edit['display']] . '</td>', t('Verify ordering field.'));
$this->assertRaw('<td>' . $types[$edit['display']] . '</td>', t('Verify display field.'));
$aid = db_query("SELECT aid FROM {uc_attributes} WHERE name = :name", array(':name' => $edit['name']))->fetchField();
$this->assertTrue($aid, t('Attribute was created.'));

View File

@ -18,7 +18,7 @@ class UbercartAttributeCheckoutTestCase extends UbercartTestHelper {
/**
* Overrides DrupalWebTestCase::setUp().
*/
function setUp() {
protected function setUp($modules = array(), $permissions = array()) {
parent::setUp(array('uc_attribute', 'uc_cart'), array('administer attributes', 'administer product attributes', 'administer product options'));
$this->drupalLogin($this->adminUser);
}

View File

@ -95,6 +95,7 @@ function uc_attribute_form($form, &$form_state, $attribute = NULL) {
'#title' => t('Label'),
'#description' => t("Enter a label that customers will see instead of the attribute name. Use &lt;none&gt; if you don't want a title to appear at all."),
'#default_value' => $label,
'#maxlength' => 255,
);
$form['description'] = array(
'#type' => 'textfield',
@ -146,7 +147,14 @@ function uc_attribute_form_submit($form, &$form_state) {
}
else {
drupal_write_record('uc_attributes', $form_state['values']);
$form_state['redirect'] = 'admin/store/products/attributes/' . $form_state['values']['aid'] . '/options';
if ($form_state['values']['display'] == 0) {
// No options needed/allowed for Textfield display type.
$form_state['redirect'] = 'admin/store/products/attributes';
}
else {
// All other display types we redirect to add options.
$form_state['redirect'] = 'admin/store/products/attributes/' . $form_state['values']['aid'] . '/options';
}
}
}
@ -584,6 +592,7 @@ function uc_object_attributes_form($form, &$form_state, $object, $type, $view =
'#title_display' => 'invisible',
'#default_value' => empty($attribute->label) ? $attribute->name : $attribute->label,
'#size' => 20,
'#maxlength' => 255,
),
'option' => array(
'#markup' => $option ? (check_plain($option->name) . ' (' . theme('uc_price', array('price' => $option->price)) . ')' ) : t('n/a'),

View File

@ -8,9 +8,9 @@ core = 7.x
files[] = tests/uc_attribute.test
files[] = tests/uc_attribute_checkout.test
; Information added by Drupal.org packaging script on 2014-10-22
version = "7.x-3.8"
; Information added by Drupal.org packaging script on 2016-07-16
version = "7.x-3.10"
core = "7.x"
project = "ubercart"
datestamp = "1413965350"
datestamp = "1468644909"

View File

@ -1280,6 +1280,12 @@ function _uc_attribute_alter_form($id, &$product, $use_ajax) {
$attributes = $product->attributes;
$priced_attributes = uc_attribute_priced_attributes($nid);
// At this point, $product->data is the node author's userdata
// as a string, as populated by user_node_load(). We don't need that.
if (empty($product->data) || !is_array($product->data)) {
$product->data = array();
}
// If the form is being built for the first time, populate attributes with their default values.
if (!isset($product->data['attributes'])) {
$values = array();
@ -1302,10 +1308,6 @@ function _uc_attribute_alter_form($id, &$product, $use_ajax) {
}
}
if (empty($product->data) || !is_array($product->data)) {
$product->data = array();
}
// Initialize the form element.
$form_attributes = array(
'#theme' => 'uc_attribute_add_to_cart',

View File

@ -13,6 +13,9 @@
* - option: The option name.
* - price: The price total or adjustment, if any.
*
* @return string
* The HTML output.
*
* @see _uc_attribute_alter_form()
* @ingroup themeable
*/

View File

@ -21,7 +21,7 @@ class UbercartCartCheckoutTestCase extends UbercartTestHelper {
/**
* Overrides DrupalWebTestCase::setUp().
*/
function setUp() {
protected function setUp($modules = array(), $permissions = array()) {
$modules = array('uc_payment', 'uc_payment_pack', 'uc_roles');
$permissions = array('administer permissions');
parent::setUp($modules, $permissions);

View File

@ -3,9 +3,9 @@ core = 7.x
dependencies[] = uc_cart
hidden = TRUE
; Information added by Drupal.org packaging script on 2014-10-22
version = "7.x-3.8"
; Information added by Drupal.org packaging script on 2016-07-16
version = "7.x-3.10"
core = "7.x"
project = "ubercart"
datestamp = "1413965350"
datestamp = "1468644909"

View File

@ -0,0 +1,76 @@
/**
* @file
* RTL Styles for uc_cart module.
*/
.order-review-table .title-col {
padding-left: inherit;
padding-right: 3em;
text-align: left;
}
.order-review-table .data-col {
padding-right: inherit;
padding-left: 3em;
}
.order-review-table .review-button-row td {
text-align: left;
}
.next-button {
text-align: left;
}
#uc-cart-view-form img {
padding-right: inherit;
padding-left: .8em;
float: right;
}
.address-book-icon {
margin-left: inherit;
margin-right: 2px;
}
/**
* CSS rules for the cart form at /cart.
*/
#uc-cart-view-form .form-actions {
text-align: left;
}
#uc-cart-view-form .form-actions a {
float: right;
}
#uc-cart-view-form #edit-continue-shopping {
float: right;
margin-left: inherit;
margin-right: .5em;
}
.uc-cart-checkout-button {
float: left;
clear: left;
}
/**
* CSS rules for the cart review table.
*/
td.price {
text-align: left;
}
td.subtotal {
text-align: left;
}
/**
* CSS rules for the bottom of the checkout form at /cart/checkout.
*/
.uc-cart-checkout-form .form-actions {
text-align: left;
}

View File

@ -27,13 +27,13 @@
.order-review-table .title-col {
font-weight: bold;
padding-left: 3em;
text-align: right;
padding-left: 3em; /* LTR */
text-align: right; /* LTR */
white-space: nowrap;
}
.order-review-table .data-col {
padding-right: 3em;
padding-right: 3em; /* LTR */
}
.order-review-table .row-border-top {
@ -51,7 +51,7 @@
.order-review-table .review-button-row td {
padding-top: 1em;
text-align: right;
text-align: right; /* LTR */
}
.order-review-table .review-button-row div,
@ -63,7 +63,7 @@
.next-button {
margin-top: 1em;
text-align: right;
text-align: right; /* LTR */
}
#uc-cart-view-form table {
@ -75,13 +75,13 @@
}
#uc-cart-view-form img {
padding-right: .8em;
float: left;
padding-right: .8em; /* LTR */
float: left; /* LTR */
}
.address-book-icon {
position: relative;
margin-left: 2px;
margin-left: 2px; /* LTR */
top: 2px;
}
@ -103,17 +103,17 @@
#uc-cart-view-form .form-actions {
margin-top: 0;
text-align: right;
text-align: right; /* LTR */
}
#uc-cart-view-form .form-actions a {
float: left;
float: left; /* LTR */
margin: .5em;
}
#uc-cart-view-form #edit-continue-shopping {
float: left;
margin-left: .5em;
float: left; /* LTR */
margin-left: .5em; /* LTR */
}
#uc-cart-view-form .form-actions input {
@ -121,8 +121,8 @@
}
.uc-cart-checkout-button {
float: right;
clear: right;
float: right; /* LTR */
clear: right; /* LTR */
}
.uc-cart-checkout-button-separator {
@ -138,7 +138,7 @@ td.qty {
}
td.price {
text-align: right;
text-align: right; /* LTR */
white-space: nowrap;
}
@ -147,7 +147,7 @@ td.products {
}
td.subtotal {
text-align: right;
text-align: right; /* LTR */
}
#subtotal-title {
@ -170,5 +170,5 @@ td.subtotal {
* CSS rules for the bottom of the checkout form at /cart/checkout.
*/
.uc-cart-checkout-form .form-actions {
text-align: right;
text-align: right; /* LTR */
}

View File

@ -16,9 +16,9 @@ files[] = uc_cart.controller.inc
configure = admin/store/settings/cart
; Information added by Drupal.org packaging script on 2014-10-22
version = "7.x-3.8"
; Information added by Drupal.org packaging script on 2016-07-16
version = "7.x-3.10"
core = "7.x"
project = "ubercart"
datestamp = "1413965350"
datestamp = "1468644909"

View File

@ -7,8 +7,9 @@ Drupal.behaviors.ucCart = {
attach: function(context, settings) {
// Add a throbber to the submit order button on the review order form.
jQuery('form#uc-cart-checkout-review-form input#edit-submit:not(.ucSubmitOrderThrobber-processed)', context).addClass('ucSubmitOrderThrobber-processed').click(function() {
jQuery(this).clone().insertAfter(this).attr('disabled', true).after('<span class="ubercart-throbber">&nbsp;&nbsp;&nbsp;&nbsp;</span>').end().hide();
jQuery('#uc-cart-checkout-review-form #edit-back').attr('disabled', true);
jQuery(this).clone().insertAfter(this).after('<span class="ubercart-throbber">&nbsp;&nbsp;&nbsp;&nbsp;</span>')[0].disabled = true;
jQuery(this).hide();
jQuery('#uc-cart-checkout-review-form #edit-back')[0].disabled = true;
});
}
}

View File

@ -18,6 +18,9 @@
* - collapsed: TRUE or FALSE indicating whether or not the cart block is
* collapsed.
*
* @return string
* The HTML output.
*
* @ingroup themeable
*/
function theme_uc_cart_block_title($variables) {

View File

@ -0,0 +1,55 @@
/**
* @file
* Styles for the uc_cart module cart block.
*/
.cart-block-icon-full,
.cart-block-icon-empty {
float: right;
margin: 2px 0 0 6px;
}
/**
* Styles for the cart block title and toggle.
*/
.cart-block-title-bar {
padding-right: inherit;
padding-left: 20px;
}
.cart-block-arrow {
right: auto;
left: 0;
}
/**
* Styles for the cart block contents and summary.
*/
.cart-block-item-price {
text-align: left;
}
.cart-block-item-desc ul.product-description {
padding: 0 1em 0.25em 0;
}
.cart-block-summary-total {
text-align: left;
}
.cart-block-summary-links td {
text-align: left;
}
.cart-block-summary-links ul.links li {
border-right: 0 none;
border-left: solid 1px;
padding: 0 .75em 0 1em;
}
.cart-block-summary-links ul.links li.last {
border-left: none;
padding-left: 0;
padding-right: inherit;
}

View File

@ -2,11 +2,12 @@
* @file
* Styles for the uc_cart module cart block.
*/
.cart-block-icon-full,
.cart-block-icon-empty {
float: left;
float: left; /* LTR */
height: 16px;
margin: 2px 6px 0 0;
margin: 2px 6px 0 0; /* LTR */
width: 16px;
}
@ -23,7 +24,7 @@
*/
.cart-block-title-bar {
display: inline;
padding-right: 20px;
padding-right: 20px; /* LTR */
position: relative;
}
@ -35,7 +36,7 @@
background: transparent url(images/bullet-arrow-up.gif) no-repeat center center;
height: 5px;
position: absolute;
right: 0;
right: 0; /* LTR */
top: 9px;
width: 10px;
}
@ -89,13 +90,13 @@
}
.cart-block-item-price {
text-align: right;
text-align: right; /* LTR */
white-space: nowrap;
}
.cart-block-item-desc ul.product-description {
margin: 0;
padding: 0 0 0.25em 1em;
padding: 0 0 0.25em 1em; /* LTR */
}
.cart-block-item-desc .product-description li {
@ -128,7 +129,7 @@
}
.cart-block-summary-total {
text-align: right;
text-align: right; /* LTR */
white-space: nowrap;
width: auto;
}
@ -139,16 +140,16 @@
}
.cart-block-summary-links td {
text-align: right;
text-align: right; /* LTR */
}
.cart-block-summary-links ul.links li {
border-right: solid 1px;
border-right: solid 1px; /* LTR */
display: inline;
padding: 0 1em 0 .75em;
padding: 0 1em 0 .75em; /* LTR */
}
.cart-block-summary-links ul.links li.last {
border-right: none;
padding-right: 0;
border-right: none; /* LTR */
padding-right: 0; /* LTR */
}

View File

@ -555,5 +555,5 @@ function theme_uc_checkout_pane_cart_review($variables) {
);
}
return theme('table', array('rows' => $rows, 'attributes' => array('class' => array('cart-review'))));;
return theme('table', array('rows' => $rows, 'attributes' => array('class' => array('cart-review'))));
}

View File

@ -21,7 +21,7 @@ class UbercartCartLinksTestCase extends UbercartTestHelper {
/**
* Overrides DrupalWebTestCase::setUp().
*/
function setUp() {
protected function setUp($modules = array(), $permissions = array()) {
parent::setUp(array('uc_cart_links', 'uc_attribute'), array('administer cart links', 'view cart links report', 'access administration pages'));
}
@ -109,8 +109,9 @@ class UbercartCartLinksTestCase extends UbercartTestHelper {
0,
t('Cart Link #@link found on page.', array('@link' => $key))
);
// Note we strip the leading / from the link for the testbot ...
$this->assertLinkByHref(
t('@link', array('@link' => $test_link)),
t('@link', array('@link' => substr($test_link, 1))),
0,
t('Cart Link @link found on page.', array('@link' => $test_link))
);

View File

@ -8,6 +8,7 @@
/**
* Defines a form to configure the Cart Links settings.
*
* @see uc_cart_links_settings_form_validate()
* @ingroup forms
*/
function uc_cart_links_settings_form($form, &$form_state) {
@ -50,6 +51,32 @@ function uc_cart_links_settings_form($form, &$form_state) {
return system_settings_form($form);
}
/**
* Validation handler for uc_cart_links_settings form.
*
* @see uc_cart_links_settings_form()
*/
function uc_cart_links_settings_form_validate($form, &$form_state) {
$messages = (string) $form_state['values']['uc_cart_links_messages'];
if (!empty($messages)) {
$data = explode("\n", $messages);
foreach ($data as $message) {
// Ignore blank lines.
if (preg_match('/^\s*$/', $message)) {
continue;
}
// Check for properly formattted messages.
// Each line must be one or more numeric characters for the key followed
// by "|" followed by one or more characters for the value. Both the key
// and the value may have leading and/or trailing whitespace.
else if (!preg_match('/^\s*[1-9][0-9]*\s*\|\s*\S+.*$/', $message)) {
form_set_error('uc_cart_links_messages', t('Invalid Cart Links message "%message". Messages must be a numeric key followed by "|" followed by a value.', array('%message' => $message)));
break;
}
}
}
}
/**
* Displays the Cart Links report.
*

View File

@ -9,9 +9,9 @@ files[] = tests/uc_cart_links.test
configure = admin/store/settings/cart-links
; Information added by Drupal.org packaging script on 2014-10-22
version = "7.x-3.8"
; Information added by Drupal.org packaging script on 2016-07-16
version = "7.x-3.10"
core = "7.x"
project = "ubercart"
datestamp = "1413965350"
datestamp = "1468644909"

View File

@ -167,6 +167,10 @@ function uc_cart_links_process($cart_actions) {
if (empty($messages)) {
$data = explode("\n", variable_get('uc_cart_links_messages', ''));
foreach ($data as $message) {
// Skip blank lines.
if (preg_match('/^\s*$/', $message)) {
continue;
}
list($mkey, $mdata) = explode('|', $message, 2);
$messages[trim($mkey)] = trim($mdata);
}

View File

@ -18,9 +18,9 @@ class UbercartCatalogTestCase extends UbercartTestHelper {
/**
* Overrides DrupalWebTestCase::setUp().
*/
public function setUp() {
protected function setUp($modules = array(), $permissions = array()) {
$modules = array('uc_catalog', 'field_ui');
$permissions = array('administer catalog', 'administer content types');
$permissions = array('administer catalog', 'administer content types', 'administer fields');
parent::setUp($modules, $permissions);
}

View File

@ -2,6 +2,7 @@
* @file
* Styles for uc_catalog module.
*/
.catalog .trail {
font-weight: bold;
}

View File

@ -15,9 +15,9 @@ files[] = tests/uc_catalog.test
configure = admin/store/settings/catalog
; Information added by Drupal.org packaging script on 2014-10-22
version = "7.x-3.8"
; Information added by Drupal.org packaging script on 2016-07-16
version = "7.x-3.10"
core = "7.x"
project = "ubercart"
datestamp = "1413965350"
datestamp = "1468644909"

View File

@ -0,0 +1,116 @@
<?php
/**
* @file
* File download product feature tests.
*/
/**
* Tests the file download purchase functionality.
*/
class UbercartFileTestCase extends UbercartTestHelper {
public static function getInfo() {
return array(
'name' => 'File downloads',
'description' => 'Ensures that the purchase of file downloads functions correctly.',
'group' => 'Ubercart',
);
}
/**
* Overrides DrupalWebTestCase::setUp().
*/
public function setUp($modules = array(), $permissions = array()) {
$modules = array('uc_payment', 'uc_payment_pack', 'uc_file');
$permissions = array();
parent::setUp($modules, $permissions);
// Need admin permissions in order to change file download settings.
$this->drupalLogin($this->adminUser);
// Set up directory for files to live in.
$this->configureDownloadDirectory();
}
function testFilePurchaseCheckout() {
// Add file download feature to the test product.
$filename = $this->uploadTestFile();
$this->drupalLogin($this->adminUser);
$this->drupalPost('node/' . $this->product->nid . '/edit/features', array('feature' => 'file'), t('Add'));
$edit = array(
'uc_file_model' => '',
'uc_file_filename' => $filename,
);
$this->drupalPost(NULL, $edit, t('Save feature'));
// Check out with the test product.
$this->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));
$order = $this->checkout();
uc_payment_enter($order->order_id, 'other', $order->order_total);
// Test that the file was granted.
$this->drupalGet('user/' . $order->uid . '/purchased-files');
$this->assertText($filename, 'File found in list of purchased files.');
// Test that the email is correct.
$mail = $this->findMail('/File Downloads for Order# ' . preg_quote($order->order_id) . '/');
// Delete the user.
user_delete($order->uid);
// Run cron to ensure deleted users are handled correctly.
$this->drupalLogout();
$this->cronRun();
}
/**
* Helper function to configure Credit Card payment method settings.
*/
protected function configureDownloadDirectory() {
// Create directory for downloads, make it readable and writeable.
// Putting this under sites/default/files because SimpleTest needs to be
// able to create the directory - this is NOT where you'd put the downloads
// directory on a live site. On a live site, it should be outside the web root.
drupal_mkdir('sites/default/files/file-downloads', 0755);
$this->drupalPost(
'admin/store/settings/products',
array(
'uc_file_base_dir' => 'sites/default/files/file-downloads',
),
t('Save configuration')
);
$this->assertFieldByName(
'uc_file_base_dir',
'sites/default/files/file-downloads',
'Download file path has been set.'
);
}
/**
* Helper function to upload test file for downloading.
*/
protected function uploadTestFile() {
$filename = 'README.txt';
// Use the Ubercart README.txt because we know it will always be there
// and we know in advance how big it is.
copy(drupal_get_path('module', 'uc_file') . '/../' . $filename,
'sites/default/files/file-downloads/README.txt'
);
return $filename;
}
/**
* {@inheritdoc}
*/
public function tearDown() {
// Cleanup file download directory after test.
drupal_unlink('sites/default/files/file-downloads/README.txt');
drupal_rmdir('sites/default/files/file-downloads');
parent::tearDown();
}
}

View File

@ -409,7 +409,7 @@ function uc_file_admin_files_form_action_submit($form, &$form_state) {
drupal_set_message(t('The selected file(s) have been deleted.'));
}
else {
drupal_set_message(t('One or more files could not be deleted.'));
drupal_set_message(t('One or more files could not be deleted.'), 'warning');
}
break;
@ -440,11 +440,11 @@ function uc_file_admin_files_form_action_submit($form, &$form_state) {
drupal_set_message(t('The file %file has been uploaded to %dir', array('%file' => $file_object->filename, '%dir' => $dir)));
}
else {
drupal_set_message(t('An error occurred while copying the file to %dir', array('%dir' => $dir)));
drupal_set_message(t('An error occurred while copying the file to %dir', array('%dir' => $dir)), 'error');
}
}
else {
drupal_set_message(t('Can not move file to %dir', array('%dir' => $dir)));
drupal_set_message(t('Can not move file to %dir', array('%dir' => $dir)), 'error');
}
break;

View File

@ -2,6 +2,7 @@
* @file
* Styles for uc_file module.
*/
.download-table-row {
vertical-align: top;
}

View File

@ -5,12 +5,15 @@ dependencies[] = uc_order
package = Ubercart - core (optional)
core = 7.x
; Test cases
files[] = tests/uc_file.test
stylesheets[all][] = uc_file.css
scripts[] = uc_file.js
; Information added by Drupal.org packaging script on 2014-10-22
version = "7.x-3.8"
; Information added by Drupal.org packaging script on 2016-07-16
version = "7.x-3.10"
core = "7.x"
project = "ubercart"
datestamp = "1413965350"
datestamp = "1468644909"

View File

@ -453,7 +453,7 @@ function uc_file_uc_add_to_cart($nid, $qty, $data) {
'%download_limit' => $file_user['download_limit'] ? $file_user['download_limit'] : t('unlimited'),
'%address_limit' => $file_user['address_limit' ] ? $file_user['address_limit' ] : t('unlimited'),
'%expiration' => $file_user['expiration' ] ? format_date($file_user['expiration'], 'small') : t('never'),
)));
)), 'warning');
}
else {
return array(array(
@ -528,11 +528,14 @@ function uc_file_uc_store_status() {
}
/**
* Product feature delete function.
* Deletes all file data associated with a given product feature.
*
* @param $pfid
* An Ubercart product feature ID.
*/
function uc_file_feature_delete($feature) {
function uc_file_feature_delete($pfid) {
db_delete('uc_file_products')
->condition('pfid', $feature['pfid'])
->condition('pfid', $pfid)
->execute();
}
@ -545,12 +548,18 @@ function uc_file_feature_delete($feature) {
*/
function uc_file_feature_form($form, &$form_state, $node, $feature) {
if (!is_dir(variable_get('uc_file_base_dir', NULL))) {
drupal_set_message(t('A file directory needs to be configured in <a href="@url">product settings</a> under the file download settings tab before a file can be selected.', array('@url' => url('admin/store/settings/products'))), 'error');
drupal_set_message(t('A file directory needs to be configured in <a href="@url">product settings</a> under the file download settings tab before a file can be selected.', array('@url' => url('admin/store/settings/products'))), 'warning');
unset($form['buttons']);
return $form;
}
// Rescan the file directory to populate {uc_files} with the current list
// because files uploaded via any method other than the Upload button
// (e.g. by FTP) won'b be in {uc_files} yet.
uc_file_refresh();
if (!db_query_range('SELECT 1 FROM {uc_files}', 0, 1)->fetchField()) {
$form['file']['file_message'] = array(
'#markup' => t(
@ -563,9 +572,6 @@ function uc_file_feature_form($form, &$form_state, $node, $feature) {
return $form;
}
// Make sure we have an up-to-date list for the autocompletion.
uc_file_refresh();
// Grab all the models on this product.
$models = uc_product_get_models($node->nid);
@ -790,7 +796,7 @@ function uc_file_feature_form_submit($form, &$form_state) {
$description .= t('<strong>Directory:</strong> !dir<br />', array('!dir' => $file_product['filename']));
}
else {
$description .= t('<strong>File:</strong> !file<br />', array('!file' => basename($file_product['filename'])));;
$description .= t('<strong>File:</strong> !file<br />', array('!file' => basename($file_product['filename'])));
}
$description .= $file_product['shippable'] ? t('<strong>Shippable:</strong> Yes') : t('<strong>Shippable:</strong> No');
@ -1238,12 +1244,12 @@ function uc_file_remove_by_id($fid, $recur) {
$remove_fields = TRUE;
}
else {
drupal_set_message(t('The directory %dir could not be deleted.', array('%dir' => $filename)));
drupal_set_message(t('The directory %dir could not be deleted.', array('%dir' => $filename)), 'warning');
$result = FALSE;
}
}
else {
drupal_set_message(t('The directory %dir could not be deleted because it is not empty.', array('%dir' => $filename)));
drupal_set_message(t('The directory %dir could not be deleted because it is not empty.', array('%dir' => $filename)), 'warning');
$result = FALSE;
}
}
@ -1254,7 +1260,7 @@ function uc_file_remove_by_id($fid, $recur) {
drupal_set_message(t('The file %dir was deleted.', array('%dir' => $filename)));
}
else {
drupal_set_message(t('The file %dir could not be deleted.', array('%dir' => $filename)));
drupal_set_message(t('The file %dir could not be deleted.', array('%dir' => $filename)), 'error');
$result = FALSE;
}
}

View File

@ -12,6 +12,9 @@
* An associative array containing:
* - form: A render element representing the form.
*
* @return string
* The HTML output.
*
* @ingroup themeable
*/
function theme_uc_file_hook_user_file_downloads($variables) {

View File

@ -7,9 +7,9 @@ dependencies[] = uc_store
package = Ubercart - extra
core = 7.x
; Information added by Drupal.org packaging script on 2014-10-22
version = "7.x-3.8"
; Information added by Drupal.org packaging script on 2016-07-16
version = "7.x-3.10"
core = "7.x"
project = "ubercart"
datestamp = "1413965350"
datestamp = "1468644909"

View File

@ -0,0 +1,98 @@
/**
* @file
* Styles for uc_order module.
*/
.view-uc-orders #edit-delivery-first-name-wrapper,
.view-uc-orders #edit-created-wrapper {
clear: right;
}
.view-uc-orders #edit-created-min-wrapper,
.view-uc-orders #edit-created-max-wrapper {
float: right;
}
.view-uc-orders .form-type-date-select .date-padding {
padding: 0 0 0 22px;
}
.view-uc-orders tbody td.views-field-order-total {
text-align: left;
}
.order-overview-form {
float: right;
padding: 0 0 0 2em;
}
.uc-orders-table img {
float: right;
margin-right: auto;
margin-left: .5em;
}
.order-admin-icons {
margin-left: auto;
margin-right: 2px;
}
.order-pane-icons {
right: auto;
left: .5em;
}
.pos-left {
float: right;
}
.abs-left {
clear: right;
}
.pos-right {
float: left;
}
.abs-right {
clear: left;
float: left;
}
.order-pane #edit-add-line-item,
.order-pane #edit-add-line-item .form-item {
float: right;
margin-right: auto;
margin-left: 1em;
}
.order-pane-table td.cost,
.order-pane-table td.price,
.order-pane-table td.total {
text-align: left;
}
.order-edit-table .oet-label {
text-align: left;
}
.address-select-box {
padding-left: inherit;
padding-right: 1em;
}
.line-item-table .li-title {
text-align: left;
}
.line-item-table .li-amount {
text-align: left;
}
.order-pane.abs-left .form-submit {
margin: 0.5em 0 0.5em 0.5em;
}
#order-pane-print_button {
padding: 0.5em 2em 0.5em 0.5em;
}

View File

@ -1274,7 +1274,7 @@ function uc_order_mail_invoice_form_submit($form, &$form_state) {
* Displays a log of changes made to an order.
*/
function uc_order_log($order) {
$result = db_query("SELECT * FROM {uc_order_log} WHERE order_id = :id ORDER BY created, order_log_id", array(':id' => $order->order_id));
$result = db_query("SELECT * FROM {uc_order_log} WHERE order_id = :id ORDER BY order_log_id DESC", array(':id' => $order->order_id));
$header = array(t('Time'), t('User'), t('Changes'));
$rows = array();

View File

@ -19,16 +19,16 @@
.view-uc-orders #edit-delivery-first-name-wrapper,
.view-uc-orders #edit-created-wrapper {
clear: left;
clear: left; /* LTR */
}
.view-uc-orders #edit-created-min-wrapper,
.view-uc-orders #edit-created-max-wrapper {
float: left;
float: left; /* LTR */
}
.view-uc-orders .form-type-date-select .date-padding {
padding: 0 22px 0 0;
padding: 0 22px 0 0; /* LTR */
}
.view-uc-orders .form-type-date-select {
@ -40,7 +40,7 @@
}
.view-uc-orders tbody td.views-field-order-total {
text-align: right;
text-align: right; /* LTR */
}
.view-uc-orders tbody td.views-field-created {
@ -48,8 +48,8 @@
}
.order-overview-form {
float: left;
padding: 0 2em 0 0;
float: left; /* LTR */
padding: 0 2em 0 0; /* LTR */
}
.order-overview-form .form-item {
@ -76,12 +76,12 @@
}
.uc-orders-table img {
float: left;
margin-right: .5em;
float: left; /* LTR */
margin-right: .5em; /* LTR */
}
.order-admin-icons {
margin-left: 2px;
margin-left: 2px; /* LTR */
}
.order-admin-icons img {
@ -110,7 +110,7 @@
.order-pane-icons {
position: absolute;
right: .5em;
right: .5em; /* LTR */
top: 5px;
}
@ -124,11 +124,11 @@
}
.pos-left {
float: left;
float: left; /* LTR */
}
.abs-left {
clear: left;
clear: left; /* LTR */
}
.order-pane.abs-left {
@ -137,12 +137,12 @@
}
.pos-right {
float: right;
float: right; /* LTR */
}
.abs-right {
clear: right;
float: right;
clear: right; /* LTR */
float: right; /* LTR */
}
.text-center {
@ -164,8 +164,8 @@
.order-pane #edit-add-line-item,
.order-pane #edit-add-line-item .form-item {
float: left;
margin-right: 1em;
float: left; /* LTR */
margin-right: 1em; /* LTR */
padding-top: 0;
}
@ -196,7 +196,7 @@
.order-pane-table td.cost,
.order-pane-table td.price,
.order-pane-table td.total {
text-align: right;
text-align: right; /* LTR */
white-space: nowrap;
}
@ -227,7 +227,7 @@
.order-edit-table .oet-label {
font-weight: bold;
text-align: right;
text-align: right; /* LTR */
}
.order-edit-table .form-item {
@ -239,7 +239,7 @@
border: solid 1px #999;
margin-bottom: 1em;
padding-bottom: 1em;
padding-left: 1em;
padding-left: 1em; /* LTR */
width: auto;
}
@ -261,12 +261,12 @@
.line-item-table .li-title {
font-weight: bold;
text-align: right;
text-align: right; /* LTR */
width: 100%;
}
.line-item-table .li-amount {
text-align: right;
text-align: right; /* LTR */
white-space: nowrap;
}
@ -313,7 +313,7 @@
}
.order-pane.abs-left .form-submit {
margin: 0.5em 0.5em 0.5em 0;
margin: 0.5em 0.5em 0.5em 0; /* LTR */
}
.order-pane #customer-select form {
@ -322,6 +322,6 @@
#order-pane-print_button {
border: 1px solid #bbb;
padding: 0.5em 0.5em 0.5em 2em;
padding: 0.5em 0.5em 0.5em 2em; /* LTR */
background: url("../uc_store/images/print.gif") no-repeat 0.5em 50%;
}
}

View File

@ -39,9 +39,9 @@ files[] = uc_order.info.inc
configure = admin/store/settings/orders
stylesheets[all][] = uc_order.css
; Information added by Drupal.org packaging script on 2014-10-22
version = "7.x-3.8"
; Information added by Drupal.org packaging script on 2016-07-16
version = "7.x-3.10"
core = "7.x"
project = "ubercart"
datestamp = "1413965350"
datestamp = "1468644909"

View File

@ -883,11 +883,17 @@ function uc_order_uri($order) {
* The operation being performed. One of 'view', 'update', 'create' or
* 'delete'.
* @param $order
* Optionally an order to check access for.
* (optional) An order to check access for.
* @param $account
* The user to check for. Leave it to NULL to check for the current user.
* (optional) The account to check, or current user if not given.
*/
function uc_order_order_entity_access($op, $order = NULL, $account = NULL) {
global $user;
if (!isset($account)) {
$account = $user;
}
if ($op == 'delete') {
if (!empty($order)) {
return uc_order_can_delete($order, $account);
@ -1052,6 +1058,9 @@ function uc_order_delete($order_id) {
// Delete line items for the order.
uc_order_delete_line_item($order_id, TRUE);
// Delete attached field values.
field_attach_delete('uc_order', $order);
// Log the action in the database.
watchdog('uc_order', 'Order @order_id deleted by user @uid.', array('@order_id' => $order_id, '@uid' => $user->uid));
}

View File

@ -255,6 +255,56 @@ function uc_order_rules_condition_info() {
),
);
$conditions['uc_order_condition_total'] = array(
'label' => t("Check an order's total"),
'group' => t('Order'),
'base' => 'uc_order_condition_total',
'parameter' => array(
'order' => array(
'type' => 'uc_order',
'label' => t('Order'),
),
'op' => array(
'type' => 'text',
'label' => t('Operator'),
'description' => t('The comparison operator.'),
'default value' => '==',
'options list' => 'uc_order_condition_value_operator_options',
'restriction' => 'input',
),
'value' => array(
'type' => 'decimal',
'label' => t('Data value'),
'description' => t('The value to compare the data with.'),
),
),
);
$conditions['uc_order_condition_subtotal'] = array(
'label' => t("Check an order's subtotal"),
'group' => t('Order'),
'base' => 'uc_order_condition_subtotal',
'parameter' => array(
'order' => array(
'type' => 'uc_order',
'label' => t('Order'),
),
'op' => array(
'type' => 'text',
'label' => t('Operator'),
'description' => t('The comparison operator.'),
'default value' => '==',
'options list' => 'uc_order_condition_value_operator_options',
'restriction' => 'input',
),
'value' => array(
'type' => 'decimal',
'label' => t('Data value'),
'description' => t('The value to compare the data with.'),
),
),
);
return $conditions;
}
@ -548,18 +598,7 @@ function uc_order_condition_count_products($order, $products, $count, $op) {
}
}
}
switch ($op) {
case 'less':
return $total < $count;
case 'less_equal':
return $total <= $count;
case 'equal':
return $total == $count;
case 'greater_equal':
return $total >= $count;
case 'greater':
return $total > $count;
}
return uc_order_condition_value_operator_comparison($total, $op, $count);
}
/**
@ -608,18 +647,7 @@ function uc_order_condition_products_weight($order, $products, $weight_units, $w
}
}
}
switch ($op) {
case 'less':
return $total < $weight_value;
case 'less_equal':
return $total <= $weight_value;
case 'equal':
return $total == $weight_value;
case 'greater_equal':
return $total >= $weight_value;
case 'greater':
return $total > $weight_value;
}
return uc_order_condition_value_operator_comparison($total, $op, $weight_value);
}
/**
@ -812,3 +840,83 @@ function uc_order_action_email_invoice_view_options() {
'checkout-mail' => t('Show all of the above plus the "thank you" message.'),
);
}
/**
* Value comparison.
*
* @param float $source
* The source value.
* @param string $op
* The comparison operator.
* @param float $target
* The target value.
*
* @return bool
* Whether the comparison meets the specified conditions.
*
* @see uc_order_condition_value_operator_options
*/
function uc_order_condition_value_operator_comparison($source, $op, $target) {
switch ($op) {
case 'less':
return $source < $target;
case 'less_equal':
return $source <= $target;
case 'equal':
return $source == $target;
case 'greater_equal':
return $source >= $target;
case 'greater':
return $source > $target;
}
}
/**
* Compare order total.
*
* @param object $order
* The order to check.
* @param string $op
* The comparison operator.
* @param float $value
* The target value.
*
* @return bool
* Whether the order total meets the specified condition.
*
* @see uc_order_condition_value_operator_options
*/
function uc_order_condition_total($order, $op, $value) {
return uc_order_condition_value_operator_comparison($order->order_total, $op, $value);
}
/**
* Compare order subtotal.
*
* @param object $order
* The order to check.
* @param string $op
* The comparison operator.
* @param float $value
* The target value.
*
* @return bool
* Whether the order subtotal meets the specified condition.
*
* @see uc_order_condition_value_operator_options
*/
function uc_order_condition_subtotal($order, $op, $value) {
if (is_array($order->line_items)) {
foreach ($order->line_items as $line_item) {
if ($line_item['type'] == 'subtotal') {
$subtotal = $line_item['amount'];
return uc_order_condition_value_operator_comparison($subtotal, $op, $value);
}
}
}
return FALSE;
}

View File

@ -18,7 +18,7 @@ class UbercartProductTestCase extends UbercartTestHelper {
/**
* Overrides DrupalWebTestCase::setUp().
*/
public function setUp() {
protected function setUp($modules = array(), $permissions = array()) {
parent::setUp(array(), array('administer content types'));
$this->drupalLogin($this->adminUser);
}
@ -169,10 +169,10 @@ class UbercartProductTestCase extends UbercartTestHelper {
// Check invalid quantity messages.
$this->drupalPost('node/' . $this->product->nid, array('qty' => 'x'), 'Add to cart');
$this->assertText('The quantity must be a number.');
$this->assertText('The quantity must be an integer.');
$this->drupalPost('node/' . $this->product->nid, array('qty' => '1a'), 'Add to cart');
$this->assertText('The quantity must be a number.');
$this->assertText('The quantity must be an integer.');
// Check cart add message.
$this->drupalPost('node/' . $this->product->nid, array('qty' => '1'), 'Add to cart');

View File

@ -0,0 +1,30 @@
/**
* @file
* Styles for uc_product module.
*/
.product-image {
clear: left;
float: left;
margin-left: auto;
margin-right: 4px;
padding-left: inherit;
padding-right: 4px;
}
.display-price {
clear: left;
float: left;
padding-left: inherit;
padding-right: 4px;
}
.model {
margin-right: auto;
margin-left: 2em;
}
.add-feature div {
padding-right: inherit;
padding-left: 1em;
}

View File

@ -67,7 +67,7 @@ function uc_product_settings_form($form, &$form_state) {
}
else {
// If we have widgets installed, add option to not use any of them
$options['none'] = "Don't use any image widgets.";
$options['none'] = t("Don't use any image widgets.");
}
$form['product']['uc_product_image_widget'] = array(

View File

@ -2,29 +2,30 @@
* @file
* Styles for uc_product module.
*/
.product-image {
clear: right;
float: right;
margin-left: 4px;
padding-left: 4px;
clear: right; /* LTR */
float: right; /* LTR */
margin-left: 4px; /* LTR */
padding-left: 4px; /* LTR */
padding-top: 4px;
text-align: center;
}
.display-price {
clear: right;
float: right;
clear: right; /* LTR */
float: right; /* LTR */
font-size: 1.3em;
font-weight: bold;
padding-bottom: 4px;
padding-left: 4px;
padding-left: 4px; /* LTR */
text-align: center;
}
.model {
display: inline;
font-weight: bold;
margin-right: 2em;
margin-right: 2em; /* LTR */
}
.uc-product-features td {
@ -32,7 +33,7 @@
}
.add-feature div {
padding-right: 1em;
padding-right: 1em; /* LTR */
}
.add-feature div,

View File

@ -20,9 +20,9 @@ files[] = views/uc_product_handler_filter_product.inc
configure = admin/store/settings/products
stylesheets[all][] = uc_product.css
; Information added by Drupal.org packaging script on 2014-10-22
version = "7.x-3.8"
; Information added by Drupal.org packaging script on 2016-07-16
version = "7.x-3.10"
core = "7.x"
project = "ubercart"
datestamp = "1413965350"
datestamp = "1468644909"

View File

@ -597,8 +597,11 @@ function uc_product_load($nodes) {
* @param $data
* Optional data to add to the product before invoking the alter hooks.
*
* @return
* @return object
* An variant of the product, altered based on the provided data.
*
* @throws \Exception
* If the caller tries to create a variant of a variant.
*/
function _uc_product_get_variant($node, $data = FALSE) {
if (!empty($node->variant)) {
@ -905,7 +908,7 @@ function uc_product_form_node_type_form_alter(&$form, &$form_state) {
$options = array('' => t('None'));
foreach ($instances as $field_name => $instance) {
if (strpos($instance['widget']['type'], 'image') !== FALSE) {
if (strpos($instance['widget']['type'], 'image') !== FALSE || ($instance['widget']['type'] == 'media_generic' && isset($instance['widget']['settings']['allowed_types']) && $instance['widget']['settings']['allowed_types'] == array('image' => 'image'))) {
$options[$field_name] = $instance['label'];
}
}
@ -1005,7 +1008,6 @@ function uc_product_uc_product_types() {
* @see uc_product_image_defaults()
*/
function uc_product_uc_store_status() {
module_load_include('inc', 'content', 'includes/content.crud');
// Check for filefields on products.
if ($field = variable_get('uc_image_product', '')) {
$instances = field_info_instances('node', 'product');
@ -1223,6 +1225,12 @@ function uc_product_add_to_cart_form($form, &$form_state, $node) {
),
);
// Ajax forms may have no form state when triggered from a cached page, so
// ensure the variant is available for form alter functions to use.
if (!empty($form_state['rebuild']) && empty($form_state['storage']['variant'])) {
$form_state['storage']['variant'] = uc_product_load_variant($form_state['values']['nid'], module_invoke_all('uc_add_to_cart_data', $form_state['values']));
}
$form['node'] = array(
'#type' => 'value',
'#value' => isset($form_state['storage']['variant']) ? $form_state['storage']['variant'] : $node,
@ -1428,7 +1436,10 @@ function uc_product_get_image_widget() {
// Find widget preference, if any.
$widget_name = variable_get('uc_product_image_widget', NULL);
if ($widget_name != NULL) {
if ($widget_name == 'none') {
// Don't use any image widgets.
}
elseif ($widget_name != NULL) {
// Widget to use has been set in admin menu.
$image_widget = $image_widgets[$widget_name];
}
@ -1669,7 +1680,7 @@ function uc_product_feature_delete($pfid) {
// Call the delete function for this product feature if it exists.
$func = uc_product_feature_data($feature['fid'], 'delete');
if (function_exists($func)) {
$func($feature);
$func($pfid);
}
db_delete('uc_product_features')
->condition('pfid', $pfid)

View File

@ -12,6 +12,9 @@
* - model: Product model number, also known as SKU.
* - attributes: (optional) Array of attributes to apply to enclosing DIV.
*
* @return string
* The HTML output.
*
* @ingroup themeable
*/
function theme_uc_product_model($variables) {

View File

@ -18,7 +18,7 @@ class UbercartProductKitTestCase extends UbercartTestHelper {
/**
* Overrides DrupalWebTestCase::setUp().
*/
public function setUp() {
protected function setUp($modules = array(), $permissions = array()) {
parent::setUp(array('uc_product_kit'), array('create product_kit content', 'edit any product_kit content'));
}

View File

@ -0,0 +1,19 @@
/**
* @file
* Styles for uc_product_kit module.
*/
#block-cart-contents .kit-component-cart-desc ul.product-description {
padding-left: inherit;
padding-right: 0;
}
#block-cart-contents .product-description .kit-component-cart-desc ul:before {
margin-right: auto;
margin-left: 0.15em;
}
.kit-component-cart-desc .item-list li {
padding-left: inherit;
padding-right: 0;
}

View File

@ -2,12 +2,13 @@
* @file
* Styles for uc_product_kit module.
*/
#block-cart-contents .kit-component-cart-desc ul.product-description {
padding-left: 0;
padding-left: 0; /* LTR */
}
#block-cart-contents .product-description .kit-component-cart-desc ul:before {
margin-right: 0.15em;
margin-right: 0.15em; /* LTR */
}
.kit-component-cart-desc .item-list li {
@ -15,7 +16,7 @@
display: inline;
font-size: 1em;
font-style: italic;
padding-left: 0;
padding-left: 0; /* LTR */
}
.kit-component-cart-desc li:after {
content: ", ";

View File

@ -10,9 +10,9 @@ files[] = tests/uc_product_kit.test
files[] = views/uc_product_kit_handler_filter_product_kit.inc
files[] = views/uc_product_kit_handler_filter_product_kit_item.inc
; Information added by Drupal.org packaging script on 2014-10-22
version = "7.x-3.8"
; Information added by Drupal.org packaging script on 2016-07-16
version = "7.x-3.10"
core = "7.x"
project = "ubercart"
datestamp = "1413965350"
datestamp = "1468644909"

View File

@ -921,7 +921,6 @@ function uc_product_kit_uc_product_types() {
*/
function uc_product_kit_uc_store_status() {
if (module_exists('filefield')) {
module_load_include('inc', 'content', 'includes/content.crud');
// Check for filefields on products.
if ($field = variable_get('uc_image_product_kit', '')) {
$instances = content_field_instance_read(array('field_name' => $field, 'type_name' => 'product_kit'));

View File

@ -2,6 +2,7 @@
* @file
* Styles for uc_reports module.
*/
.sales-year {
display: inline;
}

View File

@ -7,9 +7,9 @@ core = 7.x
configure = admin/store/settings/store
; Information added by Drupal.org packaging script on 2014-10-22
version = "7.x-3.8"
; Information added by Drupal.org packaging script on 2016-07-16
version = "7.x-3.10"
core = "7.x"
project = "ubercart"
datestamp = "1413965350"
datestamp = "1468644909"

View File

@ -1,147 +0,0 @@
diff --git a/uc_roles/uc_roles.views.inc b/uc_roles/uc_roles.views.inc
new file mode 100644
index 0000000..558e461
--- /dev/null
+++ b/uc_roles/uc_roles.views.inc
@@ -0,0 +1,110 @@
+<?php
+
+/**
+ * @file
+ * Views 2 hooks and callback registries.
+ */
+
+
+/**
+ * Implementation of hook_views_data().
+ */
+
+ function uc_roles_views_data() {
+ $data['uc_roles_expirations']['table']['group'] = t('User');
+
+ $data['uc_roles_expirations']['table']['join'] = array(
+ 'users' => array(
+ 'left_field' => 'uid',
+ 'field' => 'uid',
+ ),
+ );
+
+
+ // Expose the role expiration date
+ $data['uc_roles_expirations']['expiration'] = array(
+ 'title' => t('Ubercart Role expiration date/time'),
+ 'help' => t('Date and time the role will expire. (See also Role expiration role.)'),
+ 'field' => array(
+ 'handler' => 'views_handler_field_date',
+ 'click sortable' => TRUE,
+ ),
+ 'sort' => array(
+ 'handler' => 'views_handler_sort_date',
+ ),
+ 'filter' => array(
+ 'handler' => 'views_handler_filter_date',
+ ),
+ );
+
+
+ // Expose the role id from uc_roles_expirations
+ $data['uc_roles_expirations']['rid'] = array(
+ 'title' => t('Ubercart Role expiration role'),
+ 'help' => t('The Role that corresponds with the Role expiration date/time'),
+ // Information for displaying the rid
+ 'field' => array(
+ 'handler' => 'uc_roles_handler_field_rid',
+ 'click sortable' => TRUE,
+ ),
+ // Information for accepting a rid as an argument
+ 'argument' => array(
+ 'handler' => 'views_handler_argument_users_roles_rid',
+ 'name field' => 'title', // the field to display in the summary.
+ 'numeric' => TRUE,
+ 'validate type' => 'rid',
+ ),
+ // Information for accepting a uid as a filter
+ 'filter' => array(
+ 'handler' => 'views_handler_filter_user_roles',
+ ),
+ // Information for sorting on a uid.
+ 'sort' => array(
+ 'handler' => 'views_handler_sort',
+ ),
+ );
+
+
+ return $data;
+}
+
+class uc_roles_handler_field_rid extends views_handler_field {
+
+ // Derived from views_handler_field_user_roles
+ // Purpose: get the *names* that correspond to the role_expire_rids.
+ function pre_render($values) {
+ $roles = array();
+ $this->items = array();
+
+ // Get all the unique role ids into the keys of $roles. Initializing into
+ // array_keys helps prevent us from having a list where the same rid appears
+ // over and over and over.
+ foreach ($values as $result) {
+ $roles[$this->get_value($result, NULL, TRUE)] = FALSE;
+ }
+
+ if ($roles) {
+ $result = db_query("SELECT r.rid, r.name FROM {role} r WHERE r.rid IN (:rids) ORDER BY r.name",
+ array(':rids' => array_keys($roles)));
+ foreach ($result as $role) {
+ $this->items[$role->rid]['role'] = check_plain($role->name);
+ $this->items[$role->rid]['rid'] = $role->rid;
+ }
+ }
+ }
+
+ // Render the rid as the role name.
+ function render($values) {
+
+ // Return the role name corresponding to the role ID.
+ // TODO: Should I be using this->get_value() here?
+ $rid = $values->uc_roles_expirations_rid;
+ if ($rid) {
+ $role = $this->items[$rid]['role'];
+ if (!empty($role)) {
+ return $role;
+ }
+ }
+ }
+}
+
diff --git a/uc_roles/uc_roles.info b/uc_roles/uc_roles.info
index f7c899e..ccd2d43 100644
--- a/uc_roles/uc_roles.info
+++ b/uc_roles/uc_roles.info
@@ -2,8 +2,12 @@ name = Roles
description = Assigns permanent or expirable roles based on product purchases.
dependencies[] = uc_product
dependencies[] = uc_order
+dependencies[] = views
package = Ubercart - core (optional)
core = 7.x
; Test cases
files[] = tests/uc_roles.test
+
+; Views handlers
+files[] = uc_roles.views.inc
diff --git a/uc_roles/uc_roles.module b/uc_roles/uc_roles.module
index d7ee52c..65bdd74 100644
--- a/uc_roles/uc_roles.module
+++ b/uc_roles/uc_roles.module
@@ -1278,3 +1278,9 @@ function _uc_roles_get_expiration($duration, $granularity, $start_time = NULL) {
return strtotime($operator . $duration . ' ' . $granularity, $start_time);
}
+/**
+ * Implements hook_views_api().
+ */
+function uc_roles_views_api() {
+ return array('api' => '3.0');
+}

View File

@ -21,9 +21,10 @@ class UbercartRolesTestCase extends UbercartTestHelper {
/**
* Overrides DrupalWebTestCase::setUp().
*/
function setUp() {
protected function setUp($modules = array(), $permissions = array()) {
$modules = array('uc_payment', 'uc_payment_pack', 'uc_roles');
$permissions = array();
// Needed to see/modify roles on the /user/%/edit page
$permissions = array('administer permissions', 'administer users', 'view all role expirations');
parent::setUp($modules, $permissions);
}
@ -59,4 +60,48 @@ class UbercartRolesTestCase extends UbercartTestHelper {
$this->drupalLogout();
$this->cronRun();
}
function testRoleAdminDelete() {
// Add role assignment to the test product.
$rid = $this->drupalCreateRole(array('access content'));
$this->drupalLogin($this->adminUser);
$this->drupalPost('node/' . $this->product->nid . '/edit/features', array('feature' => 'role'), t('Add'));
$edit = array(
'uc_roles_role' => $rid,
'end_override' => TRUE,
'uc_roles_expire_relative_duration' => 1,
'uc_roles_expire_relative_granularity' => 'day',
);
$this->drupalPost(NULL, $edit, t('Save feature'));
// Check out with the test product.
$this->drupalPost('node/' . $this->product->nid, array(), t('Add to cart'));
$order = $this->checkout();
uc_payment_enter($order->order_id, 'other', $order->order_total);
// Test that the role was granted.
$account = user_load($order->uid);
$this->assertTrue(isset($account->roles[$rid]), 'Existing user was granted role.');
// Test that the role appears on the user edit page.
$this->drupalGet('user/' . $order->uid . '/edit');
$this->assertText('Ubercart roles', 'Ubercart roles fieldset found.');
$this->assertNoText('There are no pending expirations for roles this user.', 'User has a role expiration.');
// Delete the role using the Drupal user edit page
// by unchecking the role and submitting the form.
$this->drupalPost(
'user/' . $order->uid . '/edit',
array('roles[' . $rid . ']' => FALSE),
t('Save')
);
// Test that the role was removed.
$account = user_load($order->uid, TRUE);
$this->assertFalse(isset($account->roles[$rid]), 'Role was removed from user.');
// Test that the role expiration data was removed.
$this->assertText('There are no pending expirations for roles this user.', 'User has no role expirations.');
}
}

View File

@ -2,7 +2,6 @@ name = Roles
description = Assigns permanent or expirable roles based on product purchases.
dependencies[] = uc_product
dependencies[] = uc_order
dependencies[] = views
package = Ubercart - core (optional)
core = 7.x
@ -10,11 +9,11 @@ core = 7.x
files[] = tests/uc_roles.test
; Views handlers
files[] = uc_roles.views.inc
files[] = views/uc_roles_handler_field_rid.inc
; Information added by Drupal.org packaging script on 2014-10-22
version = "7.x-3.8"
; Information added by Drupal.org packaging script on 2016-07-16
version = "7.x-3.10"
core = "7.x"
project = "ubercart"
datestamp = "1413965350"
datestamp = "1468644909"

View File

@ -1,16 +0,0 @@
name = Roles
description = Assigns permanent or expirable roles based on product purchases.
dependencies[] = uc_product
dependencies[] = uc_order
package = Ubercart - core (optional)
core = 7.x
; Test cases
files[] = tests/uc_roles.test
; Information added by Drupal.org packaging script on 2014-10-22
version = "7.x-3.8"
core = "7.x"
project = "ubercart"
datestamp = "1413965350"

View File

@ -335,8 +335,9 @@ function uc_roles_user_presave(&$edit, $account, $category) {
// If a user's role is removed using Drupal, then so is any expiration data.
if (isset($edit['roles']) && is_array($edit['roles']) && isset($account->roles)) {
$allowed_uc_roles = _uc_roles_get_choices();
foreach ($account->roles as $rid => $role) {
if (!in_array($rid, array_keys($edit['roles'])) && $rid != DRUPAL_AUTHENTICATED_RID) {
if (isset($allowed_uc_roles[$rid]) && !$edit['roles'][$rid]) {
uc_roles_delete($account, $rid);
}
}
@ -953,7 +954,7 @@ function _uc_roles_get_choices($exclude = array()) {
}
/**
* Deletes all data associated with a given product feature.
* Deletes all role data associated with a given product feature.
*
* @param $pfid
* An Ubercart product feature ID.
@ -1278,9 +1279,13 @@ function _uc_roles_get_expiration($duration, $granularity, $start_time = NULL) {
return strtotime($operator . $duration . ' ' . $granularity, $start_time);
}
/**
* Implements hook_views_api().
*/
function uc_roles_views_api() {
return array('api' => '3.0');
return array(
'api' => '2.0',
'path' => drupal_get_path('module', 'uc_roles') . '/views',
);
}

View File

@ -1,110 +0,0 @@
<?php
/**
* @file
* Views 2 hooks and callback registries.
*/
/**
* Implementation of hook_views_data().
*/
function uc_roles_views_data() {
$data['uc_roles_expirations']['table']['group'] = t('User');
$data['uc_roles_expirations']['table']['join'] = array(
'users' => array(
'left_field' => 'uid',
'field' => 'uid',
),
);
// Expose the role expiration date
$data['uc_roles_expirations']['expiration'] = array(
'title' => t('Ubercart Role expiration date/time'),
'help' => t('Date and time the role will expire. (See also Role expiration role.)'),
'field' => array(
'handler' => 'views_handler_field_date',
'click sortable' => TRUE,
),
'sort' => array(
'handler' => 'views_handler_sort_date',
),
'filter' => array(
'handler' => 'views_handler_filter_date',
),
);
// Expose the role id from uc_roles_expirations
$data['uc_roles_expirations']['rid'] = array(
'title' => t('Ubercart Role expiration role'),
'help' => t('The Role that corresponds with the Role expiration date/time'),
// Information for displaying the rid
'field' => array(
'handler' => 'uc_roles_handler_field_rid',
'click sortable' => TRUE,
),
// Information for accepting a rid as an argument
'argument' => array(
'handler' => 'views_handler_argument_users_roles_rid',
'name field' => 'title', // the field to display in the summary.
'numeric' => TRUE,
'validate type' => 'rid',
),
// Information for accepting a uid as a filter
'filter' => array(
'handler' => 'views_handler_filter_user_roles',
),
// Information for sorting on a uid.
'sort' => array(
'handler' => 'views_handler_sort',
),
);
return $data;
}
class uc_roles_handler_field_rid extends views_handler_field {
// Derived from views_handler_field_user_roles
// Purpose: get the *names* that correspond to the role_expire_rids.
function pre_render($values) {
$roles = array();
$this->items = array();
// Get all the unique role ids into the keys of $roles. Initializing into
// array_keys helps prevent us from having a list where the same rid appears
// over and over and over.
foreach ($values as $result) {
$roles[$this->get_value($result, NULL, TRUE)] = FALSE;
}
if ($roles) {
$result = db_query("SELECT r.rid, r.name FROM {role} r WHERE r.rid IN (:rids) ORDER BY r.name",
array(':rids' => array_keys($roles)));
foreach ($result as $role) {
$this->items[$role->rid]['role'] = check_plain($role->name);
$this->items[$role->rid]['rid'] = $role->rid;
}
}
}
// Render the rid as the role name.
function render($values) {
// Return the role name corresponding to the role ID.
// TODO: Should I be using this->get_value() here?
$rid = $values->uc_roles_expirations_rid;
if ($rid) {
$role = $this->items[$rid]['role'];
if (!empty($role)) {
return $role;
}
}
}
}

View File

@ -0,0 +1,64 @@
<?php
/**
* @file
* Views hooks for Ubercart roles.
*/
/**
* Implements hook_views_data().
*/
function uc_roles_views_data() {
$data['uc_roles_expirations']['table']['group'] = t('User');
$data['uc_roles_expirations']['table']['join'] = array(
'users' => array(
'left_field' => 'uid',
'field' => 'uid',
),
);
// Expose the role expiration date.
$data['uc_roles_expirations']['expiration'] = array(
'title' => t('Ubercart Role expiration date/time'),
'help' => t('Date and time the role will expire. (See also Role expiration role.)'),
'field' => array(
'handler' => 'views_handler_field_date',
'click sortable' => TRUE,
),
'sort' => array(
'handler' => 'views_handler_sort_date',
),
'filter' => array(
'handler' => 'views_handler_filter_date',
),
);
// Expose the role id from uc_roles_expirations.
$data['uc_roles_expirations']['rid'] = array(
'title' => t('Ubercart Role expiration role'),
'help' => t('The Role that corresponds with the Role expiration date/time'),
// Information for displaying the rid
'field' => array(
'handler' => 'uc_roles_handler_field_rid',
'click sortable' => TRUE,
),
// Information for accepting a rid as an argument.
'argument' => array(
'handler' => 'views_handler_argument_users_roles_rid',
'name field' => 'title', // The field to display in the summary.
'numeric' => TRUE,
'validate type' => 'rid',
),
// Information for accepting a uid as a filter.
'filter' => array(
'handler' => 'views_handler_filter_user_roles',
),
// Information for sorting on a uid.
'sort' => array(
'handler' => 'views_handler_sort',
),
);
return $data;
}

View File

@ -0,0 +1,52 @@
<?php
/**
* @file
* Views handler: Role ID field.
*/
/**
* Returns a role id rendered as a role name to display in the View.
*/
class uc_roles_handler_field_rid extends views_handler_field {
/**
* Overrides views_handler_field::pre_render().
*/
function pre_render(&$values) {
$roles = array();
$this->items = array();
// Get all the unique role ids into the keys of $roles. Initializing into
// array_keys helps prevent us from having a list where the same rid appears
// over and over and over.
foreach ($values as $result) {
$roles[$this->get_value($result, NULL, TRUE)] = FALSE;
}
if ($roles) {
$result = db_query("SELECT r.rid, r.name FROM {role} r WHERE r.rid IN (:rids) ORDER BY r.name",
array(':rids' => array_keys($roles)));
foreach ($result as $role) {
$this->items[$role->rid]['role'] = check_plain($role->name);
$this->items[$role->rid]['rid'] = $role->rid;
}
}
}
/**
* Overrides views_handler_field::render().
*/
function render($values) {
// Return the role name corresponding to the role ID.
// @todo: Should we be using this->get_value() here?
$rid = $values->uc_roles_expirations_rid;
if ($rid) {
$role = $this->items[$rid]['role'];
if (!empty($role)) {
return $role;
}
}
}
}

View File

@ -18,7 +18,7 @@ class UbercartStockTestCase extends UbercartTestHelper {
/**
* Overrides DrupalWebTestCase::setUp().
*/
public function setUp() {
protected function setUp($modules = array(), $permissions = array()) {
parent::setUp(array('uc_stock'), array('administer product stock'));
$this->drupalLogin($this->adminUser);
}

View File

@ -12,9 +12,9 @@ files[] = views/uc_stock_handler_filter_below_threshold.inc
configure = admin/store/settings/stock
; Information added by Drupal.org packaging script on 2014-10-22
version = "7.x-3.8"
; Information added by Drupal.org packaging script on 2016-07-16
version = "7.x-3.10"
core = "7.x"
project = "ubercart"
datestamp = "1413965350"
datestamp = "1468644909"

View File

@ -27,5 +27,5 @@ function cyprus_install() {
}
$query->execute();
uc_set_address_format(196, "!company\n!first_name !last_name\n!street1\n!street2\n!city, !zone_code !postal_code\n!country_name_if");
uc_set_address_format(196, "!company\r\n!first_name !last_name\r\n!street1\r\n!street2\r\n!city, !zone_code !postal_code\r\n!country_name_if");
}

View File

@ -13,7 +13,7 @@ function india_install() {
'country_name' => 'India',
'country_iso_code_2' => 'IN',
'country_iso_code_3' => 'IND',
'version' => 2,
'version' => 3,
))
->execute();
@ -44,14 +44,15 @@ function india_install() {
array(356, 'ML', 'Meghalaya'),
array(356, 'MZ', 'Mizoram'),
array(356, 'NL', 'Nagaland'),
array(356, 'OR', 'Orissa'),
array(356, 'OR', 'Odisha'),
array(356, 'PY', 'Puducherry'),
array(356, 'PB', 'Punjab'),
array(356, 'RJ', 'Rajasthan'),
array(356, 'SK', 'Sikkim'),
array(356, 'TG', 'Telangana'),
array(356, 'TN', 'Tamil Nadu'),
array(356, 'TR', 'Tripura'),
array(356, 'UL', 'Uttarakhand'),
array(356, 'UT', 'Uttarakhand'),
array(356, 'UP', 'Uttar Pradesh'),
array(356, 'WB', 'West Bengal'),
);
@ -123,5 +124,33 @@ function india_update($version) {
->execute();
break;
case 3:
// Add some missing zones
$zones = array(
array(356, 'TG', 'Telangana'),
);
$query = db_insert('uc_zones')->fields(array('zone_country_id', 'zone_code', 'zone_name'));
foreach ($zones as $zone) {
$query->values($zone);
}
$query->execute();
// Correct zone name
db_update('uc_zones')
->fields(array('zone_name' => 'Odisha', 'zone_code' => 'OR'))
->condition('zone_country_id', 356)
->condition('zone_code', 'OR')
->execute();
// Correct ISO-3166-2 code
db_update('uc_zones')
->fields(array('zone_name' => 'Uttarakhand', 'zone_code' => 'UT'))
->condition('zone_country_id', 356)
->condition('zone_code', 'UL')
->execute();
break;
}
}

View File

@ -1,5 +1,4 @@
<?php
// $Id$
/**
* Implements hook_install().

View File

@ -25,7 +25,7 @@ class UbercartAddressTestCase extends UbercartTestHelper {
/**
* Overrides DrupalWebTestCase::setUp().
*/
public function setUp() {
protected function setUp($modules = array(), $permissions = array()) {
parent::setUp();
// Create a random address object for use in tests.

View File

@ -19,7 +19,7 @@ class UbercartAjaxTestCase extends UbercartTestHelper {
/**
* Overrides DrupalWebTestCase::setUp().
*/
public function setUp() {
protected function setUp($modules = array(), $permissions = array()) {
module_load_include('inc', 'uc_store', 'includes/uc_ajax_attach');
$modules = array('rules_admin', 'uc_payment', 'uc_payment_pack');
$permissions = array('administer rules', 'bypass rules access');

View File

@ -30,7 +30,7 @@ class UbercartTestHelper extends DrupalWebTestCase {
* @param $permissions
* Optional list of extra permissions for $this->adminUser.
*/
function setUp($modules = array(), $permissions = array()) {
protected function setUp($modules = array(), $permissions = array()) {
// Enable the core Ubercart modules and dependencies, along with any other modules passed as arguments.
$modules = array_merge(array('uc_store', 'rules', 'uc_order', 'uc_product', 'uc_cart'), $modules);
call_user_func_array(array('parent', 'setUp'), $modules);

View File

@ -0,0 +1,29 @@
/**
* @file
* Styles for uc_store module.
*/
.uc-inline-form .form-item {
float: right;
margin-right: auto;
margin-left: 1em;
}
.uc-default-submit {
left: auto;
right: -9999px;
}
/**
* CSS rules for address fields.
*/
.uc-store-address-field .form-item {
clear: right;
}
.uc-store-address-field .form-item label {
float: right;
padding-right: inherit;
padding-left: 4px;
text-align: left;
}

Some files were not shown because too many files have changed in this diff Show More