Version 4.7.0
This commit is contained in:
1 parent
517a5e1f70
commit
8ba7d43898
1933 files changed
+65613
-11332
No files matched your search
@@ -0,0 +1,247 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Achievement Action Extension
|
||||
* @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/
|
||||
* @subpackage Commerce
|
||||
* @since 01 Oct 2021
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\extensions\core\AchievementAction;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Achievement Action Extension
|
||||
*/
|
||||
class _Package extends \IPS\core\Achievements\Actions\AbstractAchievementAction // NOTE: Other classes exist to provided bases for common situations, like where node-based filters will be required
|
||||
{
|
||||
/**
|
||||
* Get filter form elements
|
||||
*
|
||||
* @param array|NULL $filters Current filter values (if editing)
|
||||
* @param \IPS\Http\Url $url The URL the form is being shown on
|
||||
* @return array
|
||||
*/
|
||||
public function filters( ?array $filters, \IPS\Http\Url $url ): array
|
||||
{
|
||||
$return = array();
|
||||
|
||||
$return['nodes'] = new \IPS\Helpers\Form\Node( 'achievement_filter_Package', ( $filters and isset( $filters['nodes'] ) and $filters['nodes'] ) ? $filters['nodes'] : 0, FALSE, [
|
||||
'url' => $url,
|
||||
'class' => 'IPS\nexus\Package\Group',
|
||||
'subnodes' => FALSE,
|
||||
'showAllNodes' => TRUE,
|
||||
'multiple' => TRUE
|
||||
], NULL, \IPS\Member::loggedIn()->language()->addToStack( 'achievement_filter_Package_node_prefix', FALSE, [ 'sprintf' => [
|
||||
\IPS\Member::loggedIn()->language()->addToStack( 'nexus_sub_package_id', FALSE ),
|
||||
\IPS\Member::loggedIn()->language()->addToStack( 'purchase_groups_lc', FALSE )
|
||||
] ] ) );
|
||||
|
||||
$return['milestone'] = new \IPS\Helpers\Form\Number( 'achievement_filter_Package_nth', ( $filters and isset( $filters['milestone'] ) and $filters['milestone'] ) ? $filters['milestone'] : 0, FALSE, [], NULL, \IPS\Member::loggedIn()->language()->addToStack('achievement_filter_nth_their'), \IPS\Member::loggedIn()->language()->addToStack('achievement_filter_Package_nth_suffix') );
|
||||
$return['milestone']->label = \IPS\Member::loggedIn()->language()->addToStack('achievement_filter_NewContentItem_nth');
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format filter form values
|
||||
*
|
||||
* @param array $values The values from the form
|
||||
* @return array
|
||||
*/
|
||||
public function formatFilterValues( array $values ): array
|
||||
{
|
||||
$return = [];
|
||||
if ( isset( $values['achievement_filter_Package'] ) )
|
||||
{
|
||||
$return['nodes'] = [];
|
||||
|
||||
if ( \is_array( $values['achievement_filter_Package'] ) )
|
||||
{
|
||||
foreach ( $values['achievement_filter_Package'] as $node )
|
||||
{
|
||||
$return['nodes'][] = $node->id;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( isset( $values['achievement_filter_Package_nth'] ) )
|
||||
{
|
||||
$return['milestone'] = $values['achievement_filter_Package_nth'];
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Work out if the filters applies for a given action
|
||||
*
|
||||
* Important note for milestones: consider the context. This method is called by \IPS\Member::achievementAction(). If your code
|
||||
* calls that BEFORE making its change in the database (or there is read/write separation), you will need to add
|
||||
* 1 to the value being considered for milestones
|
||||
*
|
||||
* @param \IPS\Member $subject The subject member
|
||||
* @param array $filters The value returned by formatFilterValues()
|
||||
* @param mixed $extra Any additional information about what is happening (e.g. if a post is being made: the post object)
|
||||
* @return bool
|
||||
*/
|
||||
public function filtersMatch( \IPS\Member $subject, array $filters, $extra = NULL ): bool
|
||||
{
|
||||
if ( isset( $filters['nodes'] ) and \is_array( $filters['nodes'] ) and \count( $filters['nodes'] ) )
|
||||
{
|
||||
if ( !\in_array( $extra->item()->container()->_id, $filters['nodes'] ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $filters['milestone'] ) )
|
||||
{
|
||||
if ( \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', [ 'ps_cancelled !=1 AND ps_member=?', $subject->member_id ] )->first() < $filters['milestone'] )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get identifier to prevent the member being awarded points for the same action twice
|
||||
* Must be unique within within of this domain, must not exceed 32 chars.
|
||||
*
|
||||
* @param \IPS\Member $subject The subject member
|
||||
* @param mixed $extra Any additional information about what is happening (e.g. if a post is being made: the post object)
|
||||
* @return string
|
||||
*/
|
||||
public function identifier( \IPS\Member $subject, $extra = NULL ): string
|
||||
{
|
||||
return $extra->id . '.' . $subject->member_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a description for this action to show in the log
|
||||
*
|
||||
* @param string $identifier The identifier as returned by identifier()
|
||||
* @param array $actor If the member was the "subject", "other", or both
|
||||
* @return string
|
||||
*/
|
||||
public function logRow( string $identifier, array $actor ): string
|
||||
{
|
||||
try
|
||||
{
|
||||
list( $identifier, $memberId ) = explode( '.', $identifier );
|
||||
$package = \IPS\nexus\Package::load( $identifier );
|
||||
$sprintf = [ 'htmlsprintf' => [
|
||||
\IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $package->url(), TRUE, $package->_title, FALSE )
|
||||
] ];
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
$sprintf = [ 'sprintf' => [ \IPS\Member::loggedIn()->language()->addToStack('modcp_deleted') ] ];
|
||||
}
|
||||
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'AchievementAction__Package_log', FALSE, $sprintf );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get "description" for rule
|
||||
*
|
||||
* @param \IPS\core\Achievements\Rule $rule The rule
|
||||
* @return string|NULL
|
||||
*/
|
||||
public function ruleDescription( \IPS\core\Achievements\Rule $rule ): ?string
|
||||
{
|
||||
$conditions = [];
|
||||
if ( isset( $rule->filters['milestone'] ) )
|
||||
{
|
||||
$conditions[] = \IPS\Member::loggedIn()->language()->addToStack( 'achievements_title_filter_milestone', FALSE, [
|
||||
'htmlsprintf' => [
|
||||
\IPS\Theme::i()->getTemplate( 'achievements' )->ruleDescriptionBadge( 'milestone', \IPS\Member::loggedIn()->language()->addToStack( 'achievements_title_filter_milestone_nth', FALSE, [ 'pluralize' => [ $rule->filters['milestone'] ] ] ) )
|
||||
],
|
||||
'sprintf' => [ \IPS\Member::loggedIn()->language()->addToStack('AchievementAction__Package_title_generic') ]
|
||||
] );
|
||||
}
|
||||
|
||||
if ( $nodeCondition = $this->_nodeFilterDescription( $rule ) )
|
||||
{
|
||||
$conditions[] = $nodeCondition;
|
||||
}
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'achievements' )->ruleDescription(
|
||||
\IPS\Member::loggedIn()->language()->addToStack( 'AchievementAction__Package_title' ),
|
||||
$conditions
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get "description" for rule (usually a description of the rule's filters)
|
||||
*
|
||||
* @param \IPS\core\Achievements\Rule $rule The rule
|
||||
* @return string|NULL
|
||||
*/
|
||||
protected function _nodeFilterDescription( \IPS\core\Achievements\Rule $rule ): ?string
|
||||
{
|
||||
if ( isset( $rule->filters['nodes'] ) )
|
||||
{
|
||||
$nodeNames = [];
|
||||
foreach ( $rule->filters['nodes'] as $id )
|
||||
{
|
||||
try
|
||||
{
|
||||
$nodeNames[] = \IPS\nexus\Package\Group::load( $id )->_title;
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) {}
|
||||
}
|
||||
if ( $nodeNames )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'achievements_title_filter_location', FALSE, [
|
||||
'htmlsprintf' => [
|
||||
\IPS\Theme::i()->getTemplate( 'achievements' )->ruleDescriptionBadge( 'location',
|
||||
\count( $nodeNames ) === 1 ? $nodeNames[0] : \IPS\Member::loggedIn()->language()->addToStack( 'achievements_title_filter_location_val', FALSE, [ 'sprintf' => [
|
||||
\count( $nodeNames ),
|
||||
\IPS\Member::loggedIn()->language()->addToStack( 'purchase_groups_lc', FALSE )
|
||||
] ] ),
|
||||
\count( $nodeNames ) === 1 ? NULL : $nodeNames
|
||||
)
|
||||
],
|
||||
] );
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get rebuild data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
static public function rebuildData()
|
||||
{
|
||||
return [ [
|
||||
'table' => 'nexus_purchases',
|
||||
'pkey' => 'ps_id',
|
||||
'date' => 'ps_start',
|
||||
'where' => [ [ 'ps_cancelled != 1' ] ],
|
||||
] ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the rebuild row
|
||||
*
|
||||
* @param array $row Row from database
|
||||
* @param array $data Data collected when starting rebuild [table, pkey...]
|
||||
* @return void
|
||||
*/
|
||||
public static function rebuildRow( $row, $data )
|
||||
{
|
||||
\IPS\Member::load( $row['ps_member'] )->achievementAction( 'nexus', 'Package', \IPS\nexus\Package::load( $row['ps_item_id'] ) );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -96,7 +96,7 @@ class _Subscription extends \IPS\core\Achievements\Actions\AbstractAchievementAc
|
||||
{
|
||||
if ( isset( $filters['subscriptions'] ) )
|
||||
{
|
||||
if ( !\in_array( $extra->_id, $filters['subscriptions'] ) )
|
||||
if ( !\in_array( $extra->package_id, $filters['subscriptions'] ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -108,44 +108,21 @@ class _Subscription extends \IPS\core\Achievements\Actions\AbstractAchievementAc
|
||||
{
|
||||
try
|
||||
{
|
||||
$package = \IPS\nexus\Subscription\Package::load( $id );
|
||||
\IPS\nexus\Subscription::loadByMemberAndPackage( $subject, $package, TRUE );
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) {
|
||||
return FALSE;
|
||||
\IPS\nexus\Subscription::loadByMemberAndPackage( $subject, \IPS\nexus\Subscription\Package::load( $id ), TRUE );
|
||||
|
||||
/* Still here? */
|
||||
return TRUE;
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
}
|
||||
|
||||
/* No active matches */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the labels for the people this action might give awards to
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
// You don't need to implement this if your action only gives points to the subject
|
||||
// public function awardOptions(): array
|
||||
// {
|
||||
// return [
|
||||
// 'subject' => 'achievement_filter_Subscription_receiver',
|
||||
// 'other' => 'achievement_filter_Subscription_giver'
|
||||
// ];
|
||||
// }
|
||||
|
||||
/**
|
||||
* Get the "other" people we need to award =stuff to
|
||||
*
|
||||
* @param mixed $extra Any additional information about what is happening (e.g. if a post is being made: the post object)
|
||||
* @return array
|
||||
*/
|
||||
// You don't need to implement this if your action only gives points to the subject
|
||||
// public function awardOther( $extra = NULL ): array
|
||||
// {
|
||||
// return [ \IPS\Member::loggedIn() ];
|
||||
// }
|
||||
|
||||
/**
|
||||
* Get identifier to prevent the member being awarded points for the same action twice
|
||||
* Must be unique within within of this domain, must not exceed 32 chars.
|
||||
@@ -251,7 +228,7 @@ class _Subscription extends \IPS\core\Achievements\Actions\AbstractAchievementAc
|
||||
'table' => 'nexus_member_subscriptions',
|
||||
'pkey' => 'sub_id',
|
||||
'date' => 'sub_start',
|
||||
'where' => [ ['sub_active=?', 1 ] ],
|
||||
'where' => [],
|
||||
] ];
|
||||
}
|
||||
|
||||
@@ -264,7 +241,7 @@ class _Subscription extends \IPS\core\Achievements\Actions\AbstractAchievementAc
|
||||
*/
|
||||
public static function rebuildRow( $row, $data )
|
||||
{
|
||||
\IPS\Member::load( $row['member_id'] )->achievementAction( 'nexus', 'Subscription', \IPS\nexus\Subscription::load( $row['sub_id'] ) );
|
||||
\IPS\Member::load( $row['sub_member_id'] )->achievementAction( 'nexus', 'Subscription', \IPS\nexus\Subscription::load( $row['sub_id'] ) );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -80,7 +80,7 @@ class _SupportRequest
|
||||
$request->last_new_reply = time();
|
||||
$request->started = time();
|
||||
$request->replies = 1;
|
||||
$request->title = \IPS\Member::loggedIn()->language()->get( 'contact_nexus_title' );
|
||||
$request->title = ( $values['contact_name'] ) ? sprintf( \IPS\Member::loggedIn()->language()->get( 'contact_nexus_title_with_name' ), $values['contact_name'] ) : \IPS\Member::loggedIn()->language()->get( 'contact_nexus_title' );
|
||||
|
||||
if ( \IPS\Member::loggedIn()->member_id)
|
||||
{
|
||||
|
||||
@@ -45,6 +45,32 @@ class _Store
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can whatever is posted in this editor be moderated?
|
||||
* If this returns TRUE, we must ensure the content is ran through word, link and image filters
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @param \IPS\Helpers\Form\Editor $field The editor field
|
||||
* @return bool
|
||||
*/
|
||||
public function canBeModerated( $member, $field )
|
||||
{
|
||||
/* Creating/editing a review */
|
||||
if ( preg_match( '/^(?:editComment|review)\-nexus\/store\-\d+/', $field->options['autoSaveKey'] ) )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
/* Unknown */
|
||||
else
|
||||
{
|
||||
if ( \IPS\IN_DEV )
|
||||
{
|
||||
throw new \RuntimeException( 'Unknown canBeModerated: ' . $field->options['autoSaveKey'] );
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Permission check for attachments
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief File Storage Extension: Gateways
|
||||
* @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 Commerce
|
||||
* @since 11 May 2022
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\extensions\core\FileStorage;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* File Storage Extension: Gateways
|
||||
*/
|
||||
class _Gateways
|
||||
{
|
||||
/**
|
||||
* Count stored files
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return \IPS\Db::i()->select( 'COUNT(*)', 'nexus_paymethods', array( 'm_validationfile<>?', '' ) )->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Move stored files
|
||||
*
|
||||
* @param int $offset This will be sent starting with 0, increasing to get all files stored by this extension
|
||||
* @param int $storageConfiguration New storage configuration ID
|
||||
* @param int|NULL $oldConfiguration Old storage configuration ID
|
||||
* @throws \UnderflowException When file record doesn't exist. Indicating there are no more files to move
|
||||
* @return void|int An offset integer to use on the next cycle, or nothing
|
||||
*/
|
||||
public function move( $offset, $storageConfiguration, $oldConfiguration=NULL )
|
||||
{
|
||||
$record = \IPS\Db::i()->select( '*', 'nexus_paymethods', array( 'm_validationfile<>?', '' ), 'm_id', array( $offset, 1 ) )->first();
|
||||
|
||||
try
|
||||
{
|
||||
$file = \IPS\File::get( $oldConfiguration ?: 'nexus_Gateways', $record['m_id'] )->move( $storageConfiguration );
|
||||
|
||||
if ( (string) $file != $record['m_validationfile'] )
|
||||
{
|
||||
\IPS\Db::i()->update( 'nexus_paymethods', array( 'm_validationfile' => (string) $file ), array( 'm_id=?', $record['m_id'] ) );
|
||||
}
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
/* Any issues are logged */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a file is valid
|
||||
*
|
||||
* @param string $file The file path to check
|
||||
* @return bool
|
||||
*/
|
||||
public function isValidFile( $file )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\Db::i()->select( '*', 'nexus_paymethods', array( 'm_validationfile=?', (string) $file ) )->first();
|
||||
return TRUE;
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all stored files
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
foreach( \IPS\Db::i()->select( '*', 'nexus_paymethods', array( 'm_validationfile<>?', '' ) ) as $product )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\File::get( 'nexus_Gateways', $product['m_validationfile'] )->delete();
|
||||
}
|
||||
catch( \Exception $e ){}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,7 +42,7 @@ class _Gifts extends \IPS\core\FrontNavigation\FrontNavigationAbstract
|
||||
*/
|
||||
public static function isEnabled()
|
||||
{
|
||||
return ( ( \IPS\Settings::i()->nexus_gift_vouchers and \count( json_decode( \IPS\Settings::i()->nexus_gift_vouchers, TRUE ) ) ) or \IPS\Settings::i()->nexus_gift_vouchers_free );
|
||||
return ( ( $giftVouchers = json_decode( \IPS\Settings::i()->nexus_gift_vouchers, TRUE ) and \count( $giftVouchers ) ) or \IPS\Settings::i()->nexus_gift_vouchers_free );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Admin CP Group Form
|
||||
* @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 Commerce
|
||||
* @since 12 Oct 2021
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\extensions\core\GroupForm;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Admin CP Group Form
|
||||
*/
|
||||
class _PreventDeletion
|
||||
{
|
||||
/**
|
||||
* Process Form
|
||||
*
|
||||
* @param \IPS\Helpers\Form $form The form
|
||||
* @param \IPS\Member\Group $group Existing Group
|
||||
* @return void
|
||||
*/
|
||||
public function process( &$form, $group )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Save
|
||||
*
|
||||
* @param array $values Values from form
|
||||
* @param \IPS\Member\Group $group The group
|
||||
* @return void
|
||||
*/
|
||||
public function save( $values, &$group )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Can this group be deleted?
|
||||
*
|
||||
* @param \IPS\Member\Group $group The group
|
||||
* @return void
|
||||
*/
|
||||
public function canDelete( $group ) : bool
|
||||
{
|
||||
// Is this group used for group promotion after a product purchase?
|
||||
try
|
||||
{
|
||||
\IPS\Db::i()->select( '*', 'nexus_packages', ['p_primary_group=? OR ' . \IPS\Db::i()->findInSet('p_secondary_group', [$group->g_id] ), $group->g_id ] )->first();
|
||||
return FALSE;
|
||||
}
|
||||
catch(\UnderflowException $e )
|
||||
{
|
||||
}
|
||||
|
||||
// Is this group used for group promotion after a subscription purchase?
|
||||
try
|
||||
{
|
||||
\IPS\Db::i()->select( '*', 'nexus_member_subscription_packages', ['sp_primary_group=? OR ' . \IPS\Db::i()->findInSet('sp_secondary_group', [$group->g_id] ), $group->g_id ] )->first();
|
||||
return FALSE;
|
||||
}
|
||||
catch(\UnderflowException $e )
|
||||
{
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@@ -714,11 +714,11 @@ class _Nexus
|
||||
case 'cancelrenewals':
|
||||
try
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'nexus_history_cancelrenewals_with_name', NULL, array( 'sprintf' => array( \IPS\nexus\Subscription\Package::load( $val['id'] )->_title, $byCustomer ) ) );
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'nexus_history_cancelrenewals_with_name', FALSE, array( 'sprintf' => array( \IPS\nexus\Subscription\Package::load( $val['id'] )->_title, $byCustomer ) ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'nexus_history_cancelrenewals', NULL, array( 'sprintf' => array( $byCustomer ) ) );
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'nexus_history_cancelrenewals', FALSE, array( 'sprintf' => array( $byCustomer ) ) );
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -729,7 +729,7 @@ class _Nexus
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'nexus_history_subscription_changed', NULL, array( 'sprintf' => array( ( isset( $val['system'] ) and $val['system'] ) ? '' : $byStaff ) ) );
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'nexus_history_subscription_changed', FALSE, array( 'sprintf' => array( ( isset( $val['system'] ) and $val['system'] ) ? '' : $byStaff ) ) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Background Task
|
||||
* @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 Commerce
|
||||
* @since 22 Apr 2022
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\extensions\core\Queue;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Background Task
|
||||
*/
|
||||
class _FixMissingSubscriptionPurchases
|
||||
{
|
||||
/**
|
||||
* @brief Number of subscriptions to check per cycle
|
||||
*/
|
||||
public $batch = \IPS\REBUILD_NORMAL;
|
||||
|
||||
/**
|
||||
* Parse data before queuing
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function preQueueData( $data )
|
||||
{
|
||||
try
|
||||
{
|
||||
$data['count'] = \IPS\Db::i()->select( 'count(sub_id)', 'nexus_member_subscriptions' )->first();
|
||||
}
|
||||
catch( \UnderflowException $e )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
|
||||
if( $data['count'] == 0 )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
$data['completed'] = 0;
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run Background Task
|
||||
*
|
||||
* @param mixed $data Data as it was passed to \IPS\Task::queue()
|
||||
* @param int $offset Offset
|
||||
* @return int New offset
|
||||
* @throws \IPS\Task\Queue\OutOfRangeException Indicates offset doesn't exist and thus task is complete
|
||||
*/
|
||||
public function run( &$data, $offset )
|
||||
{
|
||||
$last = null;
|
||||
|
||||
foreach( \IPS\Db::i()->select( '*', 'nexus_member_subscriptions', [ 'sub_id>?', $offset ], NULL, $this->batch ) as $subscription )
|
||||
{
|
||||
if( $subscription['sub_purchase_id'] )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\nexus\Purchase::load( $subscription['sub_purchase_id' ] );
|
||||
|
||||
/* Nothing to do here */
|
||||
$data['completed']++;
|
||||
$last = $subscription['sub_id'];
|
||||
continue;
|
||||
}
|
||||
catch( \OutOfRangeException $e ) { }
|
||||
}
|
||||
|
||||
$package = \IPS\nexus\Subscription\Package::load( $subscription['sub_package_id'] );
|
||||
|
||||
if( !$subscription['sub_added_manually'] AND $subscription['sub_renews'] )
|
||||
{
|
||||
$term = $package->renewalTerm( \IPS\nexus\Customer::load( $subscription['sub_member_id'] )->defaultCurrency() );
|
||||
$termData = $term->getTerm();
|
||||
}
|
||||
|
||||
/* Create purchase manually - we don't want to trigger any on* methods */
|
||||
$purchaseId = \IPS\Db::i()->insert( 'nexus_purchases', [
|
||||
'ps_member' => $subscription['sub_member_id'],
|
||||
'ps_name' => \IPS\nexus\Customer::load( $subscription['sub_member_id'] )->language()->get( $package::$titleLangPrefix . $subscription['sub_package_id'] ),
|
||||
'ps_active' => $subscription['sub_active'],
|
||||
'ps_cancelled' => $subscription['sub_cancelled'],
|
||||
'ps_start' => $subscription['sub_start'],
|
||||
'ps_expire' => $subscription['sub_added_manually'] ? 0 : $subscription['sub_expire'],
|
||||
'ps_renewals' => $termData['term'] ?? 0,
|
||||
'ps_renewal_price' => $term->cost->amount ?? 0,
|
||||
'ps_renewal_unit' => $termData['unit'] ?? '',
|
||||
'ps_app' => 'nexus',
|
||||
'ps_type' => 'subscription',
|
||||
'ps_item_id' => $subscription['sub_package_id'],
|
||||
'ps_renewal_currency' => $term->cost->currency ?? '',
|
||||
'ps_original_invoice' => $subscription['sub_invoice_id'],
|
||||
'ps_tax' => isset( $term->tax ) ? $term->tax->id : 0
|
||||
]);
|
||||
|
||||
/* update sub with purchase id */
|
||||
\IPS\Db::i()->update( 'nexus_member_subscriptions', [ 'sub_purchase_id' => $purchaseId ], [ 'sub_id=?', $subscription['sub_id'] ] );
|
||||
|
||||
$data['completed']++;
|
||||
$last = $subscription['sub_id'];
|
||||
}
|
||||
|
||||
if( $last === NULL )
|
||||
{
|
||||
throw new \IPS\Task\Queue\OutOfRangeException;
|
||||
}
|
||||
|
||||
return $last;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Progress
|
||||
*
|
||||
* @param mixed $data Data as it was passed to \IPS\Task::queue()
|
||||
* @param int $offset Offset
|
||||
* @return array( 'text' => 'Doing something...', 'complete' => 50 ) Text explaining task and percentage complete
|
||||
* @throws \OutOfRangeException Indicates offset doesn't exist and thus task is complete
|
||||
*/
|
||||
public function getProgress( $data, $offset )
|
||||
{
|
||||
return array( 'text' => \IPS\Member::loggedIn()->language()->addToStack( 'nexus_queue_missing_sub_purchases' ), 'complete' => $data['count'] ? ( round( 100 / $data['count'] * $data['completed'], 2 ) ) : 100 );
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,15 @@ class _MassChangePurchases
|
||||
*/
|
||||
public function run( $data, $offset )
|
||||
{
|
||||
$package = \IPS\nexus\Package::load( $data['id'] );
|
||||
try
|
||||
{
|
||||
$package = \IPS\nexus\Package::load( $data['id'] );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Task\Queue\OutOfRangeException;
|
||||
}
|
||||
|
||||
$admin = \IPS\Member::load( $data['admin'] );
|
||||
if ( $data['cancel_type'] == 'change' )
|
||||
{
|
||||
|
||||
@@ -474,4 +474,19 @@ class _CustomPackage extends \IPS\nexus\extensions\nexus\Item\Package
|
||||
{
|
||||
return \IPS\nexus\Package::load( $this->id )->showPurchaseRecord();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for member
|
||||
* If a user initially checks out as a guest and then logs in during checkout, this method
|
||||
* is ran to check the items they are purchasing can be bought.
|
||||
* Is expected to throw a DomainException with an error message to display to the user if not valid
|
||||
*
|
||||
* @param \IPS\Member $member The new member
|
||||
* @return void
|
||||
* @throws \DomainException
|
||||
*/
|
||||
public function memberCanPurchase( \IPS\Member $member )
|
||||
{
|
||||
// Custom packages do not have any purchase restrictions
|
||||
}
|
||||
}
|
||||
@@ -422,7 +422,7 @@ class _Package extends \IPS\nexus\Invoice\Item\Purchase
|
||||
}
|
||||
}
|
||||
|
||||
$renewalTerm = new \IPS\nexus\Purchase\RenewalTerm( new \IPS\nexus\Money( $renewalAmount, $invoice->currency ), new \DateInterval( 'P' . $chosenRenewOption['term'] . mb_strtoupper( $chosenRenewOption['unit'] ) ), $package->tax ? \IPS\nexus\Tax::load( $package->tax ) : NULL );
|
||||
$renewalTerm = new \IPS\nexus\Purchase\RenewalTerm( new \IPS\nexus\Money( $renewalAmount, $invoice->currency ), new \DateInterval( 'P' . $chosenRenewOption['term'] . mb_strtoupper( $chosenRenewOption['unit'] ) ), $package->tax ? \IPS\nexus\Tax::load( $package->tax ) : NULL, FALSE,$package->grace_period ? new \DateInterval( 'P' . $package->grace_period . 'D' ) : NULL );
|
||||
|
||||
if ( $chosenRenewOption['add'] )
|
||||
{
|
||||
@@ -744,7 +744,10 @@ class _Package extends \IPS\nexus\Invoice\Item\Purchase
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\nexus\Package::load( $this->id )->onPaid( $invoice );
|
||||
$package = \IPS\nexus\Package::load( $this->id );
|
||||
$makeSureThisHappens = $package->onPaid( $invoice );
|
||||
$invoice->member->achievementAction( 'nexus', 'Package', $package );
|
||||
return $makeSureThisHappens;
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
|
||||
@@ -81,7 +81,7 @@ class _Subscription extends \IPS\nexus\Invoice\Item\Purchase
|
||||
|
||||
try
|
||||
{
|
||||
$subscription = \IPS\nexus\Subscription::loadByMemberAndPurchase( $purchase->member, $purchase );
|
||||
$subscription = \IPS\nexus\Subscription::loadByMemberAndPackage( $purchase->member, \IPS\nexus\Subscription\Package::load( $purchase->item_id ) );
|
||||
$subscription->expire = \is_object( $purchase->expire ) ? $purchase->expire->getTimestamp() : ( $purchase->expire ?: 0 );
|
||||
$subscription->save();
|
||||
}
|
||||
@@ -324,7 +324,7 @@ class _Subscription extends \IPS\nexus\Invoice\Item\Purchase
|
||||
/* Delete the subscription row */
|
||||
try
|
||||
{
|
||||
$sub = \IPS\nexus\Subscription::loadByMemberAndPackage( $purchase->member, \IPS\nexus\Subscription\Package::load( $purchase->item_id ), FALSE );
|
||||
$sub = \IPS\nexus\Subscription::load( $purchase->id, 'sub_purchase_id' );
|
||||
$sub->delete();
|
||||
}
|
||||
catch( \OutOfRangeException $e ) {}
|
||||
@@ -340,9 +340,9 @@ class _Subscription extends \IPS\nexus\Invoice\Item\Purchase
|
||||
{
|
||||
try
|
||||
{
|
||||
$subs = \IPS\nexus\Subscription::loadByMemberAndPackage( $purchase->member, \IPS\nexus\Subscription\Package::load( $purchase->item_id ), FALSE );
|
||||
$subs->active = 1;
|
||||
$subs->save();
|
||||
$sub = \IPS\nexus\Subscription::load( $purchase->id, 'sub_purchase_id' );
|
||||
$sub->active = 1;
|
||||
$sub->save();
|
||||
}
|
||||
catch( \OutOfRangeException $e ) { }
|
||||
|
||||
@@ -437,6 +437,25 @@ class _Subscription extends \IPS\nexus\Invoice\Item\Purchase
|
||||
*/
|
||||
public function requiresBillingAddress()
|
||||
{
|
||||
return TRUE;
|
||||
return \in_array( 'subscriptions', explode( ',', \IPS\Settings::i()->nexus_require_billing ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for member
|
||||
* If a user initially checks out as a guest and then logs in during checkout, this method
|
||||
* is ran to check the items they are purchasing can be bought.
|
||||
* Is expected to throw a DomainException with an error message to display to the user if not valid
|
||||
*
|
||||
* @param \IPS\Member $member The new member
|
||||
* @return void
|
||||
* @throws \DomainException
|
||||
*/
|
||||
public function memberCanPurchase( \IPS\Member $member )
|
||||
{
|
||||
/* Already purchased a subscription */
|
||||
if ( $current = \IPS\nexus\Subscription::loadByMember( $member, FALSE ) AND ( $current->purchase AND ( !$current->purchase->cancelled OR $current->purchase->can_reactivate ) ) )
|
||||
{
|
||||
throw new \DomainException( $member->language()->addToStack( 'err_sub_subscription_bought' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user