Version 4.5.0

This commit is contained in:
Neo committed 2025-12-19 05:51:58 -08:00
1 parent 1a0c7fd3c2
commit f79dcf067a
3791 files changed
+248032 -76372

No files matched your search

File diff suppressed because it is too large. Load diff
@@ -12,7 +12,7 @@
namespace IPS\nexus\modules\front\clients;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -56,7 +56,7 @@ class _addresses extends \IPS\Dispatcher\Controller
*/
protected function manage()
{
$addresses = new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_customer_addresses', array( 'member=?', \IPS\Member::loggedIn()->member_id ) ), 'IPS\nexus\Customer\Address' );
$addresses = new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_customer_addresses', array( '`member`=?', \IPS\Member::loggedIn()->member_id ) ), 'IPS\nexus\Customer\Address' );
$shippingAddress = NULL;
$billingAddress = NULL;
@@ -106,9 +106,25 @@ class _addresses extends \IPS\Dispatcher\Controller
$existing = NULL;
}
}
$needTaxStatus = NULL;
foreach ( \IPS\nexus\Tax::roots() as $tax )
{
if ( $tax->type === 'eu' )
{
$needTaxStatus = 'eu';
break;
}
if ( $tax->type === 'business' )
{
$needTaxStatus = 'business';
}
}
$addressHelperClass = $needTaxStatus ? 'IPS\nexus\Form\BusinessAddress' : 'IPS\Helpers\Form\Address';
$addressHelperOptions = ( $needTaxStatus === 'eu' ) ? array( 'vat' => TRUE ) : array();
$form = new \IPS\Helpers\Form;
$form->add( new \IPS\Helpers\Form\Address( 'address', $existing ? $existing->address : NULL, TRUE ) );
$form->add( new $addressHelperClass( 'address', $existing ? $existing->address : NULL, TRUE, $addressHelperOptions ) );
if ( $values = $form->values() )
{
@@ -116,8 +132,8 @@ class _addresses extends \IPS\Dispatcher\Controller
{
$existing = new \IPS\nexus\Customer\Address;
$existing->member = \IPS\Member::loggedIn();
$existing->primary_billing = !\IPS\Db::i()->select( 'count(*)', 'nexus_customer_addresses', array( 'member=? AND primary_billing=1', \IPS\Member::loggedIn()->member_id ) )->first();
$existing->primary_shipping = !\IPS\Db::i()->select( 'count(*)', 'nexus_customer_addresses', array( 'member=? AND primary_shipping=1', \IPS\Member::loggedIn()->member_id ) )->first();
$existing->primary_billing = !\IPS\Db::i()->select( 'count(*)', 'nexus_customer_addresses', array( '`member`=? AND primary_billing=1', \IPS\Member::loggedIn()->member_id ) )->first();
$existing->primary_shipping = !\IPS\Db::i()->select( 'count(*)', 'nexus_customer_addresses', array( '`member`=? AND primary_shipping=1', \IPS\Member::loggedIn()->member_id ) )->first();
\IPS\nexus\Customer::loggedIn()->log( 'address', array( 'type' => 'add', 'details' => json_encode( $values['address'] ) ) );
}
@@ -129,13 +145,15 @@ class _addresses extends \IPS\Dispatcher\Controller
$existing->address = $values['address'];
$existing->save();
\IPS\Request::i()->setCookie( 'location', NULL );
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=nexus&module=clients&controller=addresses', 'front', 'clientsaddresses' ) );
}
if ( \IPS\Request::i()->isAjax() )
{
$form->class = 'ipsForm_vertical ipsForm_noLabels';
\IPS\Output::i()->sendOutput( $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) ) );
\IPS\Output::i()->sendOutput( $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) ) );
}
else
{
@@ -158,7 +176,7 @@ class _addresses extends \IPS\Dispatcher\Controller
if ( $address->member->member_id == \IPS\Member::loggedIn()->member_id )
{
$field = \IPS\Request::i()->primary === 'billing' ? 'primary_billing' : 'primary_shipping';
\IPS\Db::i()->update( 'nexus_customer_addresses', array( $field => 0 ), array( 'member=?', \IPS\Member::loggedIn()->member_id ) );
\IPS\Db::i()->update( 'nexus_customer_addresses', array( $field => 0 ), array( '`member`=?', \IPS\Member::loggedIn()->member_id ) );
$address->$field = TRUE;
$address->save();
@@ -166,6 +184,8 @@ class _addresses extends \IPS\Dispatcher\Controller
}
}
catch ( \OutOfRangeException $e ) {}
\IPS\Request::i()->setCookie( 'location', NULL );
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=nexus&module=clients&controller=addresses', 'front', 'clientsaddresses' ) );
}
@@ -12,7 +12,7 @@
namespace IPS\nexus\modules\front\clients;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -87,6 +87,11 @@ class _alternatives extends \IPS\Dispatcher\Controller
{
$form->add( new \IPS\Helpers\Form\Email( 'altcontact_email', NULL, TRUE, array(), function( $val )
{
if( \IPS\Member::loggedIn()->email == $val )
{
throw new \DomainException('altcontact_email_self');
}
$member = \IPS\Member::load( $val, 'email' );
if ( !$member->member_id )
{
@@ -128,7 +133,7 @@ class _alternatives extends \IPS\Dispatcher\Controller
if( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->sendOutput( $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) ) );
\IPS\Output::i()->sendOutput( $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) ) );
}
else
{
@@ -12,7 +12,7 @@
namespace IPS\nexus\modules\front\clients;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -60,7 +60,7 @@ class _billingagreements extends \IPS\Dispatcher\Controller
$where = array( 'ba_member=?', \IPS\Member::loggedIn()->member_id );
$parentContacts = \IPS\nexus\Customer::loggedIn()->parentContacts( array( 'billing=1' ) );
if ( count( $parentContacts ) )
if ( \count( $parentContacts ) )
{
$or = array();
foreach ( array_keys( iterator_to_array( $parentContacts ) ) as $id )
@@ -131,7 +131,7 @@ class _billingagreements extends \IPS\Dispatcher\Controller
}
/* Transactions */
$currentPage = isset( \IPS\Request::i()->page ) ? intval( \IPS\Request::i()->page ) : 1;
$currentPage = isset( \IPS\Request::i()->page ) ? \intval( \IPS\Request::i()->page ) : 1;
$perPage = 25;
$invoices = new \IPS\Patterns\ActiveRecordIterator(
\IPS\Db::i()->select(
@@ -139,14 +139,12 @@ class _billingagreements extends \IPS\Dispatcher\Controller
'nexus_invoices',
array( 'i_id IN(?)', \IPS\Db::i()->select( 't_invoice', 'nexus_transactions', array( 't_billing_agreement=?', $billingAgreement->id ) ) ),
'i_date DESC',
array( ( $currentPage - 1 ) * $perPage, $perPage ),
NULL,
NULL,
\IPS\Db::SELECT_SQL_CALC_FOUND_ROWS
array( ( $currentPage - 1 ) * $perPage, $perPage )
),
'IPS\nexus\Invoice'
);
$pagination = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination( $billingAgreement->url(), ceil( $invoices->count( TRUE ) / $perPage ), $currentPage, $perPage );
$invoicesCount = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_invoices', array( 'i_id IN(?)', \IPS\Db::i()->select( 't_invoice', 'nexus_transactions', array( 't_billing_agreement=?', $billingAgreement->id ) ) ) )->first();
$pagination = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination( $billingAgreement->url(), ceil( $invoicesCount / $perPage ), $currentPage, $perPage );
\IPS\Output::i()->breadcrumb[] = array( $billingAgreement->url(), $billingAgreement->gw_id );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('clients')->billingAgreement( $billingAgreement, $purchases, $invoices, $pagination );
@@ -163,7 +161,7 @@ class _billingagreements extends \IPS\Dispatcher\Controller
/* Check act */
$act = \IPS\Request::i()->act;
if ( !in_array( $act, array( 'suspend', 'reactivate', 'cancel' ) ) )
if ( !\in_array( $act, array( 'suspend', 'reactivate', 'cancel' ) ) )
{
\IPS\Output::i()->error( 'node_error', '3X321/3', 403, '' );
}
@@ -12,7 +12,7 @@
namespace IPS\nexus\modules\front\clients;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -63,10 +63,10 @@ class _cards extends \IPS\Dispatcher\Controller
{
$cardData = $card->card;
$cards[ $card->id ] = array(
'id' => $card->id,
'card_type' => $cardData->type,
'card_number' => $cardData->lastFour,
'card_expire' => ( !is_null( $cardData->expMonth ) AND !is_null( $cardData->expYear ) ) ? str_pad( $cardData->expMonth , 2, '0', STR_PAD_LEFT ). '/' . $cardData->expYear : NULL
'id' => $card->id,
'card_type' => $cardData->type,
'card_number' => $cardData->lastFour ?: $cardData->number,
'card_expire' => ( !\is_null( $cardData->expMonth ) AND !\is_null( $cardData->expYear ) ) ? str_pad( $cardData->expMonth , 2, '0', STR_PAD_LEFT ). '/' . $cardData->expYear : NULL
);
}
catch ( \Exception $e ) { }
@@ -82,8 +82,9 @@ class _cards extends \IPS\Dispatcher\Controller
*/
public function add()
{
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'checkout.css', 'nexus' ) );
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'global_gateways.js', 'nexus', 'global' ) );
$form = \IPS\nexus\Customer\CreditCard::create( \IPS\nexus\Customer::loggedIn() );
$form = \IPS\nexus\Customer\CreditCard::create( \IPS\nexus\Customer::loggedIn(), FALSE );
if ( $form instanceof \IPS\nexus\Customer\CreditCard )
{
\IPS\nexus\Customer::loggedIn()->log( 'card', array( 'type' => 'add', 'number' => $form->card->lastFour ) );
@@ -12,7 +12,7 @@
namespace IPS\nexus\modules\front\clients;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -64,17 +64,17 @@ class _credit extends \IPS\Dispatcher\Controller
/* Pending Withdrawls */
$perPage = 10;
$page = isset( \IPS\Request::i()->page ) ? intval( \IPS\Request::i()->page ) : 1;
$page = isset( \IPS\Request::i()->page ) ? \intval( \IPS\Request::i()->page ) : 1;
if( $page < 1 )
{
$page = 1;
}
$pastWithdrawalsSelect = \IPS\Db::i()->select( '*', 'nexus_payouts', array( 'po_member=?', \IPS\nexus\Customer::loggedIn()->member_id ), 'po_date DESC', array( ( $page - 1 ) * $perPage, $perPage ), NULL, NULL, \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS );
$pastWithdrawalsSelect = \IPS\Db::i()->select( '*', 'nexus_payouts', array( 'po_member=?', \IPS\nexus\Customer::loggedIn()->member_id ), 'po_date DESC', array( ( $page - 1 ) * $perPage, $perPage ) );
$pastWithdrawalsPagination = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination(
\IPS\Http\Url::internal( 'app=nexus&module=clients&controller=credit', 'front', 'clientscredit' ),
ceil( $pastWithdrawalsSelect->count( TRUE ) / $perPage ),
ceil( \IPS\Db::i()->select( 'COUNT(*)', 'nexus_payouts', array( 'po_member=?', \IPS\nexus\Customer::loggedIn()->member_id ) )->first() / $perPage ),
$page,
$perPage
);
@@ -83,7 +83,7 @@ class _credit extends \IPS\Dispatcher\Controller
/* Can we withdraw? */
$canWithdraw = FALSE;
$withdrawOptions = json_decode( \IPS\Settings::i()->nexus_payout, TRUE );
if ( count( $withdrawOptions ) )
if ( \count( $withdrawOptions ) )
{
foreach ( \IPS\nexus\Money::currencies() as $currency )
{
@@ -136,7 +136,7 @@ class _credit extends \IPS\Dispatcher\Controller
{
unset( $withdrawOptions['Stripe'] );
}
if ( count( $withdrawOptions ) )
if ( \count( $withdrawOptions ) )
{
$withdrawForm = new \IPS\Helpers\Form( 'withdraw', 'withdraw_credit' );
@@ -149,7 +149,7 @@ class _credit extends \IPS\Dispatcher\Controller
} );
$currencyOptions = array();
if ( count( $balance ) > 1 )
if ( \count( $balance ) > 1 )
{
$currencyToggles = array();
foreach ( \IPS\nexus\Money::currencies() as $currency )
@@ -207,7 +207,7 @@ class _credit extends \IPS\Dispatcher\Controller
\IPS\Member::loggedIn()->language()->words[ 'withdraw_amount_' . $currency . '_desc' ] = \IPS\Member::loggedIn()->language()->addToStack( 'max_withdrawl_exceeded' );
}
$field = new \IPS\Helpers\Form\Number( 'withdraw_amount_' . $currency, (string) $max, count( $currencyOptions ) ? NULL : TRUE, array( 'min' => $min, 'max' => (string) $max, 'decimals' => \IPS\nexus\Money::numberOfDecimalsForCurrency( $currency ), 'disabled' => ( $max <= 0 ) ), count( $currencyOptions ) ? NULL : function( $val ) use ( $currency )
$field = new \IPS\Helpers\Form\Number( 'withdraw_amount_' . $currency, (string) $max, \count( $currencyOptions ) ? NULL : TRUE, array( 'min' => $min, 'max' => (string) $max, 'decimals' => \IPS\nexus\Money::numberOfDecimalsForCurrency( $currency ), 'disabled' => ( $max <= 0 ) ), \count( $currencyOptions ) ? NULL : function( $val ) use ( $currency )
{
if ( !$val and \IPS\Request::i()->withdraw_currency === $currency )
{
@@ -229,7 +229,7 @@ class _credit extends \IPS\Dispatcher\Controller
{
$options[ $k ] = $k === 'Manual' ? $settings['name'] : 'withdraw__' . $k;
$toggles[ $k ] = array();
$class = 'IPS\nexus\Gateway\\' . $k . '\Payout';
$class = \IPS\nexus\Gateway::payoutGateways()[ $k ];
foreach ( $class::form() as $field )
{
if ( !$field->htmlId )
@@ -241,7 +241,7 @@ class _credit extends \IPS\Dispatcher\Controller
}
}
if ( count( $withdrawOptions ) > 1 )
if ( \count( $withdrawOptions ) > 1 )
{
$withdrawForm->add( new \IPS\Helpers\Form\Radio( 'withdraw_method', NULL, TRUE, array( 'options' => $options, 'toggles' => $toggles ) ) );
}
@@ -253,17 +253,17 @@ class _credit extends \IPS\Dispatcher\Controller
if ( $values = $withdrawForm->values() )
{
$currencies = array_keys( $balance );
$currency = count( $currencyOptions ) ? $values['withdraw_currency'] : array_pop( $currencies );
$currency = \count( $currencyOptions ) ? $values['withdraw_currency'] : array_pop( $currencies );
$withdrawMethods = array_keys( $options );
if ( count( $withdrawMethods ) === 1 )
if ( \count( $withdrawMethods ) === 1 )
{
$key = array_pop( $withdrawMethods );
$class = 'IPS\nexus\Gateway\\' . $key . '\Payout';
$class = \IPS\nexus\Gateway::payoutGateways()[ $key ];
}
else
{
$class = 'IPS\nexus\Gateway\\' . $values['withdraw_method'] . '\Payout';
$class = \IPS\nexus\Gateway::payoutGateways()[ $values['withdraw_method'] ];
}
$payout = new $class;
@@ -295,6 +295,10 @@ class _credit extends \IPS\Dispatcher\Controller
}
catch ( \Exception $e ) {}
}
else
{
\IPS\core\AdminNotification::send( 'nexus', 'Withdrawal', NULL, TRUE, $payout );
}
\IPS\nexus\Customer::loggedIn()->log( 'payout', array( 'type' => 'request', 'amount' => $values[ 'withdraw_amount_' . $currency ], 'currency' => $currency, 'payout_id' => $payout->id ) );
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=nexus&module=clients&controller=credit&withdraw=pending', 'front', 'clientscredit' ) );
@@ -311,7 +315,7 @@ class _credit extends \IPS\Dispatcher\Controller
\IPS\Output::i()->error( 'no_module_permission', '2X239/3', 403, '' );
}
\IPS\Output::i()->output = $withdrawForm->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) );
\IPS\Output::i()->output = $withdrawForm->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
}
/**
@@ -338,14 +342,14 @@ class _credit extends \IPS\Dispatcher\Controller
foreach ( $account->cm_credits as $value )
{
$max = $maximumBalanceAmounts ? ( ( new \IPS\Math\Number( number_format( $maximumBalanceAmounts[ $value->currency ]['amount'], \IPS\nexus\Money::numberOfDecimalsForCurrency( $value->currency ), '.', '' ) ) )->subtract( $value->amount ) ) : NULL;
if ( is_null( $max ) or $max->isGreaterThanZero() )
if ( \is_null( $max ) or $max->isGreaterThanZero() )
{
$maximums[ $account->member_id ][ $value->currency ] = is_null( $max ) ? NULL : (string) $max;
$maximums[ $account->member_id ][ $value->currency ] = \is_null( $max ) ? NULL : (string) $max;
}
}
}
if ( count( $maximums ) )
if ( \count( $maximums ) )
{
$topupForm = new \IPS\Helpers\Form( 'topup', 'checkout' );
@@ -353,20 +357,20 @@ class _credit extends \IPS\Dispatcher\Controller
foreach ( $maximums as $accountId => $data )
{
$currency = NULL;
if ( count( $data ) === 1 )
if ( \count( $data ) === 1 )
{
$currencies = array_keys( $data );
$currency = array_pop( $currencies );
}
$accountOptions[ $accountId ] = $accountId === \IPS\nexus\Customer::loggedIn()->id ? \IPS\nexus\Customer::loggedIn()->language()->addToStack( 'my_account', FALSE, array( 'sprintf' => array( \IPS\nexus\Customer::loggedIn()->cm_name ) ) ) : \IPS\nexus\Customer::load( $accountId )->cm_name;
$accountOptionToggles[ $accountId ] = ( count( $data ) > 1 ) ? array( 'topup_currency_' . $accountId ) : array( 'topup_amount_' . $accountId . '_' . $currency );
$accountOptionToggles[ $accountId ] = ( \count( $data ) > 1 ) ? array( 'topup_currency_' . $accountId ) : array( 'topup_amount_' . $accountId . '_' . $currency );
}
$topupForm->add( new \IPS\Helpers\Form\Radio( 'topup_account', NULL, TRUE, array( 'options' => $accountOptions, 'parse' => 'normal', 'toggles' => $accountOptionToggles ) ) );
foreach ( $maximums as $accountId => $data )
{
if ( count( $data ) > 1 )
if ( \count( $data ) > 1 )
{
$currencyToggles = array();
foreach ( $data as $currency => $maximum )
@@ -385,16 +389,16 @@ class _credit extends \IPS\Dispatcher\Controller
$field = new \IPS\Helpers\Form\Number( 'topup_amount_' . $accountId . '_' . $currency, NULL, NULL, array( 'decimals' => \IPS\nexus\Money::numberOfDecimalsForCurrency( $currency ) ), function( $val ) use ( $currency, $accountOptions, $accountId, $data, $min, $maximum )
{
if ( count( $accountOptions ) === 1 or \IPS\Request::i()->topup_account == $accountId )
if ( \count( $accountOptions ) === 1 or \IPS\Request::i()->topup_account == $accountId )
{
$key = "topup_currency_{$accountId}";
if ( count( $data ) === 1 or \IPS\Request::i()->$key == $currency )
if ( \count( $data ) === 1 or \IPS\Request::i()->$key == $currency )
{
if ( !$val )
{
throw new \DomainException('form_required');
}
elseif ( !is_null( $min ) and $val < $min )
elseif ( !\is_null( $min ) and $val < $min )
{
throw new \DomainException( \IPS\Member::loggedIn()->language()->addToStack( 'form_number_min', FALSE, array( 'sprintf' => array( $min ) ) ) );
}
@@ -439,7 +443,7 @@ class _credit extends \IPS\Dispatcher\Controller
\IPS\Output::i()->error( 'no_module_permission', '2X239/4', 403, '' );
}
\IPS\Output::i()->output = $topupForm->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) );
\IPS\Output::i()->output = $topupForm->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
}
/**
@@ -12,7 +12,7 @@
namespace IPS\nexus\modules\front\clients;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -90,6 +90,6 @@ class _donations extends \IPS\Dispatcher\Controller
}
\IPS\Output::i()->title = $goal->_title;
\IPS\Output::i()->output = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) );
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
}
}
@@ -12,7 +12,7 @@
namespace IPS\nexus\modules\front\clients;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -134,6 +134,10 @@ class _info extends \IPS\Dispatcher\Controller
foreach ( \IPS\nexus\Customer\CustomField::roots() as $field )
{
$column = $field->column;
if ( $field->type === 'Editor' )
{
$field::$editorOptions = array_merge( $field::$editorOptions, array( 'attachIds' => array( \IPS\nexus\Customer::loggedIn()->member_id ) ) );
}
$formElements[ $column ] = $field->buildHelper( $protected ? NULL : \IPS\nexus\Customer::loggedIn()->$column );
}
@@ -12,7 +12,7 @@
namespace IPS\nexus\modules\front\clients;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -49,29 +49,18 @@ class _invoices extends \IPS\Dispatcher\Controller
\IPS\Output::i()->error( 'node_error', '2X215/1', 404, '' );
}
}
else if ( isset( \IPS\Request::i()->do ) and \IPS\Request::i()->do == 'printout' and isset( $_SESSION['nexusMember'] ) )
{
$this->invoice = \IPS\nexus\Invoice::load( \IPS\Request::i()->id );
$guest = $this->invoice->guest_data;
if ( $guest['member']['email'] != $_SESSION['nexusMember']['email'] )
{
\IPS\Output::i()->error( 'node_error', '2X215/5', 404, '' );
}
}
else if ( isset( \IPS\Request::i()->do ) and \IPS\Request::i()->do == 'printout' and isset( \IPS\Request::i()->key ) )
{
$this->invoice = \IPS\nexus\Invoice::load( \IPS\Request::i()->id );
$guest = $this->invoice->guest_data;
if ( md5( $guest['member']['email'] . ';' . $guest['member']['joined'] ) != \IPS\Request::i()->key )
{
\IPS\Output::i()->error( 'node_error', '2X215/7', 404, '' );
}
}
else
{
\IPS\Output::i()->error( 'no_module_permission_guest', '2X215/6', 404, '' );
/* Prevent the vid key from being exposed in referrers */
\IPS\Output::i()->sendHeader( "Referrer-Policy: origin" );
$key = isset( \IPS\Request::i()->key ) ? \IPS\Request::i()->key : ( isset( \IPS\Request::i()->cookie['guestTransactionKey'] ) ? \IPS\Request::i()->cookie['guestTransactionKey'] : NULL );
$this->invoice = \IPS\nexus\Invoice::load( \IPS\Request::i()->id );
if( $this->invoice->member->member_id or !$key or !isset( $this->invoice->guest_data['guestTransactionKey'] ) or !\IPS\Login::compareHashes( $key, $this->invoice->guest_data['guestTransactionKey'] ) )
{
\IPS\Output::i()->error( 'no_module_permission_guest', '2X215/6', 404, '' );
}
}
\IPS\Output::i()->breadcrumb[] = array( \IPS\Http\Url::internal( 'app=nexus&module=clients&controller=invoices', 'front', 'clientsinvoices' ), \IPS\Member::loggedIn()->language()->addToStack('client_invoices') );
@@ -112,7 +101,7 @@ class _invoices extends \IPS\Dispatcher\Controller
{
$where = array( 'i_member=?', \IPS\Member::loggedIn()->member_id );
$parentContacts = \IPS\nexus\Customer::loggedIn()->parentContacts( array( 'billing=1' ) );
if ( count( $parentContacts ) )
if ( \count( $parentContacts ) )
{
$or = array();
foreach ( array_keys( iterator_to_array( $parentContacts ) ) as $id )
@@ -170,7 +159,7 @@ class _invoices extends \IPS\Dispatcher\Controller
$this->invoice->save();
\IPS\Output::i()->redirect( $this->invoice->url() );
}
\IPS\Output::i()->output = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) );;
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );;
}
/**
@@ -190,7 +179,7 @@ class _invoices extends \IPS\Dispatcher\Controller
$this->invoice->save();
\IPS\Output::i()->redirect( $this->invoice->url() );
}
\IPS\Output::i()->output = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) );;
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );;
}
/**
@@ -200,21 +189,7 @@ class _invoices extends \IPS\Dispatcher\Controller
*/
public function printout()
{
$address = NULL;
if ( $this->invoice->billaddress )
{
$address = $this->invoice->billaddress;
}
else
{
try
{
$address = \IPS\nexus\Customer\Address::constructFromData( \IPS\Db::i()->select( '*', 'nexus_customer_addresses', array( "member=? AND primary_billing=?", $this->invoice->member->member_id, 1 ) )->first() )->address;
}
catch( \UnderflowException $e ) {}
}
$output = \IPS\Theme::i()->getTemplate( 'invoices', 'nexus', 'global' )->printInvoice( $this->invoice, $this->invoice->summary(), $address );
$output = \IPS\Theme::i()->getTemplate( 'invoices', 'nexus', 'global' )->printInvoice( $this->invoice, $this->invoice->summary(), $this->invoice->billaddress ?: $this->invoice->member->primaryBillingAddress() );
\IPS\Output::i()->title = 'I' . $this->invoice->id;
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->blankTemplate( $output ) );
}
@@ -229,12 +204,12 @@ class _invoices extends \IPS\Dispatcher\Controller
/* CSRF check */
\IPS\Session::i()->csrfCheck();
/* Can only cancel the invoice if it's pending */
if ( $this->invoice->status !== \IPS\nexus\Invoice::STATUS_PENDING )
/* Can only cancel the invoice if it's pending and there are no processing transactions */
if ( $this->invoice->status !== \IPS\nexus\Invoice::STATUS_PENDING or \count( $this->invoice->transactions( [ \IPS\nexus\Transaction::STATUS_HELD, \IPS\nexus\Transaction::STATUS_REVIEW, \IPS\nexus\Transaction::STATUS_GATEWAY_PENDING, \IPS\nexus\Transaction::STATUS_DISPUTED ] ) ) )
{
\IPS\Output::i()->error( 'order_already_paid', '2X215/4', 403, '' );
}
/* If they have already made a partial payment, refund it to their account credit */
foreach ( $this->invoice->transactions( array( \IPS\nexus\Transaction::STATUS_PAID, \IPS\nexus\Transaction::STATUS_PART_REFUNDED ) ) as $transaction )
{
@@ -12,7 +12,7 @@
namespace IPS\nexus\modules\front\clients;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -12,7 +12,7 @@
namespace IPS\nexus\modules\front\clients;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -80,8 +80,9 @@ class _purchases extends \IPS\Dispatcher\Controller
protected function manage()
{
$where = array( array( 'ps_member=?', \IPS\Member::loggedIn()->member_id ) );
$parentContacts = \IPS\nexus\Customer::loggedIn()->parentContacts();
if ( count( $parentContacts ) )
if ( \count( $parentContacts ) )
{
$or = array();
foreach ( $parentContacts as $contact )
@@ -90,9 +91,12 @@ class _purchases extends \IPS\Dispatcher\Controller
}
}
$where[] = array( 'ps_show=1' );
/* Get only the purchases from active applications */
$where[] = array( "ps_app IN('" . implode( "','", array_keys( \IPS\Application::enabledApplications() ) ) . "')" );
$purchases = 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_active DESC, ps_expire DESC, ps_start DESC' ), 'IPS\nexus\Purchase' ) as $purchase )
{
$purchases[ $purchase->parent ][ $purchase->id ] = $purchase;
}
@@ -151,7 +155,7 @@ class _purchases extends \IPS\Dispatcher\Controller
}
elseif ( isset( \IPS\Request::i()->cycles ) and \IPS\Login::compareHashes( (string) \IPS\Session::i()->csrfKey, (string) \IPS\Request::i()->csrfKey ) )
{
$_cycles = intval( \IPS\Request::i()->cycles );
$_cycles = \intval( \IPS\Request::i()->cycles );
if ( $_cycles >= 1 and ( $cycles === TRUE or $_cycles <= $cycles ) )
{
$cycles = $_cycles;
@@ -179,14 +183,14 @@ class _purchases extends \IPS\Dispatcher\Controller
}
}
$form = new \IPS\Helpers\Form;
$form = new \IPS\Helpers\Form( 'form', 'continue' );
$form->class = 'ipsForm_vertical';
$form->add( new \IPS\Helpers\Form\Number( 'renew_for', 1, TRUE, array( 'min' => 1, 'max' => $cycles === TRUE ? NULL : $cycles ), NULL, NULL, $suffix ) );
if( $values = $form->values() or $cycles === 1 )
{
if ( $pendingInvoice = $this->purchase->invoice_pending and $pendingInvoice->status === $pendingInvoice::STATUS_PENDING )
{
if ( count( $pendingInvoice->items ) === 1 )
if ( \count( $pendingInvoice->items ) === 1 )
{
foreach ( $pendingInvoice->items as $item )
{
@@ -214,7 +218,7 @@ class _purchases extends \IPS\Dispatcher\Controller
\IPS\Output::i()->redirect( $invoice->checkoutUrl() );
}
\IPS\Output::i()->output = $form;
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
}
/**
@@ -225,7 +229,7 @@ class _purchases extends \IPS\Dispatcher\Controller
protected function cancel()
{
\IPS\Session::i()->csrfCheck();
if ( !$this->purchase->canCancel() )
{
\IPS\Output::i()->error( 'you_cannot_cancel', '2X212/5', 403, '' );
@@ -246,6 +250,10 @@ class _purchases extends \IPS\Dispatcher\Controller
$this->purchase->can_reactivate = TRUE;
$this->purchase->save();
if ( $ref = \IPS\Request::i()->referrer( FALSE, TRUE ) )
{
\IPS\Output::i()->redirect( $ref );
}
\IPS\Output::i()->redirect( $this->purchase->url() );
}
}
@@ -1,60 +0,0 @@
<?php
/**
* @brief Referrals
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Nexus
* @since 15 Aug 2014
*/
namespace IPS\nexus\modules\front\clients;
/* 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;
}
/**
* Referrals
*/
class _referrals extends \IPS\Dispatcher\Controller
{
/**
* Execute
*
* @return void
*/
public function execute()
{
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'clients.css', 'nexus' ) );
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'front_clients.js', 'nexus', 'front' ) );
\IPS\Output::i()->sidebar['enabled'] = FALSE;
parent::execute();
}
/**
* View List
*
* @return void
*/
protected function manage()
{
\IPS\Output::i()->breadcrumb[] = array( \IPS\Http\Url::internal( 'app=nexus&module=clients&controller=referrals', 'front', 'clientsreferrals' ), \IPS\Member::loggedIn()->language()->addToStack('client_referrals') );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('client_referrals');
\IPS\Output::i()->sidebar['enabled'] = FALSE;
$url = \IPS\Http\Url::internal( 'app=nexus&module=promotion&controller=referral&id=' . \IPS\Member::loggedIn()->member_id, 'front', 'referral' );
if ( isset( \IPS\Request::i()->target ) )
{
$url = $url->setQueryString( 'direct', base64_encode( \IPS\Request::i()->target ) );
}
$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')->referrals( $url, $rules );
}
}
@@ -12,7 +12,7 @@
namespace IPS\nexus\modules\front\clients;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -34,7 +34,7 @@ class _splash extends \IPS\Dispatcher\Controller
{
$where = array( array( 'ps_member=?', \IPS\Member::loggedIn()->member_id ) );
$parentContacts = \IPS\nexus\Customer::loggedIn()->parentContacts();
if ( count( $parentContacts ) )
if ( \count( $parentContacts ) )
{
$or = array();
foreach ( $parentContacts as $contact )
@@ -1,53 +0,0 @@
<?php
/**
* @brief Incoming Referrals
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Nexus
* @since 15 Aug 2014
*/
namespace IPS\nexus\modules\front\promotion;
/* 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;
}
/**
* Incoming Referrals
*/
class _referral extends \IPS\Dispatcher\Controller
{
/**
* Handle Referral
*
* @return void
*/
protected function manage()
{
\IPS\Request::i()->setCookie( 'referred_by', intval( \IPS\Request::i()->id ), \IPS\DateTime::create()->add( new \DateInterval( 'P1Y' ) ) );
try
{
$target = \IPS\Request::i()->direct ? \IPS\Http\Url::createFromString( base64_decode( \IPS\Request::i()->direct ) ) : \IPS\Http\Url::baseUrl();
}
catch( \IPS\Http\Url\Exception $e )
{
$target = NULL;
}
if ( $target instanceof \IPS\Http\Url\Internal )
{
\IPS\Output::i()->redirect( $target );
}
else
{
\IPS\Output::i()->redirect( \IPS\Settings::i()->base_url );
}
}
}
@@ -12,7 +12,7 @@
namespace IPS\nexus\modules\front\store;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -52,13 +52,13 @@ class _cart extends \IPS\Dispatcher\Controller
{
$_SESSION['cart'] = array();
}
$currency = ( isset( $_SESSION['currency'] ) and in_array( $_SESSION['currency'], \IPS\nexus\Money::currencies() ) ) ? $_SESSION['currency'] : \IPS\nexus\Customer::loggedIn()->defaultCurrency();
$currency = ( isset( \IPS\Request::i()->cookie['currency'] ) and \in_array( \IPS\Request::i()->cookie['currency'], \IPS\nexus\Money::currencies() ) ) ? \IPS\Request::i()->cookie['currency'] : \IPS\nexus\Customer::loggedIn()->defaultCurrency();
/* Display */
\IPS\Output::i()->bodyClasses[] = 'ipsLayout_minimal';
\IPS\Output::i()->sidebar['enabled'] = FALSE;
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('your_cart');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('store')->cart( ( isset( $_SESSION['location'] ) and $_SESSION['location'] ) ? \IPS\GeoLocation::buildFromJson( $_SESSION['location'] ) : NULL, $currency );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('store')->cart( ( isset( \IPS\Request::i()->cookie['location'] ) and \IPS\Request::i()->cookie['location'] ) ? \IPS\GeoLocation::buildFromJson( \IPS\Request::i()->cookie['location'] ) : NULL, $currency );
}
/**
@@ -144,8 +144,8 @@ class _cart extends \IPS\Dispatcher\Controller
if ( \IPS\Request::i()->isAjax() )
{
$currency = ( isset( $_SESSION['currency'] ) and in_array( $_SESSION['currency'], \IPS\nexus\Money::currencies() ) ) ? $_SESSION['currency'] : \IPS\nexus\Customer::loggedIn()->defaultCurrency();
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate('store')->cartContents( ( isset( $_SESSION['location'] ) and $_SESSION['location'] ) ? \IPS\GeoLocation::buildFromJson( $_SESSION['location'] ) : NULL, $currency ), 200, 'text/html' );
$currency = ( isset( \IPS\Request::i()->cookie['currency'] ) and \in_array( \IPS\Request::i()->cookie['currency'], \IPS\nexus\Money::currencies() ) ) ? \IPS\Request::i()->cookie['currency'] : \IPS\nexus\Customer::loggedIn()->defaultCurrency();
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate('store')->cartContents( ( isset( \IPS\Request::i()->cookie['location'] ) and \IPS\Request::i()->cookie['location'] ) ? \IPS\GeoLocation::buildFromJson( \IPS\Request::i()->cookie['location'] ) : NULL, $currency ), 200, 'text/html' );
}
else
{
@@ -195,7 +195,7 @@ class _cart extends \IPS\Dispatcher\Controller
{
\IPS\Session::i()->csrfCheck();
$currency = ( isset( $_SESSION['currency'] ) and in_array( $_SESSION['currency'], \IPS\nexus\Money::currencies() ) ) ? $_SESSION['currency'] : \IPS\nexus\Customer::loggedIn()->defaultCurrency();
$currency = ( isset( \IPS\Request::i()->cookie['currency'] ) and \in_array( \IPS\Request::i()->cookie['currency'], \IPS\nexus\Money::currencies() ) ) ? \IPS\Request::i()->cookie['currency'] : \IPS\nexus\Customer::loggedIn()->defaultCurrency();
$canRegister = ( !\IPS\Settings::i()->nexus_reg_force or \IPS\Member::loggedIn()->member_id );
@@ -222,7 +222,7 @@ class _cart extends \IPS\Dispatcher\Controller
\IPS\Db::i()->delete( 'nexus_cart_uploads', \IPS\Db::i()->in( 'id', $ids ) );
}
if ( !count( $invoice->items ) )
if ( !\count( $invoice->items ) )
{
\IPS\Output::i()->error( 'your_cart_empty', '2X214/2', 403, '' );
}
@@ -12,7 +12,7 @@
namespace IPS\nexus\modules\front\store;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -50,7 +50,7 @@ class _gifts extends \IPS\Dispatcher\Controller
protected function manage()
{
/* Work out what our options are */
$memberCurrency = ( ( ( isset( $_SESSION['currency'] ) and in_array( $_SESSION['currency'], \IPS\nexus\Money::currencies() ) ) and in_array( $_SESSION['currency'], \IPS\nexus\Money::currencies() ) ) ? $_SESSION['currency'] : \IPS\nexus\Customer::loggedIn()->defaultCurrency() );
$memberCurrency = ( ( ( isset( \IPS\Request::i()->cookie['currency'] ) and \in_array( \IPS\Request::i()->cookie['currency'], \IPS\nexus\Money::currencies() ) ) and \in_array( \IPS\Request::i()->cookie['currency'], \IPS\nexus\Money::currencies() ) ) ? \IPS\Request::i()->cookie['currency'] : \IPS\nexus\Customer::loggedIn()->defaultCurrency() );
$options = array();
foreach ( json_decode( \IPS\Settings::i()->nexus_gift_vouchers, TRUE ) as $voucher )
{
@@ -116,7 +116,7 @@ class _gifts extends \IPS\Dispatcher\Controller
}
/* Display */
$formTemplate = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'store', 'nexus' ) ), 'giftCardForm' ) );
$formTemplate = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'store', 'nexus' ), 'giftCardForm' ) );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('store')->giftCard( $formTemplate );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('buy_gift_voucher');
@@ -130,7 +130,7 @@ class _gifts extends \IPS\Dispatcher\Controller
*/
protected function formatCurrency()
{
\IPS\Output::i()->json( (string) new \IPS\nexus\Money( \IPS\Request::i()->amount, ( ( isset( $_SESSION['currency'] ) and in_array( $_SESSION['currency'], \IPS\nexus\Money::currencies() ) ) ? $_SESSION['currency'] : \IPS\nexus\Customer::loggedIn()->defaultCurrency() ) ) );
\IPS\Output::i()->json( (string) new \IPS\nexus\Money( \IPS\Request::i()->amount, ( ( isset( \IPS\Request::i()->cookie['currency'] ) and \in_array( \IPS\Request::i()->cookie['currency'], \IPS\nexus\Money::currencies() ) ) ? \IPS\Request::i()->cookie['currency'] : \IPS\nexus\Customer::loggedIn()->defaultCurrency() ) ) );
}
/**
@@ -179,7 +179,7 @@ class _gifts extends \IPS\Dispatcher\Controller
if( \IPS\Request::i()->isAjax() )
{
$form->class = 'ipsForm_vertical';
\IPS\Output::i()->output = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core', 'front' ) ), 'popupTemplate' ) );
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core', 'front' ), 'popupTemplate' ) );
}
else
{
@@ -12,7 +12,7 @@
namespace IPS\nexus\modules\front\store;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -43,6 +43,8 @@ class _product extends \IPS\Content\Controller
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'store_responsive.css', 'nexus', 'front' ) );
}
\IPS\Output::i()->pageCaching = FALSE;
parent::execute();
}
@@ -58,7 +60,7 @@ class _product extends \IPS\Content\Controller
{
$_SESSION['cart'] = array();
}
$memberCurrency = ( ( isset( $_SESSION['currency'] ) and in_array( $_SESSION['currency'], \IPS\nexus\Money::currencies() ) ) ? $_SESSION['currency'] : \IPS\nexus\Customer::loggedIn()->defaultCurrency() );
$memberCurrency = ( ( isset( \IPS\Request::i()->cookie['currency'] ) and \in_array( \IPS\Request::i()->cookie['currency'], \IPS\nexus\Money::currencies() ) ) ? \IPS\Request::i()->cookie['currency'] : \IPS\nexus\Customer::loggedIn()->defaultCurrency() );
/* Load Package */
$item = parent::manage();
@@ -115,14 +117,10 @@ class _product extends \IPS\Content\Controller
{
/* Where are we shipping to? */
$shipAddress = NULL;
if ( \IPS\Member::loggedIn()->member_id )
if ( \IPS\Member::loggedIn()->member_id and $primaryBillingAddress = \IPS\nexus\Customer::loggedIn()->primaryBillingAddress() )
{
try
{
$shipAddress = \IPS\nexus\Customer\Address::constructFromData( \IPS\Db::i()->select( '*', 'nexus_customer_addresses', array( 'member=? AND primary_billing=1', \IPS\Member::loggedIn()->member_id ) )->first() )->address;
$locationType = 'address';
}
catch ( \UnderflowException $e ) { }
$shipAddress = $primaryBillingAddress;
$locationType = 'address';
}
if ( !$shipAddress )
{
@@ -149,7 +147,7 @@ class _product extends \IPS\Content\Controller
}
/* Easypost */
if ( $shipAddress and \IPS\Settings::i()->easypost_api_key and \IPS\Settings::i()->easypost_show_rates and ( $package->shipping == '*' or in_array( 'easypost', explode( ',', $package->shipping ) ) ) )
if ( $shipAddress and \IPS\Settings::i()->easypost_api_key and \IPS\Settings::i()->easypost_show_rates and ( $package->shipping == '*' or \in_array( 'easypost', explode( ',', $package->shipping ) ) ) )
{
try
{
@@ -179,14 +177,31 @@ class _product extends \IPS\Content\Controller
/* Do we have renewal terms? */
$renewalTerm = NULL;
$renewOptions = $package->renew_options ? json_decode( $package->renew_options, TRUE ) : array();
if ( count( $renewOptions ) )
$initialTerm = NULL;
if ( \count( $renewOptions ) )
{
$renewalTerm = TRUE;
if ( count( $renewOptions ) === 1 )
if ( \count( $renewOptions ) === 1 )
{
$renewalTerm = array_pop( $renewOptions );
$renewalTerm = new \IPS\nexus\Purchase\RenewalTerm( new \IPS\nexus\Money( $renewalTerm['cost'][ $memberCurrency ]['amount'], $memberCurrency ), new \DateInterval( 'P' . $renewalTerm['term'] . mb_strtoupper( $renewalTerm['unit'] ) ), $package->tax ? \IPS\nexus\Tax::load( $package->tax ) : NULL, $renewalTerm['add'] );
}
if ( $package->initial_term )
{
$term = mb_substr( $package->initial_term, 0, -1 );
switch( mb_substr( $package->initial_term, -1 ) )
{
case 'D':
$initialTerm = \IPS\Member::loggedIn()->language()->pluralize( \IPS\Member::loggedIn()->language()->get('renew_days'), array( $term ) );
break;
case 'M':
$initialTerm = \IPS\Member::loggedIn()->language()->pluralize( \IPS\Member::loggedIn()->language()->get('renew_months'), array( $term ) );
break;
case 'Y':
$initialTerm = \IPS\Member::loggedIn()->language()->pluralize( \IPS\Member::loggedIn()->language()->get('renew_years'), array( $term ) );
break;
}
}
}
/* Display */
@@ -197,7 +212,7 @@ class _product extends \IPS\Content\Controller
}
else
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('store')->package( $package, $item, $this->_getForm( $package, $inCart, TRUE ), array_sum( $inCart ), $shippingMethods, $itemDataForShipping, $locationType, $renewalTerm );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('store')->package( $package, $item, $this->_getForm( $package, $inCart, TRUE ), array_sum( $inCart ), $shippingMethods, $itemDataForShipping, $locationType, $renewalTerm, $initialTerm );
}
try
@@ -222,7 +237,7 @@ class _product extends \IPS\Content\Controller
'@context' => "http://schema.org",
'@type' => "Product",
'name' => $package->_title,
'description' => strip_tags( $item->truncated() ),
'description' => $item->truncated( TRUE, NULL ),
'category' => $item->container()->_title,
'url' => (string) $package->url(),
'sku' => $package->id,
@@ -268,12 +283,24 @@ class _product extends \IPS\Content\Controller
*
* @param \IPS\nexus\Package $package The package
* @param array $inCart The number in the cart already for each of the field combinations
* @param bool $verticalForm Whether to output a vertical form (true) or not
* @return string
*/
protected function _getForm( \IPS\nexus\Package $package, $inCart, $verticalForm = FALSE )
{
/* Is this a subscription package that we've already bought? */
if ( $package->subscription )
{
try
{
$purchase = \IPS\nexus\Purchase::constructFromData( \IPS\Db::i()->select( '*', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=? AND ps_cancelled=0 AND ps_member=?', 'nexus', 'package', $package->id, \IPS\Member::loggedIn()->member_id ) )->first() );
return \IPS\Theme::i()->getTemplate( 'store', 'nexus' )->subscriptionPurchase( $purchase );
}
catch ( \UnderflowException $e ) {}
}
/* Get member's currency */
$memberCurrency = ( ( isset( $_SESSION['currency'] ) and in_array( $_SESSION['currency'], \IPS\nexus\Money::currencies() ) ) ? $_SESSION['currency'] : \IPS\nexus\Customer::loggedIn()->defaultCurrency() );
$memberCurrency = ( ( isset( \IPS\Request::i()->cookie['currency'] ) and \in_array( \IPS\Request::i()->cookie['currency'], \IPS\nexus\Money::currencies() ) ) ? \IPS\Request::i()->cookie['currency'] : \IPS\nexus\Customer::loggedIn()->defaultCurrency() );
/* Init form */
$form = new \IPS\Helpers\Form( "package_{$package->id}", 'add_to_cart' );
@@ -308,18 +335,18 @@ class _product extends \IPS\Content\Controller
}
/* Associate */
if ( count( $package->associablePackages() ) )
if ( \count( $package->associablePackages() ) )
{
$associableIds = array_keys( $package->associablePackages() );
$associableOptions = array();
foreach ( $_SESSION['cart'] as $k => $item )
{
if ( in_array( $item->id, $associableIds ) )
if ( \in_array( $item->id, $associableIds ) )
{
for ( $i = 0; $i < $item->quantity; $i++ )
{
$name = $item->name;
if ( count( $item->details ) )
if ( \count( $item->details ) )
{
$customFields = \IPS\nexus\Package\CustomField::roots();
$stickyFields = array();
@@ -330,7 +357,7 @@ class _product extends \IPS\Content\Controller
$stickyFields[] = $v;
}
}
if ( count( $stickyFields ) )
if ( \count( $stickyFields ) )
{
$name .= ' (' . implode( ' &middot; ', $stickyFields ) . ')';
}
@@ -360,7 +387,7 @@ class _product extends \IPS\Content\Controller
/* Renewal options */
$renewOptions = $package->renew_options ? json_decode( $package->renew_options, TRUE ) : array();
if ( count( $renewOptions ) > 1 )
if ( \count( $renewOptions ) > 1 )
{
$sortedRenewOptions = array();
foreach ( $renewOptions as $k => $option )
@@ -444,7 +471,14 @@ class _product extends \IPS\Content\Controller
if ( isset( $values[ 'nexus_pfield_' . $field->id ] ) )
{
$class = $field->buildHelper();
$details[ $field->id ] = $class::stringValue( $values[ 'nexus_pfield_' . $field->id ] );
if ( $class instanceof \IPS\Helpers\Form\Upload )
{
$details[ $field->id ] = (string) $values[ 'nexus_pfield_' . $field->id ];
}
else
{
$details[ $field->id ] = $class::stringValue( $values[ 'nexus_pfield_' . $field->id ] );
}
if ( !isset( \IPS\Request::i()->stockCheck ) and $field->type === 'Editor' )
{
@@ -505,16 +539,14 @@ class _product extends \IPS\Content\Controller
$normalPrice->amount = $normalPrice->amount->add( new \IPS\Math\Number( number_format( $term['cost'][ $memberCurrency ]['amount'], \IPS\nexus\Money::numberOfDecimalsForCurrency( $memberCurrency ), '.', '' ) ) );
}
$return['renewal'] = \IPS\Member::loggedIn()->language()->addToStack( 'and_renewal', FALSE, array( 'sprintf' => array(
( new \IPS\nexus\Purchase\RenewalTerm(
new \IPS\nexus\Money(
( new \IPS\Math\Number( number_format( $term['cost'][ $memberCurrency ]['amount'], \IPS\nexus\Money::numberOfDecimalsForCurrency( $memberCurrency ), '.', '' ) ) )
->add( ( new \IPS\Math\Number( number_format( $_data['renewalAdjustment'], \IPS\nexus\Money::numberOfDecimalsForCurrency( $memberCurrency ), '.', '' ) ) ) )
, $memberCurrency ),
new \DateInterval( 'P' . $term['term'] . mb_strtoupper( $term['unit'] ) ),
$package->tax ? \IPS\nexus\Tax::load( $package->tax ) : NULL, $term['add']
) )->toDisplay()
) ) );
$return['renewal'] = ( new \IPS\nexus\Purchase\RenewalTerm(
new \IPS\nexus\Money(
( new \IPS\Math\Number( number_format( $term['cost'][ $memberCurrency ]['amount'], \IPS\nexus\Money::numberOfDecimalsForCurrency( $memberCurrency ), '.', '' ) ) )
->add( ( new \IPS\Math\Number( number_format( $_data['renewalAdjustment'], \IPS\nexus\Money::numberOfDecimalsForCurrency( $memberCurrency ), '.', '' ) ) ) )
, $memberCurrency ),
new \DateInterval( 'P' . $term['term'] . mb_strtoupper( $term['unit'] ) ),
$package->tax ? \IPS\nexus\Tax::load( $package->tax ) : NULL, $term['add']
) )->toDisplay();
}
else
{
@@ -537,11 +569,11 @@ class _product extends \IPS\Content\Controller
/* Format and return */
if ( $data['price']->amount->compare( $normalPrice->amount ) !== 0 )
{
$return['price'] = \IPS\Theme::i()->getTemplate( 'store', 'nexus' )->priceDiscounted( $normalPrice, $data['price'], FALSE );
$return['price'] = \IPS\Theme::i()->getTemplate( 'store', 'nexus' )->priceDiscounted( $normalPrice, $data['price'], FALSE, FALSE, NULL );
}
else
{
$return['price'] = \IPS\Theme::i()->getTemplate( 'store', 'nexus' )->price( $data['price'], FALSE, FALSE );
$return['price'] = \IPS\Theme::i()->getTemplate( 'store', 'nexus' )->price( $data['price'], FALSE, FALSE, NULL );
}
\IPS\Output::i()->json( $return );
}
@@ -565,9 +597,9 @@ class _product extends \IPS\Content\Controller
/* Work out renewal term */
$renewalTerm = NULL;
if ( count( $renewOptions ) )
if ( \count( $renewOptions ) )
{
if ( count( $renewOptions ) === 1 )
if ( \count( $renewOptions ) === 1 )
{
$chosenRenewOption = array_pop( $renewOptions );
}
@@ -605,7 +637,7 @@ class _product extends \IPS\Content\Controller
$upsell = \IPS\nexus\Package\Item::getItemsWithPermission( array( array( 'p_upsell=1' ), array( \IPS\Db::i()->findInSet( 'p_associable', array( $package->id ) ) ) ), 'p_position' );
/* Send */
\IPS\Output::i()->json( array( 'dialog' => \IPS\Theme::i()->getTemplate('store')->cartReview( $package, $quantity, $upsell ), 'cart' => \IPS\Theme::i()->getTemplate('store')->cartHeader() ) );
\IPS\Output::i()->json( array( 'dialog' => \IPS\Theme::i()->getTemplate('store')->cartReview( $package, $quantity, $upsell ), 'cart' => \IPS\Theme::i()->getTemplate('store')->cartHeader(), 'css' => \IPS\Output::i()->cssFiles ) );
}
else
{
+307 -184
View File
@@ -12,7 +12,7 @@
namespace IPS\nexus\modules\front\store;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -28,6 +28,11 @@ class _store extends \IPS\Dispatcher\Controller
*/
protected static $productsPerPage = 50;
/**
* @brief Currency
*/
protected $currency;
/**
* Execute
*
@@ -35,13 +40,31 @@ class _store extends \IPS\Dispatcher\Controller
*/
public function execute()
{
/* Set CSS */
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'store.css', 'nexus' ) );
if ( \IPS\Theme::i()->settings['responsive'] )
{
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'store_responsive.css', 'nexus', 'front' ) );
}
/* Work out currency */
if ( isset( \IPS\Request::i()->currency ) and \in_array( \IPS\Request::i()->currency, \IPS\nexus\Money::currencies() ) )
{
if ( isset( \IPS\Request::i()->csrfKey ) and \IPS\Login::compareHashes( (string) \IPS\Session::i()->csrfKey, (string) \IPS\Request::i()->csrfKey ) )
{
$_SESSION['cart'] = array();
\IPS\Request::i()->setCookie( 'currency', \IPS\Request::i()->currency );
}
$this->currency = \IPS\Request::i()->currency;
}
else
{
$this->currency = \IPS\nexus\Customer::loggedIn()->defaultCurrency();
}
\IPS\Output::i()->pageCaching = FALSE;
/* Pass up */
parent::execute();
}
@@ -51,203 +74,303 @@ class _store extends \IPS\Dispatcher\Controller
* @return void
*/
protected function manage()
{
/* Work out currency */
if ( isset( \IPS\Request::i()->currency ) and in_array( \IPS\Request::i()->currency, \IPS\nexus\Money::currencies() ) )
{
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;
}
else
{
$currency = \IPS\nexus\Customer::loggedIn()->defaultCurrency();
}
{
/* If we have a category, display it */
if ( isset( \IPS\Request::i()->cat ) )
{
try
{
$category = \IPS\nexus\Package\Group::loadAndCheckPerms( \IPS\Request::i()->cat );
if ( \IPS\Request::i()->view )
{
\IPS\Request::i()->setCookie( 'storeView', ( \IPS\Request::i()->view == 'list' ) ? 'list' : 'grid', \IPS\DateTime::ts( time() )->add( new \DateInterval( 'P1Y' ) ) );
\IPS\Request::i()->cookie['storeView'] = ( \IPS\Request::i()->view == 'list' ) ? 'list' : 'grid';
}
$subcategories = new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_package_groups', array( 'pg_parent=?', $category->id ), 'pg_position ASC' ), 'IPS\nexus\Package\Group' );
$joins = array();
switch ( \IPS\Request::i()->sortby )
{
case 'name':
$joins['core_sys_lang_words'] = array( "word_app='nexus' AND word_key=CONCAT( 'nexus_package_', p_id ) AND lang_id=?", \IPS\Member::loggedIn()->language()->id );
$sortBy = 'word_custom';
break;
case 'price_low':
case 'price_high':
$joins['nexus_package_base_prices'] = array( 'id=p_id' );
$sortBy = \IPS\Request::i()->sortby == 'price_low' ? $currency : ( $currency . ' DESC' );
break;
case 'rating':
$sortBy = 'p_rating DESC';
break;
default:
$sortBy = 'p_position';
break;
}
$currentPage = isset( \IPS\Request::i()->page ) ? intval( \IPS\Request::i()->page ) : 1;
if( $currentPage < 1 )
{
$currentPage = 1;
}
$select = \IPS\Db::i()->select( '*', 'nexus_packages', array(
array( 'p_group=?', $category->id ),
array( 'p_store=1' ),
array( "( p_member_groups='*' OR " . \IPS\Db::i()->findInSet( 'p_member_groups', \IPS\Member::loggedIn()->groups ) . ' )' )
), $sortBy, array( ( $currentPage - 1 ) * static::$productsPerPage, static::$productsPerPage ), NULL, NULL, \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS );
foreach ( $joins as $table => $clause )
{
$select->join( $table, $clause );
}
$packages = new \IPS\Patterns\ActiveRecordIterator( $select, 'IPS\nexus\Package' );
$totalCount = \IPS\Db::i()->select( 'count(*)', 'nexus_packages', array(
array( 'p_group=?', $category->id ),
array( 'p_store=1' ),
array( "( p_member_groups='*' OR " . \IPS\Db::i()->findInSet( 'p_member_groups', \IPS\Member::loggedIn()->groups ) . ' )' )
) )->first();
$totalPages = ceil( $packages->count( TRUE ) / static::$productsPerPage );
if ( $totalPages and $currentPage > $totalPages )
{
\IPS\Output::i()->redirect( $category->url()->setQueryString( 'page', $totalPages ), NULL, 303 );
}
$pagination = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination( $category->url(), $totalPages, $currentPage, static::$productsPerPage );
$packagesWithCustomFields = array();
foreach ( iterator_to_array( \IPS\Db::i()->select( 'cf_packages', 'nexus_package_fields', 'cf_purchase=1' ) ) as $ids )
{
$packagesWithCustomFields = array_merge( $packagesWithCustomFields, array_filter( explode( ',', $ids ) ) );
}
\IPS\Output::i()->sidebar['contextual'] = \IPS\Theme::i()->getTemplate('store')->categorySidebar( $category, $subcategories );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('store')->category( $category, $subcategories, $packages, $pagination, $packagesWithCustomFields, $totalCount );
foreach ( $category->parents() as $parent )
{
\IPS\Output::i()->breadcrumb[] = array( $parent->url(), $parent->_title );
}
\IPS\Output::i()->breadcrumb[] = array( NULL, $category->_title );
\IPS\Output::i()->title = $category->_title;
/* Add JSON-LD
@note Google does not like categories marked up and instead recommends marking up each product separately.
@link https://developers.google.com/search/docs/guides/intro-structured-data#multiple-entities-on-the-same-page */
foreach( $packages as $package )
{
$item = \IPS\nexus\Package\Item::load( $package->id );
try
{
$price = $package->price();
}
catch( \OutOfBoundsException $e )
{
$price = NULL;
}
/* A product MUST have an offer, so if there's no price (i.e. due to currency configuration) don't even output */
if( $price !== NULL )
{
\IPS\Output::i()->jsonLd['package' . $package->id ] = array(
'@context' => "http://schema.org",
'@type' => "Product",
'name' => $package->_title,
'description' => strip_tags( $item->truncated() ),
'category' => $category->_title,
'url' => (string) $package->url(),
'sku' => $package->id,
'offers' => array(
'@type' => 'Offer',
'availability' => ( $package->stock > 0 OR $package->stock == -1 ) ? 'http://schema.org/InStock' : 'http://schema.org/OutOfStock',
'price' => $price->amountAsString(),
'priceCurrency' => $price->currency,
'seller' => array(
'@type' => 'Organization',
'name' => \IPS\Settings::i()->board_name
),
),
);
if( $package->image )
{
\IPS\Output::i()->jsonLd['package' . $package->id ]['image'] = (string) $package->image;
}
if( $package->reviewable and $item->averageReviewRating() )
{
\IPS\Output::i()->jsonLd['package' . $package->id ]['aggregateRating'] = array(
'@type' => 'AggregateRating',
'ratingValue' => $item->averageReviewRating(),
'ratingCount' => $item->reviews
);
}
}
}
return;
}
catch ( \OutofRangeException $e )
{
\IPS\Output::i()->error( 'node_error', '1X241/1', 404, '' );
}
return $this->_categoryView();
}
/* Otherwise, display the index */
else
{
/* New Products */
$newProducts = array();
$nexus_store_new = explode( ',', \IPS\Settings::i()->nexus_store_new );
if ( $nexus_store_new[0] )
$this->_indexView();
}
}
/**
* Show a category
*
* @return void
*/
protected function _categoryView()
{
/* Load category */
try
{
$category = \IPS\nexus\Package\Group::loadAndCheckPerms( \IPS\Request::i()->cat );
}
catch ( \OutofRangeException $e )
{
\IPS\Output::i()->error( 'node_error', '1X241/1', 404, '' );
}
$url = $category->url();
/* Set initial stuff for fetching packages */
$currentPage = isset( \IPS\Request::i()->page ) ? \intval( \IPS\Request::i()->page ) : 1;
if( $currentPage < 1 )
{
$currentPage = 1;
}
$where = array(
array( 'p_group=?', $category->id ),
array( 'p_store=1' ),
array( "( p_member_groups='*' OR " . \IPS\Db::i()->findInSet( 'p_member_groups', \IPS\Member::loggedIn()->groups ) . ' )' )
);
$havePackagesWhichAcceptReviews = (bool) \IPS\Db::i()->select( 'COUNT(*)', 'nexus_packages', array_merge( $where, array( array( 'p_reviewable=1' ) ) ) )->first();
$havePackagesWhichUseStockLevels = (bool) \IPS\Db::i()->select( 'COUNT(*)', 'nexus_packages', array_merge( $where, array( array( 'p_stock<>-1' ) ) ) )->first();
$joins = array();
/* Apply Filters */
if ( isset( \IPS\Request::i()->filter ) and \is_array( \IPS\Request::i()->filter ) )
{
$url = $url->setQueryString( 'filter', \IPS\Request::i()->filter );
foreach ( \IPS\Request::i()->filter as $filterId => $allowedValues )
{
$newProducts = \IPS\nexus\Package\Item::getItemsWithPermission( array( array( 'p_date_added>?', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . $nexus_store_new[1] . 'D' ) )->getTimestamp() ) ), 'p_date_added DESC', $nexus_store_new[0] );
$where[] = array( \IPS\Db::i()->findInSet( "filter{$filterId}.pfm_values", array_map( 'intval', explode( ',', $allowedValues ) ) ) );
$joins[] = array( 'table' => array( 'nexus_package_filters_map', "filter{$filterId}" ), 'on' => array( "filter{$filterId}.pfm_package=p_id AND filter{$filterId}.pfm_filter=?", $filterId ) );
}
/* Popular Products */
$popularProducts = array();
$nexus_store_popular = explode( ',', \IPS\Settings::i()->nexus_store_popular );
if ( $nexus_store_popular[0] )
}
foreach ( array( 'minPrice' => '>', 'maxPrice' => '<' ) as $k => $op )
{
if ( isset( \IPS\Request::i()->$k ) and \is_numeric( \IPS\Request::i()->$k ) and \floatval( \IPS\Request::i()->$k ) > 0 )
{
$where = array();
$where[] = array( 'ps_app=? AND ps_type=? AND ps_start>?', 'nexus', 'package', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . $nexus_store_popular[1] . 'D' ) )->getTimestamp() );
$where[] = "( p_member_groups='*' OR " . \IPS\Db::i()->findInSet( 'p_member_groups', \IPS\Member::loggedIn()->groups ) . ' )';
$where[] = array( 'p_store=?', 1 );
$url = $url->setQueryString( $k, \IPS\Request::i()->$k );
$joins['nexus_package_base_prices'] = array( 'table' => 'nexus_package_base_prices', 'on' => array( 'id=p_id' ) );
$where[] = array( $this->currency . $op . '=?', \floatval( \IPS\Request::i()->$k ) );
}
}
if ( isset( \IPS\Request::i()->minRating ) and \is_numeric( \IPS\Request::i()->minRating ) and \floatval( \IPS\Request::i()->minRating ) > 0 )
{
$url = $url->setQueryString( 'minRating', \IPS\Request::i()->minRating );
$where[] = array( 'p_rating>=?', \intval( \IPS\Request::i()->minRating ) );
}
if ( isset( \IPS\Request::i()->inStock ) )
{
$url = $url->setQueryString( 'inStock', \IPS\Request::i()->inStock );
$where[] = array( '( p_stock>0 OR ( p_stock=-2 AND (?)>0 ) )', \IPS\Db::i()->select( 'MAX(opt_stock)', 'nexus_product_options', 'opt_package=p_id' ) );
}
/* Figure out the sorting */
switch ( \IPS\Request::i()->sortby )
{
case 'name':
$joins['core_sys_lang_words'] = array( 'table' => 'core_sys_lang_words', 'on' => array( "word_app='nexus' AND word_key=CONCAT( 'nexus_package_', p_id ) AND lang_id=?", \IPS\Member::loggedIn()->language()->id ) );
$sortBy = 'word_custom';
break;
case 'price_low':
case 'price_high':
$joins['nexus_package_base_prices'] = array( 'table' => 'nexus_package_base_prices', 'on' => array( 'id=p_id' ) );
$sortBy = \IPS\Request::i()->sortby == 'price_low' ? $this->currency : ( $this->currency . ' DESC' );
break;
case 'rating':
$sortBy = 'p_rating DESC';
break;
default:
$sortBy = 'p_position';
break;
}
/* Fetch the packages */
$select = \IPS\Db::i()->select( '*', 'nexus_packages', $where, $sortBy, array( ( $currentPage - 1 ) * static::$productsPerPage, static::$productsPerPage ) );
foreach ( $joins as $join )
{
$select->join( $join['table'], $join['on'] );
}
$packages = new \IPS\Patterns\ActiveRecordIterator( $select, '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 ) )
/* Get packages count */
$select = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_packages', $where );
foreach ( $joins as $join )
{
$select->join( $join['table'], $join['on'] );
}
$totalCount = $select->first();
/* Pagination */
$totalPages = ceil( $totalCount / static::$productsPerPage );
if ( $totalPages and $currentPage > $totalPages )
{
\IPS\Output::i()->redirect( $category->url()->setPage( 'page', $totalPages ), NULL, 303 );
}
$pagination = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination( $category->url(), $totalPages, $currentPage, static::$productsPerPage );
/* Other stuff we need for the view */
$subcategories = new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_package_groups', array( 'pg_parent=?', $category->id ), 'pg_position ASC' ), 'IPS\nexus\Package\Group' );
$packagesWithCustomFields = array();
foreach ( iterator_to_array( \IPS\Db::i()->select( 'cf_packages', 'nexus_package_fields', 'cf_purchase=1' ) ) as $ids )
{
$packagesWithCustomFields = array_merge( $packagesWithCustomFields, array_filter( explode( ',', $ids ) ) );
}
/* List or grid? */
if ( \IPS\Request::i()->view )
{
\IPS\Session::i()->csrfCheck();
\IPS\Request::i()->setCookie( 'storeView', ( \IPS\Request::i()->view == 'list' ) ? 'list' : 'grid', \IPS\DateTime::ts( time() )->add( new \DateInterval( 'P1Y' ) ) );
\IPS\Request::i()->cookie['storeView'] = ( \IPS\Request::i()->view == 'list' ) ? 'list' : 'grid';
}
/* Output */
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->json( array(
'contents' => \IPS\Theme::i()->getTemplate('store')->categoryContents( $category, $subcategories, $packages, $pagination, $packagesWithCustomFields, $totalCount ),
'sidebar' => \IPS\Theme::i()->getTemplate('store')->categorySidebar( $category, $subcategories, $url, \count( $packages ), $this->currency, $havePackagesWhichAcceptReviews, $havePackagesWhichUseStockLevels )
)) ;
return;
}
else
{
foreach ( $category->parents() as $parent )
{
\IPS\Output::i()->breadcrumb[] = array( $parent->url(), $parent->_title );
}
\IPS\Output::i()->breadcrumb[] = array( $category->url(), $category->_title );
\IPS\Output::i()->title = $category->_title;
\IPS\Output::i()->sidebar['contextual'] = \IPS\Theme::i()->getTemplate('store')->categorySidebar( $category, $subcategories, $url, \count( $packages ), $this->currency, $havePackagesWhichAcceptReviews, $havePackagesWhichUseStockLevels );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('store')->category( $category, $subcategories, $packages, $pagination, $packagesWithCustomFields, $totalCount );
\IPS\Output::i()->globalControllers[] = 'nexus.front.store.category';
}
/* JSON-LD
@note Google does not like categories marked up and instead recommends marking up each product separately.
@link https://developers.google.com/search/docs/guides/intro-structured-data#multiple-entities-on-the-same-page */
foreach( $packages as $package )
{
$item = \IPS\nexus\Package\Item::load( $package->id );
try
{
$price = $package->price();
}
catch( \OutOfBoundsException $e )
{
$price = NULL;
}
/* A product MUST have an offer, so if there's no price (i.e. due to currency configuration) don't even output */
if( $price !== NULL )
{
\IPS\Output::i()->jsonLd['package' . $package->id ] = array(
'@context' => "http://schema.org",
'@type' => "Product",
'name' => $package->_title,
'description' => $item->truncated( TRUE, NULL ),
'category' => $category->_title,
'url' => (string) $package->url(),
'sku' => $package->id,
'offers' => array(
'@type' => 'Offer',
'availability' => ( $package->stock > 0 OR $package->stock == -1 ) ? 'http://schema.org/InStock' : 'http://schema.org/OutOfStock',
'price' => $price->amountAsString(),
'priceCurrency' => $price->currency,
'seller' => array(
'@type' => 'Organization',
'name' => \IPS\Settings::i()->board_name
),
),
);
if( $package->image )
{
$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' );
\IPS\Output::i()->jsonLd['package' . $package->id ]['image'] = (string) $package->image;
}
if( $package->reviewable and $item->averageReviewRating() )
{
\IPS\Output::i()->jsonLd['package' . $package->id ]['aggregateRating'] = array(
'@type' => 'AggregateRating',
'ratingValue' => $item->averageReviewRating(),
'ratingCount' => $item->reviews
);
}
}
/* Display */
\IPS\Output::i()->sidebar['contextual'] = \IPS\Theme::i()->getTemplate('store')->categorySidebar( );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('store')->index( \IPS\nexus\Customer::loggedIn()->cm_credits[ $currency ], $newProducts, $popularProducts );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('module__nexus_store');
}
}
/**
* Set a price filter
*
* @return void
*/
protected function priceFilter()
{
if ( !isset( \IPS\Request::i()->maxPrice ) )
{
\IPS\Request::i()->maxPrice = 0;
}
$form = new \IPS\Helpers\Form( 'price_filter', 'filter' );
$form->class = 'ipsForm_vertical';
$form->add( new \IPS\Helpers\Form\Number( 'minPrice', FALSE, 0, array( 'decimals' => \IPS\nexus\Money::numberOfDecimalsForCurrency( $this->currency ) ), NULL, NULL, $this->currency ) );
$form->add( new \IPS\Helpers\Form\Number( 'maxPrice', FALSE, 0, array( 'decimals' => \IPS\nexus\Money::numberOfDecimalsForCurrency( $this->currency ), 'unlimited' => 0 ), NULL, NULL, $this->currency ) );
if ( $values = $form->values() )
{
$url = \IPS\Request::i()->url()->setQueryString( 'do', NULL );
if ( $values['minPrice'] )
{
$url = $url->setQueryString( 'minPrice', $values['minPrice'] );
}
else
{
$url = $url->setQueryString( 'minPrice', NULL );
}
if ( $values['maxPrice'] )
{
$url = $url->setQueryString( 'maxPrice', $values['maxPrice'] );
}
else
{
$url = $url->setQueryString( 'maxPrice', NULL );
}
\IPS\Output::i()->redirect( $url );
}
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('price_filter');
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
}
/**
* Show the index
*
* @return void
*/
protected function _indexView()
{
/* New Products */
$newProducts = array();
$nexus_store_new = explode( ',', \IPS\Settings::i()->nexus_store_new );
if ( $nexus_store_new[0] )
{
$newProducts = \IPS\nexus\Package\Item::getItemsWithPermission( array( array( 'p_date_added>?', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . $nexus_store_new[1] . 'D' ) )->getTimestamp() ) ), 'p_date_added DESC', $nexus_store_new[0] );
}
/* Popular Products */
$popularProducts = array();
$nexus_store_popular = explode( ',', \IPS\Settings::i()->nexus_store_popular );
if ( $nexus_store_popular[0] )
{
$where = array();
$where[] = array( 'ps_app=? AND ps_type=? AND ps_start>?', 'nexus', 'package', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . $nexus_store_popular[1] . 'D' ) )->getTimestamp() );
$where[] = "( p_member_groups='*' OR " . \IPS\Db::i()->findInSet( 'p_member_groups', \IPS\Member::loggedIn()->groups ) . ' )';
$where[] = array( 'p_store=?', 1 );
$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 */
\IPS\Output::i()->sidebar['contextual'] = \IPS\Theme::i()->getTemplate('store')->categorySidebar( );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('store')->index( \IPS\nexus\Customer::loggedIn()->cm_credits[ $this->currency ], $newProducts, $popularProducts );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('module__nexus_store');
}
/**
@@ -262,7 +385,7 @@ class _store extends \IPS\Dispatcher\Controller
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('store')->register( \IPS\nexus\Package\Item::getItemsWithPermission( array( array( 'p_reg=1' ) ), 'pg_position, p_position', 10, 'read', \IPS\Content\Hideable::FILTER_AUTOMATIC, 0, NULL, TRUE ) );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('sign_up');
}
/**
* View Cart
*
@@ -12,7 +12,7 @@
namespace IPS\nexus\modules\front\subscriptions;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -23,6 +23,26 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
*/
class _subscriptions extends \IPS\Dispatcher\Controller
{
/**
* Execute
*
* @return void
*/
public function execute()
{
/* Work out currency */
if ( isset( \IPS\Request::i()->currency ) and \in_array( \IPS\Request::i()->currency, \IPS\nexus\Money::currencies() ) )
{
if ( isset( \IPS\Request::i()->csrfKey ) and \IPS\Login::compareHashes( (string) \IPS\Session::i()->csrfKey, (string) \IPS\Request::i()->csrfKey ) )
{
$_SESSION['cart'] = array();
\IPS\Request::i()->setCookie( 'currency', \IPS\Request::i()->currency );
}
}
parent::execute();
}
/**
* Show the subscription packages
*
@@ -34,10 +54,24 @@ class _subscriptions extends \IPS\Dispatcher\Controller
{
\IPS\Output::i()->error( 'nexus_no_subs', '2X379/1', 404, '' );
}
/* Create the table */
$table = new \IPS\nexus\Subscription\Table( \IPS\Http\Url::internal( 'app=nexus&module=subscriptions&controller=subscriptions', 'front', 'nexus_subscriptions' ) );
$table->activeSubscription = \IPS\nexus\Subscription::loadByMember( \IPS\Member::loggedIn(), FALSE );
if ( isset( \IPS\Request::i()->purchased ) and $table->activeSubscription )
{
try
{
$invoice = \IPS\nexus\Invoice::load( $table->activeSubscription->invoice_id );
/* Fire the pixel event */
\IPS\core\Facebook\Pixel::i()->Purchase = array( 'value' => $invoice->total->amount, 'currency' => $invoice->total->currency );
\IPS\Output::i()->inlineMessage = \IPS\Member::loggedIn()->language()->addToStack( 'nexus_subs_paid_flash_msg');
}
catch( \Exception $e ) { }
}
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'front_subscriptions.js', 'nexus', 'front' ) );
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'subscriptions.css', 'nexus' ) );
@@ -65,6 +99,13 @@ class _subscriptions extends \IPS\Dispatcher\Controller
{
\IPS\Output::i()->error( 'nexus_no_subs_package', '2X379/2', 404, '' );
}
/* Is the subscription purchasable ? */
if ( !$newPackage->enabled )
{
\IPS\Output::i()->error( 'node_error', '2X379/7', 403, '' );
}
try
{
@@ -108,82 +149,9 @@ class _subscriptions extends \IPS\Dispatcher\Controller
$purchase->member->log( 'subscription', array( 'type' => 'change', 'id' => $purchase->id, 'old' => $purchase->name, 'name' => $newPackage->titleForLog(), 'system' => FALSE ) );
\IPS\Output::i()->redirect( $purchase->url() );
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=nexus&module=subscriptions&controller=subscriptions', 'front', 'nexus_subscriptions' ) );
}
/**
* Cancels a subscription doens't it? Yes it does.
*
* @return void
*/
protected function cancel()
{
/* CSRF Check */
\IPS\Session::i()->csrfCheck();
$package = \IPS\nexus\Subscription\Package::load( \IPS\Request::i()->id );
$subscription = \IPS\nexus\Subscription::loadActiveByMember( \IPS\Member::loggedIn() );
/* Build Form */
$form = new \IPS\Helpers\Form;
$form->class = 'ipsForm_vertical';
if ( $subscription->renews )
{
$form->add( new \IPS\Helpers\Form\Radio( 'nexus_sub_cancel_type', 0, TRUE, array(
'options' => array( 0 => 'nexus_sub_cancel_type_renewal', 1 => 'nexus_sub_cancel_type_immediate' )
), NULL, NULL, NULL, 'nexus_sub_cancel_type' ) );
}
else
{
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_sub_cancel_now', 0, TRUE, array(), NULL, NULL, NULL, 'nexus_sub_cancel_now' ) );
}
if( $subscription->_expire )
{
\IPS\Member::loggedIn()->language()->words['nexus_sub_cancel_type_renewal_desc'] = \IPS\Member::loggedIn()->language()->addToStack( 'nexus_sub_cancel_type_renewal__desc', NULL, array( 'sprintf' => array( $subscription->_expire->dayAndMonth() . ' ' . $subscription->_expire->format('Y') ) ) );
}
if ( $values = $form->values() )
{
if ( ( isset( $values['nexus_sub_cancel_now'] ) and $values['nexus_sub_cancel_now'] ) or ( isset( $values['nexus_sub_cancel_type'] ) and $values['nexus_sub_cancel_type'] == 1 ) )
{
/* Cancel purchase */
foreach ( \IPS\nexus\extensions\nexus\Item\Subscription::getPurchases( \IPS\nexus\Customer::loggedIn(), $package->id ) as $purchase )
{
$purchase->cancelled = TRUE;
$purchase->member->log( 'purchase', array( 'type' => 'cancel', 'id' => $purchase->id, 'name' => $purchase->name ) );
$purchase->can_reactivate = FALSE;
$purchase->save();
}
/* Cancel the subscription */
$package->cancelMember( \IPS\nexus\Customer::loggedIn() );
}
else if ( isset( $values['nexus_sub_cancel_type'] ) and $values['nexus_sub_cancel_type'] == 0 )
{
/* Just stop the renewal bud */
$subscription->renews = 0;
$subscription->save();
/* Cancel renewals */
foreach ( \IPS\nexus\extensions\nexus\Item\Subscription::getPurchases( \IPS\nexus\Customer::loggedIn(), $package->id ) as $purchase )
{
$purchase->renewals = NULL;
$purchase->save();
}
$purchase->member->log( 'subscription', array( 'type' => 'cancelrenewals', 'id' => $package->id ) );
}
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=nexus&module=subscriptions&controller=subscriptions', 'front', 'nexus_subscriptions' ) );
}
/* Display */
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('nexus_subs_cancel');
\IPS\Output::i()->output = \IPS\Request::i()->isAjax() ? $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) ) : $form;
}
/**
* Purchase
*
@@ -195,12 +163,19 @@ class _subscriptions extends \IPS\Dispatcher\Controller
\IPS\Session::i()->csrfCheck();
/* Already purchased a subscription? */
if ( \IPS\nexus\Subscription::loadActiveByMember( \IPS\nexus\Customer::loggedIn() ) )
if ( \IPS\nexus\Subscription::loadByMember( \IPS\nexus\Customer::loggedIn(), FALSE ) )
{
\IPS\Output::i()->error( 'nexus_subs_already_got_package', '2X379/6', 403, '' );
}
$package = \IPS\nexus\Subscription\Package::load( \IPS\Request::i()->id );
/* Is the subscription purchasable ? */
if ( !$package->enabled )
{
\IPS\Output::i()->error( 'node_error', '2X379/7', 403, '' );
}
$price = $package->price();
$item = new \IPS\nexus\extensions\nexus\Item\Subscription( \IPS\nexus\Customer::loggedIn()->language()->get( $package->_titleLanguageKey ), $price );
@@ -210,24 +185,85 @@ class _subscriptions extends \IPS\Dispatcher\Controller
$item->tax = \IPS\nexus\Tax::load( $package->tax );
}
catch ( \OutOfRangeException $e ) { }
if ( $package->gateways !== '*' )
{
$item->paymentMethodIds = explode( ',', $package->gateways );
}
$item->renewalTerm = $package->renewalTerm( $price->currency );
if ( $package->price and $costs = json_decode( $package->price, TRUE ) and isset( $costs['cost'] ) )
{
$item->initialInterval = new \DateInterval( 'P' . $costs['term'] . mb_strtoupper( $costs['unit'] ) );
}
/* Generate the invoice */
$invoice = new \IPS\nexus\Invoice;
$invoice->currency = $price->currency;
$invoice->member = \IPS\nexus\Customer::loggedIn();
$invoice->addItem( $item );
$invoice->return_uri = "app=nexus&module=subscriptions&controller=subscriptions";
$invoice->return_uri = "app=nexus&module=subscriptions&controller=subscriptions&purchased=1";
$invoice->save();
/* Take them to it */
\IPS\Output::i()->redirect( $invoice->checkoutUrl() );
}
/**
* Reactivate
*
* @return void
*/
protected function reactivate()
{
/* CSRF Check */
\IPS\Session::i()->csrfCheck();
/* Get subscription and purchase */
try
{
$package = \IPS\nexus\Subscription\Package::load( \IPS\Request::i()->id );
}
catch( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'nexus_no_subs_package', '2X379/2', 404, '' );
}
try
{
$subscription = \IPS\nexus\Subscription::loadByMemberAndPackage( \IPS\Member::loggedIn(), $package, FALSE );
}
catch( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'nexus_no_subs_subs', '2X379/8', 404, '' );
}
$purchase = NULL;
foreach ( \IPS\nexus\extensions\nexus\Item\Subscription::getPurchases( \IPS\nexus\Customer::loggedIn(), $subscription->package->id ) as $row )
{
if ( $row->can_reactivate )
{
$purchase = $row;
break;
}
}
if ( $purchase === NULL )
{
\IPS\Output::i()->error( 'nexus_sub_no_purchase', '2X379/9', 404, '' );
}
/* Set renewal terms */
$currency = $purchase->original_invoice->currency;
$purchase->renewals = $package->renewalTerm( $currency );
$purchase->cancelled = FALSE;
$purchase->save();
$purchase->member->log( 'purchase', array( 'type' => 'info', 'id' => $purchase->id, 'name' => $purchase->name, 'info' => 'change_renewals', 'to' => array( 'cost' => $purchase->renewals->cost->amount, 'currency' => $purchase->renewals->cost->currency, 'term' => $purchase->renewals->getTerm() ) ) );
/* Either send to renewal invoice or just back to subscriptions list */
if ( !$purchase->active and $purchase->canRenewUntil() !== FALSE )
{
\IPS\Output::i()->redirect( $purchase->url()->setQueryString( 'do', 'renew' )->csrf() );
}
else
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=nexus&module=subscriptions&controller=subscriptions', 'front', 'nexus_subscriptions' ) );
}
}
}
@@ -12,7 +12,7 @@
namespace IPS\nexus\modules\front\support;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -64,7 +64,7 @@ class _home extends \IPS\Dispatcher\Controller
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack( 'new_request' ) );
$accounts = \IPS\nexus\Customer::loggedIn()->parentContacts( array( 'support=1' ) );
if ( count( $accounts ) and !isset( \IPS\Request::i()->account ) )
if ( \count( $accounts ) and !isset( \IPS\Request::i()->account ) )
{
$options = array();
$options[ \IPS\nexus\Customer::loggedIn()->member_id ] = \IPS\nexus\Customer::loggedIn()->language()->addToStack( 'my_account', FALSE, array( 'sprintf' => array( \IPS\nexus\Customer::loggedIn()->cm_name ) ) );
@@ -80,7 +80,7 @@ class _home extends \IPS\Dispatcher\Controller
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=nexus&module=support&controller=home&do=create&account={$values['support_account']}", 'front', 'support_create' ) );
}
\IPS\Output::i()->output = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) );
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
}
else
{
@@ -12,7 +12,7 @@
namespace IPS\nexus\modules\front\support;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -33,7 +33,7 @@ class _redirect extends \IPS\Dispatcher\Controller
$url = \IPS\Http\Url::internal( "app=core&module=system&controller=redirect" )->setQueryString( array(
'url' => \IPS\Request::i()->url,
'resource' => ( \IPS\Request::i()->resource ) ? 1 : NULL,
'key' => hash_hmac( "sha256", \IPS\Request::i()->url, \IPS\Settings::i()->site_secret_key ),
'key' => hash_hmac( "sha256", \IPS\Request::i()->url, \IPS\Settings::i()->site_secret_key . 'r' ),
) );
\IPS\Output::i()->redirect( $url );
@@ -12,7 +12,7 @@
namespace IPS\nexus\modules\front\support;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -63,7 +63,7 @@ class _view extends \IPS\Content\Controller
}
$allowedStatuses = \IPS\nexus\Support\Status::publicSetStatuses( $this->request );
if ( isset( \IPS\Request::i()->setStatus ) and !empty( $allowedStatuses ) and in_array( \IPS\Request::i()->setStatus, array_keys( $allowedStatuses ) ) )
if ( isset( \IPS\Request::i()->setStatus ) and !empty( $allowedStatuses ) and \in_array( \IPS\Request::i()->setStatus, array_keys( $allowedStatuses ) ) )
{
\IPS\Session::i()->csrfCheck();
$newStatus = \IPS\nexus\Support\Status::load( \IPS\Request::i()->setStatus );
@@ -135,7 +135,7 @@ class _view extends \IPS\Content\Controller
}
}
\IPS\Output::i()->output = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) );
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
}
/**
@@ -177,7 +177,6 @@ class _view extends \IPS\Content\Controller
\IPS\Output::i()->redirect( $request->url() );
}
\IPS\Output::i()->output = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) );
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
}
}