не знаю, насколько это корректно, но всё работает.
в файл /applications/nexus/sources/Subscription/Subscription.php
в самый конец перед последней } вставить:
/**
* Load a subscription by member and purchase
*
* @param \IPS\Member $member Take a guess
* @param \IPS\nexus\Purchase $purchase I mean it's really writing itself
* @return \IPS\nexus\Subscription
* @throws \OutOfRangeException
*/
public static function loadByMemberAndPurchase( \IPS\Member $member, \IPS\nexus\Purchase $purchase )
{
try
{
$where = array( array( 'sub_purchase_id=? and sub_member_id=?', $purchase->id, $member->member_id ) );
return static::constructFromData( \IPS\Db::i()->select( '*', 'nexus_member_subscriptions', $where )->first() );
}
catch( \Exception $ex )
{
throw new \OutOfRangeException;
}
}
/**
* Check if the subscription expired
*
* @return bool
*/
public function isExpired() : bool
{
return $this->expire AND $this->expire < \IPS\DateTime::create()->getTimestamp();
}
/**
* Can we cancel this subscription?
*
* @return bool
*/
public function canCancel() : bool
{
return !$this->expire or $this->isExpired();
}
в файле /applications/nexus/modules/front/subscriptions/subscriptions.php
на 182 строке заменить:
if ( $current = \IPS\nexus\Subscription::loadByMember( \IPS\nexus\Customer::loggedIn(), FALSE ) AND ( $current->purchase AND ( !$current->purchase->cancelled OR $current->purchase->can_reactivate ) ) )
на:
if ( $current = \IPS\nexus\Subscription::loadByMember( \IPS\nexus\Customer::loggedIn(), FALSE ) AND ( $current->purchase AND !$current->cancelled AND ( !$current->purchase->cancelled OR $current->purchase->can_reactivate ) ) )
и в самый конец перед последней } вставить:
/**
* Cancel an expired subscription so that we can purchase another subscription
*/
public function cancel()
{
/* CSRF Check */
\IPS\Session::i()->csrfCheck();
try
{
$purchase = \IPS\nexus\Purchase::load( \IPS\Request::i()->id );
}
catch( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'nexus_no_subs_package', '2X379/8', 404, '' );
}
try
{
$subscription = \IPS\nexus\Subscription::loadByMemberAndPurchase( \IPS\Member::loggedIn(), $purchase, FALSE );
}
catch( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'nexus_no_subs_subs', '2X379/9', 404, '' );
}
if( !$subscription->canCancel() )
{
\IPS\Output::i()->error( 'no_module_permission', '1X379/A', 403, '' );
}
foreach ( \IPS\nexus\extensions\nexus\Item\Subscription::getPurchases( \IPS\nexus\Customer::loggedIn(), $subscription->package->id, TRUE, TRUE ) as $row )
{
$row->cancelled = TRUE;
$row->save();
}
$subscription->cancelled = TRUE;
$subscription->save();
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=nexus&module=subscriptions&controller=subscriptions', 'front', 'nexus_subscriptions' ), 'cancelled' );
}
в шаблон nexus/front/subscription/row
на 25 строке заменить: {{if $subscription}}
на: {{if $subscription AND !$subscription->cancelled}}
на 57 строке заменить: {{endif}}
на:
{{elseif $subscription->canCancel()}}
<li>
<a href="{url="app=nexus&module=subscriptions&controller=subscriptions&do=cancel&id={$subscription->purchase->id}" base="front" csrf="true" )"}&ref={expression="base64_encode( \IPS\Http\Url::internal( 'app=nexus&module=subscriptions&controller=subscriptions', 'front', 'nexus_subscriptions' ) )"}" class="ipsButton ipsButton_small ipsButton_link ipsButton_link--negative ipsButton_fullWidth" data-confirm ">
{lang="nexus_subs_cancel"}
</a>
</li>
{{endif}}
вроде, всё.
мб, конечно, она включается теперь где-то, что более логично, чем вырезание функции под корень, но кто знает.