Version 4.5.0
This commit is contained in:
1 parent
1a0c7fd3c2
commit
f79dcf067a
3791 files changed
+248032
-76372
No files matched your search
@@ -12,7 +12,7 @@
|
||||
namespace IPS\nexus\Subscription;
|
||||
|
||||
/* 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,7 +49,7 @@ class _Package extends \IPS\Node\Model
|
||||
* @brief [Node] Order Database Column
|
||||
*/
|
||||
public static $databaseColumnOrder = 'position';
|
||||
|
||||
|
||||
/**
|
||||
* @brief [Node] Title prefix. If specified, will look for a language key with "{$key}_title" as the key
|
||||
*/
|
||||
@@ -88,11 +88,20 @@ class _Package extends \IPS\Node\Model
|
||||
'module' => 'subscriptions',
|
||||
'prefix' => 'subscriptions_'
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @brief URL Base
|
||||
*/
|
||||
protected static $urlBase = 'app=nexus&module=subscriptions&controller=subscriptions&id=';
|
||||
|
||||
|
||||
/**
|
||||
* @brief URL Template
|
||||
*/
|
||||
protected static $urlTemplate = 'nexus_subscription';
|
||||
|
||||
/**
|
||||
* @brief SEO Title Column
|
||||
*/
|
||||
protected static $seoTitleColumn = '';
|
||||
|
||||
/**
|
||||
@@ -122,9 +131,27 @@ class _Package extends \IPS\Node\Model
|
||||
}
|
||||
catch( \Exception $e ) {}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* [ActiveRecord] Delete Record
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
try
|
||||
{
|
||||
if( $this->image )
|
||||
{
|
||||
\IPS\File::get( 'nexus_Products', $this->image )->delete();
|
||||
}
|
||||
}
|
||||
catch( \Exception $e ){
|
||||
}
|
||||
parent::delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get buttons to display in tree
|
||||
* Example code explains return value
|
||||
@@ -159,6 +186,12 @@ class _Package extends \IPS\Node\Model
|
||||
}
|
||||
|
||||
$buttons = array_merge( $buttons, parent::getButtons( $url, $subnode ) );
|
||||
|
||||
if ( isset( $buttons['delete'] ) )
|
||||
{
|
||||
unset( $buttons['delete']['data']['delete'] );
|
||||
$buttons['delete']['data']['confirm'] = TRUE;
|
||||
}
|
||||
|
||||
return $buttons;
|
||||
}
|
||||
@@ -166,11 +199,11 @@ class _Package extends \IPS\Node\Model
|
||||
/**
|
||||
* Fetch the cover image uRL
|
||||
*
|
||||
* @return \IPS\File
|
||||
* @return \IPS\File | NULL
|
||||
*/
|
||||
public function get__image()
|
||||
{
|
||||
return \IPS\File::get( 'nexus_Products', $this->image );
|
||||
return ( $this->image ) ? \IPS\File::get( 'nexus_Products', $this->image ) : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -192,32 +225,59 @@ class _Package extends \IPS\Node\Model
|
||||
$groupsExcludingGuestsAndAdmins[ $group->g_id ] = $group->name;
|
||||
}
|
||||
|
||||
$renewOptions = array();
|
||||
if ( $this->renew_options and $_renewOptions = json_decode( $this->renew_options, TRUE ) and is_array( $_renewOptions ) )
|
||||
$renewInterval = NULL;
|
||||
$renewalTerm = NULL;
|
||||
$renewalCosts = array();
|
||||
if ( $this->renew_options and $_renewOptions = json_decode( $this->renew_options, TRUE ) and \is_array( $_renewOptions ) )
|
||||
{
|
||||
$costs = array();
|
||||
foreach ( $_renewOptions['cost'] as $cost )
|
||||
{
|
||||
$costs[ $cost['currency'] ] = new \IPS\nexus\Money( $cost['amount'], $cost['currency'] );
|
||||
$renewalCosts[ $cost['currency'] ] = new \IPS\nexus\Money( $cost['amount'], $cost['currency'] );
|
||||
}
|
||||
|
||||
/* Catch any invalid renewal terms, these can occasionally appear from legacy IP.Subscriptions */
|
||||
try
|
||||
{
|
||||
$renewOptions = new \IPS\nexus\Purchase\RenewalTerm( $costs, new \DateInterval( "P{$_renewOptions['term']}" . mb_strtoupper( $_renewOptions['unit'] ) ), NULL );
|
||||
$renewInterval = new \DateInterval( "P{$_renewOptions['term']}" . mb_strtoupper( $_renewOptions['unit'] ) );
|
||||
$renewalTerm = new \IPS\nexus\Purchase\RenewalTerm( $renewalCosts, $renewInterval, NULL );
|
||||
}
|
||||
catch( \Exception $ex ) { } // Catch any invalid renewal terms, these can occasionally appear from legacy IP.Subscriptions
|
||||
}
|
||||
|
||||
$initialPrice = NULL;
|
||||
if ( $this->price )
|
||||
{
|
||||
$initialInterval = $renewInterval;
|
||||
$initialPrices = [];
|
||||
$costs = json_decode( $this->price, TRUE );
|
||||
if ( isset( $costs['cost'] ) )
|
||||
{
|
||||
$initialInterval = new \DateInterval( 'P' . $costs['term'] . mb_strtoupper( $costs['unit'] ) );
|
||||
$costs = $costs['cost'];
|
||||
}
|
||||
foreach ( $costs as $price )
|
||||
{
|
||||
$initialPrices[ $price['currency'] ] = new \IPS\nexus\Money( $price['amount'], $price['currency'] );
|
||||
}
|
||||
catch( \Exception $ex) { }
|
||||
|
||||
if ( $initialPrices == $renewalCosts )
|
||||
{
|
||||
$renewalTerm = NULL;
|
||||
}
|
||||
|
||||
$initialPrice = new \IPS\nexus\Purchase\RenewalTerm( $initialPrices, $initialInterval );
|
||||
}
|
||||
|
||||
$form->addHeader('subscription_basic_settings');
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'sp_name', NULL, TRUE, array( 'app' => 'nexus', 'key' => $this->id ? "nexus_subs_{$this->id}" : NULL ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'sp_enabled', $this->id ? $this->enabled : TRUE, FALSE ) );
|
||||
|
||||
$form->addHeader( 'nexus_subs_cost' );
|
||||
$form->add( new \IPS\nexus\Form\Money( 'sp_price', $this->price, TRUE ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'sp_renews', !empty( $renewOptions ), FALSE, array( 'togglesOn' => array( 'sp_renew_options' ) ), NULL, NULL, NULL, 'sp_renews' ) );
|
||||
$form->add( new \IPS\nexus\Form\RenewalTerm( 'sp_renew_options', $renewOptions, NULL, array( 'allCurrencies' => TRUE ), NULL, NULL, NULL, 'sp_renew_options' ) );
|
||||
$form->add( new \IPS\nexus\Form\RenewalTerm( 'sp_price', $initialPrice, NULL, array( 'allCurrencies' => TRUE, 'initialTerm' => TRUE, 'unlimitedTogglesOn' => [ 'sp_renew_upgrade' ], 'unlimitedTogglesOff' => [ 'sp_renew_options' ] ), NULL, NULL, NULL, 'sp_initial_term' ) );
|
||||
$form->add( new \IPS\nexus\Form\RenewalTerm( 'sp_renew_options', $renewalTerm, NULL, array( 'allCurrencies' => TRUE, 'nullLang' => 'term_same_as_initial' ), NULL, NULL, NULL, 'sp_renew_options' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'sp_renew_upgrade', $this->renew_upgrade ?: 0, FALSE, array( 'options' => array(
|
||||
0 => 'sp_renew_upgrade_none',
|
||||
1 => 'sp_renew_upgrade_full',
|
||||
2 => 'sp_renew_upgrade_partial'
|
||||
) ), NULL, NULL, NULL, 'sp_renew_upgrade' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'sp_tax', (int) $this->tax, FALSE, array( 'class' => 'IPS\nexus\Tax', 'zeroVal' => 'do_not_tax' ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'sp_gateways', ( !$this->gateways or $this->gateways === '*' ) ? 0 : explode( ',', $this->gateways ), FALSE, array( 'class' => 'IPS\nexus\Gateway', 'multiple' => TRUE, 'zeroVal' => 'any' ) ) );
|
||||
|
||||
@@ -229,7 +289,7 @@ class _Package extends \IPS\Node\Model
|
||||
|
||||
|
||||
$form->addHeader('nexus_subs_display');
|
||||
$form->add( new \IPS\Helpers\Form\Upload( 'sp_image', ( ( $this->id AND $this->image ) ? \IPS\File::get( 'nexus_Products', $this->image ) : NULL ), FALSE, array( 'storageExtension' => 'nexus_Products', 'image' => TRUE ), NULL, NULL, NULL, 'sp_image' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Upload( 'sp_image', ( ( $this->id AND $this->image ) ? \IPS\File::get( 'nexus_Products', $this->image ) : NULL ), FALSE, array( 'storageExtension' => 'nexus_Products', 'image' => TRUE, 'allowStockPhotos' => TRUE ), NULL, NULL, NULL, 'sp_image' ) );
|
||||
/*$form->add( new \IPS\Helpers\Form\YesNo( 'sp_featured', $this->featured, FALSE, array(), NULL, NULL, NULL, 'sp_featured' ) );*/
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'sp_desc', NULL, FALSE, array(
|
||||
'app' => 'nexus',
|
||||
@@ -291,9 +351,23 @@ class _Package extends \IPS\Node\Model
|
||||
}
|
||||
|
||||
/* Normalise */
|
||||
$originalPrice = NULL;
|
||||
if( isset( $values['sp_price'] ) )
|
||||
{
|
||||
$values['sp_price'] = json_encode( $values['sp_price'] );
|
||||
$originalPrice = $values['sp_price'];
|
||||
if ( $values['sp_price']->interval )
|
||||
{
|
||||
$term = $values['sp_price']->getTerm();
|
||||
$values['sp_price'] = json_encode( array(
|
||||
'cost' => $values['sp_price']->cost,
|
||||
'term' => $term['term'],
|
||||
'unit' => $term['unit']
|
||||
) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$values['sp_price'] = json_encode( $values['sp_price']->cost );
|
||||
}
|
||||
}
|
||||
|
||||
if( isset( $values['sp_primary_group'] ) )
|
||||
@@ -313,13 +387,13 @@ class _Package extends \IPS\Node\Model
|
||||
|
||||
if( isset( $values['sp_gateways'] ) )
|
||||
{
|
||||
$values['sp_gateways'] = ( isset( $values['sp_gateways'] ) and is_array( $values['sp_gateways'] ) ) ? implode( ',', array_keys( $values['sp_gateways'] ) ) : '*';
|
||||
$values['sp_gateways'] = ( isset( $values['sp_gateways'] ) and \is_array( $values['sp_gateways'] ) ) ? implode( ',', array_keys( $values['sp_gateways'] ) ) : '*';
|
||||
}
|
||||
|
||||
/* Renewal options */
|
||||
if( isset( $values['sp_renews'] ) )
|
||||
if( isset( $values['sp_renew_options'] ) )
|
||||
{
|
||||
if ( $values['sp_renews'] )
|
||||
if ( $values['sp_renew_options'] )
|
||||
{
|
||||
$renewOptions = array();
|
||||
$option = $values['sp_renew_options'];
|
||||
@@ -335,8 +409,11 @@ class _Package extends \IPS\Node\Model
|
||||
{
|
||||
$values['sp_renew_options'] = '';
|
||||
}
|
||||
|
||||
unset( $values['sp_renews'] );
|
||||
}
|
||||
elseif ( isset( $values['sp_price'] ) and $originalPrice->interval )
|
||||
{
|
||||
$values['sp_renew_options'] = $values['sp_price'];
|
||||
$values['sp_price'] = json_encode( $originalPrice->cost );
|
||||
}
|
||||
|
||||
if ( isset( $values['sp_image'] ) )
|
||||
@@ -357,12 +434,16 @@ class _Package extends \IPS\Node\Model
|
||||
{
|
||||
if ( !$currency )
|
||||
{
|
||||
$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();
|
||||
}
|
||||
|
||||
$costs = json_decode( $this->price, TRUE );
|
||||
if ( isset( $costs['cost'] ) )
|
||||
{
|
||||
$costs = $costs['cost'];
|
||||
}
|
||||
|
||||
if ( is_array( $costs ) and isset( $costs[ $currency ]['amount'] ) )
|
||||
if ( \is_array( $costs ) and isset( $costs[ $currency ]['amount'] ) )
|
||||
{
|
||||
return new \IPS\nexus\Money( $costs[ $currency ]['amount'], $currency );
|
||||
}
|
||||
@@ -384,7 +465,7 @@ class _Package extends \IPS\Node\Model
|
||||
$renewalPrices = $renewal['cost'];
|
||||
if ( !$currency )
|
||||
{
|
||||
$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();
|
||||
}
|
||||
|
||||
if ( isset( $renewalPrices[ $currency ] ) )
|
||||
@@ -417,15 +498,46 @@ class _Package extends \IPS\Node\Model
|
||||
}
|
||||
|
||||
/**
|
||||
* Price Blurb
|
||||
* Price Info
|
||||
*
|
||||
* @return string|NULL
|
||||
* @return array|NULL
|
||||
*/
|
||||
public function priceBlurb()
|
||||
public function priceInfo()
|
||||
{
|
||||
if ( $price = $this->price() )
|
||||
/* Base Price */
|
||||
$price = $this->price();
|
||||
|
||||
/* Price may not have been defined in our currency - abort if we don't have one */
|
||||
if( $price === NULL )
|
||||
{
|
||||
return $price;
|
||||
}
|
||||
|
||||
/* Renewal Term */
|
||||
$renewalTerm = NULL;
|
||||
$initialTerm = NULL;
|
||||
try
|
||||
{
|
||||
$renewalTerm = $this->renewalTerm( $price->currency );
|
||||
|
||||
/* Is the initial term different? */
|
||||
$priceInfo = json_decode( $this->price, TRUE );
|
||||
if ( isset( $priceInfo['term'] ) )
|
||||
{
|
||||
$initialTerm = new \IPS\nexus\Purchase\RenewalTerm( $price, new \DateInterval( 'P' . $priceInfo['term'] . mb_strtoupper( $priceInfo['unit'] ) ) );
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) {}
|
||||
|
||||
/* If we can encompass the primary price and renewal term together, do that */
|
||||
$priceIsZero = $price->amount->isZero();
|
||||
if ( $renewalTerm and $price->amount->compare( $renewalTerm->cost->amount ) === 0 )
|
||||
{
|
||||
$price = $renewalTerm->toDisplay();
|
||||
$renewalTerm = NULL;
|
||||
}
|
||||
elseif ( $price )
|
||||
{
|
||||
/* Include tax? */
|
||||
if ( \IPS\Settings::i()->nexus_show_tax and $this->tax )
|
||||
{
|
||||
try
|
||||
@@ -436,37 +548,40 @@ class _Package extends \IPS\Node\Model
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
/* Return */
|
||||
return array(
|
||||
'primaryPrice' => $priceIsZero ? \IPS\Member::loggedIn()->language()->addToStack('nexus_sub_cost_free') : $price,
|
||||
'primaryPriceIsZero' => $priceIsZero,
|
||||
'primaryPriceDiscountedFrom' => NULL,
|
||||
'initialTerm' => $initialTerm ? $initialTerm->getTermUnit() : NULL,
|
||||
'renewalPrice' => $renewalTerm ? $renewalTerm->toDisplay() : NULL,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Price Blurb
|
||||
*
|
||||
* @return string|NULL
|
||||
*/
|
||||
public function priceBlurb()
|
||||
{
|
||||
$priceInfo = $this->priceInfo();
|
||||
|
||||
if ( $priceInfo['primaryPrice'] )
|
||||
{
|
||||
if ( $priceInfo['renewalPrice'] and $priceInfo['initialTerm'] )
|
||||
{
|
||||
$renewalTerm = $this->renewalTerm( $price->currency );
|
||||
|
||||
/* Include tax? */
|
||||
if ( \IPS\Settings::i()->nexus_show_tax and $this->tax and isset( $taxRate ) and $renewalTerm )
|
||||
{
|
||||
try
|
||||
{
|
||||
$renewalTerm->cost->amount = $renewalTerm->cost->amount->add( $renewalTerm->cost->amount->multiply( $taxRate ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
}
|
||||
|
||||
if ( $renewalTerm and $renewalTerm->cost->amount == $price->amount )
|
||||
{
|
||||
return $renewalTerm;
|
||||
}
|
||||
else if ( $renewalTerm )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'nexus_sub_cost_plus_renewal', FALSE, array( 'sprintf' => array( $price, $renewalTerm ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return $price;
|
||||
}
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'nexus_sub_cost_plus_renewal', FALSE, array( 'sprintf' => array( $priceInfo['primaryPrice'], $priceInfo['initialTerm'], $priceInfo['renewalPrice'] ) ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
elseif ( $priceInfo['renewalPrice'] )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('nexus_sub_cost_unavailable');
|
||||
return $priceInfo['renewalPrice'];
|
||||
}
|
||||
else
|
||||
{
|
||||
return $priceInfo['primaryPrice'];
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -511,13 +626,39 @@ class _Package extends \IPS\Node\Model
|
||||
}
|
||||
|
||||
$priceOfExistingPackage = json_decode( $package->price, TRUE );
|
||||
if ( isset( $priceOfExistingPackage['cost'] ) )
|
||||
{
|
||||
$priceOfExistingPackage = $priceOfExistingPackage['cost'];
|
||||
}
|
||||
$priceOfExistingPackage = $priceOfExistingPackage[ $currency ]['amount'];
|
||||
$renewalOptionsOnOldPackage = json_decode( $package->renew_options, TRUE );
|
||||
|
||||
$priceOfThisPackage = json_decode( $this->price, TRUE );
|
||||
if ( isset( $priceOfThisPackage['cost'] ) )
|
||||
{
|
||||
$priceOfThisPackage = $priceOfThisPackage['cost'];
|
||||
}
|
||||
$priceOfThisPackage = $priceOfThisPackage[ $currency ]['amount'];
|
||||
$renewalOptionsOnNewPackage = json_decode( $this->renew_options, TRUE );
|
||||
|
||||
|
||||
/* It's a non-recurring subscription */
|
||||
if ( empty( $renewalOptionsOnNewPackage ) )
|
||||
{
|
||||
switch( $this->renew_upgrade )
|
||||
{
|
||||
case 0:
|
||||
return NULL;
|
||||
|
||||
case 1:
|
||||
return new \IPS\nexus\Money( $priceOfThisPackage, $currency );
|
||||
|
||||
case 2:
|
||||
return new \IPS\nexus\Money( $priceOfThisPackage - $priceOfExistingPackage, $currency );
|
||||
}
|
||||
}
|
||||
|
||||
/* It's a recurring subscription */
|
||||
if ( $priceOfThisPackage >= $priceOfExistingPackage )
|
||||
{
|
||||
$type = \IPS\Settings::i()->nexus_subs_upgrade;
|
||||
@@ -526,7 +667,7 @@ class _Package extends \IPS\Node\Model
|
||||
{
|
||||
$type = \IPS\Settings::i()->nexus_subs_downgrade;
|
||||
}
|
||||
|
||||
|
||||
switch ( $type )
|
||||
{
|
||||
case -1:
|
||||
@@ -544,10 +685,6 @@ class _Package extends \IPS\Node\Model
|
||||
{
|
||||
return new \IPS\nexus\Money( 0, $currency );
|
||||
}
|
||||
if ( !$renewalOptionsOnNewPackage )
|
||||
{
|
||||
throw new \InvalidArgumentException;
|
||||
}
|
||||
|
||||
/* What is the closest renewal option on the new package? We'll use that one */
|
||||
$renewalOptionsInDays = array();
|
||||
@@ -593,7 +730,8 @@ class _Package extends \IPS\Node\Model
|
||||
public function upgradeDowngrade( \IPS\nexus\Purchase $purchase, \IPS\nexus\Subscription\Package $newPackage, $skipCharge = FALSE )
|
||||
{
|
||||
/* Right, that's all the "I'll tamper with the URLs for a laugh" stuff out of the way... */
|
||||
$costToUpgrade = $newPackage->costToUpgrade( \IPS\nexus\Subscription\Package::load( $purchase->item_id ), $purchase->member );
|
||||
$oldPackage = \IPS\nexus\Subscription\Package::load( $purchase->item_id );
|
||||
$costToUpgrade = $newPackage->costToUpgrade( $oldPackage, $purchase->member );
|
||||
|
||||
/* Charge / Refund */
|
||||
if ( !$skipCharge )
|
||||
@@ -629,10 +767,15 @@ class _Package extends \IPS\Node\Model
|
||||
}
|
||||
}
|
||||
|
||||
/* Get old renewal term details here */
|
||||
$oldTerm = NULL;
|
||||
$oldRenewalOptions = json_decode( $oldPackage->renew_options, TRUE );
|
||||
$oldTerm = $oldRenewalOptions;
|
||||
|
||||
/* Work out the new renewal term */
|
||||
$term = NULL;
|
||||
$renewalOptions = json_decode( $newPackage->renew_options, TRUE );
|
||||
$term = $renewalOptions;
|
||||
$term = $rawTerm = $renewalOptions;
|
||||
|
||||
if ( $term )
|
||||
{
|
||||
@@ -644,12 +787,12 @@ class _Package extends \IPS\Node\Model
|
||||
{
|
||||
$currency = $purchase->member->defaultCurrency();
|
||||
}
|
||||
$term = new \IPS\nexus\Purchase\RenewalTerm( new \IPS\nexus\Money( $term['cost'][$currency]['amount'], $currency ), new \DateInterval( 'P' . $term['term'] . mb_strtoupper( $term['unit'] ) ) );
|
||||
$term = new \IPS\nexus\Purchase\RenewalTerm( new \IPS\nexus\Money( $term['cost'][$currency]['amount'], $currency ), new \DateInterval( 'P' . $term['term'] . mb_strtoupper( $term['unit'] ) ), $newPackage->tax ? \IPS\nexus\Tax::load( $newPackage->tax ) : NULL );
|
||||
}
|
||||
|
||||
/* Remove usergroups */
|
||||
$this->_removeUsergroups( $purchase->member );
|
||||
|
||||
|
||||
/* If we didn't have an expiry date before, but the new package has a renewal term, set an expiry date */
|
||||
if ( !$purchase->expire and $term )
|
||||
{
|
||||
@@ -660,6 +803,24 @@ class _Package extends \IPS\Node\Model
|
||||
{
|
||||
$purchase->expire = NULL;
|
||||
}
|
||||
/* We have a term, but the unit is different from the existing package */
|
||||
elseif ( $purchase->expire and $term and $oldTerm and ( $rawTerm['unit'] != $oldTerm['unit'] ) )
|
||||
{
|
||||
$difference = $purchase->expire->getTimestamp() - time();
|
||||
|
||||
if ( $difference > 0 )
|
||||
{
|
||||
$newExpire = \IPS\DateTime::ts( ( time() - $difference ) );
|
||||
$newExpire = $newExpire->add( $term->interval );
|
||||
|
||||
if ( $newExpire->getTimestamp() < time() )
|
||||
{
|
||||
$newExpire = \IPS\DateTime::create()->add( $term->interval );
|
||||
}
|
||||
|
||||
$purchase->expire = $newExpire;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update Purchase */
|
||||
$purchase->name = \IPS\Member::loggedIn()->language()->get( "nexus_subs_{$newPackage->id}" );
|
||||
@@ -684,11 +845,53 @@ class _Package extends \IPS\Node\Model
|
||||
{
|
||||
\IPS\nexus\Subscription::loadActiveByMember( $purchase->member )->changePackage( $newPackage, $purchase->expire );
|
||||
}
|
||||
catch( \Exception $ex )
|
||||
catch( \Exception $e )
|
||||
{
|
||||
\IPS\Log::log( "Change Package error (" . $e->getCode() . ") " . $e->getMessage(), 'subscriptions' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renew a member to the subscription package
|
||||
*
|
||||
* @param \IPS\nexus\Customer $member The cutomer innit
|
||||
* @return \IPS\nexus\Subscription The new subscription object added
|
||||
*/
|
||||
public function renewMember( $member )
|
||||
{
|
||||
try
|
||||
{
|
||||
$expires = 0;
|
||||
$renews = 0;
|
||||
|
||||
/* Get the most recent active subscription */
|
||||
$sub = \IPS\nexus\Subscription::loadByMemberAndPackage( $member, $this, FALSE );
|
||||
|
||||
if ( $this->renew_options and $renewal = json_decode( $this->renew_options, TRUE ) )
|
||||
{
|
||||
$nextExpiration = \IPS\DateTime::ts( $sub->expire, TRUE );
|
||||
$nextExpiration->add( new \DateInterval( 'P' . $renewal['term'] . mb_strtoupper( $renewal['unit'] ) ) );
|
||||
$expires = $nextExpiration->getTimeStamp();
|
||||
$renews = 1;
|
||||
}
|
||||
|
||||
$sub->active = 1;
|
||||
$sub->cancelled = 0;
|
||||
$sub->expire = $expires;
|
||||
$sub->renews = $renews;
|
||||
$sub->save();
|
||||
|
||||
/* Member groups may have changed in the package itself */
|
||||
$this->_removeUsergroups( $member );
|
||||
$this->_addUsergroups( $member );
|
||||
|
||||
return $sub;
|
||||
}
|
||||
catch( \Exception $ex )
|
||||
{
|
||||
return $this->addMember( $member );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a member to the subscription package
|
||||
@@ -698,8 +901,16 @@ class _Package extends \IPS\Node\Model
|
||||
*/
|
||||
public function addMember( $member )
|
||||
{
|
||||
/* Make any previous subscriptions inactive */
|
||||
\IPS\nexus\Subscription::markInactiveByUser( $member );
|
||||
try
|
||||
{
|
||||
$sub = \IPS\nexus\Subscription::loadByMemberAndPackage( $member, $this, FALSE );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
$sub = new \IPS\nexus\Subscription;
|
||||
$sub->package_id = $this->id;
|
||||
$sub->member_id = $member->member_id;
|
||||
}
|
||||
|
||||
$expires = 0;
|
||||
$renews = 0;
|
||||
@@ -712,9 +923,6 @@ class _Package extends \IPS\Node\Model
|
||||
}
|
||||
|
||||
/* Create a new one */
|
||||
$sub = new \IPS\nexus\Subscription;
|
||||
$sub->package_id = $this->id;
|
||||
$sub->member_id = $member->member_id;
|
||||
$sub->active = 1;
|
||||
$sub->cancelled = 0;
|
||||
$sub->start = time();
|
||||
@@ -755,6 +963,16 @@ class _Package extends \IPS\Node\Model
|
||||
|
||||
/* Make any previous subscriptions inactive */
|
||||
\IPS\nexus\Subscription::markInactiveByUser( $member );
|
||||
|
||||
/* Cancel purchase */
|
||||
foreach ( \IPS\nexus\extensions\nexus\Item\Subscription::getPurchases( $member, $this->id ) as $purchase )
|
||||
{
|
||||
if ( $purchase->active )
|
||||
{
|
||||
$purchase->active = FALSE;
|
||||
$purchase->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -790,10 +1008,10 @@ class _Package extends \IPS\Node\Model
|
||||
$newSecondary = '';
|
||||
|
||||
/* Primary Group */
|
||||
if ( $this->primary_group and $this->primary_group != $member->member_group_id and !in_array( $member->member_group_id, explode( ',', \IPS\Settings::i()->nexus_subs_exclude_groups ) ) )
|
||||
if ( $this->primary_group and $this->primary_group != $member->member_group_id and !\in_array( $member->member_group_id, explode( ',', \IPS\Settings::i()->nexus_subs_exclude_groups ) ) )
|
||||
{
|
||||
/* Hang on, are we about to boot someone out the ACP? */
|
||||
if ( ! ( $member->isAdmin() and !in_array( $this->primary_group, array_keys( \IPS\Member::administrators()['g'] ) ) ) )
|
||||
if ( ! ( $member->isAdmin() and !\in_array( $this->primary_group, array_keys( \IPS\Member::administrators()['g'] ) ) ) )
|
||||
{
|
||||
/* Save the current group */
|
||||
$previousGroup = $member->member_group_id;
|
||||
@@ -815,7 +1033,7 @@ class _Package extends \IPS\Node\Model
|
||||
{
|
||||
foreach ( $secondary as $gid )
|
||||
{
|
||||
if ( !in_array( $gid, $newSecondary ) )
|
||||
if ( !\in_array( $gid, $newSecondary ) )
|
||||
{
|
||||
$newSecondary[] = $gid;
|
||||
}
|
||||
@@ -858,11 +1076,6 @@ class _Package extends \IPS\Node\Model
|
||||
}
|
||||
}
|
||||
|
||||
if ( $purchase === NULL )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$sub = \IPS\Db::i()->select( '*', 'nexus_member_subscriptions', array( 'sub_active=1 and sub_package_id=? and sub_member_id=?', $this->id, $member->member_id ) )->first();
|
||||
@@ -880,9 +1093,18 @@ class _Package extends \IPS\Node\Model
|
||||
/* Have we made other purchases that have changed their primary group? */
|
||||
try
|
||||
{
|
||||
$next = \IPS\Db::i()->select( array( 'ps_id', 'ps_name', 'p_primary_group' ), 'nexus_purchases', array( 'ps_member=? AND ps_app=? AND ps_type=? AND ps_active=1 AND p_primary_group<>0 AND ps_id<>?', $member->member_id, 'nexus', 'package', $purchase->id ) )
|
||||
->join( 'nexus_packages', 'p_id=ps_item_id' )
|
||||
->first();
|
||||
if( $purchase !== NULL )
|
||||
{
|
||||
$next = \IPS\Db::i()->select( array( 'ps_id', 'ps_name', 'p_primary_group' ), 'nexus_purchases', array( 'ps_member=? AND ps_app=? AND ps_type=? AND ps_active=1 AND p_primary_group<>0 AND ps_id<>?', $member->member_id, 'nexus', 'package', $purchase->id ) )
|
||||
->join( 'nexus_packages', 'p_id=ps_item_id' )
|
||||
->first();
|
||||
}
|
||||
else
|
||||
{
|
||||
$next = \IPS\Db::i()->select( array( 'ps_id', 'ps_name', 'p_primary_group' ), 'nexus_purchases', array( 'ps_member=? AND ps_app=? AND ps_type=? AND ps_active=1 AND p_primary_group<>0', $member->member_id, 'nexus', 'package' ) )
|
||||
->join( 'nexus_packages', 'p_id=ps_item_id' )
|
||||
->first();
|
||||
}
|
||||
|
||||
/* Make sure this group exists */
|
||||
try
|
||||
@@ -930,23 +1152,34 @@ class _Package extends \IPS\Node\Model
|
||||
|
||||
/* Have we made other purchases that have added secondary groups? */
|
||||
$secondaryGroupsAwardedByOtherPurchases = array();
|
||||
foreach ( \IPS\Db::i()->select( 'p_secondary_group', 'nexus_purchases', array( 'ps_member=? AND ps_app=? AND ps_type=? AND ps_active=1 AND p_secondary_group IS NOT NULL AND p_secondary_group<>? AND ps_id<>?', $member->member_id, 'nexus', 'package', '', $purchase->id ) )->join( 'nexus_packages', 'p_id=ps_item_id' ) as $secondaryGroups )
|
||||
|
||||
if( $purchase !== NULL )
|
||||
{
|
||||
$query = \IPS\Db::i()->select( 'p_secondary_group', 'nexus_purchases', array( 'ps_member=? AND ps_app=? AND ps_type=? AND ps_active=1 AND p_secondary_group IS NOT NULL AND p_secondary_group<>? AND ps_id<>?', $member->member_id, 'nexus', 'package', '', $purchase->id ) )->join( 'nexus_packages', 'p_id=ps_item_id' );
|
||||
}
|
||||
else
|
||||
{
|
||||
$query = \IPS\Db::i()->select( 'p_secondary_group', 'nexus_purchases', array( 'ps_member=? AND ps_app=? AND ps_type=? AND ps_active=1 AND p_secondary_group IS NOT NULL AND p_secondary_group<>?', $member->member_id, 'nexus', 'package', '' ) )->join( 'nexus_packages', 'p_id=ps_item_id' );
|
||||
}
|
||||
|
||||
foreach ( $query as $secondaryGroups )
|
||||
{
|
||||
$secondaryGroupsAwardedByOtherPurchases = array_merge( $secondaryGroupsAwardedByOtherPurchases, array_filter( explode( ',', $secondaryGroups ) ) );
|
||||
}
|
||||
|
||||
$secondaryGroupsAwardedByOtherPurchases = array_unique( $secondaryGroupsAwardedByOtherPurchases );
|
||||
|
||||
/* Loop through */
|
||||
foreach ( $secondaryGroupsAwardedByThisPurchase as $groupId )
|
||||
{
|
||||
/* If we had this group before we made this purchase, we're going to keep it */
|
||||
if ( in_array( $groupId, $membersPreviousSecondaryGroupsBeforeThisPurchase ) )
|
||||
if ( \in_array( $groupId, $membersPreviousSecondaryGroupsBeforeThisPurchase ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If we are being awarded this group by a different purchase, we're also going to keep it */
|
||||
if ( in_array( $groupId, $secondaryGroupsAwardedByOtherPurchases ) )
|
||||
if ( \in_array( $groupId, $secondaryGroupsAwardedByOtherPurchases ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -978,7 +1211,7 @@ class _Package extends \IPS\Node\Model
|
||||
$currentSecondaryGroups = $membersSecondaryGroups;
|
||||
foreach( $membersSecondaryGroups as $group )
|
||||
{
|
||||
if ( in_array( $group, $secondaryGroupsAwardedByThisPurchase ) )
|
||||
if ( \in_array( $group, $secondaryGroupsAwardedByThisPurchase ) )
|
||||
{
|
||||
unset( $membersSecondaryGroups[ array_search( $group, $membersSecondaryGroups ) ] );
|
||||
}
|
||||
@@ -1006,6 +1239,7 @@ class _Package extends \IPS\Node\Model
|
||||
/**
|
||||
* Determines whether this package can be converted or not.
|
||||
*
|
||||
* @param \IPS\nexus\Package $package The package we wish to convert
|
||||
* @return boolean
|
||||
*/
|
||||
public static function canConvert( \IPS\nexus\Package $package )
|
||||
@@ -1017,4 +1251,135 @@ class _Package extends \IPS\Node\Model
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update existing purchases
|
||||
*
|
||||
* @param \IPS\nexus\Purchase $purchase The purchase
|
||||
* @param array $changes The old values
|
||||
* @param bool $cancelBillingAgreementIfNecessary If making changes to renewal terms, TRUE will cancel associated billing agreements. FALSE will skip that change
|
||||
* @return void
|
||||
*/
|
||||
public function updatePurchase( \IPS\nexus\Purchase $purchase, $changes, $cancelBillingAgreementIfNecessary=FALSE )
|
||||
{
|
||||
if ( array_key_exists( 'tax', $changes ) )
|
||||
{
|
||||
if ( !$purchase->billing_agreement or $cancelBillingAgreementIfNecessary )
|
||||
{
|
||||
if ( $billingAgreement = $purchase->billing_agreement )
|
||||
{
|
||||
try
|
||||
{
|
||||
$billingAgreement->cancel();
|
||||
$billingAgreement->save();
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
}
|
||||
|
||||
$purchase->tax = $this->tax;
|
||||
$purchase->save();
|
||||
}
|
||||
}
|
||||
|
||||
if ( array_key_exists( 'renew_options', $changes ) and !empty( $changes['renew_options'] ) )
|
||||
{
|
||||
$newRenewTerms = json_decode( $this->renew_options, TRUE );
|
||||
|
||||
if( !\is_array( $newRenewTerms ) )
|
||||
{
|
||||
$newRenewTerms = array();
|
||||
}
|
||||
|
||||
switch ( $changes['renew_options']['new'] )
|
||||
{
|
||||
case 'z':
|
||||
$purchase->renewals = NULL;
|
||||
$purchase->save();
|
||||
if ( $billingAgreement = $purchase->billing_agreement )
|
||||
{
|
||||
try
|
||||
{
|
||||
$billingAgreement->cancel();
|
||||
$billingAgreement->save();
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
}
|
||||
break;
|
||||
case 'y':
|
||||
$purchase->renewals = NULL;
|
||||
$purchase->active = TRUE;
|
||||
$purchase->save();
|
||||
if ( $billingAgreement = $purchase->billing_agreement )
|
||||
{
|
||||
try
|
||||
{
|
||||
$billingAgreement->cancel();
|
||||
$billingAgreement->save();
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
}
|
||||
break;
|
||||
case 'x':
|
||||
$purchase->renewals = NULL;
|
||||
$purchase->active = FALSE;
|
||||
$purchase->save();
|
||||
if ( $billingAgreement = $purchase->billing_agreement )
|
||||
{
|
||||
try
|
||||
{
|
||||
$billingAgreement->cancel();
|
||||
$billingAgreement->save();
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
}
|
||||
break;
|
||||
case '-':
|
||||
// do nothing
|
||||
break;
|
||||
default:
|
||||
if ( $changes['renew_options']['new'] === 'o' )
|
||||
{
|
||||
if ( !$purchase->billing_agreement or $cancelBillingAgreementIfNecessary )
|
||||
{
|
||||
if ( $billingAgreement = $purchase->billing_agreement )
|
||||
{
|
||||
try
|
||||
{
|
||||
$billingAgreement->cancel();
|
||||
$billingAgreement->save();
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
}
|
||||
|
||||
|
||||
$tax = NULL;
|
||||
if ( $purchase->tax )
|
||||
{
|
||||
try
|
||||
{
|
||||
$tax = \IPS\nexus\Tax::load( $purchase->tax );
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
}
|
||||
|
||||
$currency = $purchase->renewal_currency ?: $purchase->member->defaultCurrency( );
|
||||
|
||||
$purchase->renewals = new \IPS\nexus\Purchase\RenewalTerm(
|
||||
new \IPS\nexus\Money( $newRenewTerms['cost'][ $currency ]['amount'], $currency ),
|
||||
new \DateInterval( 'P' . $newRenewTerms['term'] . mb_strtoupper( $newRenewTerms['unit'] ) ),
|
||||
$tax
|
||||
);
|
||||
$purchase->save();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( array_key_exists( 'primary_group', $changes ) or array_key_exists( 'secondary_group', $changes ) AND ( !$purchase->expire OR $purchase->expire->getTimestamp() > time() ) )
|
||||
{
|
||||
$this->_removeUsergroups( $purchase->member );
|
||||
$this->_addUsergroups( $purchase->member );
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user