Version 4.1.2

This commit is contained in:
Neo committed 2025-12-19 05:32:19 -08:00
1 parent 3ba79295ee
commit 28bd025b35
1131 files changed
+63658 -20579

No files matched your search

+82 -5
View File
@@ -37,12 +37,68 @@ class _Application extends \IPS\Application
{
try
{
$saveSubscription = FALSE;
/* Get the subscription */
$subscription = \IPS\Db::i()->select( '*', 'nexus_subscriptions', array( 's_gateway_key=? AND s_id=?', 'paypal', \IPS\Request::i()->subscr_id ) )->first();
$items = \unserialize( $subscription['s_items'] );
if ( !is_array( $items ) or empty( $items ) )
try
{
exit;
$subscription = \IPS\Db::i()->select( '*', 'nexus_subscriptions', array( 's_gateway_key=? AND s_id=?', 'paypal', \IPS\Request::i()->subscr_id ) )->first();
$items = \unserialize( $subscription['s_items'] );
if ( !is_array( $items ) or empty( $items ) )
{
/* Don't exit here, throw an underflow exception so we can see if this is a legacy subscription */
throw new \UnderflowException( 'NO_ITEMS' );
}
}
catch( \UnderflowException $e )
{
/* Was this from the old IP.Subscriptions? */
if ( isset( \IPS\Request::i()->old ) or mb_strstr( \IPS\Request::i()->custom, '-' ) !== FALSE )
{
if ( mb_strstr( \IPS\Request::i()->custom, '-' ) !== FALSE )
{
$exploded = explode( '-', \IPS\Request::i()->custom );
$memberId = intval( $exploded[0] );
$purchaseId = intval( $exploded[1] );
$item = \IPS\Db::i()->select( '*', 'nexus_purchases', array( "ps_id=?", $purchaseId ), 'ps_id' )->first();
}
else
{
$memberId = intval( \IPS\Request::i()->custom );
$item = \IPS\Db::i()->select( '*', 'nexus_purchases', array( "ps_member=? AND ps_name=?", $memberId, $itemName ), 'ps_start DESC' )->first();
}
/* If the purchase isn't valid or was cancelled just exit */
if ( !$item['ps_id'] or $item['ps_cancelled'] )
{
exit;
}
/* We need $items below, not $item */
$items = array( $item['ps_id'] );
/* Grab the first paypal method we can find */
$method = \IPS\Db::i()->select( 'm_id', 'nexus_paymethods', array( 'm_gateway=?', 'PayPal' ) )->first();
/* We are here because the subscription record doesn't exist. The 3.x code just silently and automatically added one, so do the same now.
Note that we will need the transaction ID to save the subscription, but we can set the array parameters that will be referenced below. */
$subscription = array(
's_gateway_key' => 'paypal',
's_id' => \IPS\Request::i()->subscr_id,
's_start_trans' => 0, // We will set this later after saving the transaction
's_method' => $method,
's_member' => $memberId,
);
$saveSubscription = TRUE;
}
else
{
/* Just let the exception bubble up and get caught */
throw $e;
}
}
/* If the gateway still exists, fetch it */
@@ -53,7 +109,7 @@ class _Application extends \IPS\Application
}
catch ( \OutOfRangeException $e ) { }
/* Check this waas actually a PayPal IPN message */
/* Check this was actually a PayPal IPN message */
try
{
$response = \IPS\Http\Url::external( 'https://www.' . ( \IPS\NEXUS_TEST_GATEWAYS ? 'sandbox.' : '' ) . 'paypal.com/cgi-bin/webscr/' )->request()->setHeaders( array( 'Accept' => 'application/x-www-form-urlencoded' ) )->post( array_merge( array( 'cmd' => '_notify-validate' ), $_POST ) );
@@ -114,6 +170,14 @@ class _Application extends \IPS\Application
$transaction->amount = new \IPS\nexus\Money( $_POST['mc_gross'], $_POST['mc_currency'] );
$transaction->gw_id = $_POST['txn_id'];
$transaction->approve();
/* If this was a legacy subscription payment, we'll need to save the subscription now that we have a trans ID */
if( $saveSubscription === TRUE )
{
$subscription['s_start_trans'] = $transaction->id;
\IPS\Db::i()->insert( 'nexus_subscriptions', $subscription );
}
}
catch ( \UnderflowException $e ) { }
}
@@ -181,4 +245,17 @@ class _Application extends \IPS\Application
{
return 'shopping-cart';
}
/**
* Can view page even when user is a guest when guests cannot access the site
*
* @param \IPS\Application\Module $module The module
* @param string $controller The controller
* @param string|NULL $do To "do" parameter
* @return bool
*/
public function allowGuestAccess( \IPS\Application\Module $module, $controller, $do )
{
return $module->key == 'store';
}
}
File diff suppressed because it is too large. Load diff
+76 -29
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<javascript app="nexus">
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/checkout" javascript_name="ips.checkout.billingForm.js" javascript_type="controller" javascript_version="100045" javascript_position="1000050"><![CDATA[/**
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/checkout" javascript_name="ips.checkout.billingForm.js" javascript_type="controller" javascript_version="101012" javascript_position="1000050"><![CDATA[/**
* IPS Social Suite 4
* (c) 2013 Invision Power Services - http://www.invisionpower.com
*
@@ -53,7 +53,7 @@
});
}(jQuery, _));]]></file>
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/checkout" javascript_name="ips.checkout.register.js" javascript_type="controller" javascript_version="100045" javascript_position="1000050">/**
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/checkout" javascript_name="ips.checkout.register.js" javascript_type="controller" javascript_version="101012" javascript_position="1000050">/**
* IPS Social Suite 4
* (c) 2013 Invision Power Services - http://www.invisionpower.com
*
@@ -86,7 +86,7 @@
}
});
}(jQuery, _));</file>
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/checkout" javascript_name="ips.checkout.review.js" javascript_type="controller" javascript_version="100045" javascript_position="1000050">/**
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/checkout" javascript_name="ips.checkout.review.js" javascript_type="controller" javascript_version="101012" javascript_position="1000050">/**
* IPS Social Suite 4
* (c) 2013 Invision Power Services - http://www.invisionpower.com
*
@@ -119,7 +119,7 @@
}
});
}(jQuery, _));</file>
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/checkout" javascript_name="ips.checkout.shippingForm.js" javascript_type="controller" javascript_version="100045" javascript_position="1000050">/**
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/checkout" javascript_name="ips.checkout.shippingForm.js" javascript_type="controller" javascript_version="101012" javascript_position="1000050">/**
* IPS Social Suite 4
* (c) 2013 Invision Power Services - http://www.invisionpower.com
*
@@ -142,7 +142,7 @@
}
});
}(jQuery, _));</file>
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/clients" javascript_name="ips.clients.referrals.js" javascript_type="controller" javascript_version="100045" javascript_position="1000100">/**
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/clients" javascript_name="ips.clients.referrals.js" javascript_type="controller" javascript_version="101012" javascript_position="1000100">/**
* IPS Social Suite 4
* (c) 2013 Invision Power Services - http://www.invisionpower.com
*
@@ -171,7 +171,7 @@
}
});
}(jQuery, _));</file>
<file javascript_app="nexus" javascript_location="global" javascript_path="controllers/forms" javascript_name="ips.forms.ftp.js" javascript_type="controller" javascript_version="100045" javascript_position="1000050"><![CDATA[/**
<file javascript_app="nexus" javascript_location="global" javascript_path="controllers/forms" javascript_name="ips.forms.ftp.js" javascript_type="controller" javascript_version="101012" javascript_position="1000050"><![CDATA[/**
* IPS Social Suite 4
* (c) 2013 Invision Power Services - http://www.invisionpower.com
*
@@ -226,7 +226,7 @@
});
}(jQuery, _));]]></file>
<file javascript_app="nexus" javascript_location="global" javascript_path="controllers/gateways" javascript_name="ips.gateways.authorizenet.js" javascript_type="controller" javascript_version="100045" javascript_position="1000100"><![CDATA[/**
<file javascript_app="nexus" javascript_location="global" javascript_path="controllers/gateways" javascript_name="ips.gateways.authorizenet.js" javascript_type="controller" javascript_version="101012" javascript_position="1000100"><![CDATA[/**
* IPS Social Suite 4
* (c) 2013 Invision Power Services - http://www.invisionpower.com
*
@@ -286,7 +286,7 @@
});
}(jQuery, _));]]></file>
<file javascript_app="nexus" javascript_location="global" javascript_path="controllers/gateways" javascript_name="ips.gateways.stripe.js" javascript_type="controller" javascript_version="100045" javascript_position="1000100"><![CDATA[/**
<file javascript_app="nexus" javascript_location="global" javascript_path="controllers/gateways" javascript_name="ips.gateways.stripe.js" javascript_type="controller" javascript_version="101012" javascript_position="1000100"><![CDATA[/**
* IPS Social Suite 4
* (c) 2013 Invision Power Services - http://www.invisionpower.com
*
@@ -417,7 +417,7 @@
});
}(jQuery, _));]]></file>
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/hosting" javascript_name="ips.nexus.hosting.accountform.js" javascript_type="controller" javascript_version="100045" javascript_position="1000050">/**
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/hosting" javascript_name="ips.nexus.hosting.accountform.js" javascript_type="controller" javascript_version="101012" javascript_position="1000050">/**
* IPS Social Suite 4
* (c) 2013 Invision Power Services - http://www.invisionpower.com
*
@@ -449,7 +449,7 @@
});
}(jQuery, _));</file>
<file javascript_app="nexus" javascript_location="global" javascript_path="controllers/misc" javascript_name="ips.misc.print.js" javascript_type="controller" javascript_version="100045" javascript_position="1000150">/**
<file javascript_app="nexus" javascript_location="global" javascript_path="controllers/misc" javascript_name="ips.misc.print.js" javascript_type="controller" javascript_version="101012" javascript_position="1000150">/**
* IPS Social Suite 4
* (c) 2013 Invision Power Services - http://www.invisionpower.com
*
@@ -471,7 +471,7 @@
});
}(jQuery, _));</file>
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/store" javascript_name="ips.store.cartReview.js" javascript_type="controller" javascript_version="100045" javascript_position="1000150">/**
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/store" javascript_name="ips.store.cartReview.js" javascript_type="controller" javascript_version="101012" javascript_position="1000150">/**
* IPS Social Suite 4
* (c) 2013 Invision Power Services - http://www.invisionpower.com
*
@@ -571,7 +571,47 @@
}
});
}(jQuery, _));</file>
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/store" javascript_name="ips.store.giftCard.js" javascript_type="controller" javascript_version="100045" javascript_position="1000150"><![CDATA[/**
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/store" javascript_name="ips.store.currencySelect.js" javascript_type="controller" javascript_version="101012" javascript_position="1000150">/**
* IPS Social Suite 4
* (c) 2015 Invision Power Services - http://www.invisionpower.com
*
* ips.store.currencySelect.js - Alert when changing currency
*
* Author: Mark Wade
*/
;( function($, _, undefined){
&quot;use strict&quot;;
ips.controller.register('nexus.front.store.currencySelect', {
initialize: function () {
this.on( 'click', 'a', this.currencyChangeWarning );
},
/**
* Prevent checkout button being clicked more than once
*
* @param {event} e Event object
* @returns {void}
*/
currencyChangeWarning: function (e) {
e.preventDefault();
ips.ui.alert.show({
type: 'confirm',
message: ips.getString('store_currency_change_warning'),
icon: 'warn',
callbacks: {
ok: function () {
window.location = $(e.currentTarget).attr('href');
}
}
});
}
});
}(jQuery, _));</file>
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/store" javascript_name="ips.store.giftCard.js" javascript_type="controller" javascript_version="101012" javascript_position="1000150"><![CDATA[/**
* IPS Social Suite 4
* (c) 2013 Invision Power Services - http://www.invisionpower.com
*
@@ -659,7 +699,7 @@
}
});
}(jQuery, _));]]></file>
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/store" javascript_name="ips.store.packagePage.js" javascript_type="controller" javascript_version="100045" javascript_position="1000150"><![CDATA[/**
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/store" javascript_name="ips.store.packagePage.js" javascript_type="controller" javascript_version="101012" javascript_position="1000150"><![CDATA[/**
* IPS Social Suite 4
* (c) 2013 Invision Power Services - http://www.invisionpower.com
*
@@ -781,6 +821,10 @@
// Are we already running inside of a dialog?
if( self.scope.closest('.ipsDialog').length ){
var dialogContent = self.scope.closest('.ipsDialog').find('.ipsDialog_content');
//see https://community.invisionpower.com/4bugtrack/active-reports/4013-adding-consecutive-items-from-the-list-to-the-cart-increases-number-of-continuecheckout-windows-r8137/
// We need to destroy this controller before updating the content so that event handlers are unregistered,
// otherwise this controller will continue listening for addToCart events and trigger multiple dialogs.
self.trigger('destroy');
dialogContent.html( response ).show();
$( document ).trigger( 'contentChange', [ dialogContent ] );
} else {
@@ -804,7 +848,7 @@
// Remove loading elem
loadingElem.remove();
self.updatePriceAndStock();
}
}
})
.fail(function(a){
var form = $(e.target).find('form');
@@ -844,7 +888,7 @@
});
}(jQuery, _));]]></file>
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/store" javascript_name="ips.store.productoptions.js" javascript_type="controller" javascript_version="100045" javascript_position="1000100"><![CDATA[/**
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/store" javascript_name="ips.store.productoptions.js" javascript_type="controller" javascript_version="101012" javascript_position="1000100"><![CDATA[/**
* IPS Social Suite 4
* (c) 2013 Invision Power Services - http://www.invisionpower.com
*
@@ -894,7 +938,7 @@
});
}(jQuery, _));]]></file>
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/store" javascript_name="ips.store.productselector.js" javascript_type="controller" javascript_version="100045" javascript_position="1000100"><![CDATA[/**
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/store" javascript_name="ips.store.productselector.js" javascript_type="controller" javascript_version="101012" javascript_position="1000100"><![CDATA[/**
* IPS Social Suite 4
* (c) 2013 Invision Power Services - http://www.invisionpower.com
*
@@ -947,12 +991,14 @@
* Increase Qty
*/
increaseQty: function (e) {
$( e.currentTarget ).find('input').val( parseInt( $( e.currentTarget ).find('input').val() ) + 1 );
if( !$(e.target).is('input') ) {
$( e.currentTarget ).find('input').val( parseInt( $( e.currentTarget ).find('input').val() ) + 1 );
}
}
});
}(jQuery, _));]]></file>
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/store" javascript_name="ips.store.register.js" javascript_type="controller" javascript_version="100045" javascript_position="1000150"><![CDATA[/**
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/store" javascript_name="ips.store.register.js" javascript_type="controller" javascript_version="101012" javascript_position="1000150"><![CDATA[/**
* IPS Social Suite 4
* (c) 2013 Invision Power Services - http://www.invisionpower.com
*
@@ -1078,7 +1124,7 @@
},
});
}(jQuery, _));]]></file>
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.emailsetup.js" javascript_type="controller" javascript_version="100045" javascript_position="1000150">/**
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.emailsetup.js" javascript_type="controller" javascript_version="101012" javascript_position="1000150">/**
* IPS Social Suite 4
* (c) 2013 Invision Power Services - http://www.invisionpower.com
*
@@ -1114,7 +1160,7 @@
});
}(jQuery, _));</file>
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.message.js" javascript_type="controller" javascript_version="100045" javascript_position="1000150"><![CDATA[/**
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.message.js" javascript_type="controller" javascript_version="101012" javascript_position="1000150"><![CDATA[/**
* IPS Social Suite 4
* (c) 2013 Invision Power Services - http://www.invisionpower.com
*
@@ -1153,7 +1199,8 @@
var realUrl = decodeURIComponent( ips.utils.url.getParam( 'url', elem.attr('href') ) );
elem.attr('target', '_blank');
if( realUrl != elem.text() ){
if( realUrl !== 'undefined' && realUrl != elem.text() ){
var icon = $('<i class="fa fa-external-link ipsCursor_pointer ipsType_medium" title="' + ips.getString('click_to_show_url') + '" data-ipsTooltip></i>');
icon.on( 'click', function () {
@@ -1169,7 +1216,7 @@
}
});
}(jQuery, _));]]></file>
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.metamenu.js" javascript_type="controller" javascript_version="100045" javascript_position="1000150"><![CDATA[/**
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.metamenu.js" javascript_type="controller" javascript_version="101012" javascript_position="1000150"><![CDATA[/**
* IPS Social Suite 4
* (c) 2013 Invision Power Services - http://www.invisionpower.com
*
@@ -1245,7 +1292,7 @@
});
}(jQuery, _));]]></file>
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.pendingalert.js" javascript_type="controller" javascript_version="100045" javascript_position="1000150">/**
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.pendingalert.js" javascript_type="controller" javascript_version="101012" javascript_position="1000150">/**
* IPS Social Suite 4
* (c) 2013 Invision Power Services - http://www.invisionpower.com
*
@@ -1272,7 +1319,7 @@
});
}(jQuery, _));</file>
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/support" javascript_name="ips.support.rate.js" javascript_type="controller" javascript_version="100045" javascript_position="1000200">/**
<file javascript_app="nexus" javascript_location="front" javascript_path="controllers/support" javascript_name="ips.support.rate.js" javascript_type="controller" javascript_version="101012" javascript_position="1000200">/**
* IPS Social Suite 4
* (c) 2013 Invision Power Services - http://www.invisionpower.com
*
@@ -1294,7 +1341,7 @@
}
});
}(jQuery, _));</file>
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.replyArea.js" javascript_type="controller" javascript_version="100045" javascript_position="1000150"><![CDATA[/**
<file javascript_app="nexus" javascript_location="admin" javascript_path="controllers/support" javascript_name="ips.support.replyArea.js" javascript_type="controller" javascript_version="101012" javascript_position="1000150"><![CDATA[/**
* IPS Social Suite 4
* (c) 2013 Invision Power Services - http://www.invisionpower.com
*
@@ -1378,7 +1425,7 @@
}
});
}(jQuery, _));]]></file>
<file javascript_app="nexus" javascript_location="admin" javascript_path="mixins" javascript_name="ips.support.requestTable.js" javascript_type="mixins" javascript_version="100045" javascript_position="1000200">/**
<file javascript_app="nexus" javascript_location="admin" javascript_path="mixins" javascript_name="ips.support.requestTable.js" javascript_type="mixins" javascript_version="101012" javascript_position="1000200">/**
* IPS Social Suite 4
* (c) 2013 Invision Power Services - http://www.invisionpower.com
*
@@ -1455,12 +1502,12 @@
}
});
}(jQuery, _));</file>
<file javascript_app="nexus" javascript_location="front" javascript_path="templates" javascript_name="ips.templates.store.js" javascript_type="template" javascript_version="100045" javascript_position="1000250"><![CDATA[ips.templates.set('nexus.store.productImage', " \
<file javascript_app="nexus" javascript_location="front" javascript_path="templates" javascript_name="ips.templates.store.js" javascript_type="template" javascript_version="101012" javascript_position="1000250"><![CDATA[ips.templates.set('nexus.store.productImage', " \
<a href='{{fullURL}}' data-fullURL='{{fullURL}}' class='cNexusProduct_primaryImage ipsContained' data-ipsLightbox data-ipsLightbox-group='product' data-ipsProductZoom>\
<img src='{{thumbURL}}' class='ipsImage ipsImage_thumb'>\
</a>\
");]]></file>
<file javascript_app="nexus" javascript_location="admin" javascript_path="templates" javascript_name="ips.templates.store.js" javascript_type="template" javascript_version="100045" javascript_position="1000250"><![CDATA[ips.templates.set('nexus.store.images', " \
<file javascript_app="nexus" javascript_location="admin" javascript_path="templates" javascript_name="ips.templates.store.js" javascript_type="template" javascript_version="101012" javascript_position="1000250"><![CDATA[ips.templates.set('nexus.store.images', " \
<div class='ipsGrid_span3 ipsAttach ipsImageAttach ipsPad_half ipsAreaBackground_light' id='{{id}}' data-role='file' data-fileid='{{id}}' data-fullsizeurl='{{imagesrc}}' data-thumbnailurl='{{thumbnail}}' data-isImage='1'>\
<ul class='ipsList_inline ipsImageAttach_controls'>\
<li><input type='radio' name='{{field_name}}_primary_image' value='{{id}}' title='{{#lang}}makePrimaryProductImage{{/lang}}' data-ipsTooltip></li>\
@@ -1478,7 +1525,7 @@
{{{thumb}}}\
{{/thumb}}\
</div>\
<h2 class='ipsType_reset ipsAttach_title ipsType_medium' data-role='title'>{{title}}</h2>\
<h2 class='ipsType_reset ipsAttach_title ipsType_medium ipsTruncate ipsTruncate_line' data-role='title'>{{title}}</h2>\
<p class='ipsType_light'>{{size}} &middot; <span data-role='status'>{{statusText}}</span></p>\
</div>\
");
+29 -6
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<language>
<app key="nexus" version="100045">
<app key="nexus" version="101012">
<word key="__app_nexus" js="0">Commerce</word>
<word key="menutab__nexus" js="0">Commerce</word>
<word key="menutab__nexus_icon" js="0">usd</word>
@@ -17,7 +17,13 @@
<word key="renew_days" js="0">{!#[1:day][?:# days]}</word>
<word key="renew_months" js="0">{!#[1:month][?:# months]}</word>
<word key="renew_years" js="0">{!#[1:year][?:# years]}</word>
<word key="product_reviews_container" js="0">product</word>
<word key="menu_item_4" js="0">Store</word>
<word key="menu_item_5" js="0">Support</word>
<word key="menu_item_6" js="0">My Details</word>
<word key="nexus_package_review" js="0">Product Reviews</word>
<word key="__indefart_support_request" js="0">a support request</word>
<word key="__indefart_product_reviews" js="0">a product review</word>
<word key="editor__nexus_Admin" js="0">Commerce Settings</word>
<word key="editor__nexus_Customer" js="0">Customer Fields</word>
<word key="editor__nexus_Store" js="0">Store Products</word>
@@ -92,6 +98,7 @@
<word key="gateway__Manual" js="0">Manual (check, bank wire, etc.)</word>
<word key="manual_instructions" js="0">Instructions</word>
<word key="manual_instructions_desc" js="0">Provide address to send check or bank account details for bank wire or any other instructions for submitting payment manually.</word>
<word key="manual_gateway_description_placeholder" js="0">Click to add description...</word>
<word key="gateway__SagePay" js="0">SagePay</word>
<word key="sagepay_vendor" js="0">Vendor Name</word>
<word key="sagepay_vendor_desc" js="0"><![CDATA[You must add the server IP address (%s) to your list of allowed IP addresses. <a href='{external.sagepay_ip}'>More Information</a>]]></word>
@@ -788,6 +795,7 @@
<word key="no_referrals" js="0">No referrals.</word>
<word key="see_all_support" js="0">See {!# [?:all requests][1:one request]}</word>
<word key="see_all_invoices" js="0">See {!# [?:all invoices][1:one invoice]}</word>
<word key="see_all_purchases" js="0">See {!# [?:all purchases][1:one purchase]}</word>
<word key="no_support_requests" js="0">No support requests</word>
<word key="invoice_created" js="0">Invoice created</word>
<word key="no_invoices" js="0">This customer has no invoices</word>
@@ -931,6 +939,8 @@
<word key="child_purchases" js="0">Child purchases</word>
<word key="view_purchases" js="0">View Purchases</word>
<word key="ps_id" js="0">ID</word>
<word key="members_purchases" js="0">%s's Purchases</word>
<word key="purchase_no_member" js="0">The customer associated with this purchase no longer exists.</word>
<word key="license_key" js="0">License Key</word>
<word key="generate_new_key" js="0">Generate new key</word>
<word key="lkey_using_x_of_unlimited_uses" js="0">Using %d of unlimited allowed uses</word>
@@ -946,7 +956,7 @@
<word key="license_key_uses" js="0">License key usage</word>
<word key="see_license_usage" js="0">View usage information</word>
<word key="menu__nexus_payments_payouts" js="0">Withdrawals</word>
<word key="payout_description" js="0"><![CDATA[If you have set up <a href='{internal.app=nexus&module=promotion&controller=refrules}'>referrals</a>, or you are using payment integration in another area of your community such the downloads system, members can earn money through your community.<br>All money earned will be given as account credit. If you want, you can allow members to withdraw this credit.]]></word>
<word key="payout_description" js="0"><![CDATA[If you have set up <a href='{internal.app=nexus&module=customers&controller=referrals}'>referrals</a>, or you are using payment integration in another area of your community such the downloads system, members can earn money through your community.<br>All money earned will be given as account credit. If you want, you can allow members to withdraw this credit.]]></word>
<word key="account_credit_settings" js="0">Account Credit Settings</word>
<word key="payout_settings" js="0">Withdrawal Settings</word>
<word key="commission_settings" js="0">Commission Settings</word>
@@ -965,6 +975,7 @@
<word key="paypal_api_signature" js="0">PayPal API Signature</word>
<word key="payout__front_PayPal" js="0">PayPal</word>
<word key="payout__data_PayPal" js="0">PayPal Email</word>
<word key="payout__data_Manual" js="0">Payment Details</word>
<word key="nexus_payout_min" js="0">Minimum Withdrawal</word>
<word key="nexus_payout_approve" js="0">Withdrawals must be approved?</word>
<word key="po_status" js="0">Status</word>
@@ -1150,6 +1161,7 @@
<word key="task__supportAssignedReminder" js="0">Sends a reminder email to staff members who have open support requests assigned to them.</word>
<word key="task__terminateHosting" js="0">Removes expired hosting accounts.</word>
<word key="support" js="0">Support</word>
<word key="my_support_requests" js="0">My Support Requests</word>
<word key="menu__nexus_support" js="0">Support</word>
<word key="support_title" js="0">Title</word>
<word key="support_container" js="0">Department</word>
@@ -1559,6 +1571,7 @@
<word key="package_registration" js="0">Registration</word>
<word key="p_reg" js="0">Show on registration form?</word>
<word key="p_reg_desc" js="0"><![CDATA[You can force users to purchase a product when registering in the <a href='{internal.app=nexus&module=store&controller=settings&searchResult=nexus_reg_force}'>Store Settings</a>.]]></word>
<word key="p_reg_err" js="0"><![CDATA[In order for a package to show on the registration form it must be set to show in the store and be available to the %s group. You can control these settings under the 'Store &amp; Purchase Settings' tab.]]></word>
<word key="package_relationships" js="0">Relationships</word>
<word key="package_associations" js="0">Association</word>
<word key="package_associations_desc" js="0">If you have multiple products which are related to each other, you can allow them be associated with one another to form parent/child relationships.</word>
@@ -1578,7 +1591,7 @@
<word key="p_upgrade_charge" js="0">Charge to upgrade</word>
<word key="p_upgrade_charge_none" js="0">No charge.</word>
<word key="p_upgrade_charge_full" js="0">Difference between the purchase prices.</word>
<word key="p_upgrade_charge_full_desc" js="0">For example, if the products is priced $10 and the customer upgrades to a product priced $15, they will be charged $5.</word>
<word key="p_upgrade_charge_full_desc" js="0">For example, if the product is priced $10 and the customer upgrades to a product priced $15, they will be charged $5.</word>
<word key="p_upgrade_charge_prorate" js="0">Difference between the renewal prices pro rata.</word>
<word key="p_upgrade_charge_prorate_desc" js="0">For example, if this product has a renewal charge of $10 per month and a customer has had it for half a month, and upgrades to a product which has a renewal charge of $20 per month, they will be charged the difference ($10) for the remaining half month, $5.</word>
<word key="p_allow_downgrading" js="0">Customers can downgrade from this product?</word>
@@ -1587,7 +1600,7 @@
<word key="p_downgrade_refund_desc" js="0">Refunds are given as credit on the customer's account.</word>
<word key="p_downgrade_refund_none" js="0">No refund.</word>
<word key="p_downgrade_refund_full" js="0">Difference between the purchase prices.</word>
<word key="p_downgrade_refund_full_desc" js="0">For example, if the products is priced $20 and the customer downgrades to a product priced $15, they will be refunded $5.</word>
<word key="p_downgrade_refund_full_desc" js="0">For example, if the product is priced $20 and the customer downgrades to a product priced $15, they will be refunded $5.</word>
<word key="p_downgrade_refund_prorate" js="0">Difference between the renewal prices pro rata.</word>
<word key="p_downgrade_refund_prorate_desc" js="0">For example, if this product has a renewal charge of $20 per month and a customer has had it for half a month, and downgrades to a product which has a renewal charge of $10 per month, they will be charged the difference ($10) for the remaining half month, $5.</word>
<word key="package_benefits" js="0">Purchase Benefits</word>
@@ -1843,6 +1856,7 @@
<word key="module__nexus_clients" js="0"><![CDATA[Billing & Purchases]]></word>
<word key="manage" js="0">Manage</word>
<word key="client_purchases" js="0">Manage Purchases</word>
<word key="client_area_my_details" js="0">My Details</word>
<word key="referrals" js="0">Referrals</word>
<word key="referrals_title" js="0">Earning Commission</word>
<word key="referrals_desc" js="0">You can earn commission by referring new customers to our site</word>
@@ -2059,8 +2073,14 @@
<word key="easypost_enable" js="0">Enable EasyPost integration?</word>
<word key="easypost_api_key" js="0">EasyPost API Key</word>
<word key="easypost_api_key_desc" js="0"><![CDATA[You can obtain your API key from <a href='{external.easypost_api_key}' target='_blank'>your EasyPost account</a>.]]></word>
<word key="easypost_address_select" js="0">Shipment 'From' Address</word>
<word key="easypost_address_select_desc" js="0">This is the address that is provided to EasyPost as the 'From' address where you will send shipments from.</word>
<word key="easypost_address_default" js="0">Site Physical Address (%s)</word>
<word key="easypost_address_default_desc" js="0"><![CDATA[Set in <a href='{internal.app=core&module=settings&controller=general}'>General Configuration</a>.]]></word>
<word key="easypost_address_choose" js="0">Other</word>
<word key="easypost_address_custom" js="0">Shipment 'From' Address</word>
<word key="easypost_phone" js="0">Your Phone Number</word>
<word key="easypost_phone_desc" js="0"><![CDATA[Some carriers require your phone number in case they need to contact you about a shipment. Your other details (company name and physical address) use the values given in your <a href='{internal.app=core&module=settings&controller=general}'>General Configuration</a>.]]></word>
<word key="easypost_phone_desc" js="0">Some carriers require your phone number in case they need to contact you about a shipment.</word>
<word key="easypost_bad_api_key" js="0">Invalid API key.</word>
<word key="address_couldnt_validate" js="0">That is not a valid shipping address.</word>
<word key="shipment_ship_method" js="0">How do you want to ship this product?</word>
@@ -2153,6 +2173,7 @@
<word key="easypost_test_no_length" js="0">The product %s has no length defined. You will need to edit the product and provide the length.</word>
<word key="easypost_test_no_width" js="0">The product %s has no width defined. You will need to edit the product and provide the width.</word>
<word key="easypost_test_no_weight" js="0">The product %s has no weight defined. You will need to edit the product and provide the weight.</word>
<word key="easypost_test_no_site_address" js="0"><![CDATA[You must <a href='{internal.app=core&module=settings&controller=general}'>set up a physical address</a> to test EasyPost settings.]]></word>
<word key="easypost_carrier" js="0">Carrier</word>
<word key="easypost_service" js="0">Service</word>
<word key="easypost_no_results" js="0">No carriers are able to ship that parcel to that location. Contact EasyPost or your carriers for more information.</word>
@@ -2517,7 +2538,7 @@ At this stage, no further action is required from you. We will send you an addit
<word key="email_invoice_number" js="0">Invoice Number</word>
<word key="email_purchase_date" js="0">Purchased On</word>
<word key="email_order_total" js="0">Order Total</word>
<word key="email_payout_message" js="0">Your withdrawl request for %s (placed on %s) has been processed successfully by %s.</word>
<word key="email_payout_message" js="0">Your withdrawal request for %s (placed on %s) has been processed successfully by %s.</word>
<word key="email_paid_by" js="0">Paid by</word>
<word key="email_invoice_outstanding" js="0">%s is outstanding.</word>
<word key="email_payment_unsuccessful" js="0">We tried to take payment by %s but it was unsuccessful.</word>
@@ -2573,6 +2594,7 @@ At this stage, no further action is required from you. We will send you an addit
<word key="can_hide_product_reviews" js="0">Can hide product reviews?</word>
<word key="can_unhide_product_reviews" js="0">Can unhide product reviews?</word>
<word key="can_view_hidden_product_reviews" js="0">Can view hidden product reviews?</word>
<word key="frontnavigation_support" js="0">Support</word>
<word key="payment_error" js="1">There was an error processing the payment. Please try a different payment method or contact us for assistance.</word>
<word key="support_ajax_error" js="1">An error occurred. Your session may have expired. Refresh the page and try again.</word>
<word key="click_to_show_url" js="1">Click to show real URL</word>
@@ -2583,5 +2605,6 @@ At this stage, no further action is required from you. We will send you an addit
<word key="changeShippingAddress" js="1">Change Shipping Address</word>
<word key="makePrimaryProductImage" js="1">Make this the primary image</word>
<word key="removeProductImage" js="1">Remove this image</word>
<word key="store_currency_change_warning" js="1">If you change the currency, you will lose all items currently in your cart.</word>
</app>
</language>
+20 -20
View File
@@ -386,18 +386,18 @@
"zerofill": false
},
"t_amount": {
"allow_null": false,
"auto_increment": false,
"binary": false,
"comment": "",
"decimals": null,
"default": "0",
"length": 0,
"name": "t_amount",
"type": "FLOAT",
"unsigned": false,
"type": "DECIMAL",
"length": 20,
"decimals": 2,
"values": [],
"zerofill": false
"allow_null": false,
"default": "0",
"comment": "",
"unsigned": false,
"zerofill": false,
"auto_increment": false,
"binary": false
},
"t_date": {
"allow_null": false,
@@ -1113,18 +1113,18 @@
"zerofill": false
},
"ps_renewal_price": {
"allow_null": false,
"auto_increment": false,
"binary": false,
"comment": "",
"decimals": null,
"default": "0",
"length": 0,
"name": "ps_renewal_price",
"type": "FLOAT",
"unsigned": false,
"type": "DECIMAL",
"length": 20,
"decimals": 2,
"values": [],
"zerofill": false
"allow_null": false,
"default": "0",
"comment": "",
"unsigned": false,
"zerofill": false,
"auto_increment": false,
"binary": false
},
"ps_renewal_unit": {
"allow_null": false,
+16
View File
@@ -1,4 +1,8 @@
[
{
"key": "card_storage_gateways",
"default": "0"
},
{
"key": "cm_invoice_expireafter",
"default": "30"
@@ -19,6 +23,18 @@
"key": "cm_ref_on",
"default": "0"
},
{
"key": "customer_fields",
"default": "0"
},
{
"key": "donation_goals",
"default": "0"
},
{
"key": "easypost_address",
"default": ""
},
{
"key": "easypost_api_key",
"default": ""
+103 -114
View File
@@ -576,11 +576,6 @@
</ul>
</div>
</div>
{{if \IPS\Request::i()->split}}
<div class='ipsMessage ipsMessage_info'>
You are paying <strong>{$amountToPay}</strong> with this payment
</div>
{{endif}}
{{else}}
<ul class='ipsList_reset ipsSpacer_bottom'>
{$input->rowHtml()|raw}
@@ -695,7 +690,6 @@
{{endif}}]]></template>
<template template_group="clients" template_name="addresses" template_data="$billingAddress = NULL, $shippingAddress = NULL, $otherAddresses" template_location="front" template_app="nexus"><![CDATA[<a href='{url="app=nexus&module=clients&controller=addresses&do=form" seoTemplate="clientsaddresses"}' class='ipsPos_right ipsButton ipsButton_important ipsButton_verySmall' title="{lang="address_add_title"}">{lang="address_add"}</a>
<h1 class='ipsType_pageTitle'>{lang="address_book"}</h1>
<hr class='ipsHr'>
<p class='ipsType_normal ipsSpacer_bottom ipsSpacer_double'>
{lang="address_book_info"}
@@ -733,7 +727,6 @@
{{endif}}]]></template>
<template template_group="clients" template_name="alternatives" template_data="" template_location="front" template_app="nexus"><![CDATA[<a href='{url="app=nexus&module=clients&controller=alternatives&do=form" seoTemplate="clientsalternatives"}' class='ipsPos_right ipsButton ipsButton_important ipsButton_verySmall' title="{lang="altcontact_add_title"}" data-ipsDialog data-ipsDialog-size='medium' data-ipsDialog-title="{lang="altcontact_add"}">{lang="altcontact_add"}</a>
<h1 class='ipsType_pageTitle'>{lang="altcontact_title"}</h1>
<hr class='ipsHr'>
<p class='ipsType_normal'>
{lang="altcontact_info"}
@@ -831,7 +824,6 @@
<template template_group="clients" template_name="cards" template_data="$cards" template_location="front" template_app="nexus"><![CDATA[
<a href='{url="app=nexus&module=clients&controller=cards&do=add" seoTemplate="clientscards"}' class='ipsPos_right ipsButton ipsButton_important ipsButton_verySmall' title="{lang="cards_add_title"}">{lang="cards_add"}</a>
<h1 class='ipsType_pageTitle'>{lang="cards_title"}</h1>
<hr class='ipsHr'>
<p class='ipsType_normal'>
{lang="cards_info"}
@@ -857,7 +849,6 @@
</ul>]]></template>
<template template_group="clients" template_name="credit" template_data="$balance, $pastWithdrawals, $pastWithdrawalsPagination, $canWithdraw, $canTopup" template_location="front" template_app="nexus"><![CDATA[
<h1 class='ipsType_pageTitle'>{lang="credit_title"}</h1>
<hr class='ipsHr'>
<div class='ipsColumns ipsColumns_collapsePhone'>
<div class='ipsColumn ipsColumn_wide'>
@@ -972,7 +963,6 @@
</div>]]></template>
<template template_group="clients" template_name="donations" template_data="" template_location="front" template_app="nexus"><![CDATA[
<h1 class='ipsType_pageTitle'>{lang="current_donation_goals"}</h1>
<hr class='ipsHr'>
{{if request.thanks}}
<p class="ipsMessage ipsMessage_success">{lang="thanks_for_your_donation"}</p>
@@ -1010,7 +1000,6 @@
{{endforeach}}]]></template>
<template template_group="clients" template_name="info" template_data="$form" template_location="front" template_app="nexus"><![CDATA[
<h1 class='ipsType_pageTitle'>{lang="customerinfo_title"}</h1>
<hr class='ipsHr'>
{$form|raw}]]></template>
<template template_group="clients" template_name="invoice" template_data="$invoice" template_location="front" template_app="nexus"><![CDATA[
@@ -1228,7 +1217,6 @@
{{endif}}]]></template>
<template template_group="clients" template_name="invoices" template_data="$invoices" template_location="front" template_app="nexus"><![CDATA[
{template="pageHeader" group="global" app="core" params="\IPS\Member::loggedIn()->language()->get('orders_title')"}
<hr class='ipsHr'>
{{if count( $invoices )}}
<ul class='ipsDataList ipsDataList_large cNexusOrderList'>
@@ -1565,7 +1553,6 @@
{{endforeach}}]]></template>
<template template_group="clients" template_name="purchases" template_data="$purchases" template_location="front" template_app="nexus"><![CDATA[
<h1 class='ipsType_pageTitle'>{lang="purchases_title"}</h1>
<hr class='ipsHr'>
{{if count( $purchases )}}
<p class='ipsType_normal'>
@@ -1583,7 +1570,6 @@
{{endif}}]]></template>
<template template_group="clients" template_name="referrals" template_data="$url, $rules" template_location="front" template_app="nexus"><![CDATA[
<h1 class='ipsType_pageTitle'>{lang="referrals"}</h1>
<hr class='ipsHr'>
{{if settings.nexus_com_rules}}
<h2 class='ipsType_sectionHead'>{lang="referrals_title"}</h2>
@@ -1662,11 +1648,11 @@
<div class='ipsGrid'>
<div class='ipsGrid_span6'>
<h3 class='ipsType_minorHeading'>{lang="referral_html"}</h3>
<input type='text' class='ipsField_fullWidth' value="&lt;a href='{$url}'&gt;&lt;img src='{$banner->url()}' alt='{setting="board_name"}'&gt;&lt;/a&gt;">
<input type='text' class='ipsField_fullWidth' value="&lt;a href='{$url}'&gt;&lt;img src='{$banner->url}' alt='{setting="board_name"}'&gt;&lt;/a&gt;">
</div>
<div class='ipsGrid_span6'>
<h3 class='ipsType_minorHeading'>{lang="referral_bbcode"}</h3>
<input type='text' class='ipsField_fullWidth' value="[url='{$url}'][img]{$banner->url()}[/img][/url]">
<input type='text' class='ipsField_fullWidth' value="[url='{$url}'][img]{$banner->url}[/img][/url]">
</div>
</div>
</div>
@@ -1676,39 +1662,6 @@
</div>
</div>
{{endif}}]]></template>
<template template_group="clients" template_name="template" template_data="$content" template_location="front" template_app="nexus"><![CDATA[
<h1 class='ipsType_pageTitle'>{lang="module__nexus_clients"}</h1>
<div class="ipsColumns ipsColumns_collapsePhone ipsSpacer_top">
<div class="ipsColumn ipsColumn_wide">
<div class='ipsAreaBackground_light ipsPad'>
<div class="ipsSideMenu" id='elBillingAndPurchasesMenu' data-ipsSideMenu>
<h3 class="ipsSideMenu_mainTitle ipsAreaBackground_reset ipsType_medium">
<a href="#elBillingAndPurchasesMenu" class="ipsPad_double" data-action="openSideMenu"><i class="fa fa-bars"></i> &nbsp;{lang="module__nexus_clients"}&nbsp;<i class="fa fa-caret-down"></i></a>
</h3>
<ul class="ipsSideMenu_list">
{{foreach \IPS\nexus\Customer::loggedIn()->clientAreaLinks() as $k}}
<li class="ipsSideMenu_item {{if request.controller === $k}}ipsSideMenu_itemActive{{endif}}">
{{if $k === 'invoices'}}
<a href="{url="app=nexus&module=clients&controller={$k}" seoTemplate="clients" protocol="\IPS\Settings::i()->nexus_https"}">
{{elseif $k === 'networkStatus'}}
<a href="{url="app=nexus&module=clients&controller={$k}" seoTemplate="clients{$k}"}">
{{else}}
<a href="{url="app=nexus&module=clients&controller={$k}" seoTemplate="clients{$k}" protocol="\IPS\Settings::i()->nexus_https"}">
{{endif}}
{lang="client_{$k}"}
</a>
</li>
{{endforeach}}
</ul>
</div>
</div>
</div>
<div class="ipsColumn ipsColumn_fluid">
<div>
{$content|raw}
</div>
</div>
</div>]]></template>
<template template_group="customers" template_name="addressItem" template_data="$address" template_location="admin" template_app="nexus"><![CDATA[
<div class='ipsType_normal'>
{$address['address']|raw}
@@ -2002,7 +1955,11 @@
<br>
{template="money" group="forms" location="global" params="$field->name . '[3]', json_decode( $field->value[2], TRUE ), array( 'unlimitedLang' => NULL )"}
</div>
<br> {lang="or"} <input type="checkbox" name="{$field->name}[4]" id="{$field->name}_nr" data-control="unlimited" {{if !$field->value[1]}}checked{{endif}}> <label for="{$field->name}_nr" class='ipsField_unlimited'>{lang="no_restriction"}</label>]]></template>
<br> {lang="or"}
<span class='ipsCustomInput'>
<input type="checkbox" name="{$field->name}[4]" id="{$field->name}_nr" data-control="unlimited" {{if !$field->value[1]}}checked{{endif}}>
<span></span>
</span> <label for="{$field->name}_nr" class='ipsField_unlimited'>{lang="no_restriction"}</label>]]></template>
<template template_group="customers" template_name="purchaseValueField" template_data="$field" template_location="admin" template_app="nexus"><![CDATA[<select name="{$field->name}[0]">
<option value="g" {{if $field->value[0] === 'g'}}selected{{endif}}>{lang="greater_than"}</option>
<option value="e" {{if $field->value[0] === 'e'}}selected{{endif}}>{lang="exactly"}</option>
@@ -2010,7 +1967,11 @@
</select>
<br>
{template="money" group="forms" location="global" params="$field->name . '[1]', json_decode( $field->value[1], TRUE ), array( 'unlimitedLang' => NULL )"}
<br> {lang="or"} <input type="checkbox" name="{$field->name}[2]" id="{$field->name}_nr" data-control="unlimited" {{if !$field->value[0]}}checked{{endif}}> <label for="{$field->name}_nr" class='ipsField_unlimited'>{lang="no_restriction"}</label>]]></template>
<br> {lang="or"}
<span class='ipsCustomInput'>
<input type="checkbox" name="{$field->name}[2]" id="{$field->name}_nr" data-control="unlimited" {{if !$field->value[0]}}checked{{endif}}>
<span></span>
</span> <label for="{$field->name}_nr" class='ipsField_unlimited'>{lang="no_restriction"}</label>]]></template>
<template template_group="customers" template_name="referralsOverview" template_data="$table, $headers, $rows, $quickSearch" template_location="admin" template_app="nexus"><![CDATA[
{{if count( $rows )}}
<ul class='ipsList_reset cCustomerOther_list'>
@@ -2065,7 +2026,7 @@
</td>
</tr>
{{endforeach}}]]></template>
<template template_group="customers" template_name="view" template_data="$customer, $notes, $noteCount, $primaryBillingAddress, $cards, $cardCount, $parents, $alternativeContacts, $altContactCount, $purchases, $purchaseCount, $invoices, $invoiceCount, $history, $referredBy, $refers, $referCount, $standing, $support, $supportCount, $sparkline" template_location="admin" template_app="nexus"><![CDATA[
<template template_group="customers" template_name="view" template_data="$customer, $notes, $noteCount, $primaryBillingAddress, $cards, $cardCount, $parents, $alternativeContacts, $altContactCount, $purchases, $purchaseCount, $invoices, $invoiceCount, $history, $referredBy, $refers, $referCount, $standing, $support, $supportCount, $sparkline, $purchaseRootCount" template_location="admin" template_app="nexus"><![CDATA[
<div class='ipsColumns ipsColumns_collapsePhone'>
<div class='ipsColumn ipsColumn_wide'>
<div class='ipsAreaBackground_light ipsPad'>
@@ -2086,7 +2047,7 @@
<ul class='ipsToolList ipsToolList_vertical ipsSpacer_top'>
{{if \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'invoices_add' )}}
<li><a href='{url="app=nexus&module=payments&controller=invoices&do=generate&member={$customer->member_id}"}' class='ipsButton ipsButton_primary ipsButton_fullWidth ipsButton_small'>{lang="add_invoice"}</a></li>
<li><a href='{url="app=nexus&module=payments&controller=invoices&do=generate&member={$customer->member_id}&_new=1"}' class='ipsButton ipsButton_primary ipsButton_fullWidth ipsButton_small'>{lang="add_invoice"}</a></li>
{{endif}}
<li><a href='{url="app=nexus&module=support&controller=requests&do=create&member={$customer->member_id}"}' data-ipsDialog data-ipsDialog-title='{lang="customer_new_request"}' class='ipsButton ipsButton_primary ipsButton_fullWidth ipsButton_small'>{lang="customer_new_request"}</a></li>
</ul>
@@ -2319,7 +2280,7 @@
<div class='ipsGrid ipsGrid_collapsePhone'>
<div class='ipsGrid_span6'>
<h2 class='acpBlock_title acpBlock_titleDark acpBlock_titleSmall ipsType_reset'>{lang="account_items"}</h2>
<div class='ipsTabs ipsClearfix ipsJS_show acpFormTabBar' id='tabs_customer' data-ipsTabBar data-ipsTabBar-stretch data-ipsTabBar-contentArea='#ipsTabs_content_customer'>
<div class='ipsTabs ipsTabs_stretch ipsClearfix ipsJS_show acpFormTabBar' id='tabs_customer' data-ipsTabBar data-ipsTabBar-contentArea='#ipsTabs_content_customer'>
<a href='#tabs_customer' data-action='expandTabs'><i class='fa fa-caret-down'></i></a>
<ul role='tablist'>
<li class='ipsType_center'>
@@ -2345,6 +2306,11 @@
<div id='ipsTabs_content_customer' class='acpFormTabContent'>
<div id='ipsTabs_tabs_customer_customer_tab_purchases_panel' class="ipsTabs_panel" aria-labelledby="customer_tab_purchases" aria-hidden="false">
{$purchases|raw}
{{if $purchaseRootCount > $purchases->rootsPerPage}}
<div class="ipsType_center ipsAreaBackground_light ipsPad">
<a href="{url="app=nexus&module=customers&controller=view&do=purchaseList&id={$customer->member_id}"}" class="ipsButton ipsButton_verySmall ipsButton_normal">{lang="see_all_purchases" pluralize="$purchaseCount"}</a>
</div>
{{endif}}
</div>
<div id='ipsTabs_tabs_customer_customer_tab_invoices_panel' class="ipsTabs_panel" aria-labelledby="customer_tab_invoices" aria-hidden="false">
{$invoices|raw}
@@ -2797,7 +2763,10 @@
&nbsp;
{lang="or"}
&nbsp;
<input type="checkbox" role='checkbox' data-control="unlimited" name="{$name}[unlimited]" value="1" {{if $unlimitedChecked}}checked aria-checked='true'{{endif}} id="{$name}-unlimitedCheck"> <label for='{$name}-unlimitedCheck' class='ipsField_unlimited'>{lang="$unlimited"}</label>
<span class='ipsCustomInput'>
<input type="checkbox" role='checkbox' data-control="unlimited" name="{$name}[unlimited]" value="1" {{if $unlimitedChecked}}checked aria-checked='true'{{endif}} id="{$name}-unlimitedCheck">
<span></span>
</span> <label for='{$name}-unlimitedCheck' class='ipsField_unlimited'>{lang="$unlimited"}</label>
<br>
{{endif}}]]></template>
<template template_group="global" template_name="commentTableHeader" template_data="$comment, $package, $item" template_location="front" template_app="nexus"><![CDATA[
@@ -2810,8 +2779,7 @@
<h3 class='ipsType_sectionHead'><a href="{$package->url()}" data-role='productLink' class='' itemprop="name">{$package->_title}</a></h3>
<p class='ipsType_normal ipsType_light ipsType_blendLinks ipsType_reset'>{lang="in"} <a href='{$item->container()->url()}'>{$item->container()->_title}</a></p>
<p class='ipsType_reset' itemprop="offers" itemscope itemtype="http://schema.org/Offer">
<span data-role="price" itemprop="price" content="{$package->price()->amount}">{$package->priceToDisplay()|raw}</span>
<meta itemprop="priceCurrency" content="{$package->price()->currency}">
<span data-role="price">{$package->priceToDisplay()|raw}</span>
</p>
</div>
</div>
@@ -3277,7 +3245,12 @@
{lang="invoice_po_number"}: {$invoice->po}<br>
<br>
{{endif}}
{$invoice->member->cm_name}<br>
{{if $invoice->member->member_id}}
{$invoice->member->cm_name}
{{else}}
{$invoice->guest_data['member']['name']}
{{endif}}
<br>
{{if $invoice->billaddress}}{$invoice->billaddress->toString('<br>')|raw}{{endif}}
</div>
<div class="ipsPos_right">
@@ -3767,6 +3740,7 @@
</div>
</li>]]></template>
<template template_group="payouts" template_name="link" template_data="$payout" template_location="admin" template_app="nexus"><![CDATA[<a href="{$payout->acpUrl()}">{$payout->amount}</a>]]></template>
<template template_group="payouts" template_name="Manual" template_data="$payout" template_location="admin" template_app="nexus"><![CDATA[<pre>{$payout->data}</pre>]]></template>
<template template_group="payouts" template_name="PayPal" template_data="$payout" template_location="admin" template_app="nexus"><![CDATA[<div class="ipsType_center">
<span class="ipsType_large">{$payout->data}</span>
</div>
@@ -3850,9 +3824,7 @@
<div class="ipsAreaBackground_light">
<h2 class="ipsType_sectionTitle">{lang="payout__data_{$payout->gateway}"}</h2>
<div class='ipsPad'>
{{if method_exists( \IPS\Theme::i()->getTemplate( 'payouts' ), $payout->gateway )}}
{template="$payout->gateway" params="$payout" group="payouts"}
{{endif}}
{template="$payout->gateway" params="$payout" group="payouts"}
</div>
</div>
</div>
@@ -3943,7 +3915,7 @@
<br>
{{endif}}
{{if $data['message']}}
{expression="nl2br( htmlentities( $data['message'], \IPS\HTMLENTITIES, 'UTF-8', FALSE ) )" raw="true"}
{expression="nl2br( htmlspecialchars( $data['message'], \IPS\HTMLENTITIES, 'UTF-8', FALSE ) )" raw="true"}
{{endif}}
{{if $data['sender']}}
<br><br>
@@ -4179,7 +4151,7 @@
{{endif}}
{{if $data['message']}}
<div id='message'>
{expression="nl2br( htmlentities( $data['message'], \IPS\HTMLENTITIES, 'UTF-8', FALSE ) )" raw="true"}
{expression="nl2br( htmlspecialchars( $data['message'], \IPS\HTMLENTITIES, 'UTF-8', FALSE ) )" raw="true"}
</div>
{{endif}}
{{if $data['sender']}}
@@ -4645,7 +4617,7 @@
{$customFieldsForm|raw}
]]></template>
<template template_group="purchases" template_name="view" template_data="$purchase, $children, $invoices, $customFields" template_location="admin" template_app="nexus"><![CDATA[<div class="ipsGrid">
<template template_group="purchases" template_name="view" template_data="$purchase, $customer, $children, $invoices, $customFields" template_location="admin" template_app="nexus"><![CDATA[<div class="ipsGrid">
<div class='ipsGrid_span4'>
{{if $purchase->cancelled}}
<p class='ipsAreaBackground_negative ipsPad ipsType_center ipsSpacer_bottom ipsSpacer_double ipsType_reset'>
@@ -4737,15 +4709,21 @@
<div class="ipsAreaBackground_light">
<h2 class="acpBlock_title acpBlock_titleDark acpBlock_titleSmall ipsType_blendLinks">{lang="purchase_customer_info"}</h2>
<div class='ipsPad ipsPhotoPanel ipsPhotoPanel_small ipsClearfix'>
<a href="{$purchase->member->acpUrl()}" class='ipsPos_left'><img src='{$purchase->member->photo}' class='ipsUserPhoto ipsUserPhoto_small'></a>
<div class='ipsType_normal'>
<h3 class='ipsType_large ipsType_reset ipsType_blendLinks'><strong><a href="{$purchase->member->acpUrl()}">{$purchase->member->cm_name}</a></strong></h3>
{$purchase->member->email}<br>
{lang="transaction_customer_since" sprintf="$purchase->member->joined->localeDate()"}<br>
{lang="transaction_spent" sprintf="$purchase->member->totalSpent()"}
{{if $customer}}
<div class='ipsPad ipsPhotoPanel ipsPhotoPanel_small ipsClearfix'>
<a href="{$purchase->member->acpUrl()}" class='ipsPos_left'><img src='{$purchase->member->photo}' class='ipsUserPhoto ipsUserPhoto_small'></a>
<div class='ipsType_normal'>
<h3 class='ipsType_large ipsType_reset ipsType_blendLinks'><strong><a href="{$purchase->member->acpUrl()}">{$purchase->member->cm_name}</a></strong></h3>
{$purchase->member->email}<br>
{lang="transaction_customer_since" sprintf="$purchase->member->joined->localeDate()"}<br>
{lang="transaction_spent" sprintf="$purchase->member->totalSpent()"}
</div>
</div>
</div>
{{else}}
<div class='ipsPad ipsClearfix'>
<p class="ipsMessage ipsMessage_error">{lang="purchase_no_member"}</p>
</div>
{{endif}}
</div>
<br><br>
</div>
@@ -5103,6 +5081,7 @@
<a class="ipsButton ipsButton_large ipsButton_light ipsButton_fullWidth" href="{url="app=nexus&module=store" seoTemplate="store"}" title=""><i class='fa fa-chevron-left ipsPos_middle'></i>&nbsp; {lang="continue_shopping"}</a>
</li>
</ul>
<br>
{{else}}
<div class='ipsBox ipsPad ipsType_center ipsType_large ipsType_light'>
{lang="your_cart_empty"}
@@ -5317,7 +5296,7 @@
<a href='#elCategories_menu' class='ipsPad_double' data-action='openSideMenu'><i class='fa fa-bars'></i> &nbsp;{lang="categories"}&nbsp;<i class='fa fa-caret-down'></i></a>
</h3>
<p class='ipsType_reset ipsType_medium cNexusCategoriesBox_back'>
<a href='{$category->url()}'><i class='fa fa-chevron-left'></i> {lang="all_categories"}</a>
<a href='{url="app=nexus&module=store&controller=store" seoTemplate="store"}'><i class='fa fa-chevron-left'></i> {lang="all_categories"}</a>
</p>
<hr class='ipsHr'>
<h4 class='ipsSideMenu_title ipsSpacer_top ipsSpacer_half'>{$category->_title}</h4>
@@ -5327,10 +5306,10 @@
<a href='{$subcategory->url()}' class='ipsSideMenu_item'><strong>{$subcategory->_title}</strong></a>
{{if $subcategory->hasSubgroups()}}
<ul class='ipsSideMenu_list'>
{{foreach $subcategory->children() as $cidx => $child}}
{{foreach $subcategory->children( 'view', NULL, FALSE ) as $cidx => $child}}
<li>
{{if $cidx >= 5}}
<a href='{$subcategory->url()}' class='ipsSideMenu_item'><span class='ipsType_light ipsType_small'>{lang="and_x_more" sprintf="count( $subcategory->children() ) - 5"}</span></a>
<a href='{$subcategory->url()}' class='ipsSideMenu_item'><span class='ipsType_light ipsType_small'>{lang="and_x_more" sprintf="count( $subcategory->children( 'view', NULL, FALSE ) ) - 5"}</span></a>
{{break;}}
{{else}}
<a href="{$child->url()}" class='ipsSideMenu_item ipsTruncate ipsTruncate_line'>{$child->_title}</a>
@@ -5344,7 +5323,7 @@
</ul>
</div>
{{elseif $category && $category->parent()}}
{{$siblings = $category->parent()->children();}}
{{$siblings = $category->parent()->children( 'view', NULL, FALSE );}}
<div class='ipsSideMenu ipsSideMenu_withRadios ipsType_medium' id='elCategories_menu'>
<h3 class='ipsSideMenu_mainTitle ipsAreaBackground_light ipsType_medium'>
<a href='#elCategories_menu' class='ipsPad_double' data-action='openSideMenu'><i class='fa fa-bars'></i> &nbsp;{lang="categories"}&nbsp;<i class='fa fa-caret-down'></i></a>
@@ -5360,10 +5339,10 @@
<a href='{$sibling->url()}' class='ipsSideMenu_item {{if $category && $category == $sibling}}ipsSideMenu_itemActive{{endif}}'>{$sibling->_title}</a>
{{if $sibling instanceof \IPS\nexus\Package\Group && $sibling->hasSubgroups()}}
<ul class='ipsSideMenu_list'>
{{foreach $sibling->children() as $cidx => $child}}
{{foreach $sibling->children( 'view', NULL, FALSE ) as $cidx => $child}}
<li>
{{if $cidx >= 5}}
<a href='{$sibling->url()}' class='ipsSideMenu_item'><span class='ipsType_light ipsType_small'>{lang="and_x_more" sprintf="count( $sibling->children() ) - 5"}</span></a>
<a href='{$sibling->url()}' class='ipsSideMenu_item'><span class='ipsType_light ipsType_small'>{lang="and_x_more" sprintf="count( $sibling->children( 'view', NULL, FALSE ) ) - 5"}</span></a>
{{break;}}
{{else}}
<a href="{$child->url()}" class='ipsSideMenu_item ipsTruncate ipsTruncate_line'>{$child->_title}</a>
@@ -5387,10 +5366,10 @@
<a href='{$group->url()}' class='ipsSideMenu_item {{if $category && $category == $group}}ipsSideMenu_itemActive{{endif}}'><strong>{$group->_title}</strong></a>
{{if $group->hasSubgroups()}}
<ul class='ipsSideMenu_list'>
{{foreach $group->children() as $idx => $child}}
{{foreach $group->children( 'view', NULL, FALSE ) as $idx => $child}}
<li>
{{if $idx >= 5}}
<a href='{$group->url()}' class='ipsSideMenu_item'><span class='ipsType_light ipsType_small'>{lang="and_x_more" sprintf="count( $group->children() ) - 5"}</span></a>
<a href='{$group->url()}' class='ipsSideMenu_item'><span class='ipsType_light ipsType_small'>{lang="and_x_more" sprintf="count( $group->children( 'view', NULL, FALSE ) ) - 5"}</span></a>
{{break;}}
{{else}}
<a href="{$child->url()}" class='ipsSideMenu_item ipsTruncate ipsTruncate_line'>{$child->_title}</a>
@@ -5420,7 +5399,7 @@
</div>]]></template>
<template template_group="store" template_name="chooseCurrency" template_data="$baseUrl" template_location="front" template_app="nexus"><![CDATA[{{if count( \IPS\nexus\Money::currencies() ) > 1}}
{{$memberCurrency = ( isset( $_SESSION['currency'] ) ? $_SESSION['currency'] : \IPS\nexus\Customer::loggedIn()->defaultCurrency() );}}
<div class='ipsType_center ipsAreaBackground_light ipsPad ipsSpacer_top ipsSpacer_half'>
<div class='ipsType_center ipsAreaBackground_light ipsPad ipsSpacer_top ipsSpacer_half' {{if isset( $_SESSION['cart'] ) and count( $_SESSION['cart'] )}}data-controller="nexus.front.store.currencySelect"{{endif}}>
<span class='ipsType_normal'>{lang="show_prices_in"}</span><br>
<ul class='ipsList_inline'>
{{foreach \IPS\nexus\Money::currencies() as $currency}}
@@ -5816,8 +5795,7 @@
</div>
<div class='ipsDataItem_generic ipsDataItem_size5 ipsPos_top ipsType_right'>
<div class='ipsPad_half' itemprop="offers" itemscope itemtype="http://schema.org/Offer">
<span data-role="price" itemprop="price" content="{$package->price()->amount}">{$package->priceToDisplay()|raw}</span>
<meta itemprop="priceCurrency" content="{$package->price()->currency}">
<span data-role="price">{$package->priceToDisplay()|raw}</span>
{{if $package->physical}}
{{if $package->stock !== 0}}
@@ -5915,7 +5893,11 @@
{{endforeach}}
<td data-role="unlimitedCatch">
<input type="number" name="custom_fields[{$k}][stock]" class="ipsField_short" {{if isset( $existingValues[ $k ] ) and $existingValues[ $k ]['opt_stock'] != -1}}value="{$existingValues[ $k ]['opt_stock']}"{{endif}}><br>
{lang="or"} <input type="checkbox" name="custom_fields[{$k}][unlimitedStock]" id="custom_fields_{$k}_unlimitedStock" data-control="unlimited" {{if isset( $existingValues[ $k ] ) and $existingValues[ $k ]['opt_stock'] == -1}}checked{{endif}}> <label for="custom_fields_{$k}_unlimitedStock" class='ipsField_unlimited'>{lang="unlimited"}</label>
{lang="or"}
<span class='ipsCustomInput'>
<input type="checkbox" name="custom_fields[{$k}][unlimitedStock]" id="custom_fields_{$k}_unlimitedStock" data-control="unlimited" {{if isset( $existingValues[ $k ] ) and $existingValues[ $k ]['opt_stock'] == -1}}checked{{endif}}>
<span></span>
</span> <label for="custom_fields_{$k}_unlimitedStock" class='ipsField_unlimited'>{lang="unlimited"}</label>
</td>
<td>
{{$values = isset( $existingValues[ $k ] ) ? json_decode( $existingValues[ $k ]['opt_base_price'], TRUE ) : array();}}
@@ -5997,7 +5979,7 @@
<p class='ipsType_right ipsType_normal'><a href='{url="app=core&module=system&controller=register&noPurchase=1" seoTemplate="register"}'>{lang="continue_without_purchasing"} <i class='fa fa-caret-right'></i></a></p>
{{endif}}
</div>]]></template>
<template template_group="store" template_name="reviews" template_data="$item" template_location="front" template_app="nexus"><![CDATA[<div data-controller='core.front.core.commentFeed' data-baseURL='{$item->url()}' {{if $item->isLastPage('reviews')}}data-lastPage{{endif}} data-feedID='product-{$item->id}-reviews'>
<template template_group="store" template_name="reviews" template_data="$item" template_location="front" template_app="nexus"><![CDATA[<div data-controller='core.front.core.commentFeed' {{if settings.auto_polling_enabled}}data-autoPoll{{endif}} data-baseURL='{$item->url()}' {{if $item->isLastPage('reviews')}}data-lastPage{{endif}} data-feedID='product-{$item->id}-reviews'>
{{if $item->canReview()}}
<div id='elProductReviewForm'>
{$item->reviewForm()|raw}
@@ -6014,8 +5996,8 @@
{{endif}}
{{endif}}
{{if count( $item->reviews() )}}
<hr class='ipsHr'>
<div class="ipsClearfix ipsSpacer_both">
{{if !$item->hasReviewed()}}<hr class='ipsHr'>{{endif}}
<div class="ipsClearfix ipsSpacer_bottom">
{{if $item->reviewPageCount() > 1}}
<div class="ipsPos_left ipsResponsive_noFloat">
{$item->reviewPagination( array( 'tab', 'sort' ) )|raw}
@@ -6046,6 +6028,8 @@
{$item->reviewPagination( array( 'tab', 'sort' ) )|raw}
</div>
{{endif}}
{{elseif !$item->canReview()}}
<p class="ipsType_normal ipsType_light ipsType_reset" data-role="noReviews">{lang="no_reviews"}</p>
{{endif}}
</div>]]></template>
<template template_group="store" template_name="storeIndexProductsSetting" template_data="$key, $name, $value" template_location="admin" template_app="nexus"><![CDATA[{lang="$key" htmlsprintf="'<input type=\'number\' name=\'' . $name . '[0]\' value=\'' . $value[0] . '\' class=\'ipsField_tiny\'>', '<input type=\'number\' name=\'' . $name . '[1]\' value=\'' . ( isset( $value[1] ) ? $value[1] : '' ). '\' class=\'ipsField_tiny\'>'"}]]></template>
@@ -6080,7 +6064,11 @@
</select>
<label>{lang="ago"}</label>
<br><br>
{lang="or"} <input type="checkbox" name="{$name}[3]" {{if !$number}}checked{{endif}} data-control="unlimited" id="{$name}_unlimited"> <label for="{$name}_unlimited" class='ipsField_unlimited'>{lang="do_not_highlight_requests"}</label>]]></template>
{lang="or"}
<span class='ipsCustomInput'>
<input type="checkbox" name="{$name}[3]" {{if !$number}}checked{{endif}} data-control="unlimited" id="{$name}_unlimited">
<span></span>
</span> <label for="{$name}_unlimited" class='ipsField_unlimited'>{lang="do_not_highlight_requests"}</label>]]></template>
<template template_group="support" template_name="latestFeedback" template_data="$table, $headers, $rows" template_location="admin" template_app="nexus"><![CDATA[{{if $table->pages > 1}}
<div data-role="tablePagination">
{template="pagination" group="global" app="core" location="global" params="$table->baseUrl, $table->pages, $table->page, $table->limit"}
@@ -6390,7 +6378,7 @@
</div>
</div>
</div>
<div class='ipsPad ipsAreaBackground_light' data-controller='core.front.core.commentFeed' data-baseURL='{$request->acpUrl()}' data-feedID='request-{$request->id}'>
<div class='ipsPad ipsAreaBackground_light' data-controller='core.front.core.commentFeed' {{if settings.auto_polling_enabled}}data-autoPoll{{endif}} data-baseURL='{$request->acpUrl()}' data-feedID='request-{$request->id}'>
{{$order = isset( \IPS\Request::i()->order ) ? \IPS\Request::i()->order : ( isset( \IPS\Request::i()->cookie['support_order'] ) ? \IPS\Request::i()->cookie['support_order'] : 'desc' );}}
<div class="ipsType_right ipsType_small">
{{if $order === 'desc'}}
@@ -8620,20 +8608,20 @@ html[dir="rtl"] .cNexusPurchase {
background-repeat: no-repeat;
}
.cPayment_visa { background-image: url( {resource="cards/visa.png" app="nexus" location="front"} ); }
.cPayment_mastercard { background-image: url( {resource="cards/mastercard.png" app="nexus" location="front"} ); }
.cPayment_american_express { background-image: url( {resource="cards/amex.png" app="nexus" location="front"} ); }
.cPayment_discover { background-image: url( {resource="cards/discover.png" app="nexus" location="front"} ); }
.cPayment_diners_club { background-image: url( {resource="cards/dinersclub.png" app="nexus" location="front"} ); }
.cPayment_jcb { background-image: url( {resource="cards/jcb.png" app="nexus" location="front"} ); }
.cPayment_visa { background-image: url( "{resource="cards/visa.png" app="nexus" location="front"}" ); }
.cPayment_mastercard { background-image: url( "{resource="cards/mastercard.png" app="nexus" location="front"}" ); }
.cPayment_american_express { background-image: url( "{resource="cards/amex.png" app="nexus" location="front"}" ); }
.cPayment_discover { background-image: url( "{resource="cards/discover.png" app="nexus" location="front"}" ); }
.cPayment_diners_club { background-image: url( "{resource="cards/dinersclub.png" app="nexus" location="front"}" ); }
.cPayment_jcb { background-image: url( "{resource="cards/jcb.png" app="nexus" location="front"}" ); }
@media screen and (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
.cPayment_visa { background-image: url( {resource="cards/visa@2x.png" app="nexus" location="front"} ); }
.cPayment_mastercard { background-image: url( {resource="cards/mastercard@2x.png" app="nexus" location="front"} ); }
.cPayment_american_express { background-image: url( {resource="cards/amex@2x.png" app="nexus" location="front"} ); }
.cPayment_discover { background-image: url( {resource="cards/discover@2x.png" app="nexus" location="front"} ); }
.cPayment_diners_club { background-image: url( {resource="cards/dinersclub@2x.png" app="nexus" location="front"} ); }
.cPayment_jcb { background-image: url( {resource="cards/jcb@2x.png" app="nexus" location="front"} ); }
.cPayment_visa { background-image: url( "{resource="cards/visa@2x.png" app="nexus" location="front"}" ); }
.cPayment_mastercard { background-image: url( "{resource="cards/mastercard@2x.png" app="nexus" location="front"}" ); }
.cPayment_american_express { background-image: url( "{resource="cards/amex@2x.png" app="nexus" location="front"}" ); }
.cPayment_discover { background-image: url( "{resource="cards/discover@2x.png" app="nexus" location="front"}" ); }
.cPayment_diners_club { background-image: url( "{resource="cards/dinersclub@2x.png" app="nexus" location="front"}" ); }
.cPayment_jcb { background-image: url( "{resource="cards/jcb@2x.png" app="nexus" location="front"}" ); }
}]]></css>
<css css_location="front" css_app="nexus" css_attributes="" css_path="." css_name="donations.css">.cDonateProgressBar {
width: 100%;
@@ -8894,20 +8882,20 @@ ul.cInvoiceUnpaidConsequences ul {
background-repeat: no-repeat;
}
.cPayment_visa { background-image: url( {resource="cards/visa.png" app="nexus" location="front" noprotocol="true"} ); }
.cPayment_mastercard { background-image: url( {resource="cards/mastercard.png" app="nexus" location="front" noprotocol="true"} ); }
.cPayment_american_express { background-image: url( {resource="cards/amex.png" app="nexus" location="front" noprotocol="true"} ); }
.cPayment_discover { background-image: url( {resource="cards/discover.png" app="nexus" location="front" noprotocol="true"} ); }
.cPayment_diners_club { background-image: url( {resource="cards/dinersclub.png" app="nexus" location="front" noprotocol="true"} ); }
.cPayment_jcb { background-image: url( {resource="cards/jcb.png" app="nexus" location="front" noprotocol="true"} ); }
.cPayment_visa { background-image: url( "{resource="cards/visa.png" app="nexus" location="front" noprotocol="true"}" ); }
.cPayment_mastercard { background-image: url( "{resource="cards/mastercard.png" app="nexus" location="front" noprotocol="true"}" ); }
.cPayment_american_express { background-image: url( "{resource="cards/amex.png" app="nexus" location="front" noprotocol="true"}" ); }
.cPayment_discover { background-image: url( "{resource="cards/discover.png" app="nexus" location="front" noprotocol="true"}" ); }
.cPayment_diners_club { background-image: url( "{resource="cards/dinersclub.png" app="nexus" location="front" noprotocol="true"}" ); }
.cPayment_jcb { background-image: url( "{resource="cards/jcb.png" app="nexus" location="front" noprotocol="true"}" ); }
@media screen and (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
.cPayment_visa { background-image: url( {resource="cards/visa@2x.png" app="nexus" location="front" noprotocol="true"} ); }
.cPayment_mastercard { background-image: url( {resource="cards/mastercard@2x.png" app="nexus" location="front" noprotocol="true"} ); }
.cPayment_american_express { background-image: url( {resource="cards/amex@2x.png" app="nexus" location="front" noprotocol="true"} ); }
.cPayment_discover { background-image: url( {resource="cards/discover@2x.png" app="nexus" location="front" noprotocol="true"} ); }
.cPayment_diners_club { background-image: url( {resource="cards/dinersclub@2x.png" app="nexus" location="front" noprotocol="true"} ); }
.cPayment_jcb { background-image: url( {resource="cards/jcb@2x.png" app="nexus" location="front" noprotocol="true"} ); }
.cPayment_visa { background-image: url( "{resource="cards/visa@2x.png" app="nexus" location="front" noprotocol="true"}" ); }
.cPayment_mastercard { background-image: url( "{resource="cards/mastercard@2x.png" app="nexus" location="front" noprotocol="true"}" ); }
.cPayment_american_express { background-image: url( "{resource="cards/amex@2x.png" app="nexus" location="front" noprotocol="true"}" ); }
.cPayment_discover { background-image: url( "{resource="cards/discover@2x.png" app="nexus" location="front" noprotocol="true"}" ); }
.cPayment_diners_club { background-image: url( "{resource="cards/dinersclub@2x.png" app="nexus" location="front" noprotocol="true"}" ); }
.cPayment_jcb { background-image: url( "{resource="cards/jcb@2x.png" app="nexus" location="front" noprotocol="true"}" ); }
}
.cNexusCard_expiry select {
@@ -9717,7 +9705,8 @@ html[dir="rtl"] .cNexusSupportForm_sendTo .ipsForm_horizontal .ipsFieldRow:not(
}
.cNexusAdminSupportMessage_author {
margin: 7px 15px 0 15px;
margin: 0 15px 0 15px;
padding-top: 7px;
padding-bottom: 7px;
border-bottom: 1px solid rgba(0,0,0,0.1);
}
+14 -1
View File
@@ -111,5 +111,18 @@
"100042": "4.0.12",
"100043": "4.0.12.1",
"100044": "4.0.13",
"100045": "4.0.13.1"
"100045": "4.0.13.1",
"101000": "4.1.0 Beta 1",
"101001": "4.1.0 Beta 2",
"101002": "4.1.0 Beta 3",
"101003": "4.1.0 Beta 4",
"101004": "4.1.0 Beta 5",
"101005": "4.1.0 Beta 6",
"101006": "4.1.0 Beta 7",
"101007": "4.1.0 Beta 8",
"101008": "4.1.0 Beta 9",
"101009": "4.1.0 Beta 10",
"101010": "4.1.0",
"101011": "4.1.1",
"101012": "4.1.2"
}
@@ -65,10 +65,18 @@ class _EasyPost
{
return $this->_test();
}
$haveSiteAddress = ( \IPS\Settings::i()->site_address and \IPS\Settings::i()->site_address != 'null' );
$form = new \IPS\Helpers\Form;
$form->add( new \IPS\Helpers\Form\YesNo( 'easypost_enable', (bool) \IPS\Settings::i()->easypost_api_key, FALSE, array( 'togglesOn' => array( 'easypost_api_key', 'easypost_phone', 'easypost_show_rates' ) ) ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'easypost_enable', (bool) \IPS\Settings::i()->easypost_api_key, FALSE, array( 'togglesOn' => array( 'easypost_api_key', ( $haveSiteAddress ? 'easypost_address_select' : 'easypost_address_custom' ), 'easypost_phone', 'easypost_show_rates' ) ) ) );
$form->add( new \IPS\Helpers\Form\Text( 'easypost_api_key', \IPS\Settings::i()->easypost_api_key, FALSE, array(), NULL, NULL, NULL, 'easypost_api_key' ) );
if ( $haveSiteAddress )
{
$form->add( new \IPS\Helpers\Form\Radio( 'easypost_address_select', \IPS\Settings::i()->easypost_address ? 1 : 0, FALSE, array( 'options' => array( 0 => 'easypost_address_default', 1 => 'easypost_address_choose' ), 'toggles' => array( 1 => array( 'easypost_address_custom' ) ) ), NULL, NULL, NULL, 'easypost_address_select' ) );
\IPS\Member::loggedIn()->language()->words['easypost_address_default'] = sprintf( \IPS\Member::loggedIn()->language()->get( 'easypost_address_default' ), \IPS\GeoLocation::buildFromJson( \IPS\Settings::i()->site_address ) );
}
$form->add( new \IPS\Helpers\Form\Address( 'easypost_address_custom', \IPS\Settings::i()->easypost_address ? \IPS\GeoLocation::buildFromJson( \IPS\Settings::i()->easypost_address ) : NULL, FALSE, array(), NULL, NULL, NULL, 'easypost_address_custom' ) );
$form->add( new \IPS\Helpers\Form\Tel( 'easypost_phone', \IPS\Settings::i()->easypost_phone, FALSE, array(), NULL, NULL, NULL, 'easypost_phone' ) );
$form->add( new \IPS\Helpers\Form\Radio( 'easypost_show_rates', \IPS\Settings::i()->easypost_show_rates, FALSE, array(
'options' => array( 1 => 'easypost_show_rates_1', 0 => 'easypost_show_rates_0' ),
@@ -81,6 +89,7 @@ class _EasyPost
{
$values['easypost_tax'] = $values['easypost_tax'] ? $values['easypost_tax']->_id : 0;
$values['easypost_price_adjustment'] = json_encode( $values['easypost_price_adjustment'] );
$values['easypost_address'] = ( !$haveSiteAddress or $values['easypost_address_select'] ) ? json_encode( $values['easypost_address_custom'] ) : '';
try
{
if ( $values['easypost_enable'] )
@@ -164,6 +173,11 @@ class _EasyPost
*/
protected function _test()
{
if( !\IPS\Settings::i()->site_address or \IPS\Settings::i()->site_address == 'null' )
{
throw new \DomainException( \IPS\Member::loggedIn()->language()->addToStack( 'easypost_test_no_site_address' ) );
}
$form = new \IPS\Helpers\Form;
$form->addMessage( 'easypost_test_blurb' );
$form->add( new \IPS\Helpers\Form\Radio( 'easypost_test_method', \IPS\Settings::i()->easypost_show_rates, TRUE, array(
@@ -23,11 +23,25 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
* @brief Content Router extension: Reviews
*/
class _Reviews
{
{
/**
* @brief Content Item Classes
*/
public $classes = array( 'IPS\nexus\Package\Review' );
public $classes = array();
/**
* Constructor
*
* @param \IPS\Member|NULL $member If checking access, the member to check for, or NULL to not check access
* @return void
*/
public function __construct( \IPS\Member $member = NULL )
{
if ( ( $member === NULL or $member->canAccessModule( \IPS\Application\Module::get( 'nexus', 'store', 'front' ) ) ) and \IPS\Db::i()->select( 'COUNT(*)', 'nexus_packages', array( 'p_store=1 AND p_reviewable=1' ) )->first() )
{
$this->classes[] = 'IPS\nexus\Package\Review';
}
}
/**
* @brief Item Classes for embed only
@@ -0,0 +1,76 @@
<?php
/**
* @brief Front Navigation Extension: Addresses
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Nexus
* @since 29 Apr 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\nexus\extensions\core\FrontNavigation;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Front Navigation Extension: Addresses
*/
class _Addresses extends \IPS\core\FrontNavigation\FrontNavigationAbstract
{
/**
* Get Type Title which will display in the AdminCP Menu Manager
*
* @return string
*/
public static function typeTitle()
{
return \IPS\Member::loggedIn()->language()->addToStack('client_addresses');
}
/**
* Can access?
*
* @return bool
*/
public function canView()
{
return parent::canView() and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'nexus', 'clients' ) );
}
/**
* Get Title
*
* @return string
*/
public function title()
{
return \IPS\Member::loggedIn()->language()->addToStack('client_addresses');
}
/**
* Get Link
*
* @return \IPS\Http\Url
*/
public function link()
{
return \IPS\Http\Url::internal( "app=nexus&module=clients&controller=addresses", 'front', 'clientsaddresses', \IPS\Settings::i()->nexus_https );
}
/**
* Is Active?
*
* @return bool
*/
public function active()
{
return \IPS\Dispatcher::i()->application->directory === 'nexus' and \IPS\Dispatcher::i()->module and \IPS\Dispatcher::i()->module->key === 'clients' and \IPS\Dispatcher::i()->controller == 'addresses';
}
}
@@ -0,0 +1,76 @@
<?php
/**
* @brief Front Navigation Extension: Alternative Contacts
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Nexus
* @since 29 Apr 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\nexus\extensions\core\FrontNavigation;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Front Navigation Extension: Alternative Contacts
*/
class _Alternatives extends \IPS\core\FrontNavigation\FrontNavigationAbstract
{
/**
* Get Type Title which will display in the AdminCP Menu Manager
*
* @return string
*/
public static function typeTitle()
{
return \IPS\Member::loggedIn()->language()->addToStack('client_alternatives');
}
/**
* Can access?
*
* @return bool
*/
public function canView()
{
return parent::canView() and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'nexus', 'clients' ) );
}
/**
* Get Title
*
* @return string
*/
public function title()
{
return \IPS\Member::loggedIn()->language()->addToStack('client_alternatives');
}
/**
* Get Link
*
* @return \IPS\Http\Url
*/
public function link()
{
return \IPS\Http\Url::internal( "app=nexus&module=clients&controller=alternatives", 'front', 'clientsalternatives', \IPS\Settings::i()->nexus_https );
}
/**
* Is Active?
*
* @return bool
*/
public function active()
{
return \IPS\Dispatcher::i()->application->directory === 'nexus' and \IPS\Dispatcher::i()->module and \IPS\Dispatcher::i()->module->key === 'clients' and \IPS\Dispatcher::i()->controller == 'alternatives';
}
}
@@ -0,0 +1,76 @@
<?php
/**
* @brief Front Navigation Extension: Cards
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Nexus
* @since 29 Apr 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\nexus\extensions\core\FrontNavigation;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Front Navigation Extension: Cards
*/
class _Cards extends \IPS\core\FrontNavigation\FrontNavigationAbstract
{
/**
* Get Type Title which will display in the AdminCP Menu Manager
*
* @return string
*/
public static function typeTitle()
{
return \IPS\Member::loggedIn()->language()->addToStack('client_cards');
}
/**
* Can access?
*
* @return bool
*/
public function canView()
{
return \IPS\Settings::i()->card_storage_gateways and parent::canView() and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'nexus', 'clients' ) );
}
/**
* Get Title
*
* @return string
*/
public function title()
{
return \IPS\Member::loggedIn()->language()->addToStack('client_cards');
}
/**
* Get Link
*
* @return \IPS\Http\Url
*/
public function link()
{
return \IPS\Http\Url::internal( "app=nexus&module=clients&controller=cards", 'front', 'clientscards', \IPS\Settings::i()->nexus_https );
}
/**
* Is Active?
*
* @return bool
*/
public function active()
{
return \IPS\Dispatcher::i()->application->directory === 'nexus' and \IPS\Dispatcher::i()->module and \IPS\Dispatcher::i()->module->key === 'clients' and \IPS\Dispatcher::i()->controller == 'cards';
}
}
@@ -0,0 +1,77 @@
<?php
/**
* @brief Front Navigation Extension: Account Credit
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Nexus
* @since 29 Apr 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\nexus\extensions\core\FrontNavigation;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Front Navigation Extension: Account Credit
*/
class _Credit extends \IPS\core\FrontNavigation\FrontNavigationAbstract
{
/**
* Get Type Title which will display in the AdminCP Menu Manager
*
* @return string
*/
public static function typeTitle()
{
return \IPS\Member::loggedIn()->language()->addToStack('client_credit');
}
/**
* Can access?
*
* @return bool
*/
public function canView()
{
return ( \IPS\Settings::i()->nexus_min_topup or count( json_decode( \IPS\Settings::i()->nexus_payout, TRUE ) ) ) and parent::canView() and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'nexus', 'clients' ) );
}
/**
* Get Title
*
* @return string
*/
public function title()
{
return \IPS\Member::loggedIn()->language()->addToStack('client_credit');
}
/**
* Get Link
*
* @return \IPS\Http\Url
*/
public function link()
{
return \IPS\Http\Url::internal( "app=nexus&module=clients&controller=credit", 'front', 'clientscredit', \IPS\Settings::i()->nexus_https );
}
/**
* Is Active?
*
* @return bool
*/
public function active()
{
return \IPS\Dispatcher::i()->application->directory === 'nexus' and \IPS\Dispatcher::i()->module and \IPS\Dispatcher::i()->module->key === 'clients' and \IPS\Dispatcher::i()->controller == 'credit';
}
}
@@ -0,0 +1,76 @@
<?php
/**
* @brief Front Navigation Extension: Donations
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Nexus
* @since 29 Apr 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\nexus\extensions\core\FrontNavigation;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Front Navigation Extension: Donations
*/
class _Donations extends \IPS\core\FrontNavigation\FrontNavigationAbstract
{
/**
* Get Type Title which will display in the AdminCP Menu Manager
*
* @return string
*/
public static function typeTitle()
{
return \IPS\Member::loggedIn()->language()->addToStack('client_donations');
}
/**
* Can access?
*
* @return bool
*/
public function canView()
{
return \IPS\Settings::i()->donation_goals and parent::canView() and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'nexus', 'clients' ) );
}
/**
* Get Title
*
* @return string
*/
public function title()
{
return \IPS\Member::loggedIn()->language()->addToStack('client_donations');
}
/**
* Get Link
*
* @return \IPS\Http\Url
*/
public function link()
{
return \IPS\Http\Url::internal( "app=nexus&module=clients&controller=donations", 'front', 'clientsdonations', \IPS\Settings::i()->nexus_https );
}
/**
* Is Active?
*
* @return bool
*/
public function active()
{
return \IPS\Dispatcher::i()->application->directory === 'nexus' and \IPS\Dispatcher::i()->module and \IPS\Dispatcher::i()->module->key === 'clients' and \IPS\Dispatcher::i()->controller == 'donations';
}
}
@@ -0,0 +1,76 @@
<?php
/**
* @brief Front Navigation Extension: Personal Information
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Nexus
* @since 29 Apr 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\nexus\extensions\core\FrontNavigation;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Front Navigation Extension: Personal Information
*/
class _Info extends \IPS\core\FrontNavigation\FrontNavigationAbstract
{
/**
* Get Type Title which will display in the AdminCP Menu Manager
*
* @return string
*/
public static function typeTitle()
{
return \IPS\Member::loggedIn()->language()->addToStack('client_info');
}
/**
* Can access?
*
* @return bool
*/
public function canView()
{
return \IPS\Settings::i()->customer_fields and parent::canView() and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'nexus', 'clients' ) );
}
/**
* Get Title
*
* @return string
*/
public function title()
{
return \IPS\Member::loggedIn()->language()->addToStack('client_info');
}
/**
* Get Link
*
* @return \IPS\Http\Url
*/
public function link()
{
return \IPS\Http\Url::internal( "app=nexus&module=clients&controller=info", 'front', 'clientsinfo', \IPS\Settings::i()->nexus_https );
}
/**
* Is Active?
*
* @return bool
*/
public function active()
{
return \IPS\Dispatcher::i()->application->directory === 'nexus' and \IPS\Dispatcher::i()->module and \IPS\Dispatcher::i()->module->key === 'clients' and \IPS\Dispatcher::i()->controller == 'info';
}
}
@@ -0,0 +1,76 @@
<?php
/**
* @brief Front Navigation Extension: Network Status
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Nexus
* @since 08 Apr 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\nexus\extensions\core\FrontNavigation;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Front Navigation Extension: Network Status
*/
class _NetworkStatus extends \IPS\core\FrontNavigation\FrontNavigationAbstract
{
/**
* Get Type Title which will display in the AdminCP Menu Manager
*
* @return string
*/
public static function typeTitle()
{
return \IPS\Member::loggedIn()->language()->addToStack('network_status');
}
/**
* Can access?
*
* @return bool
*/
public function canView()
{
return \IPS\Settings::i()->network_status and parent::canView() and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'nexus', 'clients' ) );
}
/**
* Get Title
*
* @return string
*/
public function title()
{
return \IPS\Member::loggedIn()->language()->addToStack('network_status');
}
/**
* Get Link
*
* @return \IPS\Http\Url
*/
public function link()
{
return \IPS\Http\Url::internal( "app=nexus&module=clients&controller=networkStatus", 'front', 'nexus_network_status' );
}
/**
* Is Active?
*
* @return bool
*/
public function active()
{
return \IPS\Dispatcher::i()->application->directory === 'nexus' and \IPS\Dispatcher::i()->module and \IPS\Dispatcher::i()->module->key === 'clients' and \IPS\Dispatcher::i()->controller == 'networkStatus';
}
}
@@ -0,0 +1,76 @@
<?php
/**
* @brief Front Navigation Extension: Orders
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Nexus
* @since 29 Apr 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\nexus\extensions\core\FrontNavigation;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Front Navigation Extension: Orders
*/
class _Orders extends \IPS\core\FrontNavigation\FrontNavigationAbstract
{
/**
* Get Type Title which will display in the AdminCP Menu Manager
*
* @return string
*/
public static function typeTitle()
{
return \IPS\Member::loggedIn()->language()->addToStack('client_invoices');
}
/**
* Can access?
*
* @return bool
*/
public function canView()
{
return parent::canView() and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'nexus', 'clients' ) );
}
/**
* Get Title
*
* @return string
*/
public function title()
{
return \IPS\Member::loggedIn()->language()->addToStack('client_invoices');
}
/**
* Get Link
*
* @return \IPS\Http\Url
*/
public function link()
{
return \IPS\Http\Url::internal( "app=nexus&module=clients&controller=invoices", 'front', 'clients', \IPS\Settings::i()->nexus_https );
}
/**
* Is Active?
*
* @return bool
*/
public function active()
{
return \IPS\Dispatcher::i()->application->directory === 'nexus' and \IPS\Dispatcher::i()->module and \IPS\Dispatcher::i()->module->key === 'clients' and ( !\IPS\Dispatcher::i()->controller or \IPS\Dispatcher::i()->controller == 'invoices' );
}
}
@@ -0,0 +1,76 @@
<?php
/**
* @brief Front Navigation Extension: Purchases
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Nexus
* @since 29 Apr 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\nexus\extensions\core\FrontNavigation;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Front Navigation Extension: Orders
*/
class _Purchases extends \IPS\core\FrontNavigation\FrontNavigationAbstract
{
/**
* Get Type Title which will display in the AdminCP Menu Manager
*
* @return string
*/
public static function typeTitle()
{
return \IPS\Member::loggedIn()->language()->addToStack('client_purchases');
}
/**
* Can access?
*
* @return bool
*/
public function canView()
{
return parent::canView() and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'nexus', 'clients' ) ) and \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_member=? AND ps_show=1', \IPS\Member::loggedIn()->member_id ) );
}
/**
* Get Title
*
* @return string
*/
public function title()
{
return \IPS\Member::loggedIn()->language()->addToStack('client_purchases');
}
/**
* Get Link
*
* @return \IPS\Http\Url
*/
public function link()
{
return \IPS\Http\Url::internal( "app=nexus&module=clients&controller=purchases", 'front', 'clientspurchases', \IPS\Settings::i()->nexus_https );
}
/**
* Is Active?
*
* @return bool
*/
public function active()
{
return \IPS\Dispatcher::i()->application->directory === 'nexus' and \IPS\Dispatcher::i()->module and \IPS\Dispatcher::i()->module->key === 'clients' and \IPS\Dispatcher::i()->controller == 'purchases';
}
}
@@ -0,0 +1,76 @@
<?php
/**
* @brief Front Navigation Extension: Referrals
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Nexus
* @since 29 Apr 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\nexus\extensions\core\FrontNavigation;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Front Navigation Extension: Referrals
*/
class _Referrals extends \IPS\core\FrontNavigation\FrontNavigationAbstract
{
/**
* Get Type Title which will display in the AdminCP Menu Manager
*
* @return string
*/
public static function typeTitle()
{
return \IPS\Member::loggedIn()->language()->addToStack('client_referrals');
}
/**
* Can access?
*
* @return bool
*/
public function canView()
{
return \IPS\Settings::i()->cm_ref_on and parent::canView() and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'nexus', 'clients' ) );
}
/**
* Get Title
*
* @return string
*/
public function title()
{
return \IPS\Member::loggedIn()->language()->addToStack('client_referrals');
}
/**
* Get Link
*
* @return \IPS\Http\Url
*/
public function link()
{
return \IPS\Http\Url::internal( "app=nexus&module=clients&controller=donations", 'front', 'clientsreferrals', \IPS\Settings::i()->nexus_https );
}
/**
* Is Active?
*
* @return bool
*/
public function active()
{
return \IPS\Dispatcher::i()->application->directory === 'nexus' and \IPS\Dispatcher::i()->module and \IPS\Dispatcher::i()->module->key === 'clients' and \IPS\Dispatcher::i()->controller == 'referrals';
}
}
@@ -22,8 +22,18 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
/**
* Front Navigation Extension: Store
*/
class _Store
class _Store extends \IPS\core\FrontNavigation\FrontNavigationAbstract
{
/**
* Get Type Title which will display in the AdminCP Menu Manager
*
* @return string
*/
public static function typeTitle()
{
return \IPS\Member::loggedIn()->language()->addToStack('module__nexus_store');
}
/**
* Can access?
*
@@ -31,7 +41,7 @@ class _Store
*/
public function canView()
{
return !\IPS\Application::load('nexus')->hide_tab and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'nexus', 'store' ) );
return parent::canView() and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'nexus', 'store' ) );
}
/**
@@ -61,16 +71,6 @@ class _Store
*/
public function active()
{
return \IPS\Dispatcher::i()->application->directory === 'nexus' and \IPS\Dispatcher::i()->module and \IPS\Dispatcher::i()->module->key === 'store';
}
/**
* Children
*
* @return array
*/
public function children()
{
return array();
return \IPS\Dispatcher::i()->application->directory === 'nexus' and \IPS\Dispatcher::i()->module and ( \IPS\Dispatcher::i()->module->key === 'store' or \IPS\Dispatcher::i()->module->key === 'clients' );
}
}
@@ -22,8 +22,18 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
/**
* Front Navigation Extension: Support
*/
class _Support
{
class _Support extends \IPS\core\FrontNavigation\FrontNavigationAbstract
{
/**
* Get Type Title which will display in the AdminCP Menu Manager
*
* @return string
*/
public static function typeTitle()
{
return \IPS\Member::loggedIn()->language()->addToStack( 'frontnavigation_support' );
}
/**
* Can access?
*
@@ -31,7 +41,7 @@ class _Support
*/
public function canView()
{
return !\IPS\Application::load('nexus')->hide_tab and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'nexus', 'support' ) );
return parent::canView() and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'nexus', 'support' ) );
}
/**
@@ -41,7 +51,7 @@ class _Support
*/
public function title()
{
return \IPS\Member::loggedIn()->language()->addToStack('support');
return \IPS\Member::loggedIn()->language()->addToStack( 'frontnavigation_support' );
}
/**
@@ -63,14 +73,4 @@ class _Support
{
return \IPS\Dispatcher::i()->application->directory === 'nexus' and \IPS\Dispatcher::i()->module and \IPS\Dispatcher::i()->module->key === 'support';
}
/**
* Children
*
* @return array
*/
public function children()
{
return array();
}
}
@@ -185,8 +185,6 @@ class _Support
static::makeAndClaimAttachments( $email->data['attachments'], $note );
}
$request->sendNotifications();
/* Return */
return TRUE;
@@ -243,8 +241,6 @@ class _Support
}
$confirmationEmail->send( $member->member_id ? $member : $email->data['from'] );
}
$request->sendNotifications();
}
/* Return */
@@ -1,67 +0,0 @@
<?php
/**
* @brief IP Address Lookup extension
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage
* @since 18 Sep 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\nexus\extensions\core\IpAddresses;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* IP Address Lookup extension
*/
class _CustomerHistory
{
/**
* Find Records by IP
*
* @param string $ip The IP Address
* @param \IPS\Http\Url $baseUrl URL table will be displayed on or NULL to return a count
* @return \IPS\Helpers\Table|null
*/
public function findByIp( $ip, \IPS\Http\Url $baseUrl = NULL )
{
/* Return count */
if ( $baseUrl === NULL )
{
return \IPS\Db::i()->select( 'COUNT(*)', 'nexus_customer_history', array( "log_ip_address LIKE CONCAT( ?, '%' )", $ip ) )->first();
}
return (string) new \IPS\nexus\Customer\History( $baseUrl, array( "log_ip_address LIKE CONCAT( ?, '%' )", $ip ), FALSE, TRUE );
}
/**
* Find IPs by Member
*
* @code
return array(
'::1' => array(
'ip' => '::1'// string (IP Address)
'count' => ... // int (number of times this member has used this IP)
'first' => ... // int (timestamp of first use)
'last' => ... // int (timestamp of most recent use)
),
...
);
* @endcode
* @param \IPS\Member $member The member
* @return array|NULL
*/
public function findByMember( $member )
{
return \IPS\Db::i()->select( "log_ip_address AS ip, COUNT(*) AS count, MIN(log_date) AS first, MAX(log_date) AS last", 'nexus_customer_history', array( "log_member=?", $member->member_id ), NULL, NULL, "log_ip_address" )->setKeyField( 'ip' );
}
}
@@ -45,7 +45,7 @@ class _Nexus
/**
* Process Form
*
* @param \IPS\Form\Tabbed $form The form
* @param \IPS\Helpers\Form $form The form
* @param \IPS\Member $member Existing Member
* @return void
*/
@@ -55,9 +55,9 @@ class _CouponDiscount extends \IPS\nexus\Invoice\Item\Charge
try
{
$coupon = \IPS\nexus\Coupon::load( $this->id );
if ( $coupon->max_uses >= 1 )
if ( $coupon->uses >= 1 )
{
$coupon->max_uses--;
$coupon->uses--;
$coupon->save();
}
}
@@ -76,9 +76,9 @@ class _CouponDiscount extends \IPS\nexus\Invoice\Item\Charge
try
{
$coupon = \IPS\nexus\Coupon::load( $this->id );
if ( $coupon->max_uses != -1 )
if ( $coupon->uses != -1 )
{
$coupon->max_uses++;
$coupon->uses++;
$coupon->save();
}
+13 -36
View File
@@ -8,14 +8,6 @@ public static function hookData() {
return array_merge_recursive( array (
'userBar' =>
array (
0 =>
array (
'selector' => '#elAccountSettingsLink',
'type' => 'add_after',
'content' => '{{if \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( \'nexus\', \'clients\' ) )}}
<li class=\'ipsMenu_item\'><a href=\'{url="app=nexus&module=clients&controller=splash" seoTemplate="clients" protocol="\IPS\Settings::i()->nexus_https"}\' title=\'{lang="module__nexus_clients"}\'>{lang="module__nexus_clients"}</a></li>
{{endif}}',
),
1 =>
array (
'selector' => '#cUserLink',
@@ -32,37 +24,12 @@ public static function hookData() {
{template="cartHeader" app="nexus" group="store" params=""}
{{endif}}',
),
),
'footer' =>
array (
0 =>
3 =>
array (
'selector' => '#elFooterLinks',
'type' => 'add_inside_end',
'content' => '{{if \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( \'nexus\', \'clients\' ) ) and settings.network_status}}
<li><a href=\'{url="app=nexus&module=clients&controller=networkStatus" seoTemplate="nexus_network_status"}\'>{lang=\'network_status\'}</a></li>
{{endif}}',
),
),
'mobileNavigation' =>
array (
0 =>
array (
'selector' => '#elAccountSettingsLinkMobile',
'selector' => '#elAccountSettingsLink',
'type' => 'add_after',
'content' => '{{if \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( \'nexus\', \'clients\' ) )}}
<li><a href=\'{url="app=nexus&module=clients&controller=splash" seoTemplate="clients" protocol="\IPS\Settings::i()->nexus_https"}\' title=\'{lang="module__nexus_clients"}\'>{lang="module__nexus_clients"}</a></li>
{{endif}}',
),
),
'mobileNavBar' =>
array (
0 =>
array (
'selector' => '#elMobileNav li:last-child',
'type' => 'add_before',
'content' => '{{if \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( \'nexus\', \'store\' ) )}}
{template="cartHeaderMobile" app="nexus" group="store" params=""}
<li class=\'ipsMenu_item\'><a href=\'{url="app=nexus&module=clients&controller=splash" seoTemplate="clients" protocol="\IPS\Settings::i()->nexus_https"}\' title=\'{lang="module__nexus_clients"}\'>{lang="module__nexus_clients"}</a></li>
{{endif}}',
),
),
@@ -92,6 +59,16 @@ public static function hookData() {
@@ -39,7 +39,7 @@ class Api
* @param bool $validateIdentifier Should the identifier be validated?
* @return \IPS\nexus\Purchase\LicenseKey
*/
protected function getKey( $validateIdentifier=FALSE )
protected function getKey( $validateIdentifier=TRUE )
{
try
{
@@ -103,10 +103,20 @@ class _purchases extends \IPS\Dispatcher\Controller
}
catch ( \OutOfRangeException $e ) { }
}
/* Get customer */
try
{
$customer = $this->purchase->member;
}
catch ( \OutOfRangeException $e )
{
$customer = NULL;
}
/* Display */
\IPS\Output::i()->sidebar['actions'] = $this->purchase->buttons();
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'purchases' )->view( $this->purchase, $children, $invoices, $customFields );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'purchases' )->view( $this->purchase, $customer, $children, $invoices, $customFields );
}
/**
@@ -147,7 +147,13 @@ class _view extends \IPS\Dispatcher\Controller
/* Purchases */
$purchaseCount = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_member=? AND ps_show=1', $this->member->member_id ) )->first();
$purchaseRootCount = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_member=? AND ps_show=1 AND ps_parent=0', $this->member->member_id ) )->first();
$purchases = \IPS\nexus\Purchase::tree( $this->member->acpUrl()->setQueryString( 'tab', 'purchases' ), array( array( 'ps_member=?', $this->member->member_id ) ) );
$purchases->rootsPerPage = 15;
$purchases->getTotalRoots = function()
{
return NULL;
};
if ( \IPS\Request::i()->isAjax() and \IPS\Request::i()->tab === 'purchases' )
{
\IPS\Output::i()->output = $purchases;
@@ -402,7 +408,14 @@ class _view extends \IPS\Dispatcher\Controller
},
'email' => function( $v, $row )
{
return \IPS\nexus\Customer::load( $row['member_id'] )->email;
try
{
return \IPS\nexus\Customer::load( $row['member_id'] )->email;
}
catch ( \OutOfRangeException $e )
{
return \IPS\Member::loggedIn()->language()->addToStack('deleted_member');
}
},
'amount' => function( $v ) use ( $member )
{
@@ -472,7 +485,14 @@ class _view extends \IPS\Dispatcher\Controller
/* Average monthly spend */
$sum = "( SUM(t_amount) / ( ( {$time} - core_members.joined ) / 2592000 ) )";
$where = array( array( "( t_status=? OR t_status=? ) AND ({$time} - core_members.joined > 2592000) AND t_currency=?", \IPS\nexus\Transaction::STATUS_PAID, \IPS\nexus\Transaction::STATUS_PART_REFUNDED, $currency ) );
$val = \IPS\Db::i()->select( "{$sum} as sum", 'nexus_transactions', array_merge( $where, array( array( 't_member=?', $this->member->member_id ) ) ) )->join( 'core_members', 'member_id=t_member' )->first();
try
{
$val = \IPS\Db::i()->select( "{$sum} as sum", 'nexus_transactions', array_merge( $where, array( array( 't_member=?', $this->member->member_id ) ) ), 'joined', NULL, 'joined' )->join( 'core_members', 'member_id=t_member' )->first();
}
catch( \UnderflowException $e )
{
$val = 0;
}
$comparisons = \IPS\Db::i()->select( 'AVG(xval) AS avg, MAX(xval) AS max, MIN(xval) AS min', \IPS\Db::i()->select( "{$sum} as xval", 'nexus_transactions', array_merge( $where, array( array( 't_member<>0' ) ) ), NULL, NULL, 't_member' ) )->join( 'core_members', 'member_id=t_member' )->first();
$standing[ \IPS\Member::loggedIn()->language()->addToStack( 'average_spend_currency', FALSE, array( 'sprintf' => array( $currency ) ) ) ] = array(
'value' => new \IPS\nexus\Money( $val, $currency ),
@@ -492,7 +512,7 @@ class _view extends \IPS\Dispatcher\Controller
$sum = "ROUND( ( AVG( i_paid - i_date ) / 86400 ), 2 )";
$where = array( array( "i_status=? AND i_date>0 AND i_paid>0", \IPS\nexus\Invoice::STATUS_PAID ) );
$val = \IPS\Db::i()->select( "{$sum} as sum", 'nexus_invoices', array_merge( $where, array( array( 'i_member=?', $this->member->member_id ) ) ) )->join( 'core_members', 'member_id=i_member' )->first();
$comparisons = \IPS\Db::i()->select( 'AVG(xval) AS avg, MAX(xval) AS max, MIN(xval) AS min', \IPS\Db::i()->select( "{$sum} as xval", 'nexus_invoices', array_merge( $where, array( array( 'i_member<>0' ) ) ), NULL, NULL, 'i_member' ) )->join( 'core_members', 'member_id=i_member' )->first();
$comparisons = \IPS\Db::i()->select( 'AVG(xval) AS avg, MAX(xval) AS max, MIN(xval) AS min', \IPS\Db::i()->select( "{$sum} as xval", 'nexus_invoices', array_merge( $where, array( array( 'i_member<>0' ) ) ), NULL, NULL, array( 'i_member', 'joined' ) ) )->join( 'core_members', 'member_id=i_member' )->first();
$standing[ \IPS\Member::loggedIn()->language()->addToStack( 'average_time_to_pay' ) ] = array(
'value' => \IPS\Member::loggedIn()->language()->formatNumber( $val, 2 ) . ' ' . \IPS\Member::loggedIn()->language()->addToStack('days'),
'avg' => \IPS\Member::loggedIn()->language()->formatNumber( $comparisons['avg'], 2 ) . ' ' . \IPS\Member::loggedIn()->language()->addToStack('days'),
@@ -508,8 +528,15 @@ class _view extends \IPS\Dispatcher\Controller
);
$sum = "( COUNT(*) / ( ( {$time} - core_members.joined ) / 2592000 ) )";
$val = \IPS\Db::i()->select( "{$sum} as sum", 'nexus_support_requests', array( 'r_member=?', $this->member->member_id ) )->join( 'core_members', 'member_id=r_member' )->first();
$comparisons = \IPS\Db::i()->select( 'AVG(xval) AS avg, MAX(xval) AS max, MIN(xval) AS min', \IPS\Db::i()->select( "{$sum} as xval", 'nexus_support_requests', 'r_member<>0' ) )->join( 'core_members', 'member_id=r_member' )->first();
try
{
$val = \IPS\Db::i()->select( "{$sum} as sum", 'nexus_support_requests', array( 'r_member=?', $this->member->member_id ), 'joined', NULL, 'joined' )->join( 'core_members', 'member_id=r_member' )->first();
}
catch( \UnderflowException $e )
{
$val = 0;
}
$comparisons = \IPS\Db::i()->select( 'AVG(xval) AS avg, MAX(xval) AS max, MIN(xval) AS min', \IPS\Db::i()->select( "{$sum} as xval", 'nexus_support_requests', 'r_member<>0', NULL, NULL, 'joined' ) )->join( 'core_members', 'member_id=r_member' )->first();
$standing[ \IPS\Member::loggedIn()->language()->addToStack( 'average_monthly_support_requests' ) ] = array(
'value' => \IPS\Member::loggedIn()->language()->formatNumber( $val, 2 ),
'avg' => \IPS\Member::loggedIn()->language()->formatNumber( $comparisons['avg'], 2 ),
@@ -603,7 +630,24 @@ class _view extends \IPS\Dispatcher\Controller
'link' => \IPS\Http\Url::internal( 'app=core&module=members&controller=members&do=edit&id=' . $this->member->member_id )
);
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('customers')->view( $member, (string) $notes, $noteCount, $primaryBillingAddress, (string) $cards, $cardCount, $parents, (string) $alternativeContacts, $altContactCount, $purchases, $purchaseCount, $invoices, $invoiceCount, $history, $referredBy, $referrals, $referCount, $standing, $support, $supportCount, $sparkline );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('customers')->view( $member, (string) $notes, $noteCount, $primaryBillingAddress, (string) $cards, $cardCount, $parents, (string) $alternativeContacts, $altContactCount, $purchases, $purchaseCount, $invoices, $invoiceCount, $history, $referredBy, $referrals, $referCount, $standing, $support, $supportCount, $sparkline, $purchaseRootCount );
}
/**
* View Purchase List
*
* @return void
*/
protected function purchaseList()
{
$purchases = \IPS\nexus\Purchase::tree( $this->member->acpUrl()->setQueryString( 'do', 'purchaseList' ), array( array( 'ps_member=?', $this->member->member_id ) ) );
$purchases->rootsPerPage = 25;
$purchases->getTotalRoots = function()
{
return \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_member=? AND ps_show=1 AND ps_parent=0', $this->member->member_id ) )->first();
};
\IPS\Output::i()->output = $purchases;
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'members_purchases', FALSE, array( 'sprintf' => array( $this->member->cm_name ) ) );
}
/**
@@ -975,7 +975,7 @@ class _invoices extends \IPS\Dispatcher\Controller
{
$class = $itemTypes[ \IPS\Request::i()->add ];
$formUrl = \IPS\Http\Url::internal('app=nexus&module=payments&controller=invoices&do=generate')->setQueryString( 'add', \IPS\Request::i()->add );
$formUrl = $url->setQueryString( 'add', \IPS\Request::i()->add );
$form = new \IPS\Helpers\Form( 'add', 'invoice_add_item', $formUrl );
if ( method_exists( $class, 'formSecondStep' ) )
{
@@ -308,7 +308,7 @@ class _shipping extends \IPS\Dispatcher\Controller
}, NULL, 'oz', 'easypost_package_weight' ) );
$matrix = NULL;
$fromCountry = \IPS\GeoLocation::buildFromJson( \IPS\Settings::i()->site_address )->country;
$fromCountry = \IPS\GeoLocation::buildFromJson( \IPS\Settings::i()->easypost_address ?: \IPS\Settings::i()->site_address )->country;
if ( $fromCountry != $shipment->data['address']['country'] )
{
$originCountries = array();
@@ -418,7 +418,7 @@ class _shipping extends \IPS\Dispatcher\Controller
/* Send API call */
$toAddress = $shipment->data['address'];
$fromAddress = \IPS\GeoLocation::buildFromJson( \IPS\Settings::i()->site_address );
$fromAddress = \IPS\GeoLocation::buildFromJson( \IPS\Settings::i()->easypost_address ?: \IPS\Settings::i()->site_address );
$easyPost = \IPS\Http\Url::external( 'https://api.easypost.com/v2/shipments' )->request()->login( \IPS\Settings::i()->easypost_api_key, '' )->post( array( 'shipment' => array(
'to_address' => array(
'street1' => array_shift( $toAddress['addressLines'] ),
@@ -71,7 +71,7 @@ class _coupons extends \IPS\Node\Controller
$table->parsers = array(
'coupon_customer' => function ( $val )
{
return \IPS\Theme::i()->getTemplate('global')->userLink( \IPS\Member::load( $val ) );
return is_numeric( $val ) ? \IPS\Theme::i()->getTemplate('global')->userLink( \IPS\Member::load( $val ) ) : $val;
}
);
$table->sortBy = 'coupon_uses';
@@ -83,8 +83,18 @@ class _packages extends \IPS\Node\Controller
}
}
}
/* If something has changed, see if anyone has purchased */
$purchases = 0;
if( count( $changes ) )
{
$purchases = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=?', 'nexus', 'package', $new->id ) )->first();
}
if ( !empty( $changes ) )
/* Only show this screen if the package has been purchased. Otherwise even just copying a package and saving asks if you want to update
existing purchases unnecessarily */
if ( !empty( $changes ) AND $purchases )
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->decision( 'product_change_blurb', array(
'product_change_blurb_existing' => \IPS\Http\Url::internal( "app=nexus&module=store&controller=packages&do=updateExisting&id={$new->_id}" )->setQueryString( 'changes', json_encode( $changes ) ),
@@ -193,14 +203,14 @@ class _packages extends \IPS\Node\Controller
$matrix->rows['x'] = array( 'any_other_amount', '-' );
if ( $values = $matrix->values() )
{
{
$renewOptions = json_decode( $changes['renew_options'], TRUE );
$changes['renew_options'] = array();
foreach ( $renewOptions as $k => $data )
{
$changes['renew_options'][] = array( 'old' => $data, 'new' => $values[ $k ]['now_pay'] );
$changes['renew_options'][ $k ] = array( 'old' => $data, 'new' => $values[ $k ]['now_pay'] );
}
$changes['renew_options'][] = array( 'old' => 'x', 'new' => $values['x']['now_pay'] );
$changes['renew_options']['x'] = array( 'old' => 'x', 'new' => $values['x']['now_pay'] );
}
else
{
@@ -334,7 +344,7 @@ class _packages extends \IPS\Node\Controller
\IPS\Output::i()->error( 'node_error', '2X249/2', 404, '' );
}
$table = new \IPS\Helpers\Table\Db( 'nexus_purchases', \IPS\Http\Url::internal( "app=nexus&module=store&controller=packages&do=view_purchases&id={$package->id}" ), array( 'ps_app=? AND ps_type=? AND ps_item_id=?', 'nexus', 'package', $package->id ) );
$table = new \IPS\Helpers\Table\Db( 'nexus_purchases', \IPS\Http\Url::internal( "app=nexus&module=store&controller=packages&do=view_purchases&id={$package->id}" ), array( array( 'ps_app=? AND ps_type=? AND ps_item_id=?', 'nexus', 'package', $package->id ) ) );
$table->include = array( 'ps_id', 'ps_member', 'purchase_status', 'ps_start', 'ps_expire', 'ps_renewals' );
$table->quickSearch = 'ps_id';
$table->advancedSearch = array(
@@ -307,15 +307,16 @@ class _checkout extends \IPS\Dispatcher\Controller
}
$form->add( new \IPS\Helpers\Form\Checkbox( 'reg_admin_mails', $guestData ? $guestData['member']['allow_admin_mails'] : TRUE, FALSE ) );
\IPS\Member::loggedIn()->language()->words[ "reg_agreed_terms" ] = \IPS\Member::loggedIn()->language()->get( 'reg_agreed_terms', FALSE, array( 'sprintf' => array( \IPS\Http\Url::internal( 'app=core&module=system&controller=terms', 'front', 'terms' ) ) ) );
\IPS\Member::loggedIn()->language()->words[ "reg_agreed_terms" ] = sprintf( \IPS\Member::loggedIn()->language()->get("reg_agreed_terms"), \IPS\Http\Url::internal( 'app=core&module=system&controller=terms', 'front', 'terms', array(), PROTOCOL_RELATIVE ) );
/* Build the appropriate links for registration terms & privacy policy */
if ( \IPS\Settings::i()->privacy_type == "internal" )
{
\IPS\Member::loggedIn()->language()->words[ "reg_agreed_terms" ] .= \IPS\Member::loggedIn()->language()->get( 'reg_privacy_link', FALSE, array( 'sprintf' => array( \IPS\Http\Url::internal( 'app=core&module=system&controller=privacy', 'front', 'privacy' ), 'data-ipsDialog data-ipsDialog-size="wide" data-ipsDialog-title="' . \IPS\Member::loggedIn()->language()->get("privacy") . '"' ) ) );
\IPS\Member::loggedIn()->language()->words[ "reg_agreed_terms" ] .= sprintf( \IPS\Member::loggedIn()->language()->get("reg_privacy_link"), \IPS\Http\Url::internal( 'app=core&module=system&controller=privacy', 'front', 'privacy', array(), PROTOCOL_RELATIVE ), 'data-ipsDialog data-ipsDialog-size="wide" data-ipsDialog-title="' . \IPS\Member::loggedIn()->language()->get("privacy") . '"' );
}
else if ( \IPS\Settings::i()->privacy_type == "external" )
{
\IPS\Member::loggedIn()->language()->words[ "reg_agreed_terms" ] .= \IPS\Member::loggedIn()->language()->get( 'reg_privacy_link', FALSE, array( 'sprintf' => array( \IPS\Http\Url::external( \IPS\Settings::i()->privacy_link ), 'target="_blank"' ) ) );
\IPS\Member::loggedIn()->language()->words[ "reg_agreed_terms" ] .= sprintf( \IPS\Member::loggedIn()->language()->get("reg_privacy_link"), \IPS\Http\Url::external( \IPS\Settings::i()->privacy_link ), 'target="_blank"' );
}
$form->add( new \IPS\Helpers\Form\Checkbox( 'reg_agreed_terms', (bool) $guestData, TRUE, array(), function( $val )
{
@@ -552,7 +553,7 @@ class _checkout extends \IPS\Dispatcher\Controller
$shipMethods = array();
foreach ( \IPS\nexus\Shipping\FlatRate::roots() as $rate )
{
if ( $rate->isAvailable( $this->invoice->shipaddress ) )
if ( $rate->isAvailable( $this->invoice->shipaddress, iterator_to_array( $this->invoice->items ), $this->invoice->currency, $this->invoice ) )
{
$shipMethods[ $rate->id ] = $rate;
}
@@ -612,14 +613,18 @@ class _checkout extends \IPS\Dispatcher\Controller
foreach ( $data['items'] as $item )
{
$weightInOz += ( $item->weight->float('oz') * $item->quantity );
foreach ( array( 'length', 'width', 'height' ) as $k )
$heightInInches += ( $item->height->float('in') * $item->quantity );
foreach ( array( 'length', 'width' ) as $k )
{
$v = "{$k}InInches";
$$v += ( $item->$k->float('in') * $item->quantity );
if ( $item->$k->float('in') > $$v )
{
$$v = $item->$k->float('in');
}
}
}
try
{
$easyPost = \IPS\nexus\Shipping\EasyPostRate::getRates( $lengthInInches, $widthInInches, $heightInInches, $weightInOz, $this->invoice->member, $this->invoice->shipaddress, $this->invoice->currency );
@@ -846,6 +851,7 @@ class _checkout extends \IPS\Dispatcher\Controller
public function _pay( $data )
{
/* How much are we paying? */
$this->invoice->recalculateTotal();
$amountToPay = $this->invoice->amountToPay();
if ( isset( \IPS\Request::i()->split ) and \IPS\Request::i()->split < $amountToPay->amount )
{
@@ -943,7 +949,12 @@ class _checkout extends \IPS\Dispatcher\Controller
{
$paymentMethodOptions[0] = \IPS\Member::loggedIn()->language()->addToStack( 'account_credit_with_amount', FALSE, array( 'sprintf' => array( \IPS\nexus\Customer::loggedIn()->cm_credits[ $this->invoice->currency ] ) ) );
}
$form = new \IPS\Helpers\Form( 'select_method', 'checkout_pay', $this->invoice->checkoutUrl() );
if ( isset( \IPS\Request::i()->split ) )
{
$form->hiddenValues['split'] = $amountToPay->amount;
}
$form->class = 'ipsForm_vertical';
if ( count( $paymentMethodOptions ) > 1 )
{
@@ -955,7 +966,7 @@ class _checkout extends \IPS\Dispatcher\Controller
}
if ( \IPS\Settings::i()->nexus_tac === 'checkbox' )
{
$form->add( new \IPS\Helpers\Form\Checkbox( 'i_agree_to_tac', FALSE, TRUE, array( 'labelHtmlSprintf' => array( "<a href='" . htmlentities( \IPS\Settings::i()->nexus_tac_link, \IPS\HTMLENTITIES, 'UTF-8', FALSE ) . "' target='_blank'>" . \IPS\Member::loggedIn()->language()->addToStack( 'terms_and_conditions' ) . '</a>' ) ), function( $val )
$form->add( new \IPS\Helpers\Form\Checkbox( 'i_agree_to_tac', FALSE, TRUE, array( 'labelHtmlSprintf' => array( "<a href='" . htmlspecialchars( \IPS\Settings::i()->nexus_tac_link, \IPS\HTMLENTITIES, 'UTF-8', FALSE ) . "' target='_blank'>" . \IPS\Member::loggedIn()->language()->addToStack( 'terms_and_conditions' ) . '</a>' ) ), function( $val )
{
if ( !$val )
{
@@ -79,7 +79,7 @@ class _addresses extends \IPS\Dispatcher\Controller
}
}
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('clients')->template( \IPS\Theme::i()->getTemplate('clients')->addresses( $billingAddress, $shippingAddress, $otherAddresses ) );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('clients')->addresses( $billingAddress, $shippingAddress, $otherAddresses );
}
/**
@@ -138,7 +138,7 @@ class _addresses extends \IPS\Dispatcher\Controller
}
else
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('clients')->template( $form );
\IPS\Output::i()->output = $form;
}
}
@@ -60,7 +60,7 @@ class _alternatives extends \IPS\Dispatcher\Controller
$contact->alt_id;
}
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('clients')->template( \IPS\Theme::i()->getTemplate('clients')->alternatives() );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('clients')->alternatives();
}
/**
@@ -131,7 +131,7 @@ class _alternatives extends \IPS\Dispatcher\Controller
}
else
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('clients')->template( $form );
\IPS\Output::i()->output = $form;
}
}
@@ -71,7 +71,7 @@ class _cards extends \IPS\Dispatcher\Controller
catch ( \Exception $e ) { }
}
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('clients')->template( \IPS\Theme::i()->getTemplate('clients')->cards( $cards ) );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('clients')->cards( $cards );
}
/**
@@ -89,7 +89,7 @@ class _cards extends \IPS\Dispatcher\Controller
}
else
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('clients')->template( $form );
\IPS\Output::i()->output = $form;
}
}
@@ -120,7 +120,7 @@ class _credit extends \IPS\Dispatcher\Controller
}
/* Display */
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('clients')->template( \IPS\Theme::i()->getTemplate('clients')->credit( $balance, $pastWithdrawals, $pastWithdrawalsPagination, $canWithdraw, $canTopup ) );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('clients')->credit( $balance, $pastWithdrawals, $pastWithdrawalsPagination, $canWithdraw, $canTopup );
}
/**
@@ -63,7 +63,7 @@ class _donations extends \IPS\Dispatcher\Controller
\IPS\Output::i()->sidebar['enabled'] = FALSE;
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'donations.css' ) );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('clients')->template( \IPS\Theme::i()->getTemplate('clients')->donations() );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('clients')->donations();
}
/**
@@ -86,6 +86,6 @@ class _info extends \IPS\Dispatcher\Controller
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=nexus&module=clients&controller=info', 'front', 'clientsinfo', array(), \IPS\Settings::i()->nexus_https ) );
}
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('clients')->template( \IPS\Theme::i()->getTemplate('clients')->info( $form ) );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('clients')->info( $form );
}
}
@@ -92,7 +92,7 @@ class _invoices extends \IPS\Dispatcher\Controller
}
$invoices = new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_invoices', $where, 'i_date DESC' ), 'IPS\nexus\Invoice' );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('clients')->template( \IPS\Theme::i()->getTemplate('clients')->invoices( $invoices ) );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('clients')->invoices( $invoices );
}
/**
@@ -103,7 +103,7 @@ class _invoices extends \IPS\Dispatcher\Controller
public function view()
{
$shipments = $this->invoice->shipments();
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('clients')->template( \IPS\Theme::i()->getTemplate('clients')->invoice( $this->invoice ) );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('clients')->invoice( $this->invoice );
}
/**
@@ -102,7 +102,7 @@ class _purchases extends \IPS\Dispatcher\Controller
{
$purchases[ $purchase->parent ][ $purchase->id ] = $purchase;
}
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('clients')->template( \IPS\Theme::i()->getTemplate('clients')->purchases( $purchases ) );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('clients')->purchases( $purchases );
}
/**
@@ -112,7 +112,7 @@ class _purchases extends \IPS\Dispatcher\Controller
*/
public function view()
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('clients')->template( \IPS\Theme::i()->getTemplate('clients')->purchase( $this->purchase ) );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('clients')->purchase( $this->purchase );
}
/**
@@ -130,7 +130,7 @@ class _purchases extends \IPS\Dispatcher\Controller
}
else
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('clients')->template( $output );
\IPS\Output::i()->output = $output;
}
}
else
@@ -212,7 +212,7 @@ class _purchases extends \IPS\Dispatcher\Controller
\IPS\Output::i()->redirect( $invoice->checkoutUrl() );
}
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('clients')->template( $form );
\IPS\Output::i()->output = $form;
}
/**
@@ -61,6 +61,6 @@ class _referrals extends \IPS\Dispatcher\Controller
$rules = new \IPS\nexus\CommissionRule\Iterator( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_referral_rules' ), 'IPS\nexus\CommissionRule' ), \IPS\Member::loggedIn() );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('clients')->template( \IPS\Theme::i()->getTemplate('clients')->referrals( $url, $rules ) );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('clients')->referrals( $url, $rules );
}
}
@@ -68,7 +68,6 @@ class _product extends \IPS\Content\Controller
\IPS\Output::i()->error( 'node_error', '2X240/1', 404, '' );
}
$package = \IPS\nexus\Package::load( $item->id );
$category = \IPS\nexus\Package\Group::load( $item->group );
/* Do we have any in the cart already (this will affect stock level)? */
$inCart = 0;
@@ -89,6 +88,17 @@ class _product extends \IPS\Content\Controller
/* No - show the full page */
else
{
/* We need to create a dummy item so we can work out ship times/prices */
$itemDataForShipping = NULL;
if ( $package->physical )
{
try
{
$itemDataForShipping = $package->createItemForCart( $package->price() );
}
catch ( \OutOfBoundsException $e ) { }
}
/* If physical, get available shipping methods */
$shippingMethods = array();
$locationType = 'none';
@@ -123,7 +133,7 @@ class _product extends \IPS\Content\Controller
}
foreach ( \IPS\nexus\Shipping\FlatRate::roots( NULL, NULL, $where ) as $rate )
{
if ( ( $shipAddress and $rate->isAvailable( $shipAddress ) ) or ( $rate->locations === '*' ) )
if ( ( $shipAddress and $rate->isAvailable( $shipAddress, array( $itemDataForShipping ), $memberCurrency ) ) or ( $rate->locations === '*' ) )
{
$shippingMethods[] = $rate;
}
@@ -134,7 +144,7 @@ class _product extends \IPS\Content\Controller
{
try
{
$fromAddress = \IPS\GeoLocation::buildFromJson( \IPS\Settings::i()->site_address );
$fromAddress = \IPS\GeoLocation::buildFromJson( \IPS\Settings::i()->easypost_address ?: \IPS\Settings::i()->site_address );
$length = new \IPS\nexus\Shipping\Length( $package->length );
$width = new \IPS\nexus\Shipping\Length( $package->width );
@@ -156,18 +166,7 @@ class _product extends \IPS\Content\Controller
catch ( \IPS\Http\Request\Exception $e ) { }
}
}
/* We need to create a dummy item so we can work out ship times/prices */
$itemDataForShipping = NULL;
if ( count( $shippingMethods ) )
{
try
{
$itemDataForShipping = $package->createItemForCart( $package->price() );
}
catch ( \OutOfBoundsException $e ) { }
}
/* Do we have renewal terms? */
$renewalTerm = NULL;
$renewOptions = $package->renew_options ? json_decode( $package->renew_options, TRUE ) : array();
@@ -58,6 +58,7 @@ class _store extends \IPS\Dispatcher\Controller
{
if ( isset( \IPS\Request::i()->csrfKey ) and \IPS\Request::i()->csrfKey === \IPS\Session\Front::i()->csrfKey )
{
$_SESSION['cart'] = array();
$_SESSION['currency'] = \IPS\Request::i()->currency;
}
$currency = \IPS\Request::i()->currency;
@@ -175,7 +176,11 @@ class _store extends \IPS\Dispatcher\Controller
$where[] = "( p_member_groups='*' OR " . \IPS\Db::i()->findInSet( 'p_member_groups', \IPS\Member::loggedIn()->groups ) . ' )';
$where[] = array( 'p_store=?', 1 );
$popularProducts = new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( 'nexus_packages.*', 'nexus_purchases', $where, 'COUNT(*) DESC', $nexus_store_popular[0], 'ps_item_id' )->join( 'nexus_packages', 'ps_item_id=p_id' ), 'IPS\nexus\Package' );
$popularIds = \IPS\Db::i()->select( 'nexus_purchases.ps_item_id', 'nexus_purchases', $where, 'COUNT(ps_item_id) DESC', $nexus_store_popular[0], 'ps_item_id' )->join( 'nexus_packages', 'ps_item_id=p_id' );
if( count( $popularIds ) )
{
$popularProducts = new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( 'nexus_packages.*', 'nexus_packages', array( \IPS\Db::i()->in( 'p_id', iterator_to_array( $popularIds ) ) ), 'FIELD(p_id, ' . implode( ',', iterator_to_array($popularIds) ) . ')' ), 'IPS\nexus\Package' );
}
}
/* Display */
@@ -0,0 +1,243 @@
<?php
/**
* @brief 4.0.99 Upgrade Code
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Commerce
* @since 23 Jul 2015
* @version SVN_VERSION_NUMBER
*/
namespace IPS\nexus\setup\upg_101000;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* 4.0.99 Upgrade Code
*/
class _Upgrade
{
/**
* Store certain informaiton in settings to ease performance on menu
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step1()
{
foreach ( array(
'card_storage_gateways' => count( \IPS\nexus\Gateway::cardStorageGateways() ),
'donation_goals' => count( \IPS\nexus\Donation\Goal::roots() ),
'customer_fields' => count( \IPS\nexus\Customer\CustomField::roots() )
) as $k => $v )
{
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => $v ), array( 'conf_key=?', $k ) );
\IPS\Settings::i()->$k = $v;
}
unset( \IPS\Data\Store::i()->settings );
return TRUE;
}
/**
* Fix shipping methods
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step2()
{
if( !isset( \IPS\Settings::i()->nexus_currency ) )
{
return TRUE;
}
$statesFrom3 = array(
//'GB' => array( "LONDON" => 'London', "ESSEX" => 'Essex' ),
'CA' => array(
"ALBERTA" => "Alberta",
"BRITISH COLUMBIA" => "British Columbia",
"MANITOBA" => "Manitoba",
"NEW BRUNSWICK" => "New Brunswick",
"NEWFOUNDLAND AND LABRADOR" => "Newfoundland and Labrador",
"NORTHWEST TERRITORIES" => "Northwest Territories",
"NOVA SCOTIA" => "Nova Soctia",
"NUNAVUT" => "Nunavut",
"ONTARIO" => "Ontario",
"PRINCE EDWARD ISLAND" => "Prince Edward Island",
"QUEBEC" => "Quebec",
"SASKATCHEWAN" => "Saskatchewan",
"YUKON" => "Yukon",
),
'US' => array(
'ALABAMA' => "AL",
'ALASKA' => "AK",
'AMERICAN SAMOA' => "AS",
'ARIZONA' => "AZ",
'ARKANSAS' => "AR",
'CALIFORNIA' => "CA",
'COLORADO' => "CO",
'CONNECTICUT' => "CT",
'DELAWARE' => "DE",
'DISTRICT OF COLUMBIA' => "DC",
'FEDERATED STATES OF MICRONESIA' => "FM",
'FLORIDA' => "FL",
'GEORGIA' => "GA",
'GUAM' => "GU",
'HAWAII' => "HI",
'IDAHO' => "ID",
'ILLINOIS' => "IL",
'INDIANA' => "IN",
'IOWA' => "IA",
'KANSAS' => "KS",
'KENTUCKY' => "KY",
'LOUISIANA' => "LA",
'MAINE' => "ME",
'MARSHALL ISLANDS' => "MH",
'MARYLAND' => "MD",
'MASSACHUSETTS' => "MA",
'MICHIGAN' => "MI",
'MINNESOTA' => "MN",
'MISSISSIPPI' => "MS",
'MISSOURI' => "MO",
'MONTANA' => "MT",
'NEBRASKA' => "NE",
'NEVADA' => "NV",
'NEW HAMPSHIRE' => "NH",
'NEW JERSEY' => "NJ",
'NEW MEXICO' => "NM",
'NEW YORK' => "NY",
'NORTH CAROLINA' => "NC",
'NORTH DAKOTA' => "ND",
'NORTHERN MARIANA ISLANDS' => "MP",
'OHIO' => "OH",
'OKLAHOMA' => "OK",
'OREGON' => "OR",
'PALAU' => "PW",
'PENNSYLVANIA' => "PA",
'PUERTO RICO' => "PR",
'RHODE ISLAND' => "RI",
'SOUTH CAROLINA' => "SC",
'SOUTH DAKOTA' => "SD",
'TENNESSEE' => "TN",
'TEXAS' => "TX",
'UTAH' => "UT",
'VERMONT' => "VT",
'VIRGIN ISLANDS' => "VI",
'VIRGINIA' => "VA",
'WASHINGTON' => "WA",
'WEST VIRGINIA' => "WV",
'WISCONSIN' => "WI",
'WYOMING' => "WY",
'ARMED FORCES - AMERICAS' => "AA",
'ARMED FORCES - EUROPE' => "AE",
'ARMED FORCES - PACIFIC' => "AP",
),
'PT' => array(
'AVEIRO' => "Aveiro",
'AZORES' => "Azores",
'BEJA' => "Beja",
'BRAGA' => "Braga",
'BRAGANCA' => "Braganca",
'CASTELO BRANCO' => "Castelo Branco",
'COIMBRA' => "Coimbra",
'EVORA' => "Evora",
'FARO' => "Faro",
'GUARDA' => "Guarda",
'LEIRIA' => "Leiria",
'LISBOA' => "Lisboa",
'MADEIRA ISLANDS' => "Madeira Islands",
'PORTALEGRE' => "Portalegre",
'PORTO' => "Porto",
'SANTAREM' => "Santarem",
'SETUBAL' => "Setubal",
'VIANA DO CASTELO' => "Viana do Castelo",
'VILA REAL' => "Vila Real",
'VISEU' => "Viseu",
),
'AU' => array(
'AUSTRALIAN CAPITAL TERRITORY' => 'ACT',
'NEW SOUTH WALES' => 'NSW',
'NORTHERN TERRITORY' => 'NT',
'QUEENSLAND' => 'QLD',
'SOUTH AUSTRALIA' => 'SA',
'TASMANIA' => 'TAS',
'VICTORIA' => 'VIC',
'WESTERN AUSTRALIA' => 'WA',
),
);
$offset = isset( \IPS\Request::i()->extra ) ? \IPS\Request::i()->extra : 0;
$select = \IPS\Db::i()->select( '*', 'nexus_shipping', NULL, 's_id', array( $offset, 100 ) );
if ( count( $select ) )
{
foreach ( $select as $row )
{
$update = array();
$decoded = json_decode( $row['s_rates'], TRUE );
if( !empty( $decoded ) )
{
foreach ( $decoded as $k => $value )
{
if ( !isset( $value['min'] ) )
{
$decoded[ $k ] = array(
'min' => array( \IPS\Settings::i()->nexus_currency => floatval( $value['value'] ) ),
'max' => isset( $decoded[ $k + 1 ] ) ? array( \IPS\Settings::i()->nexus_currency => floatval( $decoded[ $k + 1 ]['value'] ) ) : '*',
'price' => array( \IPS\Settings::i()->nexus_currency => floatval( $value['cost'] ) )
);
}
}
if ( json_encode( $decoded ) != $row['s_rates'] )
{
$update['s_rates'] = json_encode( $decoded );
}
}
if ( $decoded = @\unserialize( $row['s_locations'] ) )
{
foreach ( $decoded as $countryCode => $locations )
{
if ( $locations != '*' and isset( $statesFrom3[ $countryCode ] ) and isset( \IPS\GeoLocation::$states[ $countryCode ] ) )
{
foreach ( $locations as $i => $location )
{
if ( !in_array( $location, \IPS\GeoLocation::$states[ $countryCode ] ) )
{
if ( $key = array_search( $location, $statesFrom3[ $countryCode ] ) )
{
if ( $key = array_search( mb_strtolower( $key ), array_map( 'mb_strtolower', \IPS\GeoLocation::$states[ $countryCode ] ) ) )
{
$decoded[ $countryCode ][ $i ] = \IPS\GeoLocation::$states[ $countryCode ][ $key ];
}
}
}
}
}
}
$update['s_locations'] = json_encode( $decoded );
}
if ( !empty( $update ) )
{
\IPS\Db::i()->update( 'nexus_shipping', $update, array( 's_id=?', $row['s_id'] ) );
}
}
return $offset + 100;
}
else
{
unset( $_SESSION['_step16Count'] );
return TRUE;
}
}
}
@@ -0,0 +1,23 @@
{
"1": {
"method": "changeColumn",
"params": [
"nexus_transactions",
"t_amount",
{
"name": "t_amount",
"type": "DECIMAL",
"length": 20,
"decimals": 2,
"values": [],
"allow_null": false,
"default": "0",
"comment": "",
"unsigned": false,
"zerofill": false,
"auto_increment": false,
"binary": false
}
]
}
}
@@ -0,0 +1,23 @@
{
"1": {
"method": "changeColumn",
"params": [
"nexus_purchases",
"ps_renewal_price",
{
"name": "ps_renewal_price",
"type": "DECIMAL",
"length": 20,
"decimals": 2,
"values": [],
"allow_null": false,
"default": "0",
"comment": "",
"unsigned": false,
"zerofill": false,
"auto_increment": false,
"binary": false
}
]
}
}
@@ -185,10 +185,6 @@ class _Upgrade
\IPS\Db::i()->update( 'nexus_donate_goals', array( 'd_currency' => \IPS\Settings::i()->nexus_currency ) );
$toRun = \IPS\core\Setup\Upgrade::runManualQueries( array( array(
'table' => 'core_members',
'query' => "ALTER TABLE " . \IPS\Db::i()->prefix . "core_members CHANGE cm_credits cm_credits TEXT NULL;"
),
array(
'table' => 'core_members',
'query' => "UPDATE " . \IPS\Db::i()->prefix . "core_members SET cm_credits=CONCAT( '{\"" . \IPS\Settings::i()->nexus_currency . "\":', cm_credits, '}' );"
) ) );
+5 -4
View File
@@ -290,9 +290,10 @@ class _Coupon extends \IPS\Node\Model
/* Maximum uses per member? */
$uses = $this->used_by ? json_decode( $this->used_by, TRUE ) : array();
$customerIdentifier = $customer->member_id ?: $invoice->guest_data['member']['email'];
if ( $this->member_uses != -1 )
{
if ( isset( $uses[ $customer->member_id ] ) and $uses[ $customer->member_id ] >= $this->member_uses )
if ( isset( $uses[ $customerIdentifier ] ) and $uses[ $customerIdentifier ] >= $this->member_uses )
{
throw new \DomainException( 'coupon_exceeded_member_uses' );
}
@@ -395,13 +396,13 @@ class _Coupon extends \IPS\Node\Model
}
/* Save that we've used it */
if ( isset( $uses[ $customer->member_id ] ) )
if ( isset( $uses[ $customerIdentifier ] ) )
{
$uses[ $customer->member_id ]++;
$uses[ $customerIdentifier ]++;
}
else
{
$uses[ $customer->member_id ] = 1;
$uses[ $customerIdentifier ] = 1;
}
$this->used_by = json_encode( $uses );
$this->save();
@@ -142,4 +142,40 @@ class _CustomField extends \IPS\CustomField
$this->save();
}
}
/**
* [ActiveRecord] Save Changed Columns
*
* @return void
*/
public function save()
{
parent::save();
\IPS\Widget::deleteCaches( 'donations', 'nexus' );
static::recountCustomerFields();
}
/**
* [ActiveRecord] Delete
*
* @return void
*/
public function delete()
{
parent::delete();
static::recountCustomerFields();
}
/**
* Recount card storage gateays
*
* @return void
*/
protected static function recountCustomerFields()
{
$count = count( static::roots() );
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => $count ), array( 'conf_key=?', 'customer_fields' ) );
\IPS\Settings::i()->customer_fields = $count;
unset( \IPS\Data\Store::i()->settings );
}
}
@@ -368,20 +368,40 @@ class _History extends \IPS\Helpers\Table\Db
switch ( $val['type'] )
{
case 'used':
/* If the customer who used this gift card no longer exists, then we need to load up a guest customer object to avoid an OutOfRangeException */
try
{
$customer = \IPS\nexus\Customer::load( $val['by'] );
}
catch( \OutOfRangeException $e )
{
$customer = new \IPS\nexus\Customer;
}
return
\IPS\Member::loggedIn()->language()->addToStack( 'history_giftvoucher_used', FALSE, array( 'htmlsprintf' => array(
new \IPS\nexus\Money( $val['amount'], $currency ),
$val['code'],
\IPS\Theme::i()->getTemplate('global', 'nexus')->userLink( \IPS\nexus\Customer::load( $val['by'] ) )
\IPS\Theme::i()->getTemplate('global', 'nexus')->userLink( $customer )
) ) );
break;
case 'redeemed':
/* If the customer who redeemed this gift card no longer exists, then we need to load up a guest customer object to avoid an OutOfRangeException */
try
{
$customer = \IPS\nexus\Customer::load( $val['ps_member'] );
}
catch( \OutOfRangeException $e )
{
$customer = new \IPS\nexus\Customer;
}
return
\IPS\Member::loggedIn()->language()->addToStack( 'history_giftvoucher_redeemed', FALSE, array( 'htmlsprintf' => array(
new \IPS\nexus\Money( $val['amount'], $currency ),
$val['code'],
\IPS\Theme::i()->getTemplate('global', 'nexus')->userLink( \IPS\nexus\Customer::load( $val['ps_member'] ) ),
\IPS\Theme::i()->getTemplate('global', 'nexus')->userLink( $customer ),
new \IPS\nexus\Money( $val['newCreditAmount'], $currency )
) ) );
break;
@@ -557,7 +577,7 @@ class _History extends \IPS\Helpers\Table\Db
}
catch ( \OutOfRangeException $e )
{
$options = array( 'htmlsprintf' => array( $file, htmlentities( $val['ps_name'], ENT_QUOTES | \IPS\HTMLENTITIES, 'UTF-8', FALSE ) ) );
$options = array( 'htmlsprintf' => array( $file, htmlspecialchars( $val['ps_name'], ENT_QUOTES | \IPS\HTMLENTITIES, 'UTF-8', FALSE ) ) );
}
return \IPS\Member::loggedIn()->language()->addToStack( 'history_download_with_purchase', FALSE, $options );
}
+27 -2
View File
@@ -142,9 +142,9 @@ class _Goal extends \IPS\Node\Model
return $values;
}
/**
* Save Changed Columns
* [ActiveRecord] Save Changed Columns
*
* @return void
*/
@@ -152,6 +152,31 @@ class _Goal extends \IPS\Node\Model
{
parent::save();
\IPS\Widget::deleteCaches( 'donations', 'nexus' );
static::recountDonationGoals();
}
/**
* [ActiveRecord] Delete
*
* @return void
*/
public function delete()
{
parent::delete();
static::recountDonationGoals();
}
/**
* Recount card storage gateays
*
* @return void
*/
protected static function recountDonationGoals()
{
$count = count( static::roots() );
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => $count ), array( 'conf_key=?', 'donation_goals' ) );
\IPS\Settings::i()->donation_goals = $count;
unset( \IPS\Data\Store::i()->settings );
}
/**
+36 -13
View File
@@ -52,9 +52,7 @@ class _StateSelect extends \IPS\Helpers\Form\FormAbstract
* @return mixed
*/
public function getValue()
{
$value = array();
{
if ( $this->options['unlimitedLang'] )
{
$unlimitedName = "{$this->name}_unlimited";
@@ -64,21 +62,46 @@ class _StateSelect extends \IPS\Helpers\Form\FormAbstract
}
}
foreach ( parent::getValue() as $v )
return parent::getValue();
}
/**
* Get Value
*
* @return mixed
*/
public function formatValue()
{
if ( is_array( $this->value ) )
{
if ( preg_match( '/^([A-Z]{2})-(.*)$/', $v, $matches ) )
$value = array();
foreach ( $this->value as $k => $v )
{
if ( !isset( $value[ $matches[1] ] ) )
if ( in_array( (string) $k, \IPS\GeoLocation::$countries ) )
{
$value[ $matches[1] ] = array();
$value[ $k ] = $v;
}
else
{
if ( preg_match( '/^([A-Z]{2})-(.*)$/', $v, $matches ) )
{
if ( !isset( $value[ $matches[1] ] ) )
{
$value[ $matches[1] ] = array();
}
$value[ $matches[1] ][] = $matches[2];
}
else
{
$value[ $v ] = '*';
}
}
$value[ $matches[1] ][] = $matches[2];
}
else
{
$value[ $v ] = '*';
}
return $value;
}
else
{
return $this->value;
}
return $value;
}
}
@@ -227,6 +227,41 @@ class _Gateway extends \IPS\Node\Model
return $return;
}
/**
* [ActiveRecord] Save Changed Columns
*
* @return void
*/
public function save()
{
parent::save();
static::recountCardStorageGateways();
}
/**
* [ActiveRecord] Delete
*
* @return void
*/
public function delete()
{
parent::delete();
static::recountCardStorageGateways();
}
/**
* Recount card storage gateays
*
* @return void
*/
protected static function recountCardStorageGateways()
{
$count = count( static::cardStorageGateways() );
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => $count ), array( 'conf_key=?', 'card_storage_gateways' ) );
\IPS\Settings::i()->card_storage_gateways = $count;
unset( \IPS\Data\Store::i()->settings );
}
/* !Features (Each gateway will override) */
const SUPPORTS_REFUNDS = FALSE;
@@ -55,7 +55,7 @@ class _Manual extends \IPS\nexus\Gateway
*/
public function settings( &$form )
{
$form->add( new \IPS\Helpers\Form\Translatable( 'manual_instructions', NULL, TRUE, array( 'app' => 'nexus', 'key' => ( $this->id ? "nexus_gateway_{$this->id}_ins" : NULL ), 'editor' => array( 'app' => 'nexus', 'key' => 'Admin', 'autoSaveKey' => ( $this->id ? "nexus-gateway-{$this->id}" : "nexus-new-gateway" ), 'attachIds' => $this->id ? array( $this->id, NULL, 'description' ) : NULL, 'minimize' => 'forum_description_placeholder' ) ) ) );
$form->add( new \IPS\Helpers\Form\Translatable( 'manual_instructions', NULL, TRUE, array( 'app' => 'nexus', 'key' => ( $this->id ? "nexus_gateway_{$this->id}_ins" : NULL ), 'editor' => array( 'app' => 'nexus', 'key' => 'Admin', 'autoSaveKey' => ( $this->id ? "nexus-gateway-{$this->id}" : "nexus-new-gateway" ), 'attachIds' => $this->id ? array( $this->id, NULL, 'description' ) : NULL, 'minimize' => 'manual_gateway_description_placeholder' ) ) ) );
}
/**
@@ -336,8 +336,8 @@ class _PayPal extends \IPS\nexus\Gateway
'expire_month' => intval( $card->expMonth ),
'expire_year' => intval( $card->expYear ),
'cvv2' => intval( $card->ccv ),
'first_name' => $transaction->member->cm_first_name,
'last_name' => $transaction->member->cm_last_name,
'first_name' => $transaction->invoice->member->cm_first_name,
'last_name' => $transaction->invoice->member->cm_last_name,
'billing_address' => $billingAddress
)
),
+25 -4
View File
@@ -824,7 +824,7 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
/* Add it all together */
$return['total'] = new \IPS\nexus\Money( $subtotal + $shipping + $tax, $this->currency );
$return['total'] = $return['total']->round(); // Total value must also be a valid currency amount
return $return;
}
@@ -1050,10 +1050,10 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
/* If we're still here, we're applying commission */
$amountToGive = round( ( ( $amountToApplyCommissionOn / 100 ) * $commissionRule->commission ), 2 );
if ( $commissionRule->commission_limit )
if ( $commissionRule->commission_limit and $commissionRule->commission_limit != '*' )
{
$limit = json_decode( $commissionRule->commission_limit, TRUE );
if ( $amountToGive > $limit[ $this->currency ]['amount'] )
if ( isset( $limit[ $this->currency ] ) and $amountToGive > $limit[ $this->currency ]['amount'] )
{
$amountToGive = $limit[ $this->currency ]['amount'];
}
@@ -1135,7 +1135,7 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
}
}
return $amountToPay;
return $amountToPay->round();
}
/**
@@ -1361,6 +1361,27 @@ class _Invoice extends \IPS\Patterns\ActiveRecord
/* Update associated transactions */
\IPS\Db::i()->update( 'nexus_transactions', array( 't_member' => $this->member->member_id ), array( 't_invoice=? AND t_member=0', $this->id ) );
/* Did we use any coupons? */
foreach ( $this->items as $item )
{
if ( $item instanceof \IPS\nexus\extensions\nexus\Item\CouponDiscount )
{
$coupon = \IPS\nexus\Coupon::load( $item->id );
$uses = $coupon->used_by ? json_decode( $coupon->used_by, TRUE ) : array();
if ( isset( $uses[ $this->member->email ] ) )
{
$uses[ $this->member->member_id ] = $uses[ $this->member->email ];
unset( $uses[ $this->member->email ] );
}
else
{
$uses[ $this->member->member_id ] = 1;
}
$coupon->used_by = json_encode( $uses );
$coupon->save();
}
}
}
/* Init */
+33 -1
View File
@@ -123,10 +123,42 @@ class _Money
{
/* If the server has intl installed, use that */
if ( function_exists( 'numfmt_format_currency' ) )
{
{
/* Unfortunately a bug in intl means that locales which use commas for decimal separation are broken.
@link https://community.invisionpower.com/4bugtrack/active-reports/nexus-money-formatting-r6911/ .
What we'll do is store the current locale, reset to English, then reset back to current locale afterwards. */
$currentLocale = setlocale( LC_ALL, '0' );
if( mb_strtoupper( mb_substr( PHP_OS, 0, 3 ) ) === 'WIN' )
{
setlocale( LC_ALL, 'english' );
}
else
{
setlocale( LC_ALL, 'en_US' );
}
$format = numfmt_create( $language->short, \NumberFormatter::CURRENCY );
if ( $return = numfmt_format_currency( $format, $this->amount, $this->currency ) and $return !== 'NaN' )
{
/* Now we have to reset locale back to what it was */
foreach( explode( ";", $currentLocale ) as $locale )
{
if( mb_strpos( $locale, '=' ) !== FALSE )
{
$parts = explode( "=", $locale );
if( in_array( $parts[0], array( 'LC_ALL', 'LC_COLLATE', 'LC_CTYPE', 'LC_MONETARY', 'LC_NUMERIC', 'LC_TIME' ) ) )
{
setlocale( constant( $parts[0] ), $parts[1] );
}
}
else
{
setLocale( LC_ALL, $locale );
}
}
return $return;
}
}
+9 -6
View File
@@ -140,14 +140,17 @@ class _Ad extends \IPS\nexus\Package
unset( $values['p_max_dims'] );
}
$locations = $values['p_locations'];
$customKey = array_search( '_ad_custom_', $locations );
if ( $customKey !== FALSE )
if ( isset( $values['p_locations'] ) )
{
unset( $locations[ $customKey ] );
$locations = array_merge( $locations, $values['p_locations_custom'] );
$locations = $values['p_locations'];
$customKey = array_search( '_ad_custom_', $locations );
if ( $customKey !== FALSE )
{
unset( $locations[ $customKey ] );
$locations = array_merge( $locations, $values['p_locations_custom'] );
}
$values['p_locations'] = implode( ',', $locations );
}
$values['p_locations'] = implode( ',', $locations );
unset( $values['p_locations_custom'] );
return parent::formatFormValues( $values );
@@ -257,4 +257,19 @@ class _Item extends \IPS\Content\Item implements \IPS\Content\Featurable, \IPS\C
$product = \IPS\nexus\Package::load( $this->id );
return $product->_data['image'] ? \IPS\File::get( 'nexus_Products', $product->_data['image'] ) : NULL;
}
/**
* Get mapped value
*
* @param string $key date,content,ip_address,first
* @return mixed
*/
public function mapped( $key )
{
if ( $key === 'title' )
{
return $this->title;
}
return parent::mapped($key);
}
}
+19 -16
View File
@@ -791,7 +791,13 @@ class _Package extends \IPS\Node\Model
$form->add( $field );
}
$form->addHeader('package_registration');
$form->add( new \IPS\Helpers\Form\YesNo( 'p_reg', $this->reg ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'p_reg', $this->reg, FALSE, array(), function( $val )
{
if ( $val and ( !\IPS\Request::i()->p_store_checkbox or ( \IPS\Request::i()->p_member_groups and !in_array( \IPS\Settings::i()->guest_group, \IPS\Request::i()->p_member_groups ) ) ) )
{
throw new \DomainException( \IPS\Member::loggedIn()->language()->addToStack( 'p_reg_err', FALSE, array( 'sprintf' => array( \IPS\Member\Group::load( \IPS\Settings::i()->guest_group )->name ) ) ) );
}
} ) );
$form->addHeader('package_associations');
$form->addMessage('package_associations_desc');
$form->add( new \IPS\Helpers\Form\Radio( 'p_associate', ( $this->force_assoc and count( $this->associablePackages() ) ) ? 2 : ( count( $this->associablePackages() ) ? 1 : 0 ), FALSE, array(
@@ -1300,19 +1306,22 @@ class _Package extends \IPS\Node\Model
{
$newRenewTerms = array();
}
$key = 'x';
foreach ( $changes['renew_options'] as $k => $data )
if ( $purchase->renewals )
{
if ( $data['old'] != 'x' )
foreach ( $changes['renew_options'] as $k => $data )
{
if ( $data['old']['cost'][ $purchase->renewals->cost->currency ]['amount'] == $purchase->renewals->cost->amount )
if ( $data['old'] != 'x' )
{
$term = $purchase->renewals->getTerm();
if ( $data['old']['term'] == $term['term'] and $data['old']['unit'] == $term['unit'] )
if ( $data['old']['cost'][ $purchase->renewals->cost->currency ]['amount'] == $purchase->renewals->cost->amount )
{
$key = $k;
break;
$term = $purchase->renewals->getTerm();
if ( $data['old']['term'] == $term['term'] and $data['old']['unit'] == $term['unit'] )
{
$key = $k;
break;
}
}
}
}
@@ -2802,13 +2811,7 @@ class _Package extends \IPS\Node\Model
catch ( \UnderflowException $e )
{
$purchase->member->member_group_id = $purchase->member->cm_return_group;
/* Don't move them back into validating */
if ( $purchase->member->member_group_id == \IPS\Settings::i()->auth_group )
{
$purchase->member->member_group_id = \IPS\Settings::i()->member_group;
}
/* Does this group exist? */
try
{
@@ -35,13 +35,13 @@ class _Purchase extends \IPS\Node\Model
* @return \IPS\Helpers\Tree
*/
public static function tree( \IPS\Http\Url $url, array $where, $ref = 'c', \IPS\nexus\Purchase $root = NULL, $includeRoot = TRUE )
{
{
$where[] = array( 'ps_show=1' );
return new \IPS\Helpers\Tree\Tree(
$url,
'Purchases',
function() use ( $url, $where, $ref, $root, $includeRoot )
function( $limit ) use ( $url, $where, $ref, $root, $includeRoot )
{
if ( $root )
{
@@ -60,7 +60,7 @@ class _Purchase extends \IPS\Node\Model
}
$rows = array();
foreach( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_purchases', $where ), 'IPS\nexus\Purchase' ) as $purchase )
foreach( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_purchases', $where, 'ps_start DESC', $limit ), 'IPS\nexus\Purchase' ) as $purchase )
{
$rows[ $purchase->id ] = $purchase->treeRow( $url, $ref );
}
@@ -82,6 +82,16 @@ class _Purchase extends \IPS\Node\Model
$rows[ $child->id ] = $child->treeRow( $url, $ref );
}
return $rows;
},
NULL,
FALSE,
FALSE,
FALSE,
NULL,
function()
{
$where[] = array( 'ps_parent=0' );
return \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', $where )->first();
}
);
}
@@ -40,12 +40,15 @@ class _EasyPostRate implements \IPS\nexus\Shipping\Rate
}
/**
* Is available to destination?
* Is available?
*
* @param \IPS\GeoLocation $destination Desired destination
* @param \IPS\GeoLocation $destination Desired destination
* @param array $items Items
* @param string $currency Desired currency
* @param \IPS\nexus\Invoice|NULL $invoice The invoice
* @return bool
*/
public function isAvailable( \IPS\GeoLocation $destination )
public function isAvailable( \IPS\GeoLocation $destination, array $items, $currency, \IPS\nexus\Invoice $invoice = NULL )
{
return TRUE;
}
@@ -141,7 +144,7 @@ class _EasyPostRate implements \IPS\nexus\Shipping\Rate
*/
public static function getRates( $lengthInInches, $widthInInches, $heightInInches, $weightInOz, \IPS\nexus\Customer $toCustomer, \IPS\Geolocation $toAddress, $currency )
{
$fromAddress = \IPS\GeoLocation::buildFromJson( \IPS\Settings::i()->site_address );
$fromAddress = \IPS\GeoLocation::buildFromJson( \IPS\Settings::i()->easypost_address ?: \IPS\Settings::i()->site_address );
return \IPS\Http\Url::external( 'https://api.easypost.com/v2/shipments' )->request()->login( \IPS\Settings::i()->easypost_api_key, '' )->post( array( 'shipment' => array(
'to_address' => array(
@@ -363,35 +363,56 @@ class _FlatRate extends \IPS\Node\Model implements \IPS\nexus\Shipping\Rate
}
/**
* Is available to destination?
* Is available?
*
* @param \IPS\GeoLocation $destination Desired destination
* @param \IPS\GeoLocation $destination Desired destination
* @param array $items Items
* @param string $currency Desired currency
* @param \IPS\nexus\Invoice|NULL $invoice The invoice
* @return bool
*/
public function isAvailable( \IPS\GeoLocation $destination )
public function isAvailable( \IPS\GeoLocation $destination, array $items, $currency, \IPS\nexus\Invoice $invoice = NULL )
{
if ( $this->locations === '*' )
{
return TRUE;
}
else
/* Is available to destination? */
if ( $this->locations !== '*' )
{
$locations = json_decode( $this->locations, TRUE );
if ( isset( $locations[ $destination->country ] ) )
{
if ( $locations[ $destination->country ] === '*' )
if ( $locations[ $destination->country ] !== '*' and !in_array( $destination->region, $locations[ $destination->country ] ) )
{
return TRUE;
}
else
{
return in_array( $destination->region, $locations[ $destination->country ] );
return FALSE;
}
}
return FALSE;
else
{
return FALSE;
}
}
/* Is it available for what's being bought? */
$criteria = $this->_getCriteria( $items, $invoice );
$rates = json_decode( $this->rates, TRUE );
foreach ( $rates as $rate )
{
$min = $rate['min'];
if ( is_array( $min ) )
{
$min = $min[ $currency ];
}
$max = $rate['max'];
if ( is_array( $max ) )
{
$max = $max[ $currency ];
}
if ( ( $min === '*' or $criteria >= $min ) and ( $max === '*' or $criteria <= $max ) )
{
return TRUE;
}
}
return FALSE;
}
/**
@@ -405,14 +426,13 @@ class _FlatRate extends \IPS\Node\Model implements \IPS\nexus\Shipping\Rate
}
/**
* Price
* Get criteria
*
* @param array $items Items
* @param string $currency Desired currency
* @param \IPS\nexus\Invoice|NULL $invoice The invoice
* @return \IPS\nexus\Money
* @return The criteria the rased is based on (e.g. if the rate is based on invoice total, will return the invoice total)
*/
public function getPrice( array $items, $currency, \IPS\nexus\Invoice $invoice = NULL )
protected function _getCriteria( array $items, \IPS\nexus\Invoice $invoice = NULL )
{
switch ( $this->type )
{
@@ -450,6 +470,21 @@ class _FlatRate extends \IPS\Node\Model implements \IPS\nexus\Shipping\Rate
}
}
return $criteria;
}
/**
* Price
*
* @param array $items Items
* @param string $currency Desired currency
* @param \IPS\nexus\Invoice|NULL $invoice The invoice
* @return \IPS\nexus\Money
*/
public function getPrice( array $items, $currency, \IPS\nexus\Invoice $invoice = NULL )
{
$criteria = $this->_getCriteria( $items, $invoice );
$rates = json_decode( $this->rates, TRUE );
foreach ( $rates as $rate )
{
+6 -3
View File
@@ -25,12 +25,15 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
interface Rate
{
/**
* Is available to destination?
* Is available?
*
* @param \IPS\GeoLocation $destination Desired destination
* @param \IPS\GeoLocation $destination Desired destination
* @param array $items Items
* @param string $currency Desired currency
* @param \IPS\nexus\Invoice|NULL $invoice The invoice
* @return bool
*/
public function isAvailable( \IPS\GeoLocation $destination );
public function isAvailable( \IPS\GeoLocation $destination, array $items, $currency, \IPS\nexus\Invoice $invoice = NULL );
/**
* Name
+1 -1
View File
@@ -294,7 +294,7 @@ class _Reply extends \IPS\Content\Comment implements \IPS\Content\Hideable
if ( !in_array( $staffId, $sentTo ) and ( $this->item()->department->staff === '*' or in_array( $staffId, explode( ',', $this->item()->department->staff ) ) ) )
{
$email = \IPS\Email::buildFromTemplate( 'nexus', $this->type === static::REPLY_HIDDEN ? 'staffNotifyNote' : 'staffNotifyReply', array( $this ) );
$email->from = $this->item()->department->email;
$email->from = ( $this->item()->department->email ) ? $this->item()->department->email : \IPS\Settings::i()->email_out;
switch ( \IPS\Settings::i()->nexus_sout_from )
{
case 'staff':
@@ -256,7 +256,7 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
}
else
{
return htmlentities( $row['r_email'], \IPS\HTMLENTITIES, 'UTF-8', FALSE );
return htmlspecialchars( $row['r_email'], \IPS\HTMLENTITIES, 'UTF-8', FALSE );
}
},
'r_last_reply_by' => function( $val, $row )
@@ -773,7 +773,7 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
$invoice->member = \IPS\nexus\Customer::loggedIn();
$invoice->return_uri = "app=nexus&module=support&controller=home&do=create&department={$department->id}&title=" . urlencode( $values['support_title'] );
$item = new \IPS\nexus\extensions\nexus\Item\SupportCharge( $department->_title, $ppiCost );
$item = new \IPS\nexus\extensions\nexus\Item\SupportCharge( \IPS\Member::loggedIn()->language()->get( 'nexus_department_' . $department->_id ), $ppiCost );
$item->id = $department->id;
if ( $department->ppi_tax )
{
@@ -900,6 +900,8 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
}
parent::processAfterCreate( $comment, $values );
$this->sendNotifications();
}
/**
@@ -1348,7 +1350,7 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
if ( $this->department->staff === '*' or count( array_intersect( \IPS\nexus\Support\Department::staffDepartmentPerms( $member ), explode( ',', $this->department->staff ) ) ) )
{
$email = \IPS\Email::buildFromTemplate( 'nexus', 'staffNotifyNew', array( $this ) );
$email->from = $this->department->email;
$email->from = ( $this->department->email ) ? $this->department->email : \IPS\Settings::i()->email_out;
switch ( \IPS\Settings::i()->nexus_sout_from )
{
case 'staff':
@@ -258,4 +258,20 @@ class _Status extends \IPS\Node\Model
return $buttons;
}
/**
* [ActiveRecord] Duplicate
*
* @return void
*/
public function __clone()
{
$oldId = $this->_id;
parent::__clone();
\IPS\Lang::saveCustom( 'nexus', "nexus_status_{$this->id}_admin", iterator_to_array( \IPS\Db::i()->select( 'CONCAT(word_custom, \' ' . \IPS\Member::loggedIn()->language()->get('copy_noun') . '\') as word_custom, lang_id', 'core_sys_lang_words', array( 'word_key=?', "nexus_status_{$oldId}_admin" ) )->setKeyField( 'lang_id' )->setValueField('word_custom') ) );
\IPS\Lang::saveCustom( 'nexus', "nexus_status_{$this->id}_front", iterator_to_array( \IPS\Db::i()->select( 'word_custom, lang_id', 'core_sys_lang_words', array( 'word_key=?', "nexus_status_{$oldId}_front" ) )->setKeyField( 'lang_id' )->setValueField('word_custom') ) );
\IPS\Lang::saveCustom( 'nexus', "nexus_status_{$this->id}_set", iterator_to_array( \IPS\Db::i()->select( 'word_custom, lang_id', 'core_sys_lang_words', array( 'word_key=?', "nexus_status_{$oldId}_set" ) )->setKeyField( 'lang_id' )->setValueField('word_custom') ) );
}
}
+1 -1
View File
@@ -138,7 +138,7 @@ class _Tax extends \IPS\Node\Model
* @return array
*/
public function formatFormValues( $values )
{
{
$rates = array();
if( isset( $values['rates'] ) )
@@ -116,41 +116,47 @@ class _generateRenewalInvoices extends \IPS\Task
/* Charge to card */
if ( $invoice->status !== $invoice::STATUS_PAID )
{
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_customer_cards', array( 'card_member=?', $member->member_id ) ), 'IPS\nexus\Customer\CreditCard' ) as $card )
{
$amountToPay = $invoice->amountToPay();
$gateway = $card->method;
$transaction = new \IPS\nexus\Transaction;
$transaction->member = $member;
$transaction->invoice = $invoice;
$transaction->method = $gateway;
$transaction->amount = $amountToPay;
$transaction->currency = $currency;
$transaction->extra = array( 'automatic' => TRUE );
try
try
{
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_customer_cards', array( 'card_member=?', $member->member_id ) ), 'IPS\nexus\Customer\CreditCard' ) as $card )
{
$transaction->auth = $gateway->auth( $transaction, array(
( $gateway->id . '_card' ) => $card
) );
$transaction->capture();
$transaction->member->log( 'transaction', array(
'type' => 'paid',
'status' => \IPS\nexus\Transaction::STATUS_PAID,
'id' => $transaction->id,
'invoice_id' => $invoice->id,
'invoice_title' => $invoice->title,
'automatic' => TRUE,
), FALSE );
$transaction->approve();
$amountToPay = $invoice->amountToPay();
$gateway = $card->method;
$transaction = new \IPS\nexus\Transaction;
$transaction->member = $member;
$transaction->invoice = $invoice;
$transaction->method = $gateway;
$transaction->amount = $amountToPay;
$transaction->currency = $currency;
$transaction->extra = array( 'automatic' => TRUE );
try
{
$transaction->auth = $gateway->auth( $transaction, array(
( $gateway->id . '_card' ) => $card
) );
$transaction->capture();
$transaction->member->log( 'transaction', array(
'type' => 'paid',
'status' => \IPS\nexus\Transaction::STATUS_PAID,
'id' => $transaction->id,
'invoice_id' => $invoice->id,
'invoice_title' => $invoice->title,
'automatic' => TRUE,
), FALSE );
$transaction->approve();
}
catch ( \Exception $e ){}
$invoice->status = $transaction->invoice->status;
}
catch ( \Exception $e ){}
$invoice->status = $transaction->invoice->status;
}
// credit card doesn't exist anymore , move on
catch ( \OutOfRangeException $e ){}
}
/* Update the purchase */