Version 5.0.0 beta 1
This commit is contained in:
1 parent
25ddeb65d6
commit
15c7beabc5
6736 files changed
+627902
-497943
No files matched your search
@@ -0,0 +1,301 @@
|
||||
<?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 16 Mar 2023
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\extensions\core\AchievementAction;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
|
||||
use IPS\core\Achievements\Actions\AchievementActionAbstract;
|
||||
use IPS\core\Achievements\Rule;
|
||||
use IPS\Db;
|
||||
use IPS\Db\Select;
|
||||
use IPS\Helpers\Form\Node;
|
||||
use IPS\Helpers\Form\Number;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Donation\Goal;
|
||||
use IPS\Theme;
|
||||
use OutOfRangeException;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
use function is_array;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ($_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0') . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Achievement Action Extension
|
||||
*/
|
||||
class Donation extends AchievementActionAbstract // 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 Url $url The URL the form is being shown on
|
||||
* @return array
|
||||
*/
|
||||
public function filters( ?array $filters, Url $url ): array
|
||||
{
|
||||
$return = array();
|
||||
|
||||
$return['nodes'] = new Node( 'achievement_filter_Donation_nodes', ( $filters and isset( $filters['nodes'] ) and $filters['nodes'] ) ? $filters['nodes'] : 0, FALSE, [
|
||||
'url' => $url,
|
||||
'class' => 'IPS\nexus\Donation\Goal',
|
||||
'showAllNodes' => TRUE,
|
||||
'multiple' => TRUE,
|
||||
], NULL, Member::loggedIn()->language()->addToStack( 'achievement_filter_NewContentItem_node_prefix', FALSE, [ 'sprintf' => [
|
||||
Member::loggedIn()->language()->addToStack( 'donation_lc', FALSE ),
|
||||
Member::loggedIn()->language()->addToStack( 'goals_sg', FALSE, [ 'strtolower' => TRUE ] )
|
||||
] ] ) );
|
||||
$return['nodes']->label = Member::loggedIn()->language()->addToStack( 'achievement_filter_NewContentItem_node', FALSE, [ 'sprintf' => [ Member::loggedIn()->language()->addToStack( 'goals_sg', FALSE, [ 'strtolower' => TRUE ] ) ] ] );
|
||||
|
||||
$return['milestone'] = new Number( 'achievement_filter_Donation_nth', ( $filters and isset( $filters['milestone'] ) and $filters['milestone'] ) ? $filters['milestone'] : 0, FALSE, [], NULL, Member::loggedIn()->language()->addToStack('achievement_filter_nth_their'), Member::loggedIn()->language()->addToStack('achievement_filter_Donation_nth_suffix') );
|
||||
$return['milestone']->label = 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_Donation_nodes'] ) )
|
||||
{
|
||||
$return['nodes'] = array_keys( $values['achievement_filter_Donation_nodes'] );
|
||||
}
|
||||
if ( isset( $values['achievement_filter_Donation_nth'] ) )
|
||||
{
|
||||
$return['milestone'] = $values['achievement_filter_Donation_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 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( Member $subject, array $filters, mixed $extra = NULL ): bool
|
||||
{
|
||||
if ( isset( $filters['nodes'] ) )
|
||||
{
|
||||
if ( !in_array( $extra->_id, $filters['nodes'] ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $filters['milestone'] ) )
|
||||
{
|
||||
$query = $this->getQuery( 'COUNT(*)', [ [ 'dl_member=?', $subject->member_id ] ], NULL, NULL, $filters );
|
||||
|
||||
if ( $query->first() + 1 < $filters['milestone'] )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the labels for the people this action might give awards to
|
||||
*
|
||||
* @param array|NULL $filters Current filter values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function awardOptions( ?array $filters ): array
|
||||
{
|
||||
return [
|
||||
'subject' => 'achievement_filter_Donation_donor',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 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( Member $subject, mixed $extra = NULL ): string
|
||||
{
|
||||
return 'Donation:' . $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
|
||||
{
|
||||
$exploded = explode( ':', $identifier );
|
||||
|
||||
try
|
||||
{
|
||||
$goal = Goal::load( $exploded[1] );
|
||||
$sprintf = [ 'htmlsprintf' => [
|
||||
Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $goal->url(), TRUE, '@todo goal title', FALSE )
|
||||
] ];
|
||||
}
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
$sprintf = [ 'sprintf' => [ Member::loggedIn()->language()->addToStack('modcp_deleted') ] ];
|
||||
}
|
||||
|
||||
return Member::loggedIn()->language()->addToStack( 'AchievementAction__Donation_log', FALSE, $sprintf );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get "description" for rule
|
||||
*
|
||||
* @param Rule $rule The rule
|
||||
* @return string|NULL
|
||||
*/
|
||||
public function ruleDescription( Rule $rule ): ?string
|
||||
{
|
||||
$conditions = [];
|
||||
if ( isset( $rule->filters['milestone'] ) )
|
||||
{
|
||||
$conditions[] = Member::loggedIn()->language()->addToStack( 'achievements_title_filter_milestone', FALSE, [
|
||||
'htmlsprintf' => [
|
||||
Theme::i()->getTemplate( 'achievements' )->ruleDescriptionBadge( 'milestone', Member::loggedIn()->language()->addToStack( 'achievements_title_filter_milestone_nth', FALSE, [ 'pluralize' => [ $rule->filters['milestone'] ] ] ) )
|
||||
],
|
||||
'sprintf' => [ Member::loggedIn()->language()->addToStack('donation_lc') ]
|
||||
] );
|
||||
}
|
||||
if ( $nodeCondition = $this->_nodeFilterDescription( $rule ) )
|
||||
{
|
||||
$conditions[] = $nodeCondition;
|
||||
}
|
||||
|
||||
return Theme::i()->getTemplate( 'achievements' )->ruleDescription(
|
||||
Member::loggedIn()->language()->addToStack( 'AchievementAction__Donation_title' ),
|
||||
$conditions
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get "description" for rule (usually a description of the rule's filters)
|
||||
*
|
||||
* @param Rule $rule The rule
|
||||
* @return string|NULL
|
||||
*/
|
||||
protected function _nodeFilterDescription( Rule $rule ): ?string
|
||||
{
|
||||
if ( isset( $rule->filters['nodes'] ) )
|
||||
{
|
||||
$nodeNames = [];
|
||||
foreach ( $rule->filters['nodes'] as $id )
|
||||
{
|
||||
try
|
||||
{
|
||||
$nodeNames[] = Goal::load( $id )->_title; //@todo
|
||||
}
|
||||
catch ( OutOfRangeException ) {}
|
||||
}
|
||||
if ( $nodeNames )
|
||||
{
|
||||
return Member::loggedIn()->language()->addToStack( 'achievements_title_filter_location', FALSE, [
|
||||
'htmlsprintf' => [
|
||||
Theme::i()->getTemplate( 'achievements' )->ruleDescriptionBadge( 'location',
|
||||
count( $nodeNames ) === 1 ? $nodeNames[0] : Member::loggedIn()->language()->addToStack( 'achievements_title_filter_location_val', FALSE, [ 'sprintf' => [
|
||||
count( $nodeNames ),
|
||||
Member::loggedIn()->language()->addToStack( 'goals', FALSE, [ 'strtolower' => TRUE ] ) //@todo
|
||||
] ] ),
|
||||
count( $nodeNames ) === 1 ? NULL : $nodeNames
|
||||
)
|
||||
],
|
||||
] );
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a query to use for multiple methods within this extension
|
||||
* @param string $select Select for the query
|
||||
* @param array|NULL $where Where for the query
|
||||
* @param int|NULL $limit Limit for the query
|
||||
* @param string|NULL $order Order by for the query
|
||||
* @param array $filters Rule filters
|
||||
* @return Select
|
||||
*/
|
||||
public function getQuery( string $select, ?array $where, ?int $limit, ?string $order, array $filters ): Select
|
||||
{
|
||||
$joinContainers = FALSE;
|
||||
$extraJoinCondition = NULL;
|
||||
$where = is_array( $where ) ? $where : array();
|
||||
|
||||
/* Limit by node */
|
||||
if ( isset( $filters['nodes'] ) )
|
||||
{
|
||||
$joinContainers = TRUE;
|
||||
$extraJoinCondition = ' AND ' . Db::i()->in( 'nexus_donate_logs.dl_goal', $filters['nodes'] );
|
||||
}
|
||||
|
||||
$query = Db::i()->select( $select, 'nexus_donate_logs', $where, $order, $limit );
|
||||
|
||||
if ( $joinContainers )
|
||||
{
|
||||
$query->join( 'nexus_donate_goals', 'nexus_donate_logs.dl_goal=nexus_donate_goals.d_id' . $extraJoinCondition, 'INNER' );
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get rebuild data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
static public function rebuildData(): array
|
||||
{
|
||||
return [ [
|
||||
'table' => 'nexus_donate_logs',
|
||||
'pkey' => 'dl_id'
|
||||
] ];
|
||||
}
|
||||
|
||||
/**
|
||||
* 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( array $row, array $data ) : void
|
||||
{
|
||||
Member::load( $row['dl_member'] )->achievementAction( 'nexus', 'Donation', [ Goal::load( $row['dl_goal'] ) ] );
|
||||
}
|
||||
}
|
||||
@@ -11,41 +11,58 @@
|
||||
namespace IPS\nexus\extensions\core\AchievementAction;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\core\Achievements\Actions\AchievementActionAbstract;
|
||||
use IPS\core\Achievements\Rule;
|
||||
use IPS\Db;
|
||||
use IPS\Helpers\Form\Node;
|
||||
use IPS\Helpers\Form\Number;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Package as NexusPackage;
|
||||
use IPS\nexus\Package\Group;
|
||||
use IPS\Theme;
|
||||
use OutOfRangeException;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
use function is_array;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_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
|
||||
class Package extends AchievementActionAbstract // 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
|
||||
* @param Url $url The URL the form is being shown on
|
||||
* @return array
|
||||
*/
|
||||
public function filters( ?array $filters, \IPS\Http\Url $url ): array
|
||||
public function filters( ?array $filters, 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, [
|
||||
$return['nodes'] = new 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 )
|
||||
], NULL, Member::loggedIn()->language()->addToStack( 'achievement_filter_Package_node_prefix', FALSE, [ 'sprintf' => [
|
||||
Member::loggedIn()->language()->addToStack( 'nexus_sub_package_id', FALSE ),
|
||||
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['milestone'] = new Number( 'achievement_filter_Package_nth', ( $filters and isset( $filters['milestone'] ) and $filters['milestone'] ) ? $filters['milestone'] : 0, FALSE, [], NULL, Member::loggedIn()->language()->addToStack('achievement_filter_nth_their'), Member::loggedIn()->language()->addToStack('achievement_filter_Package_nth_suffix') );
|
||||
$return['milestone']->label = Member::loggedIn()->language()->addToStack('achievement_filter_NewContentItem_nth');
|
||||
|
||||
return $return;
|
||||
}
|
||||
@@ -63,7 +80,7 @@ class _Package extends \IPS\core\Achievements\Actions\AbstractAchievementAction
|
||||
{
|
||||
$return['nodes'] = [];
|
||||
|
||||
if ( \is_array( $values['achievement_filter_Package'] ) )
|
||||
if ( is_array( $values['achievement_filter_Package'] ) )
|
||||
{
|
||||
foreach ( $values['achievement_filter_Package'] as $node )
|
||||
{
|
||||
@@ -85,16 +102,16 @@ class _Package extends \IPS\core\Achievements\Actions\AbstractAchievementAction
|
||||
* 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 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
|
||||
public function filtersMatch( Member $subject, array $filters, mixed $extra = NULL ): bool
|
||||
{
|
||||
if ( isset( $filters['nodes'] ) and \is_array( $filters['nodes'] ) and \count( $filters['nodes'] ) )
|
||||
if ( isset( $filters['nodes'] ) and is_array( $filters['nodes'] ) and count( $filters['nodes'] ) )
|
||||
{
|
||||
if ( !\in_array( $extra->item()->container()->_id, $filters['nodes'] ) )
|
||||
if ( !in_array( $extra->item()->container()->_id, $filters['nodes'] ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -102,7 +119,7 @@ class _Package extends \IPS\core\Achievements\Actions\AbstractAchievementAction
|
||||
|
||||
if ( isset( $filters['milestone'] ) )
|
||||
{
|
||||
if ( \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', [ 'ps_cancelled !=1 AND ps_member=?', $subject->member_id ] )->first() < $filters['milestone'] )
|
||||
if ( Db::i()->select( 'COUNT(*)', 'nexus_purchases', [ 'ps_cancelled !=1 AND ps_member=?', $subject->member_id ] )->first() < $filters['milestone'] )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -115,11 +132,11 @@ class _Package extends \IPS\core\Achievements\Actions\AbstractAchievementAction
|
||||
* 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 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
|
||||
public function identifier( Member $subject, mixed $extra = NULL ): string
|
||||
{
|
||||
return $extra->id . '.' . $subject->member_id;
|
||||
}
|
||||
@@ -136,35 +153,35 @@ class _Package extends \IPS\core\Achievements\Actions\AbstractAchievementAction
|
||||
try
|
||||
{
|
||||
list( $identifier, $memberId ) = explode( '.', $identifier );
|
||||
$package = \IPS\nexus\Package::load( $identifier );
|
||||
$package = NexusPackage::load( $identifier );
|
||||
$sprintf = [ 'htmlsprintf' => [
|
||||
\IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $package->url(), TRUE, $package->_title, FALSE )
|
||||
Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $package->url(), TRUE, $package->_title, FALSE )
|
||||
] ];
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
$sprintf = [ 'sprintf' => [ \IPS\Member::loggedIn()->language()->addToStack('modcp_deleted') ] ];
|
||||
$sprintf = [ 'sprintf' => [ Member::loggedIn()->language()->addToStack('modcp_deleted') ] ];
|
||||
}
|
||||
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'AchievementAction__Package_log', FALSE, $sprintf );
|
||||
return Member::loggedIn()->language()->addToStack( 'AchievementAction__Package_log', FALSE, $sprintf );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get "description" for rule
|
||||
*
|
||||
* @param \IPS\core\Achievements\Rule $rule The rule
|
||||
* @param Rule $rule The rule
|
||||
* @return string|NULL
|
||||
*/
|
||||
public function ruleDescription( \IPS\core\Achievements\Rule $rule ): ?string
|
||||
public function ruleDescription( Rule $rule ): ?string
|
||||
{
|
||||
$conditions = [];
|
||||
if ( isset( $rule->filters['milestone'] ) )
|
||||
{
|
||||
$conditions[] = \IPS\Member::loggedIn()->language()->addToStack( 'achievements_title_filter_milestone', FALSE, [
|
||||
$conditions[] = 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'] ] ] ) )
|
||||
Theme::i()->getTemplate( 'achievements' )->ruleDescriptionBadge( 'milestone', Member::loggedIn()->language()->addToStack( 'achievements_title_filter_milestone_nth', FALSE, [ 'pluralize' => [ $rule->filters['milestone'] ] ] ) )
|
||||
],
|
||||
'sprintf' => [ \IPS\Member::loggedIn()->language()->addToStack('AchievementAction__Package_title_generic') ]
|
||||
'sprintf' => [ Member::loggedIn()->language()->addToStack('AchievementAction__Package_title_generic') ]
|
||||
] );
|
||||
}
|
||||
|
||||
@@ -173,8 +190,8 @@ class _Package extends \IPS\core\Achievements\Actions\AbstractAchievementAction
|
||||
$conditions[] = $nodeCondition;
|
||||
}
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'achievements' )->ruleDescription(
|
||||
\IPS\Member::loggedIn()->language()->addToStack( 'AchievementAction__Package_title' ),
|
||||
return Theme::i()->getTemplate( 'achievements' )->ruleDescription(
|
||||
Member::loggedIn()->language()->addToStack( 'AchievementAction__Package_title' ),
|
||||
$conditions
|
||||
);
|
||||
}
|
||||
@@ -182,10 +199,10 @@ class _Package extends \IPS\core\Achievements\Actions\AbstractAchievementAction
|
||||
/**
|
||||
* Get "description" for rule (usually a description of the rule's filters)
|
||||
*
|
||||
* @param \IPS\core\Achievements\Rule $rule The rule
|
||||
* @param Rule $rule The rule
|
||||
* @return string|NULL
|
||||
*/
|
||||
protected function _nodeFilterDescription( \IPS\core\Achievements\Rule $rule ): ?string
|
||||
protected function _nodeFilterDescription( Rule $rule ): ?string
|
||||
{
|
||||
if ( isset( $rule->filters['nodes'] ) )
|
||||
{
|
||||
@@ -194,20 +211,20 @@ class _Package extends \IPS\core\Achievements\Actions\AbstractAchievementAction
|
||||
{
|
||||
try
|
||||
{
|
||||
$nodeNames[] = \IPS\nexus\Package\Group::load( $id )->_title;
|
||||
$nodeNames[] = Group::load( $id )->_title;
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) {}
|
||||
catch ( OutOfRangeException ) {}
|
||||
}
|
||||
if ( $nodeNames )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'achievements_title_filter_location', FALSE, [
|
||||
return 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 )
|
||||
Theme::i()->getTemplate( 'achievements' )->ruleDescriptionBadge( 'location',
|
||||
count( $nodeNames ) === 1 ? $nodeNames[0] : Member::loggedIn()->language()->addToStack( 'achievements_title_filter_location_val', FALSE, [ 'sprintf' => [
|
||||
count( $nodeNames ),
|
||||
Member::loggedIn()->language()->addToStack( 'purchase_groups_lc', FALSE )
|
||||
] ] ),
|
||||
\count( $nodeNames ) === 1 ? NULL : $nodeNames
|
||||
count( $nodeNames ) === 1 ? NULL : $nodeNames
|
||||
)
|
||||
],
|
||||
] );
|
||||
@@ -222,7 +239,7 @@ class _Package extends \IPS\core\Achievements\Actions\AbstractAchievementAction
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
static public function rebuildData()
|
||||
static public function rebuildData(): array
|
||||
{
|
||||
return [ [
|
||||
'table' => 'nexus_purchases',
|
||||
@@ -239,9 +256,9 @@ class _Package extends \IPS\core\Achievements\Actions\AbstractAchievementAction
|
||||
* @param array $data Data collected when starting rebuild [table, pkey...]
|
||||
* @return void
|
||||
*/
|
||||
public static function rebuildRow( $row, $data )
|
||||
public static function rebuildRow( array $row, array $data ) : void
|
||||
{
|
||||
\IPS\Member::load( $row['ps_member'] )->achievementAction( 'nexus', 'Package', \IPS\nexus\Package::load( $row['ps_item_id'] ) );
|
||||
Member::load( $row['ps_member'] )->achievementAction( 'nexus', 'Package', NexusPackage::load( $row['ps_item_id'] ) );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,16 +11,32 @@
|
||||
namespace IPS\nexus\extensions\core\AchievementAction;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\core\Achievements\Actions\AchievementActionAbstract;
|
||||
use IPS\core\Achievements\Rule;
|
||||
use IPS\Helpers\Form\Node;
|
||||
use IPS\Helpers\Form\YesNo;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Subscription as NexusSubscription;
|
||||
use IPS\nexus\Subscription\Package;
|
||||
use IPS\Settings;
|
||||
use IPS\Theme;
|
||||
use OutOfRangeException;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Achievement Action Extension
|
||||
*/
|
||||
class _Subscription extends \IPS\core\Achievements\Actions\AbstractAchievementAction // NOTE: Other classes exist to provided bases for common situations, like where node-based filters will be required
|
||||
class Subscription extends AchievementActionAbstract // NOTE: Other classes exist to provided bases for common situations, like where node-based filters will be required
|
||||
{
|
||||
/**
|
||||
* Can use this rule?
|
||||
@@ -29,32 +45,32 @@ class _Subscription extends \IPS\core\Achievements\Actions\AbstractAchievementAc
|
||||
*/
|
||||
public function canUse(): bool
|
||||
{
|
||||
return (bool) parent::canUse() and \IPS\Settings::i()->nexus_subs_enabled;
|
||||
return parent::canUse() and Settings::i()->nexus_subs_enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param Url $url The URL the form is being shown on
|
||||
* @return array
|
||||
*/
|
||||
public function filters( ?array $filters, \IPS\Http\Url $url ): array
|
||||
public function filters( ?array $filters, Url $url ): array
|
||||
{
|
||||
$return = array();
|
||||
|
||||
$return['subscriptions'] = new \IPS\Helpers\Form\Node( 'achievement_filter_Subscriptions', ( $filters and isset( $filters['subscriptions'] ) and $filters['subscriptions'] ) ? $filters['subscriptions'] : 0, FALSE, [
|
||||
$return['subscriptions'] = new Node( 'achievement_filter_Subscriptions', ( $filters and isset( $filters['subscriptions'] ) and $filters['subscriptions'] ) ? $filters['subscriptions'] : 0, FALSE, [
|
||||
'url' => $url,
|
||||
'class' => 'IPS\nexus\Subscription\Package',
|
||||
'showAllNodes' => TRUE,
|
||||
'multiple' => TRUE,
|
||||
], NULL, \IPS\Member::loggedIn()->language()->addToStack( 'achievement_filter_Subscriptions_node_prefix', FALSE, [ 'sprintf' => [
|
||||
\IPS\Member::loggedIn()->language()->addToStack( 'nexus_sub_package_id', FALSE ),
|
||||
\IPS\Member::loggedIn()->language()->addToStack( 'calendars_sg', FALSE, [ 'strtolower' => TRUE ] )
|
||||
], NULL, Member::loggedIn()->language()->addToStack( 'achievement_filter_Subscriptions_node_prefix', FALSE, [ 'sprintf' => [
|
||||
Member::loggedIn()->language()->addToStack( 'nexus_sub_package_id', FALSE ),
|
||||
Member::loggedIn()->language()->addToStack( 'calendars_sg', FALSE, [ 'strtolower' => TRUE ] )
|
||||
] ] ) );
|
||||
|
||||
$return['subscriptions_active'] = new \IPS\Helpers\Form\YesNo( 'achievement_filter_Subscriptions_active', $filters and isset( $filters['subscriptions_active'] ) and $filters['subscriptions_active'], FALSE, [],NULL,
|
||||
\IPS\Member::loggedIn()->language()->addToStack( 'nexus_sub_active', FALSE )
|
||||
$return['subscriptions_active'] = new YesNo( 'achievement_filter_Subscriptions_active', $filters and isset( $filters['subscriptions_active'] ) and $filters['subscriptions_active'], FALSE, [],NULL,
|
||||
Member::loggedIn()->language()->addToStack( 'nexus_sub_active', FALSE )
|
||||
);
|
||||
|
||||
return $return;
|
||||
@@ -87,16 +103,16 @@ class _Subscription extends \IPS\core\Achievements\Actions\AbstractAchievementAc
|
||||
* 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 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
|
||||
public function filtersMatch( Member $subject, array $filters, mixed $extra = NULL ): bool
|
||||
{
|
||||
if ( isset( $filters['subscriptions'] ) )
|
||||
{
|
||||
if ( !\in_array( $extra->package_id, $filters['subscriptions'] ) )
|
||||
if ( !in_array( $extra->package_id, $filters['subscriptions'] ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -108,12 +124,12 @@ class _Subscription extends \IPS\core\Achievements\Actions\AbstractAchievementAc
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\nexus\Subscription::loadByMemberAndPackage( $subject, \IPS\nexus\Subscription\Package::load( $id ), TRUE );
|
||||
NexusSubscription::loadByMemberAndPackage( $subject, Package::load( $id ), TRUE );
|
||||
|
||||
/* Still here? */
|
||||
return TRUE;
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
catch ( OutOfRangeException ) { }
|
||||
}
|
||||
|
||||
/* No active matches */
|
||||
@@ -127,11 +143,11 @@ class _Subscription extends \IPS\core\Achievements\Actions\AbstractAchievementAc
|
||||
* 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 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
|
||||
public function identifier( Member $subject, mixed $extra = NULL ): string
|
||||
{
|
||||
return (string) $extra->id;
|
||||
}
|
||||
@@ -151,20 +167,20 @@ class _Subscription extends \IPS\core\Achievements\Actions\AbstractAchievementAc
|
||||
/**
|
||||
* Get "description" for rule
|
||||
*
|
||||
* @param \IPS\core\Achievements\Rule $rule The rule
|
||||
* @param Rule $rule The rule
|
||||
* @return string|NULL
|
||||
*/
|
||||
public function ruleDescription( \IPS\core\Achievements\Rule $rule ): ?string
|
||||
public function ruleDescription( Rule $rule ): ?string
|
||||
{
|
||||
$conditions = [];
|
||||
|
||||
if ( isset( $rule->filters['subscriptions_active'] ) AND $rule->filters['subscriptions_active'] )
|
||||
{
|
||||
$conditions[] = \IPS\Member::loggedIn()->language()->addToStack( 'achievement_filter_Subscriptions_active');
|
||||
$conditions[] = Member::loggedIn()->language()->addToStack( 'achievement_filter_Subscriptions_active');
|
||||
}
|
||||
else
|
||||
{
|
||||
$conditions[] = \IPS\Member::loggedIn()->language()->addToStack( 'achievement_filter_Subscriptions_node_prefix');
|
||||
$conditions[] = Member::loggedIn()->language()->addToStack( 'achievement_filter_Subscriptions_node_prefix');
|
||||
}
|
||||
|
||||
if ( $nodeCondition = $this->_nodeFilterDescription( $rule ) )
|
||||
@@ -172,8 +188,8 @@ class _Subscription extends \IPS\core\Achievements\Actions\AbstractAchievementAc
|
||||
$conditions[] = $nodeCondition;
|
||||
}
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'achievements' )->ruleDescription(
|
||||
\IPS\Member::loggedIn()->language()->addToStack( 'AchievementAction__Subscription_title' ),
|
||||
return Theme::i()->getTemplate( 'achievements' )->ruleDescription(
|
||||
Member::loggedIn()->language()->addToStack( 'AchievementAction__Subscription_title' ),
|
||||
$conditions
|
||||
);
|
||||
}
|
||||
@@ -181,10 +197,10 @@ class _Subscription extends \IPS\core\Achievements\Actions\AbstractAchievementAc
|
||||
/**
|
||||
* Get "description" for rule (usually a description of the rule's filters)
|
||||
*
|
||||
* @param \IPS\core\Achievements\Rule $rule The rule
|
||||
* @param Rule $rule The rule
|
||||
* @return string|NULL
|
||||
*/
|
||||
protected function _nodeFilterDescription( \IPS\core\Achievements\Rule $rule ): ?string
|
||||
protected function _nodeFilterDescription( Rule $rule ): ?string
|
||||
{
|
||||
if ( isset( $rule->filters['subscriptions'] ) )
|
||||
{
|
||||
@@ -193,21 +209,21 @@ class _Subscription extends \IPS\core\Achievements\Actions\AbstractAchievementAc
|
||||
{
|
||||
try
|
||||
{
|
||||
$nodeNames[] = \IPS\nexus\Subscription\Package::load( $id )->_title;
|
||||
$nodeNames[] = Package::load( $id )->_title;
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) {}
|
||||
catch ( OutOfRangeException ) {}
|
||||
}
|
||||
|
||||
if ( $nodeNames )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'achievements_filter_Subscription_type', FALSE, [
|
||||
return Member::loggedIn()->language()->addToStack( 'achievements_filter_Subscription_type', FALSE, [
|
||||
'htmlsprintf' => [
|
||||
\IPS\Theme::i()->getTemplate( 'achievements' )->ruleDescriptionBadge( 'achievements_filter_Subscription_type',
|
||||
\count( $nodeNames ) === 1 ? $nodeNames[0] : \IPS\Member::loggedIn()->language()->addToStack( 'achievements_filter_Subscription_pl', FALSE, [ 'sprintf' => [
|
||||
\count( $nodeNames ),
|
||||
\IPS\Member::loggedIn()->language()->addToStack( 'nexus_sub_package_id', FALSE, [ 'strtolower' => TRUE ] )
|
||||
Theme::i()->getTemplate( 'achievements' )->ruleDescriptionBadge( 'achievements_filter_Subscription_type',
|
||||
count( $nodeNames ) === 1 ? $nodeNames[0] : Member::loggedIn()->language()->addToStack( 'achievements_filter_Subscription_pl', FALSE, [ 'sprintf' => [
|
||||
count( $nodeNames ),
|
||||
Member::loggedIn()->language()->addToStack( 'nexus_sub_package_id', FALSE, [ 'strtolower' => TRUE ] )
|
||||
] ] ),
|
||||
\count( $nodeNames ) === 1 ? NULL : $nodeNames
|
||||
count( $nodeNames ) === 1 ? NULL : $nodeNames
|
||||
)
|
||||
],
|
||||
] );
|
||||
@@ -222,7 +238,7 @@ class _Subscription extends \IPS\core\Achievements\Actions\AbstractAchievementAc
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
static public function rebuildData()
|
||||
static public function rebuildData(): array
|
||||
{
|
||||
return [ [
|
||||
'table' => 'nexus_member_subscriptions',
|
||||
@@ -239,9 +255,9 @@ class _Subscription extends \IPS\core\Achievements\Actions\AbstractAchievementAc
|
||||
* @param array $data Data collected when starting rebuild [table, pkey...]
|
||||
* @return void
|
||||
*/
|
||||
public static function rebuildRow( $row, $data )
|
||||
public static function rebuildRow( array $row, array $data ) : void
|
||||
{
|
||||
\IPS\Member::load( $row['sub_member_id'] )->achievementAction( 'nexus', 'Subscription', \IPS\nexus\Subscription::load( $row['sub_id'] ) );
|
||||
Member::load( $row['sub_member_id'] )->achievementAction( 'nexus', 'Subscription', NexusSubscription::load( $row['sub_id'] ) );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,38 +11,48 @@
|
||||
namespace IPS\nexus\extensions\core\AdminNotifications;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\core\AdminNotification;
|
||||
use IPS\core\modules\admin\promotion\advertisements;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use UnderflowException;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* ACP Notification: Advertisements Requiring Approval
|
||||
*/
|
||||
class _Advertisement extends \IPS\core\AdminNotification
|
||||
class Advertisement extends AdminNotification
|
||||
{
|
||||
/**
|
||||
* @brief Identifier for what to group this notification type with on the settings form
|
||||
*/
|
||||
public static $group = 'commerce';
|
||||
public static string $group = 'commerce';
|
||||
|
||||
/**
|
||||
* @brief Priority 1-5 (1 being highest) for this group compared to others
|
||||
*/
|
||||
public static $groupPriority = 4;
|
||||
public static int $groupPriority = 4;
|
||||
|
||||
/**
|
||||
* @brief Priority 1-5 (1 being highest) for this notification type compared to others in the same group
|
||||
*/
|
||||
public static $itemPriority = 4;
|
||||
public static int $itemPriority = 4;
|
||||
|
||||
/**
|
||||
* Title for settings
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function settingsTitle()
|
||||
public static function settingsTitle(): string
|
||||
{
|
||||
return 'acp_notification_Advertisement';
|
||||
}
|
||||
@@ -50,9 +60,9 @@ class _Advertisement extends \IPS\core\AdminNotification
|
||||
/**
|
||||
* Is this type of notification ever optional (controls if it will be selectable as "viewable" in settings)
|
||||
*
|
||||
* @return string
|
||||
* @return bool
|
||||
*/
|
||||
public static function mayBeOptional()
|
||||
public static function mayBeOptional(): bool
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@@ -62,7 +72,7 @@ class _Advertisement extends \IPS\core\AdminNotification
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function mayRecur()
|
||||
public static function mayRecur(): bool
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@@ -70,18 +80,18 @@ class _Advertisement extends \IPS\core\AdminNotification
|
||||
/**
|
||||
* @brief Current count
|
||||
*/
|
||||
protected $count = NULL;
|
||||
protected ?int $count = NULL;
|
||||
|
||||
/**
|
||||
* Get count
|
||||
*
|
||||
* @return bool
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
public function count(): int
|
||||
{
|
||||
if ( $this->count === NULL )
|
||||
{
|
||||
$this->count = \IPS\Db::i()->select( 'COUNT(*)', 'core_advertisements', array( 'ad_active=-1' ) )->first();
|
||||
$this->count = Db::i()->select( 'COUNT(*)', 'core_advertisements', array( 'ad_active=-1' ) )->first();
|
||||
}
|
||||
return $this->count;
|
||||
}
|
||||
@@ -89,12 +99,12 @@ class _Advertisement extends \IPS\core\AdminNotification
|
||||
/**
|
||||
* Can a member access this type of notification?
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @param Member $member The member
|
||||
* @return bool
|
||||
*/
|
||||
public static function permissionCheck( \IPS\Member $member )
|
||||
public static function permissionCheck( Member $member ): bool
|
||||
{
|
||||
return $member->hasAcpRestriction( 'core', 'promotion', 'advertisements_manage' ) and \IPS\Db::i()->select( 'COUNT(*)', 'nexus_packages_ads' )->first();
|
||||
return $member->hasAcpRestriction( 'core', 'promotion', 'advertisements_manage' ) and Db::i()->select( 'COUNT(*)', 'nexus_packages_ads' )->first();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -102,23 +112,23 @@ class _Advertisement extends \IPS\core\AdminNotification
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function title()
|
||||
public function title(): string
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'acpNotification_nexusAdvertisements', FALSE, array( 'pluralize' => array( $this->count() ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'acpNotification_nexusAdvertisements', FALSE, array( 'pluralize' => array( $this->count() ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification Subtitle (no HTML)
|
||||
*
|
||||
* @return string
|
||||
* @return string|null
|
||||
*/
|
||||
public function subtitle()
|
||||
public function subtitle(): ?string
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\DateTime::ts( \IPS\Db::i()->select( 'ad_start', 'core_advertisements', array( 'ad_active=-1' ), 'ad_start asc', 1 )->first() )->relative();
|
||||
return DateTime::ts( Db::i()->select( 'ad_start', 'core_advertisements', array( 'ad_active=-1' ), 'ad_start asc', 1 )->first() )->relative();
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
catch ( UnderflowException )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -127,15 +137,15 @@ class _Advertisement extends \IPS\core\AdminNotification
|
||||
/**
|
||||
* Notification Body (full HTML, must be escaped where necessary)
|
||||
*
|
||||
* @return string
|
||||
* @return string|null
|
||||
*/
|
||||
public function body()
|
||||
public function body(): ?string
|
||||
{
|
||||
$table = \IPS\core\modules\admin\promotion\advertisements::table( \IPS\Http\Url::internal('app=core&module=overview&controller=notifications&_table=nexus_Advertisement') );
|
||||
$table = advertisements::table( Url::internal('app=core&module=overview&controller=notifications&_table=nexus_Advertisement') );
|
||||
$table->limit = 10;
|
||||
$table->filters = array();
|
||||
$table->quickSearch = NULL;
|
||||
$table->advancedSearch = NULL;
|
||||
$table->advancedSearch = [];
|
||||
$table->where[] = array( 'ad_active=-1' );
|
||||
|
||||
return (string) $table;
|
||||
@@ -146,7 +156,7 @@ class _Advertisement extends \IPS\core\AdminNotification
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function severity()
|
||||
public function severity(): string
|
||||
{
|
||||
return static::SEVERITY_OPTIONAL;
|
||||
}
|
||||
@@ -156,7 +166,7 @@ class _Advertisement extends \IPS\core\AdminNotification
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function dismissible()
|
||||
public function dismissible(): string
|
||||
{
|
||||
return static::DISMISSIBLE_NO;
|
||||
}
|
||||
@@ -164,9 +174,9 @@ class _Advertisement extends \IPS\core\AdminNotification
|
||||
/**
|
||||
* Style
|
||||
*
|
||||
* @return bool
|
||||
* @return string
|
||||
*/
|
||||
public function style()
|
||||
public function style(): string
|
||||
{
|
||||
return static::STYLE_INFORMATION;
|
||||
}
|
||||
@@ -174,11 +184,11 @@ class _Advertisement extends \IPS\core\AdminNotification
|
||||
/**
|
||||
* Quick link from popup menu
|
||||
*
|
||||
* @return bool
|
||||
* @return Url
|
||||
*/
|
||||
public function link()
|
||||
public function link(): Url
|
||||
{
|
||||
return \IPS\Http\Url::internal('app=core&module=promotion&controller=advertisements&filter=ad_filters_pending');
|
||||
return Url::internal('app=core&module=promotion&controller=advertisements&filter=ad_filters_pending');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -187,7 +197,7 @@ class _Advertisement extends \IPS\core\AdminNotification
|
||||
* @note This is checked every time the notification shows. Should be lightweight.
|
||||
* @return bool
|
||||
*/
|
||||
public function selfDismiss()
|
||||
public function selfDismiss(): bool
|
||||
{
|
||||
return !$this->count();
|
||||
}
|
||||
|
||||
@@ -11,38 +11,49 @@
|
||||
namespace IPS\nexus\extensions\core\AdminNotifications;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\core\AdminNotification;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Gateway;
|
||||
use IPS\Theme;
|
||||
use OutOfRangeException;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function substr;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* ACP Notification Extension
|
||||
*/
|
||||
class _ConfigurationError extends \IPS\core\AdminNotification
|
||||
class ConfigurationError extends AdminNotification
|
||||
{
|
||||
/**
|
||||
* @brief Identifier for what to group this notification type with on the settings form
|
||||
*/
|
||||
public static $group = 'commerce';
|
||||
public static string $group = 'commerce';
|
||||
|
||||
/**
|
||||
* @brief Priority 1-5 (1 being highest) for this group compared to others
|
||||
*/
|
||||
public static $groupPriority = 4;
|
||||
public static int $groupPriority = 4;
|
||||
|
||||
/**
|
||||
* @brief Priority 1-5 (1 being highest) for this notification type compared to others in the same group
|
||||
*/
|
||||
public static $itemPriority = 5;
|
||||
public static int $itemPriority = 5;
|
||||
|
||||
/**
|
||||
* Title for settings
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function settingsTitle()
|
||||
public static function settingsTitle(): string
|
||||
{
|
||||
return 'acp_notification_ConfigurationError';
|
||||
}
|
||||
@@ -50,10 +61,10 @@ class _ConfigurationError extends \IPS\core\AdminNotification
|
||||
/**
|
||||
* Can a member access this type of notification?
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @param Member $member The member
|
||||
* @return bool
|
||||
*/
|
||||
public static function permissionCheck( \IPS\Member $member )
|
||||
public static function permissionCheck( Member $member ): bool
|
||||
{
|
||||
return $member->hasAcpRestriction( 'nexus', 'payments', 'gateways_manage' );
|
||||
}
|
||||
@@ -61,9 +72,9 @@ class _ConfigurationError extends \IPS\core\AdminNotification
|
||||
/**
|
||||
* Is this type of notification ever optional (controls if it will be selectable as "viewable" in settings)
|
||||
*
|
||||
* @return string
|
||||
* @return bool
|
||||
*/
|
||||
public static function mayBeOptional()
|
||||
public static function mayBeOptional(): bool
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@@ -73,7 +84,7 @@ class _ConfigurationError extends \IPS\core\AdminNotification
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function mayRecur()
|
||||
public static function mayRecur(): bool
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@@ -83,64 +94,62 @@ class _ConfigurationError extends \IPS\core\AdminNotification
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function title()
|
||||
public function title(): string
|
||||
{
|
||||
if( mb_substr( $this->extra, 0, 2 ) === 'pm' )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('acp_notification_nexus_config_error_paymethod');
|
||||
return Member::loggedIn()->language()->addToStack('acp_notification_nexus_config_error_paymethod');
|
||||
}
|
||||
elseif( mb_substr( $this->extra, 0, 2 ) === 'po' )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'acp_notification_nexus_config_error_payoutmethod' );
|
||||
return Member::loggedIn()->language()->addToStack( 'acp_notification_nexus_config_error_payoutmethod' );
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'acpNotification_nexusBACancelErrors', FALSE, array( 'pluralize' => array( \count( json_decode( $this->extra, TRUE ) ) ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'acpNotification_nexusBACancelErrors', FALSE, array( 'pluralize' => array( count( json_decode( $this->extra, TRUE ) ) ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification Subtitle (no HTML)
|
||||
*
|
||||
* @return string
|
||||
* @return string|null
|
||||
*/
|
||||
public function subtitle()
|
||||
public function subtitle(): ?string
|
||||
{
|
||||
if( mb_substr( $this->extra, 0, 2 ) === 'pm' )
|
||||
{
|
||||
try
|
||||
{
|
||||
$method = \IPS\nexus\Gateway::load( \substr( $this->extra, 2 ) );
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'acp_notification_nexus_config_error_paymethod_desc', FALSE, array( 'sprintf' => array( $method->_title ) ) );
|
||||
$method = Gateway::load( substr( $this->extra, 2 ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'acp_notification_nexus_config_error_paymethod_desc', FALSE, array( 'sprintf' => array( $method->_title ) ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
catch ( OutOfRangeException ) { }
|
||||
}
|
||||
elseif( mb_substr( $this->extra, 0, 2 ) === 'po' )
|
||||
{
|
||||
$gateway = mb_substr( $this->extra, 2 );
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'acp_notification_nexus_config_error_payoutmethod_desc', FALSE, array( 'sprintf' => array( $gateway ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return '';
|
||||
return Member::loggedIn()->language()->addToStack( 'acp_notification_nexus_config_error_payoutmethod_desc', FALSE, array( 'sprintf' => array( $gateway ) ) );
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification Body (full HTML, must be escaped where necessary)
|
||||
*
|
||||
* @return string
|
||||
* @return string|null
|
||||
*/
|
||||
public function body()
|
||||
public function body(): ?string
|
||||
{
|
||||
if( mb_substr( $this->extra, 0, 2 ) === 'pm' )
|
||||
{
|
||||
try
|
||||
{
|
||||
$method = \IPS\nexus\Gateway::load( \substr( $this->extra, 2 ) );
|
||||
return \IPS\Theme::i()->getTemplate( 'notifications', 'nexus', 'admin' )->paymentMethodError( $method );
|
||||
$method = Gateway::load( substr( $this->extra, 2 ) );
|
||||
return Theme::i()->getTemplate( 'notifications', 'nexus', 'admin' )->paymentMethodError( $method );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
return '';
|
||||
}
|
||||
@@ -148,11 +157,11 @@ class _ConfigurationError extends \IPS\core\AdminNotification
|
||||
elseif( mb_substr( $this->extra, 0, 2 ) === 'po' )
|
||||
{
|
||||
$gateway = mb_substr( $this->extra, 2 );
|
||||
return \IPS\Theme::i()->getTemplate( 'notifications', 'nexus', 'admin' )->payoutSettingsError( $gateway );
|
||||
return Theme::i()->getTemplate( 'notifications', 'nexus', 'admin' )->payoutSettingsError( $gateway );
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'notifications', 'nexus', 'admin' )->baCancellationError( json_decode( $this->extra, TRUE ) );
|
||||
return Theme::i()->getTemplate( 'notifications', 'nexus', 'admin' )->baCancellationError( json_decode( $this->extra, TRUE ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,7 +170,7 @@ class _ConfigurationError extends \IPS\core\AdminNotification
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function severity()
|
||||
public function severity(): string
|
||||
{
|
||||
return ( mb_substr( $this->extra, 0, 2 ) === 'pm' OR mb_substr( $this->extra, 0, 2 ) === 'po' ) ? static::SEVERITY_CRITICAL : static::SEVERITY_OPTIONAL;
|
||||
}
|
||||
@@ -171,7 +180,7 @@ class _ConfigurationError extends \IPS\core\AdminNotification
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function dismissible()
|
||||
public function dismissible(): string
|
||||
{
|
||||
return ( mb_substr( $this->extra, 0, 2 ) === 'pm' OR mb_substr( $this->extra, 0, 2 ) === 'po' ) ? static::DISMISSIBLE_NO : static::DISMISSIBLE_PERMANENT;
|
||||
}
|
||||
@@ -182,16 +191,16 @@ class _ConfigurationError extends \IPS\core\AdminNotification
|
||||
* @note This is checked every time the notification shows. Should be lightweight.
|
||||
* @return bool
|
||||
*/
|
||||
public function selfDismiss()
|
||||
public function selfDismiss(): bool
|
||||
{
|
||||
if( mb_substr( $this->extra, 0, 2 ) === 'pm' )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\nexus\Gateway::load( \substr( $this->extra, 2 ) );
|
||||
Gateway::load( substr( $this->extra, 2 ) );
|
||||
return FALSE;
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
catch( OutOfRangeException )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@@ -205,9 +214,9 @@ class _ConfigurationError extends \IPS\core\AdminNotification
|
||||
/**
|
||||
* Style
|
||||
*
|
||||
* @return bool
|
||||
* @return string
|
||||
*/
|
||||
public function style()
|
||||
public function style(): string
|
||||
{
|
||||
return ( mb_substr( $this->extra, 0, 2 ) === 'pm' OR mb_substr( $this->extra, 0, 2 ) === 'po' ) ? static::STYLE_ERROR : static::STYLE_WARNING;
|
||||
}
|
||||
@@ -215,19 +224,19 @@ class _ConfigurationError extends \IPS\core\AdminNotification
|
||||
/**
|
||||
* Quick link from popup menu
|
||||
*
|
||||
* @return \IPS\Http\Url
|
||||
* @return Url|null
|
||||
*/
|
||||
public function link()
|
||||
public function link(): Url|null
|
||||
{
|
||||
if( mb_substr( $this->extra, 0, 2 ) === 'pm' )
|
||||
{
|
||||
return \IPS\Http\Url::internal( 'app=nexus&module=payments&controller=paymentsettings&tab=gateways&do=form&id=' . \substr( $this->extra, 2 ) );
|
||||
return Url::internal( 'app=nexus&module=payments&controller=paymentsettings&tab=gateways&do=form&id=' . substr( $this->extra, 2 ) );
|
||||
}
|
||||
elseif( mb_substr( $this->extra, 0, 2 ) === 'po' )
|
||||
{
|
||||
return \IPS\Http\Url::internal( 'app=nexus&module=payments&controller=payouts&do=settings' );
|
||||
return Url::internal( 'app=nexus&module=payments&controller=payouts&do=settings' );
|
||||
}
|
||||
|
||||
parent::link();
|
||||
return parent::link();
|
||||
}
|
||||
}
|
||||
@@ -11,38 +11,45 @@
|
||||
namespace IPS\nexus\extensions\core\AdminNotifications;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\core\AdminNotification;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\Theme;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* ACP Notification Extension
|
||||
*/
|
||||
class _Maxmind extends \IPS\core\AdminNotification
|
||||
class Maxmind extends AdminNotification
|
||||
{
|
||||
/**
|
||||
* @brief Identifier for what to group this notification type with on the settings form
|
||||
*/
|
||||
public static $group = 'commerce';
|
||||
public static string $group = 'commerce';
|
||||
|
||||
/**
|
||||
* @brief Priority 1-5 (1 being highest) for this group compared to others
|
||||
*/
|
||||
public static $groupPriority = 3;
|
||||
public static int $groupPriority = 3;
|
||||
|
||||
/**
|
||||
* @brief Priority 1-5 (1 being highest) for this notification type compared to others in the same group
|
||||
*/
|
||||
public static $itemPriority = 1;
|
||||
public static int $itemPriority = 1;
|
||||
|
||||
/**
|
||||
* Title for settings
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function settingsTitle()
|
||||
public static function settingsTitle(): string
|
||||
{
|
||||
return 'acp_notification_Maxmind';
|
||||
}
|
||||
@@ -50,10 +57,10 @@ class _Maxmind extends \IPS\core\AdminNotification
|
||||
/**
|
||||
* Can a member access this type of notification?
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @param Member $member The member
|
||||
* @return bool
|
||||
*/
|
||||
public static function permissionCheck( \IPS\Member $member )
|
||||
public static function permissionCheck( Member $member ): bool
|
||||
{
|
||||
return true;// $member->hasAcpRestriction( ... );
|
||||
}
|
||||
@@ -61,9 +68,9 @@ class _Maxmind extends \IPS\core\AdminNotification
|
||||
/**
|
||||
* Is this type of notification ever optional (controls if it will be selectable as "viewable" in settings)
|
||||
*
|
||||
* @return string
|
||||
* @return bool
|
||||
*/
|
||||
public static function mayBeOptional()
|
||||
public static function mayBeOptional(): bool
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -73,7 +80,7 @@ class _Maxmind extends \IPS\core\AdminNotification
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function mayRecur()
|
||||
public static function mayRecur(): bool
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -83,29 +90,29 @@ class _Maxmind extends \IPS\core\AdminNotification
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function title()
|
||||
public function title(): string
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('acp_notification_nexus_maxmind');
|
||||
return Member::loggedIn()->language()->addToStack('acp_notification_nexus_maxmind');
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification Subtitle (no HTML)
|
||||
*
|
||||
* @return string
|
||||
* @return string|null
|
||||
*/
|
||||
public function subtitle()
|
||||
public function subtitle(): ?string
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'acp_notification_nexus_maxmind_sub', FALSE );
|
||||
return Member::loggedIn()->language()->addToStack( 'acp_notification_nexus_maxmind_sub', FALSE );
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification Body (full HTML, must be escaped where necessary)
|
||||
*
|
||||
* @return string
|
||||
* @return string|null
|
||||
*/
|
||||
public function body()
|
||||
public function body(): ?string
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'notifications', 'nexus', 'admin' )->maxmind();
|
||||
return Theme::i()->getTemplate( 'notifications', 'nexus', 'admin' )->maxmind();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,7 +120,7 @@ class _Maxmind extends \IPS\core\AdminNotification
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function severity()
|
||||
public function severity(): string
|
||||
{
|
||||
return static::SEVERITY_HIGH;
|
||||
}
|
||||
@@ -123,7 +130,7 @@ class _Maxmind extends \IPS\core\AdminNotification
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function dismissible()
|
||||
public function dismissible(): string
|
||||
{
|
||||
return static::DISMISSIBLE_TEMPORARY;
|
||||
}
|
||||
@@ -131,9 +138,9 @@ class _Maxmind extends \IPS\core\AdminNotification
|
||||
/**
|
||||
* Style
|
||||
*
|
||||
* @return bool
|
||||
* @return string
|
||||
*/
|
||||
public function style()
|
||||
public function style(): string
|
||||
{
|
||||
return static::STYLE_ERROR;
|
||||
}
|
||||
@@ -141,9 +148,9 @@ class _Maxmind extends \IPS\core\AdminNotification
|
||||
/**
|
||||
* Quick link from popup menu
|
||||
*
|
||||
* @return \IPS\Http\Url
|
||||
* @return Url|null
|
||||
*/
|
||||
public function link()
|
||||
public function link(): Url|null
|
||||
{
|
||||
return parent::link(); // \IPS\Http\Url::internal( '...' );
|
||||
}
|
||||
|
||||
@@ -1,194 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief ACP Notification: Pending Shipping Orders
|
||||
* @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
|
||||
* @since 26 Jul 2018
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\extensions\core\AdminNotifications;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* ACP Notification: Pending Shipping Orders
|
||||
*/
|
||||
class _Shipment extends \IPS\core\AdminNotification
|
||||
{
|
||||
/**
|
||||
* @brief Identifier for what to group this notification type with on the settings form
|
||||
*/
|
||||
public static $group = 'commerce';
|
||||
|
||||
/**
|
||||
* @brief Priority 1-5 (1 being highest) for this group compared to others
|
||||
*/
|
||||
public static $groupPriority = 4;
|
||||
|
||||
/**
|
||||
* @brief Priority 1-5 (1 being highest) for this notification type compared to others in the same group
|
||||
*/
|
||||
public static $itemPriority = 3;
|
||||
|
||||
/**
|
||||
* Title for settings
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function settingsTitle()
|
||||
{
|
||||
return 'acp_notification_Shipments';
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this type of notification ever optional (controls if it will be selectable as "viewable" in settings)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function mayBeOptional()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this type of notification might recur (controls what options will be available for the email setting)
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function mayRecur()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Current count
|
||||
*/
|
||||
protected $count = NULL;
|
||||
|
||||
/**
|
||||
* Get count
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
if ( $this->count === NULL )
|
||||
{
|
||||
$this->count = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_ship_orders', array( 'o_status=?', 'pend' ) )->first();
|
||||
}
|
||||
return $this->count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can a member access this type of notification?
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @return bool
|
||||
*/
|
||||
public static function permissionCheck( \IPS\Member $member )
|
||||
{
|
||||
return $member->hasAcpRestriction( 'nexus', 'payments', 'shiporders_manage' ) and \IPS\Db::i()->select( 'COUNT(*)', 'nexus_shipping' )->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification Title (full HTML, must be escaped where necessary)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function title()
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'acpNotification_nexusShipments', FALSE, array( 'pluralize' => array( $this->count() ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification Subtitle (no HTML)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function subtitle()
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\DateTime::ts( \IPS\Db::i()->select( 'o_date', 'nexus_ship_orders', array( 'o_status=?', 'pend' ), 'o_date asc', 1 )->first() )->relative();
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification Body (full HTML, must be escaped where necessary)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function body()
|
||||
{
|
||||
$table = \IPS\nexus\Shipping\Order::table( \IPS\Http\Url::internal('app=core&module=overview&controller=notifications&_table=nexus_Shipment') );
|
||||
$table->limit = 10;
|
||||
$table->filters = array();
|
||||
$table->quickSearch = NULL;
|
||||
$table->advancedSearch = NULL;
|
||||
$table->where[] = array( 'o_status=?', 'pend' );
|
||||
|
||||
return $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Severity
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function severity()
|
||||
{
|
||||
return static::SEVERITY_OPTIONAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dismissible?
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function dismissible()
|
||||
{
|
||||
return static::DISMISSIBLE_NO;
|
||||
}
|
||||
|
||||
/**
|
||||
* Style
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function style()
|
||||
{
|
||||
return static::STYLE_INFORMATION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Quick link from popup menu
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function link()
|
||||
{
|
||||
return \IPS\Http\Url::internal('app=nexus&module=payments&controller=shipping');
|
||||
}
|
||||
|
||||
/**
|
||||
* Should this notification dismiss itself?
|
||||
*
|
||||
* @note This is checked every time the notification shows. Should be lightweight.
|
||||
* @return bool
|
||||
*/
|
||||
public function selfDismiss()
|
||||
{
|
||||
return !$this->count();
|
||||
}
|
||||
}
|
||||
@@ -1,268 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief ACP Notification: Open Support Requests
|
||||
* @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
|
||||
* @since 26 Jul 2018
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\extensions\core\AdminNotifications;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* ACP Notification: Open Support Requests
|
||||
*/
|
||||
class _Support extends \IPS\core\AdminNotification
|
||||
{
|
||||
/**
|
||||
* @brief Identifier for what to group this notification type with on the settings form
|
||||
*/
|
||||
public static $group = 'commerce';
|
||||
|
||||
/**
|
||||
* @brief Priority 1-5 (1 being highest) for this group compared to others
|
||||
*/
|
||||
public static $groupPriority = 4;
|
||||
|
||||
/**
|
||||
* @brief Priority 1-5 (1 being highest) for this notification type compared to others in the same group
|
||||
*/
|
||||
public static $itemPriority = 1;
|
||||
|
||||
/**
|
||||
* Title for settings
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function settingsTitle()
|
||||
{
|
||||
return 'acp_notification_Support';
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this type of notification ever optional (controls if it will be selectable as "viewable" in settings)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function mayBeOptional()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this type of notification might recur (controls what options will be available for the email setting)
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function mayRecur()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Current count (that this admin can see)
|
||||
*/
|
||||
protected $count = NULL;
|
||||
|
||||
/**
|
||||
* Get count
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @return bool
|
||||
*/
|
||||
public function count( \IPS\Member $member = NULL )
|
||||
{
|
||||
if ( $this->count === NULL )
|
||||
{
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
$where = array();
|
||||
|
||||
$openStatuses = array();
|
||||
foreach ( \IPS\nexus\Support\Status::roots() as $status )
|
||||
{
|
||||
if ( $status->open )
|
||||
{
|
||||
$openStatuses[] = $status->_id;
|
||||
}
|
||||
}
|
||||
$where[] = array( \IPS\Db::i()->in( 'r_status', $openStatuses ) );
|
||||
|
||||
$departments = array_keys( iterator_to_array( \IPS\nexus\Support\Department::departmentsWithPermission( $member ) ) );
|
||||
if ( $departments )
|
||||
{
|
||||
$where[] = array( \IPS\Db::i()->in( 'r_department', $departments ) );
|
||||
}
|
||||
|
||||
$this->count = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_support_requests', $where )->first();
|
||||
}
|
||||
return $this->count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can a member access this type of notification?
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @return bool
|
||||
*/
|
||||
public static function permissionCheck( \IPS\Member $member )
|
||||
{
|
||||
return $member->hasAcpRestriction( 'nexus', 'support', 'requests_manage' ) and \count( \IPS\nexus\Support\Department::departmentsWithPermission( $member ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification Title (full HTML, must be escaped where necessary)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function title()
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'acpNotification_nexusSupport', FALSE, array( 'pluralize' => array( $this->count() ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification Subtitle (no HTML)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function subtitle()
|
||||
{
|
||||
try
|
||||
{
|
||||
$where = array();
|
||||
|
||||
$openStatuses = array();
|
||||
foreach ( \IPS\nexus\Support\Status::roots() as $status )
|
||||
{
|
||||
if ( $status->open )
|
||||
{
|
||||
$openStatuses[] = $status->_id;
|
||||
}
|
||||
}
|
||||
$where[] = array( \IPS\Db::i()->in( 'r_status', $openStatuses ) );
|
||||
|
||||
$departments = array_keys( iterator_to_array( \IPS\nexus\Support\Department::departmentsWithPermission( \IPS\Member::loggedIn() ) ) );
|
||||
if ( $departments )
|
||||
{
|
||||
$where[] = array( \IPS\Db::i()->in( 'r_department', $departments ) );
|
||||
}
|
||||
|
||||
return \IPS\DateTime::ts( \IPS\Db::i()->select( 'r_started', 'nexus_support_requests', $where, 'r_started asc', 1 )->first() )->relative();
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification Body (full HTML, must be escaped where necessary)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function body()
|
||||
{
|
||||
$sortBy = ( isset( \IPS\Request::i()->cookie['support_sort'] ) and \in_array( \IPS\Request::i()->cookie['support_sort'], array( 'r_started', 'r_last_new_reply', 'r_last_reply', 'r_last_staff_reply' ) ) ) ? \IPS\Request::i()->cookie['support_sort'] : 'r_last_new_reply';
|
||||
$sortDir = ( isset( \IPS\Request::i()->cookie['support_order'] ) and \in_array( \IPS\Request::i()->cookie['support_order'], array( 'ASC', 'DESC' ) ) ) ? \IPS\Request::i()->cookie['support_order'] : 'ASC';
|
||||
|
||||
$i = 0;
|
||||
$results = array();
|
||||
$allIds = array();
|
||||
foreach ( \IPS\nexus\Support\Stream::myStreams( \IPS\Member::loggedIn() ) as $stream )
|
||||
{
|
||||
$results[ $stream->id ] = $stream->results( \IPS\Member::loggedIn(), "{$sortBy} {$sortDir}", 1, 3 );
|
||||
$allIds += array_keys( iterator_to_array( $results[ $stream->id ] ) );
|
||||
|
||||
$i++;
|
||||
if ( $i >= 3 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$tracked = iterator_to_array( \IPS\Db::i()->select( array( 'request_id', 'notify' ), 'nexus_support_tracker', array( array( 'member_id=?', \IPS\Member::loggedIn()->member_id ), array( \IPS\Db::i()->in( 'request_id', $allIds ) ) ) )->setKeyField( 'request_id' )->setValueField( 'notify' ) );
|
||||
$participatedIn = iterator_to_array( \IPS\Db::i()->select( 'DISTINCT reply_request', 'nexus_support_replies', array( array( 'reply_member=?', \IPS\Member::loggedIn()->member_id ), array( \IPS\Db::i()->in( 'reply_request', $allIds ) ) ) ) );
|
||||
|
||||
$resultsHtml = array();
|
||||
foreach ( $results as $streamId => $resultSet )
|
||||
{
|
||||
$resultsHtml[ $streamId ] = \IPS\Theme::i()->getTemplate( 'support', 'nexus' )->requestsTableResults( $resultSet, NULL, FALSE, $tracked, $participatedIn, FALSE );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'support.css', 'nexus', 'admin' ) );
|
||||
return \IPS\Theme::i()->getTemplate( 'notifications', 'nexus' )->support( $resultsHtml );
|
||||
}
|
||||
|
||||
/**
|
||||
* Severity
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function severity()
|
||||
{
|
||||
return static::SEVERITY_DYNAMIC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dismissible?
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function dismissible()
|
||||
{
|
||||
return static::DISMISSIBLE_NO;
|
||||
}
|
||||
|
||||
/**
|
||||
* Style
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function style()
|
||||
{
|
||||
return static::STYLE_INFORMATION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Quick link from popup menu
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function link()
|
||||
{
|
||||
return \IPS\Http\Url::internal('app=nexus&module=support&controller=requests');
|
||||
}
|
||||
|
||||
/**
|
||||
* For dynamic notifications: should this show for this member?
|
||||
*
|
||||
* @note This is checked every time the notification shows. Should be lightweight.
|
||||
* @param \IPS\Member $member The member
|
||||
* @return bool
|
||||
*/
|
||||
public function dynamicShow( \IPS\Member $member )
|
||||
{
|
||||
return (bool) $this->count( $member );
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom per-admin setting for if email shoild be sent for this notification
|
||||
*
|
||||
* @param string $key Setting field key
|
||||
* @param mixed $value Current value
|
||||
* @return \IPS\Helpers\Form\FormAbstract|NULL
|
||||
*/
|
||||
public static function customEmailConfigurationSetting( $key, $value )
|
||||
{
|
||||
return new \IPS\Helpers\Form\Custom( $key, NULL, FALSE, array( 'getHtml' => function() {
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( \IPS\Http\Url::internal('app=nexus&module=support&controller=requests&do=preferences'), TRUE, \IPS\Member::loggedIn()->language()->addToStack('acp_notifications_email_configure') );
|
||||
} ) );
|
||||
}
|
||||
}
|
||||
@@ -11,31 +11,45 @@
|
||||
namespace IPS\nexus\extensions\core\AdminNotifications;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\core\AdminNotification;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Transaction as NexusTransaction;
|
||||
use IPS\Output;
|
||||
use IPS\Patterns\ActiveRecordIterator;
|
||||
use IPS\Theme;
|
||||
use UnderflowException;
|
||||
use function count;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* ACP Notification: Transactions Requiring Attention
|
||||
*/
|
||||
class _Transaction extends \IPS\core\AdminNotification
|
||||
class Transaction extends AdminNotification
|
||||
{
|
||||
/**
|
||||
* @brief Identifier for what to group this notification type with on the settings form
|
||||
*/
|
||||
public static $group = 'commerce';
|
||||
public static string $group = 'commerce';
|
||||
|
||||
/**
|
||||
* @brief Priority 1-5 (1 being highest) for this group compared to others
|
||||
*/
|
||||
public static $groupPriority = 4;
|
||||
public static int $groupPriority = 4;
|
||||
|
||||
/**
|
||||
* @brief Priority 1-5 (1 being highest) for this notification type compared to others in the same group
|
||||
*/
|
||||
public static $itemPriority = 2;
|
||||
public static int $itemPriority = 2;
|
||||
|
||||
/**
|
||||
* Get queue HTML
|
||||
@@ -43,13 +57,13 @@ class _Transaction extends \IPS\core\AdminNotification
|
||||
* @param string $status Status to show
|
||||
* @return string
|
||||
*/
|
||||
public static function queueHtml( $status )
|
||||
public static function queueHtml( string $status ) : string
|
||||
{
|
||||
$select = \IPS\Db::i()->select( '*', 'nexus_transactions', array( 't_status=?', $status ), 't_date ASC', array( 0, 12 ) );
|
||||
$select = Db::i()->select( '*', 'nexus_transactions', array( 't_status=?', $status ), 't_date ASC', array( 0, 12 ) );
|
||||
|
||||
if ( \count( $select ) )
|
||||
if ( count( $select ) )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'notifications', 'nexus' )->transactions( new \IPS\Patterns\ActiveRecordIterator( $select, 'IPS\nexus\Transaction' ) );
|
||||
return Theme::i()->getTemplate( 'notifications', 'nexus' )->transactions( new ActiveRecordIterator( $select, 'IPS\nexus\Transaction' ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -62,7 +76,7 @@ class _Transaction extends \IPS\core\AdminNotification
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function settingsTitle()
|
||||
public static function settingsTitle(): string
|
||||
{
|
||||
return 'acp_notification_Transaction';
|
||||
}
|
||||
@@ -70,9 +84,9 @@ class _Transaction extends \IPS\core\AdminNotification
|
||||
/**
|
||||
* Is this type of notification ever optional (controls if it will be selectable as "viewable" in settings)
|
||||
*
|
||||
* @return string
|
||||
* @return bool
|
||||
*/
|
||||
public static function mayBeOptional()
|
||||
public static function mayBeOptional(): bool
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@@ -82,7 +96,7 @@ class _Transaction extends \IPS\core\AdminNotification
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function mayRecur()
|
||||
public static function mayRecur(): bool
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@@ -90,18 +104,18 @@ class _Transaction extends \IPS\core\AdminNotification
|
||||
/**
|
||||
* @brief Current count
|
||||
*/
|
||||
protected $count = NULL;
|
||||
protected ?int $count = NULL;
|
||||
|
||||
/**
|
||||
* Get count
|
||||
*
|
||||
* @return bool
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
public function count(): int
|
||||
{
|
||||
if ( $this->count === NULL )
|
||||
{
|
||||
$this->count = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_transactions', array( 't_status=?', $this->extra ) )->first();
|
||||
$this->count = Db::i()->select( 'COUNT(*)', 'nexus_transactions', array( 't_status=?', $this->extra ) )->first();
|
||||
}
|
||||
return $this->count;
|
||||
}
|
||||
@@ -109,10 +123,10 @@ class _Transaction extends \IPS\core\AdminNotification
|
||||
/**
|
||||
* Can a member access this type of notification?
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @param Member $member The member
|
||||
* @return bool
|
||||
*/
|
||||
public static function permissionCheck( \IPS\Member $member )
|
||||
public static function permissionCheck( Member $member ): bool
|
||||
{
|
||||
return $member->hasAcpRestriction( 'nexus', 'payments', 'transactions_manage' );
|
||||
}
|
||||
@@ -122,23 +136,23 @@ class _Transaction extends \IPS\core\AdminNotification
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function title()
|
||||
public function title(): string
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'acpNotification_nexusTransaction_' . $this->extra, FALSE, array( 'pluralize' => array( $this->count() ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'acpNotification_nexusTransaction_' . $this->extra, FALSE, array( 'pluralize' => array( $this->count() ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification Subtitle (no HTML)
|
||||
*
|
||||
* @return string
|
||||
* @return string|null
|
||||
*/
|
||||
public function subtitle()
|
||||
public function subtitle(): ?string
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\DateTime::ts( \IPS\Db::i()->select( 't_date', 'nexus_transactions', array( 't_status=?', $this->extra ), 't_date asc', 1 )->first() )->relative();
|
||||
return DateTime::ts( Db::i()->select( 't_date', 'nexus_transactions', array( 't_status=?', $this->extra ), 't_date asc', 1 )->first() )->relative();
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
catch ( UnderflowException )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -147,11 +161,11 @@ class _Transaction extends \IPS\core\AdminNotification
|
||||
/**
|
||||
* Notification Body (full HTML, must be escaped where necessary)
|
||||
*
|
||||
* @return string
|
||||
* @return string|null
|
||||
*/
|
||||
public function body()
|
||||
public function body(): ?string
|
||||
{
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js('admin_notifications.js', 'nexus') );
|
||||
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js('admin_notifications.js', 'nexus') );
|
||||
|
||||
return static::queueHtml( $this->extra );
|
||||
}
|
||||
@@ -161,7 +175,7 @@ class _Transaction extends \IPS\core\AdminNotification
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function severity()
|
||||
public function severity(): string
|
||||
{
|
||||
return static::SEVERITY_OPTIONAL;
|
||||
}
|
||||
@@ -171,7 +185,7 @@ class _Transaction extends \IPS\core\AdminNotification
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function dismissible()
|
||||
public function dismissible(): string
|
||||
{
|
||||
return static::DISMISSIBLE_NO;
|
||||
}
|
||||
@@ -179,11 +193,11 @@ class _Transaction extends \IPS\core\AdminNotification
|
||||
/**
|
||||
* Style
|
||||
*
|
||||
* @return bool
|
||||
* @return string
|
||||
*/
|
||||
public function style()
|
||||
public function style(): string
|
||||
{
|
||||
if ( $this->extra === \IPS\nexus\Transaction::STATUS_DISPUTED )
|
||||
if ( $this->extra === NexusTransaction::STATUS_DISPUTED )
|
||||
{
|
||||
return static::STYLE_WARNING;
|
||||
}
|
||||
@@ -196,11 +210,11 @@ class _Transaction extends \IPS\core\AdminNotification
|
||||
/**
|
||||
* Quick link from popup menu
|
||||
*
|
||||
* @return bool
|
||||
* @return Url
|
||||
*/
|
||||
public function link()
|
||||
public function link(): Url
|
||||
{
|
||||
return \IPS\Http\Url::internal('app=nexus&module=payments&controller=transactions&attn=1');
|
||||
return Url::internal('app=nexus&module=payments&controller=transactions&attn=1');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -209,7 +223,7 @@ class _Transaction extends \IPS\core\AdminNotification
|
||||
* @note This is checked every time the notification shows. Should be lightweight.
|
||||
* @return bool
|
||||
*/
|
||||
public function selfDismiss()
|
||||
public function selfDismiss(): bool
|
||||
{
|
||||
return !$this->count();
|
||||
}
|
||||
|
||||
@@ -11,38 +11,49 @@
|
||||
namespace IPS\nexus\extensions\core\AdminNotifications;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\core\AdminNotification;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Payout;
|
||||
use IPS\Settings;
|
||||
use UnderflowException;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* ACP Notification: Pending Credit Withdrawals
|
||||
*/
|
||||
class _Withdrawal extends \IPS\core\AdminNotification
|
||||
class Withdrawal extends AdminNotification
|
||||
{
|
||||
/**
|
||||
* @brief Identifier for what to group this notification type with on the settings form
|
||||
*/
|
||||
public static $group = 'commerce';
|
||||
public static string $group = 'commerce';
|
||||
|
||||
/**
|
||||
* @brief Priority 1-5 (1 being highest) for this group compared to others
|
||||
*/
|
||||
public static $groupPriority = 4;
|
||||
public static int $groupPriority = 4;
|
||||
|
||||
/**
|
||||
* @brief Priority 1-5 (1 being highest) for this notification type compared to others in the same group
|
||||
*/
|
||||
public static $itemPriority = 4;
|
||||
public static int $itemPriority = 4;
|
||||
|
||||
/**
|
||||
* Title for settings
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function settingsTitle()
|
||||
public static function settingsTitle(): string
|
||||
{
|
||||
return 'acp_notification_Withdrawals';
|
||||
}
|
||||
@@ -50,9 +61,9 @@ class _Withdrawal extends \IPS\core\AdminNotification
|
||||
/**
|
||||
* Is this type of notification ever optional (controls if it will be selectable as "viewable" in settings)
|
||||
*
|
||||
* @return string
|
||||
* @return bool
|
||||
*/
|
||||
public static function mayBeOptional()
|
||||
public static function mayBeOptional(): bool
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@@ -62,7 +73,7 @@ class _Withdrawal extends \IPS\core\AdminNotification
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function mayRecur()
|
||||
public static function mayRecur(): bool
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@@ -70,18 +81,18 @@ class _Withdrawal extends \IPS\core\AdminNotification
|
||||
/**
|
||||
* @brief Current count
|
||||
*/
|
||||
protected $count = NULL;
|
||||
protected ?int $count = NULL;
|
||||
|
||||
/**
|
||||
* Get count
|
||||
*
|
||||
* @return bool
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
public function count(): int
|
||||
{
|
||||
if ( $this->count === NULL )
|
||||
{
|
||||
$this->count = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_payouts', array( 'po_status=?', \IPS\nexus\Payout::STATUS_PENDING ) )->first();
|
||||
$this->count = Db::i()->select( 'COUNT(*)', 'nexus_payouts', array( 'po_status=?', Payout::STATUS_PENDING ) )->first();
|
||||
}
|
||||
return $this->count;
|
||||
}
|
||||
@@ -89,12 +100,12 @@ class _Withdrawal extends \IPS\core\AdminNotification
|
||||
/**
|
||||
* Can a member access this type of notification?
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @param Member $member The member
|
||||
* @return bool
|
||||
*/
|
||||
public static function permissionCheck( \IPS\Member $member )
|
||||
public static function permissionCheck( Member $member ): bool
|
||||
{
|
||||
return \IPS\Settings::i()->nexus_payout and $member->hasAcpRestriction( 'nexus', 'payments', 'payouts_manage' );
|
||||
return Settings::i()->nexus_payout and $member->hasAcpRestriction( 'nexus', 'payments', 'payouts_manage' );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -102,23 +113,23 @@ class _Withdrawal extends \IPS\core\AdminNotification
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function title()
|
||||
public function title(): string
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'acpNotification_nexusWithdrawals', FALSE, array( 'pluralize' => array( $this->count() ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'acpNotification_nexusWithdrawals', FALSE, array( 'pluralize' => array( $this->count() ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification Subtitle (no HTML)
|
||||
*
|
||||
* @return string
|
||||
* @return string|null
|
||||
*/
|
||||
public function subtitle()
|
||||
public function subtitle(): ?string
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\DateTime::ts( \IPS\Db::i()->select( 'po_date', 'nexus_payouts', array( 'po_status=?', \IPS\nexus\Payout::STATUS_PENDING ), 'po_date asc', 1 )->first() )->relative();
|
||||
return DateTime::ts( Db::i()->select( 'po_date', 'nexus_payouts', array( 'po_status=?', Payout::STATUS_PENDING ), 'po_date asc', 1 )->first() )->relative();
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
catch ( UnderflowException )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -127,15 +138,15 @@ class _Withdrawal extends \IPS\core\AdminNotification
|
||||
/**
|
||||
* Notification Body (full HTML, must be escaped where necessary)
|
||||
*
|
||||
* @return string
|
||||
* @return string|null
|
||||
*/
|
||||
public function body()
|
||||
public function body(): ?string
|
||||
{
|
||||
$table = \IPS\nexus\Payout::table( array( 'po_status=?', 'pend' ), \IPS\Http\Url::internal('app=nexus&module=payments&controller=payouts&filter=postatus_pend') );
|
||||
$table = Payout::table( array( 'po_status=?', 'pend' ), Url::internal('app=nexus&module=payments&controller=payouts&filter=postatus_pend') );
|
||||
$table->limit = 10;
|
||||
$table->filters = array();
|
||||
$table->quickSearch = NULL;
|
||||
$table->advancedSearch = NULL;
|
||||
$table->advancedSearch = [];
|
||||
|
||||
return $table;
|
||||
}
|
||||
@@ -145,7 +156,7 @@ class _Withdrawal extends \IPS\core\AdminNotification
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function severity()
|
||||
public function severity(): string
|
||||
{
|
||||
return static::SEVERITY_OPTIONAL;
|
||||
}
|
||||
@@ -155,7 +166,7 @@ class _Withdrawal extends \IPS\core\AdminNotification
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function dismissible()
|
||||
public function dismissible(): string
|
||||
{
|
||||
return static::DISMISSIBLE_NO;
|
||||
}
|
||||
@@ -163,9 +174,9 @@ class _Withdrawal extends \IPS\core\AdminNotification
|
||||
/**
|
||||
* Style
|
||||
*
|
||||
* @return bool
|
||||
* @return string
|
||||
*/
|
||||
public function style()
|
||||
public function style(): string
|
||||
{
|
||||
return static::STYLE_INFORMATION;
|
||||
}
|
||||
@@ -173,11 +184,11 @@ class _Withdrawal extends \IPS\core\AdminNotification
|
||||
/**
|
||||
* Quick link from popup menu
|
||||
*
|
||||
* @return bool
|
||||
* @return Url
|
||||
*/
|
||||
public function link()
|
||||
public function link(): Url
|
||||
{
|
||||
return \IPS\Http\Url::internal('app=nexus&module=payments&controller=payouts&filter=postatus_pend');
|
||||
return Url::internal('app=nexus&module=payments&controller=payouts&filter=postatus_pend');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -186,7 +197,7 @@ class _Withdrawal extends \IPS\core\AdminNotification
|
||||
* @note This is checked every time the notification shows. Should be lightweight.
|
||||
* @return bool
|
||||
*/
|
||||
public function selfDismiss()
|
||||
public function selfDismiss(): bool
|
||||
{
|
||||
return !$this->count();
|
||||
}
|
||||
|
||||
@@ -1,297 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Community Enhancements: EasyPost
|
||||
* @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 18 Jun 2014
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\extensions\core\CommunityEnhancements;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Community Enhancement: EasyPost
|
||||
*/
|
||||
class _EasyPost
|
||||
{
|
||||
/**
|
||||
* @brief Enhancement is enabled?
|
||||
*/
|
||||
public $enabled = FALSE;
|
||||
|
||||
/**
|
||||
* @brief IPS-provided enhancement?
|
||||
*/
|
||||
public $ips = FALSE;
|
||||
|
||||
/**
|
||||
* @brief Enhancement has configuration options?
|
||||
*/
|
||||
public $hasOptions = TRUE;
|
||||
|
||||
/**
|
||||
* @brief Icon data
|
||||
*/
|
||||
public $icon = "easypost.png";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->enabled = (bool) \IPS\Settings::i()->easypost_api_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
if ( isset( \IPS\Request::i()->test ) )
|
||||
{
|
||||
return $this->_test();
|
||||
}
|
||||
|
||||
$haveSiteAddress = ( \IPS\Settings::i()->site_address and \IPS\Settings::i()->site_address != 'null' );
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'easypost_enable', (bool) \IPS\Settings::i()->easypost_api_key, FALSE, array( 'togglesOn' => array( 'easypost_api_key', ( $haveSiteAddress ? 'easypost_address_select' : 'easypost_address_custom' ), 'easypost_phone', 'easypost_show_rates' ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'easypost_api_key', \IPS\Settings::i()->easypost_api_key, FALSE, array(), NULL, NULL, NULL, 'easypost_api_key' ) );
|
||||
if ( $haveSiteAddress )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'easypost_address_select', \IPS\Settings::i()->easypost_address ? 1 : 0, FALSE, array( 'options' => array( 0 => 'easypost_address_default', 1 => 'easypost_address_choose' ), 'toggles' => array( 1 => array( 'easypost_address_custom' ) ) ), NULL, NULL, NULL, 'easypost_address_select' ) );
|
||||
\IPS\Member::loggedIn()->language()->words['easypost_address_default'] = sprintf( \IPS\Member::loggedIn()->language()->get( 'easypost_address_default' ), \IPS\GeoLocation::buildFromJson( \IPS\Settings::i()->site_address ) );
|
||||
}
|
||||
$form->add( new \IPS\Helpers\Form\Address( 'easypost_address_custom', \IPS\Settings::i()->easypost_address ? \IPS\GeoLocation::buildFromJson( \IPS\Settings::i()->easypost_address ) : NULL, FALSE, array(), NULL, NULL, NULL, 'easypost_address_custom' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Tel( 'easypost_phone', \IPS\Settings::i()->easypost_phone, FALSE, array(), NULL, NULL, NULL, 'easypost_phone' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'easypost_show_rates', \IPS\Settings::i()->easypost_show_rates, FALSE, array(
|
||||
'options' => array( 1 => 'easypost_show_rates_1', 0 => 'easypost_show_rates_0' ),
|
||||
'toggles' => array( 1 => array( 'easypost_tax', 'easypost_price_adjustment', 'easypost_delivery_adjustment' ) )
|
||||
), NULL, NULL, NULL, 'easypost_show_rates' ) );
|
||||
|
||||
$taxClass = NULL;
|
||||
|
||||
if( \IPS\Settings::i()->easypost_tax )
|
||||
{
|
||||
try
|
||||
{
|
||||
$taxClass = \IPS\nexus\Tax::load( \IPS\Settings::i()->easypost_tax );
|
||||
}
|
||||
catch( \OutOfRangeException $e ){}
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'easypost_tax', $taxClass, FALSE, array( 'class' => '\IPS\nexus\Tax', 'zeroVal' => 'do_not_tax' ), NULL, NULL, NULL, 'easypost_tax' ) );
|
||||
$form->add( new \IPS\nexus\Form\Money( 'easypost_price_adjustment', \IPS\Settings::i()->easypost_price_adjustment, FALSE, array(), NULL, NULL, NULL, 'easypost_price_adjustment' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Interval( 'easypost_delivery_adjustment', \IPS\Settings::i()->easypost_delivery_adjustment, FALSE, array( 'valueAs' => \IPS\Helpers\Form\Interval::DAYS, 'min' => NULL ), NULL, NULL, NULL, 'easypost_delivery_adjustment' ) );
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
$values['easypost_tax'] = $values['easypost_tax'] ? $values['easypost_tax']->_id : 0;
|
||||
$values['easypost_price_adjustment'] = json_encode( $values['easypost_price_adjustment'] );
|
||||
$values['easypost_address'] = ( !$haveSiteAddress or $values['easypost_address_select'] ) ? json_encode( $values['easypost_address_custom'] ) : '';
|
||||
|
||||
if( $haveSiteAddress )
|
||||
{
|
||||
unset( $values['easypost_address_select'] );
|
||||
}
|
||||
|
||||
unset( $values['easypost_address_custom'] );
|
||||
|
||||
try
|
||||
{
|
||||
if ( $values['easypost_enable'] )
|
||||
{
|
||||
unset( $values['easypost_enable'] );
|
||||
$this->testSettings( $values['easypost_api_key'] );
|
||||
$form->saveAsSettings( $values );
|
||||
}
|
||||
else
|
||||
{
|
||||
unset( $values['easypost_enable'] );
|
||||
$values['easypost_api_key'] = '';
|
||||
$form->saveAsSettings( $values );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->inlineMessage = \IPS\Member::loggedIn()->language()->addToStack('saved');
|
||||
}
|
||||
catch ( \LogicException $e )
|
||||
{
|
||||
$form->error = $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->sidebar['actions'] = array(
|
||||
'help' => array(
|
||||
'title' => 'learn_more',
|
||||
'icon' => 'question-circle',
|
||||
'link' => \IPS\Http\Url::ips( 'docs/easypost' ),
|
||||
'target' => '_blank'
|
||||
),
|
||||
'test' => array(
|
||||
'title' => 'easypost_test',
|
||||
'icon' => 'cog',
|
||||
'link' => \IPS\Http\Url::internal( 'app=core&module=applications&controller=enhancements&do=edit&id=nexus_EasyPost&test=1' ),
|
||||
),
|
||||
);
|
||||
|
||||
\IPS\Output::i()->output = $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/Disable
|
||||
*
|
||||
* @param $enabled bool Enable/Disable
|
||||
* @return void
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function toggle( $enabled )
|
||||
{
|
||||
if ( $enabled )
|
||||
{
|
||||
throw new \LogicException;
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Settings::i()->changeValues( array( 'easypost_api_key' => '' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Settings (on save to check if API key is valid)
|
||||
*
|
||||
* @param string|NULL $key Key to check
|
||||
* @return void
|
||||
* @throws \LogicException
|
||||
*/
|
||||
protected function testSettings( $key=NULL )
|
||||
{
|
||||
$response = \IPS\Http\Url::external( 'https://api.easypost.com/v2/addresses' )->request()->login( $key, '' )->get();
|
||||
if ( $response->httpResponseCode != 200 )
|
||||
{
|
||||
throw new \LogicException( \IPS\Member::loggedIn()->language()->addToStack('easypost_bad_api_key') );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Settings (full test)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function _test()
|
||||
{
|
||||
if( !\IPS\Settings::i()->site_address or \IPS\Settings::i()->site_address == 'null' )
|
||||
{
|
||||
throw new \DomainException( \IPS\Member::loggedIn()->language()->addToStack( 'easypost_test_no_site_address' ) );
|
||||
}
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->addMessage( 'easypost_test_blurb' );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'easypost_test_method', \IPS\Settings::i()->easypost_show_rates, TRUE, array(
|
||||
'options' => array( 1 => 'easypost_test_method_1', 0 => 'easypost_test_method_0' ),
|
||||
'toggles' => array(
|
||||
1 => array( 'easypost_test_products' ),
|
||||
0 => array( 'easypost_test_length', 'easypost_test_width', 'easypost_test_height', 'easypost_test_weight' )
|
||||
)
|
||||
) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'easypost_test_products', NULL, NULL, array( 'class' => 'IPS\nexus\Package\Group', 'multiple' => TRUE, 'permissionCheck' => function( $node )
|
||||
{
|
||||
if ( !( $node instanceof \IPS\nexus\Package\Product ) or !$node->physical )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
} ), function( $val )
|
||||
{
|
||||
if ( \IPS\Request::i()->easypost_test_method )
|
||||
{
|
||||
if ( empty( $val ) )
|
||||
{
|
||||
throw new \DomainException('form_required');
|
||||
}
|
||||
foreach ( $val as $package )
|
||||
{
|
||||
if ( !$package->physical )
|
||||
{
|
||||
throw new \DomainException( \IPS\Member::loggedIn()->language()->addToStack( 'easypost_test_not_physical', FALSE, array( 'sprintf' => array( $package->_title ) ) ) );
|
||||
}
|
||||
foreach ( array( 'width', 'height', 'length' ) as $k )
|
||||
{
|
||||
if ( !$package->$k )
|
||||
{
|
||||
throw new \DomainException( \IPS\Member::loggedIn()->language()->addToStack( 'easypost_test_no_' . $k, FALSE, array( 'sprintf' => array( $package->_title ) ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, NULL, NULL, 'easypost_test_products' ) );
|
||||
$form->add( new \IPS\nexus\Form\Length( 'easypost_test_length', NULL, NULL, array(), NULL, NULL, NULL, 'easypost_test_length' ) );
|
||||
$form->add( new \IPS\nexus\Form\Length( 'easypost_test_width', NULL, NULL, array(), NULL, NULL, NULL, 'easypost_test_width' ) );
|
||||
$form->add( new \IPS\nexus\Form\Length( 'easypost_test_height', NULL, NULL, array(), NULL, NULL, NULL, 'easypost_test_height' ) );
|
||||
$form->add( new \IPS\nexus\Form\Weight( 'easypost_test_weight', NULL, NULL, array(), NULL, NULL, NULL, 'easypost_test_weight' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Member( 'easypost_test_customer', \IPS\Member::loggedIn(), TRUE ) );
|
||||
$form->add( new \IPS\Helpers\Form\Address( 'easypost_test_address', NULL, TRUE ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
if ( $values['easypost_test_method'] )
|
||||
{
|
||||
$lengthInInches = 0;
|
||||
$widthInInches = 0;
|
||||
$heightInInches = 0;
|
||||
$weightInOz = 0;
|
||||
foreach ( $values['easypost_test_products'] as $package )
|
||||
{
|
||||
$weight = new \IPS\nexus\Shipping\Weight( $package->weight );
|
||||
$weightInOz += $weight->float('oz');
|
||||
|
||||
foreach ( array( 'length', 'width', 'height' ) as $k )
|
||||
{
|
||||
$length = new \IPS\nexus\Shipping\Length( $package->$k );
|
||||
|
||||
$v = "{$k}InInches";
|
||||
$$v += $length->float('in');
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$lengthInInches = $values['easypost_test_length']->float('in');
|
||||
$widthInInches = $values['easypost_test_width']->float('in');
|
||||
$heightInInches = $values['easypost_test_height']->float('in');
|
||||
$weightInOz = $values['easypost_test_weight']->float('oz');
|
||||
}
|
||||
|
||||
$customer = \IPS\nexus\Customer::load( $values['easypost_test_customer']->member_id );
|
||||
|
||||
try
|
||||
{
|
||||
$rates = \IPS\nexus\Shipping\EasyPostRate::getRates( $lengthInInches, $widthInInches, $heightInInches, $weightInOz, $customer, $values['easypost_test_address'], $customer->defaultCurrency() );
|
||||
if ( isset( $rates['error'] ) )
|
||||
{
|
||||
\IPS\Output::i()->error( $rates['error']['message'], $rates['error']['code'] );
|
||||
}
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
\IPS\Output::i()->error( $e->getMessage(), $e->getCode() );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'shiporders', 'nexus' )->easypostTest( $rates );
|
||||
return;
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = $form;
|
||||
}
|
||||
}
|
||||
@@ -12,36 +12,54 @@
|
||||
namespace IPS\nexus\extensions\core\CommunityEnhancements;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\core\AdminNotification;
|
||||
use IPS\Extensions\CommunityEnhancementsAbstract;
|
||||
use IPS\GeoLocation;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\Node;
|
||||
use IPS\Helpers\Form\Radio;
|
||||
use IPS\Helpers\Form\Text;
|
||||
use IPS\Helpers\Form\YesNo;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
use IPS\Settings;
|
||||
use LogicException;
|
||||
use function defined;
|
||||
use function is_array;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Community Enhancement
|
||||
*/
|
||||
class _MaxMind
|
||||
class MaxMind extends CommunityEnhancementsAbstract
|
||||
{
|
||||
/**
|
||||
* @brief Enhancement is enabled?
|
||||
*/
|
||||
public $enabled = FALSE;
|
||||
public bool $enabled = FALSE;
|
||||
|
||||
/**
|
||||
* @brief IPS-provided enhancement?
|
||||
*/
|
||||
public $ips = FALSE;
|
||||
public bool $ips = FALSE;
|
||||
|
||||
/**
|
||||
* @brief Enhancement has configuration options?
|
||||
*/
|
||||
public $hasOptions = TRUE;
|
||||
public bool $hasOptions = TRUE;
|
||||
|
||||
/**
|
||||
* @brief Icon data
|
||||
*/
|
||||
public $icon = "maxmind.png";
|
||||
public string $icon = "maxmind.png";
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@@ -50,7 +68,7 @@ class _MaxMind
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->enabled = (bool) \IPS\Settings::i()->maxmind_key;
|
||||
$this->enabled = (bool) Settings::i()->maxmind_key;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,15 +76,15 @@ class _MaxMind
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function edit()
|
||||
public function edit() : void
|
||||
{
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'maxmind_enable', (bool) \IPS\Settings::i()->maxmind_key, FALSE, array( 'togglesOn' => array( 'maxmind_key', 'maxmind_gateways', 'maxmind_error' ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'maxmind_id', \IPS\Settings::i()->maxmind_id, FALSE, array(), NULL, NULL, NULL, 'maxmind_id' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'maxmind_key', \IPS\Settings::i()->maxmind_key, FALSE, array(), NULL, NULL, NULL, 'maxmind_key' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'maxmind_gateways', ( !\IPS\Settings::i()->maxmind_gateways or \IPS\Settings::i()->maxmind_gateways === '*' ) ? 0 : explode( ',', \IPS\Settings::i()->maxmind_gateways ), FALSE, array( 'class' => 'IPS\nexus\Gateway', 'multiple' => TRUE, 'zeroVal' => 'all' ), NULL, NULL, NULL, 'maxmind_gateways' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'maxmind_error', \IPS\Settings::i()->maxmind_error, FALSE, array( 'options' => array( 'okay' => 'maxmind_error_okay', 'hold' => 'maxmind_error_hold' ) ), NULL, NULL, NULL, 'maxmind_error' ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'maxmind_tracking_code', (bool) \IPS\Settings::i()->maxmind_tracking_code, FALSE, array(), NULL, NULL, NULL, 'maxmind_tracking_code' ) );
|
||||
$form = new Form;
|
||||
$form->add( new YesNo( 'maxmind_enable', (bool) Settings::i()->maxmind_key, FALSE, array( 'togglesOn' => array( 'maxmind_key', 'maxmind_gateways', 'maxmind_error' ) ) ) );
|
||||
$form->add( new Text( 'maxmind_id', Settings::i()->maxmind_id, FALSE, array(), NULL, NULL, NULL, 'maxmind_id' ) );
|
||||
$form->add( new Text( 'maxmind_key', Settings::i()->maxmind_key, FALSE, array(), NULL, NULL, NULL, 'maxmind_key' ) );
|
||||
$form->add( new Node( 'maxmind_gateways', ( !Settings::i()->maxmind_gateways or Settings::i()->maxmind_gateways === '*' ) ? 0 : explode( ',', Settings::i()->maxmind_gateways ), FALSE, array( 'class' => 'IPS\nexus\Gateway', 'multiple' => TRUE, 'zeroVal' => 'all' ), NULL, NULL, NULL, 'maxmind_gateways' ) );
|
||||
$form->add( new Radio( 'maxmind_error', Settings::i()->maxmind_error, FALSE, array( 'options' => array( 'okay' => 'maxmind_error_okay', 'hold' => 'maxmind_error_hold' ) ), NULL, NULL, NULL, 'maxmind_error' ) );
|
||||
$form->add( new YesNo( 'maxmind_tracking_code', (bool) Settings::i()->maxmind_tracking_code, FALSE, array(), NULL, NULL, NULL, 'maxmind_tracking_code' ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
@@ -76,7 +94,7 @@ class _MaxMind
|
||||
{
|
||||
unset( $values['maxmind_enable'] );
|
||||
$this->testSettings( $values['maxmind_key'], $values['maxmind_id'] );
|
||||
$values['maxmind_gateways'] = \is_array( $values['maxmind_gateways'] ) ? implode( ',', array_keys( $values['maxmind_gateways'] ) ) : '*';
|
||||
$values['maxmind_gateways'] = is_array( $values['maxmind_gateways'] ) ? implode( ',', array_keys( $values['maxmind_gateways'] ) ) : '*';
|
||||
$form->saveAsSettings( $values );
|
||||
}
|
||||
else
|
||||
@@ -88,25 +106,25 @@ class _MaxMind
|
||||
$form->saveAsSettings( $values );
|
||||
}
|
||||
|
||||
\IPS\core\AdminNotification::remove( 'nexus', 'Maxmind' );
|
||||
\IPS\Output::i()->inlineMessage = \IPS\Member::loggedIn()->language()->addToStack('saved');
|
||||
AdminNotification::remove( 'nexus', 'Maxmind' );
|
||||
Output::i()->inlineMessage = Member::loggedIn()->language()->addToStack('saved');
|
||||
}
|
||||
catch ( \LogicException $e )
|
||||
catch ( LogicException $e )
|
||||
{
|
||||
$form->error = $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->sidebar['actions'] = array(
|
||||
Output::i()->sidebar['actions'] = array(
|
||||
'help' => array(
|
||||
'title' => 'learn_more',
|
||||
'icon' => 'question-circle',
|
||||
'link' => \IPS\Http\Url::ips( 'docs/maxmind' ),
|
||||
'link' => Url::ips( 'docs/maxmind' ),
|
||||
'target' => '_blank'
|
||||
),
|
||||
);
|
||||
|
||||
\IPS\Output::i()->output = $form;
|
||||
Output::i()->output = $form;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -114,32 +132,32 @@ class _MaxMind
|
||||
*
|
||||
* @param $enabled bool Enable/Disable
|
||||
* @return void
|
||||
* @throws \LogicException
|
||||
* @throws LogicException
|
||||
*/
|
||||
public function toggle( $enabled )
|
||||
public function toggle( bool $enabled ) : void
|
||||
{
|
||||
if ( $enabled )
|
||||
{
|
||||
throw new \LogicException;
|
||||
throw new LogicException;
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Settings::i()->changeValues( array( 'maxmind_key' => '', 'maxmind_id' => '' ) );
|
||||
\IPS\core\AdminNotification::remove( 'nexus', 'Maxmind' );
|
||||
Settings::i()->changeValues( array( 'maxmind_key' => '', 'maxmind_id' => '' ) );
|
||||
AdminNotification::remove( 'nexus', 'Maxmind' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Settings
|
||||
*
|
||||
* @param string|NULL $key Key to check
|
||||
* @param string|NULL $id ID to check
|
||||
* @param string|null $key Key to check
|
||||
* @param string|null $id ID to check
|
||||
* @return void
|
||||
* @throws \LogicException
|
||||
* @throws LogicException
|
||||
*/
|
||||
protected function testSettings( $key=NULL, $id=NULL )
|
||||
protected function testSettings( string $key=NULL, string $id=NULL ) : void
|
||||
{
|
||||
$testAddress = new \IPS\GeoLocation;
|
||||
$testAddress = new GeoLocation;
|
||||
$testAddress->addressLines = array( 'Invision Power Services, Inc.', 'PO Box 2365' );
|
||||
$testAddress->city = 'Forest';
|
||||
$testAddress->region = 'VA';
|
||||
@@ -147,13 +165,13 @@ class _MaxMind
|
||||
$testAddress->postalCode = '24551';
|
||||
|
||||
$maxMind = new \IPS\nexus\Fraud\MaxMind\Request( FALSE, $key, $id );
|
||||
$maxMind->setIpAddress( \IPS\Request::i()->ipAddress() );
|
||||
$maxMind->setIpAddress( Request::i()->ipAddress() );
|
||||
$maxMind->setBillingAddress( $testAddress );
|
||||
$maxMind = $maxMind->request();
|
||||
|
||||
if ( $maxMind->error )
|
||||
{
|
||||
throw new \LogicException( $maxMind->error );
|
||||
throw new LogicException( $maxMind->error );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Contact Us 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/
|
||||
* @package Invision Community
|
||||
* @since 29 Sep 2016
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\extensions\core\ContactUs;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Contact Us extension
|
||||
*/
|
||||
class _SupportRequest
|
||||
{
|
||||
/**
|
||||
* Process Form
|
||||
*
|
||||
* @param \IPS\Helpers\Form $form The form
|
||||
* @param array $formFields Additional Configuration Formfields
|
||||
* @param array $options Type Radio Form Options
|
||||
* @param array $toggles Type Radio Form Toggles
|
||||
* @param array $disabled Type Radio Form Disabled Options
|
||||
* @return void
|
||||
*/
|
||||
public function process( &$form, &$formFields, &$options, &$toggles, &$disabled )
|
||||
{
|
||||
if ( \count( \IPS\nexus\Support\Department::roots() ) )
|
||||
{
|
||||
$options['contact_nexus_department'] = 'contact_nexus_department';
|
||||
}
|
||||
else
|
||||
{
|
||||
$options['contact_nexus_no_departments'] = 'contact_nexus_no_departments';
|
||||
$disabled['contact_nexus_no_departments'] = 'contact_nexus_no_departments';
|
||||
}
|
||||
$toggles['contact_nexus_department'] = array( 'contact_nexus' );
|
||||
|
||||
if ( \count( \IPS\nexus\Support\Department::roots() ) )
|
||||
{
|
||||
$formFields[] = new \IPS\Helpers\Form\Node( 'contact_nexus_department', \IPS\Settings::i()->contact_nexus_department , FALSE, array( 'class' => 'IPS\nexus\Support\Department' ), function( $value ){
|
||||
if( !$value AND \IPS\Request::i()->contact_type == 'contact_nexus_department' )
|
||||
{
|
||||
throw new \DomainException( 'form_required' );
|
||||
}
|
||||
}, NULL, NULL, 'contact_nexus' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the Form
|
||||
*
|
||||
* @param array $values Values from form
|
||||
* @return bool
|
||||
*/
|
||||
public function handleForm( $values )
|
||||
{
|
||||
if ( \IPS\Settings::i()->contact_type == 'contact_nexus_department' )
|
||||
{
|
||||
$fromEmail = ( \IPS\Member::loggedIn()->member_id ) ? \IPS\Member::loggedIn()->email : $values['email_address'];
|
||||
$content = $values['contact_text'];
|
||||
if ( isset( $values['contact_referrer'] ) AND $values['contact_referrer'] )
|
||||
{
|
||||
$content .= \IPS\Theme::i()->getTemplate( 'system', 'core', 'front' )->contactFormReferrer( $values['contact_referrer'] );
|
||||
}
|
||||
|
||||
$department = \IPS\nexus\Support\Department::load( \IPS\Settings::i()->contact_nexus_department );
|
||||
$member = \IPS\Member::loggedIn();
|
||||
|
||||
$request = new \IPS\nexus\Support\Request;
|
||||
$request->status = \IPS\nexus\Support\Status::load( TRUE, 'status_default_member' );
|
||||
$request->severity = \IPS\nexus\Support\Severity::load( TRUE, 'sev_default' );
|
||||
$request->last_reply = time();
|
||||
$request->last_reply_by = (int) $member->member_id;
|
||||
$request->last_new_reply = time();
|
||||
$request->started = time();
|
||||
$request->replies = 1;
|
||||
$request->title = ( isset( $values['contact_name'] ) AND $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)
|
||||
{
|
||||
$request->member = \IPS\Member::loggedIn()->member_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
$request->email = $fromEmail;
|
||||
}
|
||||
$request->department = $department;
|
||||
$request->save();
|
||||
|
||||
$reply = new \IPS\nexus\Support\Reply;
|
||||
$reply->request = $request->id;
|
||||
$reply->member = (int) \IPS\Member::loggedIn()->member_id;
|
||||
$reply->post = $content;
|
||||
$reply->type = \IPS\Member::loggedIn()->member_id ? $reply::REPLY_MEMBER : $reply::REPLY_EMAIL;
|
||||
$reply->date = time();
|
||||
$reply->email = $fromEmail;
|
||||
$reply->ip_address = \IPS\Request::i()->ipAddress();
|
||||
$reply->save();
|
||||
$request->processAfterCreate( $reply, $values );
|
||||
$request->sendNotifications();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows extensions to do something before the form is shown... e.g. add your own custom fields, or redirect the page
|
||||
*
|
||||
* @param \IPS\Helpers\Form $form The form
|
||||
* @return void
|
||||
*/
|
||||
public function runBeforeFormOutput( &$form )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Whitespace-only changes.
@@ -12,36 +12,33 @@
|
||||
namespace IPS\nexus\extensions\core\ContentRouter;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Application\Module;
|
||||
use IPS\Extensions\ContentRouterAbstract;
|
||||
use IPS\Member;
|
||||
use IPS\Member\Group;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Content Router extension: Products & Reviews
|
||||
*/
|
||||
class _Reviews
|
||||
class Reviews extends ContentRouterAbstract
|
||||
{
|
||||
/**
|
||||
* @brief Content Item Classes
|
||||
*/
|
||||
public $classes = array();
|
||||
|
||||
/**
|
||||
* @brief Can be shown in similar content
|
||||
*/
|
||||
public $similarContent = FALSE;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param \IPS\Member|IPS\Member\Group|NULL $member If checking access, the member/group to check for, or NULL to not check access
|
||||
* @param Member|Group|null $member If checking access, the member/group to check for, or NULL to not check access
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( $member = NULL )
|
||||
public function __construct( Member|Group|null $member = NULL )
|
||||
{
|
||||
if ( ( $member === NULL or $member->canAccessModule( \IPS\Application\Module::get( 'nexus', 'store', 'front' ) ) ) )
|
||||
if ( ( $member === NULL or $member->canAccessModule( Module::get( 'nexus', 'store', 'front' ) ) ) )
|
||||
{
|
||||
$this->classes[] = 'IPS\nexus\Package\Item';
|
||||
}
|
||||
|
||||
@@ -12,25 +12,36 @@
|
||||
namespace IPS\nexus\extensions\core\Dashboard;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DateInterval;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Extensions\DashboardAbstract;
|
||||
use IPS\Helpers\Chart;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Money;
|
||||
use IPS\nexus\Transaction;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dashboard extension: Income
|
||||
*/
|
||||
class _Income
|
||||
class Income extends DashboardAbstract
|
||||
{
|
||||
/**
|
||||
* Can the current user view this dashboard item?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canView()
|
||||
public function canView(): bool
|
||||
{
|
||||
return \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus' , 'transactions', 'transactions_manage' );
|
||||
return Member::loggedIn()->hasAcpRestriction( 'nexus' , 'transactions', 'transactions_manage' );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -38,20 +49,20 @@ class _Income
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBlock()
|
||||
public function getBlock(): string
|
||||
{
|
||||
$chart = new \IPS\Helpers\Chart;
|
||||
$chart = new Chart;
|
||||
|
||||
$chart->addHeader( "Day", 'date' );
|
||||
foreach ( \IPS\nexus\Money::currencies() as $currency )
|
||||
foreach ( Money::currencies() as $currency )
|
||||
{
|
||||
$chart->addHeader( $currency, 'number' );
|
||||
}
|
||||
|
||||
$thirtyDaysAgo = \IPS\DateTime::create()->sub( new \DateInterval('P30D') );
|
||||
$thirtyDaysAgo = DateTime::create()->sub( new DateInterval('P30D') );
|
||||
|
||||
$results = array();
|
||||
foreach( \IPS\Db::i()->select( "t_currency, DATE_FORMAT( FROM_UNIXTIME( t_date ), '%e %c %Y' ) AS date, SUM(t_amount)-SUM(t_partial_refund) AS amount", 'nexus_transactions', array( 't_date>? AND (t_status=? OR t_status=?) AND t_method>0', $thirtyDaysAgo->getTimestamp(), \IPS\nexus\Transaction::STATUS_PAID, \IPS\nexus\Transaction::STATUS_PART_REFUNDED ), NULL, NULL, array( 't_currency', 'date' ) ) as $result )
|
||||
foreach( Db::i()->select( "t_currency, DATE_FORMAT( FROM_UNIXTIME( t_date ), '%e %c %Y' ) AS date, SUM(t_amount)-SUM(t_partial_refund) AS amount", 'nexus_transactions', array( 't_date>? AND (t_status=? OR t_status=?) AND t_method>0', $thirtyDaysAgo->getTimestamp(), Transaction::STATUS_PAID, Transaction::STATUS_PART_REFUNDED ), NULL, NULL, array( 't_currency', 'date' ) ) as $result )
|
||||
{
|
||||
$results[ $result['date'] ][ $result['t_currency'] ] = $result['amount'];
|
||||
}
|
||||
@@ -59,16 +70,16 @@ class _Income
|
||||
$monthAndYear = date( 'n' ) . ' ' . date( 'Y' );
|
||||
foreach ( range( 30, 0 ) as $daysAgo )
|
||||
{
|
||||
$datetime = new \IPS\DateTime;
|
||||
$datetime->setTime( 0, 0, 0 );
|
||||
$datetime->sub( new \DateInterval( 'P' . $daysAgo . 'D' ) );
|
||||
$datetime = new DateTime;
|
||||
$datetime->setTime( 0, 0 );
|
||||
$datetime->sub( new DateInterval( 'P' . $daysAgo . 'D' ) );
|
||||
$resultString = $datetime->format('j n Y');
|
||||
|
||||
if ( isset( $results[ $resultString ] ) )
|
||||
{
|
||||
$row = array( $datetime );
|
||||
|
||||
foreach ( \IPS\nexus\Money::currencies() as $currency )
|
||||
foreach ( Money::currencies() as $currency )
|
||||
{
|
||||
if ( !isset( $results[ $resultString ][ $currency ] ) )
|
||||
{
|
||||
@@ -85,7 +96,7 @@ class _Income
|
||||
else
|
||||
{
|
||||
$row = array( $datetime );
|
||||
foreach ( \IPS\nexus\Money::currencies() as $currency )
|
||||
foreach ( Money::currencies() as $currency )
|
||||
{
|
||||
$row[] = 0;
|
||||
}
|
||||
@@ -101,24 +112,4 @@ class _Income
|
||||
'areaOpacity' => 0.4,
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the block information
|
||||
*
|
||||
* @return array array( 'name' => 'Block title', 'key' => 'unique_key', 'size' => [1,2,3], 'by' => 'Author name' )
|
||||
*/
|
||||
public function getInfo()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the block data submitted. This method is only necessary if your block accepts some sort of submitted data to save (such as the 'admin notes' block).
|
||||
*
|
||||
* @return void
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function saveBlock()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -12,31 +12,40 @@
|
||||
namespace IPS\nexus\extensions\core\Dashboard;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Db;
|
||||
use IPS\Extensions\DashboardAbstract;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Payout;
|
||||
use IPS\nexus\Transaction;
|
||||
use IPS\Output;
|
||||
use IPS\Settings;
|
||||
use IPS\Theme;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Dashboard extension: PendingActions
|
||||
*/
|
||||
class _PendingActions
|
||||
class PendingActions extends DashboardAbstract
|
||||
{
|
||||
/**
|
||||
* Can the current user view this dashboard item?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canView()
|
||||
public function canView(): bool
|
||||
{
|
||||
return ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'transactions_manage' )
|
||||
return ( Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'transactions_manage' )
|
||||
or
|
||||
\IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'shiporders_manage' )
|
||||
Member::loggedIn()->hasAcpRestriction( 'core', 'promotion', 'advertisements_manage' )
|
||||
or
|
||||
\IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'promotion', 'advertisements_manage' )
|
||||
or
|
||||
\IPS\Settings::i()->nexus_payout and \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'payouts_manage' ) );
|
||||
Settings::i()->nexus_payout and Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'payouts_manage' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,36 +53,25 @@ class _PendingActions
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBlock()
|
||||
public function getBlock(): string
|
||||
{
|
||||
/* Pending transactions *might* happen some weird way, so always get the count... but only show the count if we have fraud rules set up */
|
||||
$pendingTransactions = NULL;
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'transactions_manage' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'transactions_manage' ) )
|
||||
{
|
||||
$pendingTransactions = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_transactions', array( \IPS\Db::i()->in( 't_status', array( \IPS\nexus\Transaction::STATUS_HELD, \IPS\nexus\Transaction::STATUS_WAITING, \IPS\nexus\Transaction::STATUS_REVIEW, \IPS\nexus\Transaction::STATUS_DISPUTED ) ) ) )->first();
|
||||
if ( !$pendingTransactions and !\IPS\Db::i()->select( 'COUNT(*)', 'nexus_fraud_rules' )->first() )
|
||||
$pendingTransactions = Db::i()->select( 'COUNT(*)', 'nexus_transactions', array( Db::i()->in( 't_status', array( Transaction::STATUS_HELD, Transaction::STATUS_WAITING, Transaction::STATUS_REVIEW, Transaction::STATUS_DISPUTED ) ) ) )->first();
|
||||
if ( !$pendingTransactions and !Db::i()->select( 'COUNT(*)', 'nexus_fraud_rules' )->first() )
|
||||
{
|
||||
$pendingTransactions = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Same with shipments */
|
||||
$pendingShipments = NULL;
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'shiporders_manage' ) )
|
||||
{
|
||||
$pendingShipments = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_ship_orders', array( 'o_status=?', \IPS\nexus\Shipping\Order::STATUS_PENDING ) )->first();
|
||||
if ( !$pendingShipments and !\IPS\Db::i()->select( 'COUNT(*)', 'nexus_packages_products', 'p_physical=1' )->first() )
|
||||
{
|
||||
$pendingShipments = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* And advertisements */
|
||||
$pendingAdvertisements = NULL;
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'promotion', 'advertisements_manage' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'core', 'promotion', 'advertisements_manage' ) )
|
||||
{
|
||||
$pendingAdvertisements = \IPS\Db::i()->select( 'COUNT(*)', 'core_advertisements', array( 'ad_active=-1' ) )->first();
|
||||
if ( !$pendingAdvertisements and !\IPS\Db::i()->select( 'COUNT(*)', 'nexus_packages_ads' )->first() )
|
||||
$pendingAdvertisements = Db::i()->select( 'COUNT(*)', 'core_advertisements', array( 'ad_active=-1' ) )->first();
|
||||
if ( !$pendingAdvertisements and !Db::i()->select( 'COUNT(*)', 'nexus_packages_ads' )->first() )
|
||||
{
|
||||
$pendingAdvertisements = NULL;
|
||||
}
|
||||
@@ -81,41 +79,13 @@ class _PendingActions
|
||||
|
||||
/* Withdrawals will only be if enabled */
|
||||
$pendingWithdrawals = NULL;
|
||||
if ( \IPS\Settings::i()->nexus_payout and \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'payouts_manage' ) )
|
||||
if ( Settings::i()->nexus_payout and Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'payouts_manage' ) )
|
||||
{
|
||||
$pendingWithdrawals = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_payouts', array( 'po_status=?', \IPS\nexus\Payout::STATUS_PENDING ) )->first();
|
||||
$pendingWithdrawals = Db::i()->select( 'COUNT(*)', 'nexus_payouts', array( 'po_status=?', Payout::STATUS_PENDING ) )->first();
|
||||
}
|
||||
|
||||
/* Show support if there are departments we can see */
|
||||
$openSupportRequests = NULL;
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'support', 'requests_manage' ) and \IPS\Db::i()->select( '*', 'nexus_support_departments', array( "( dpt_staff='*' OR " . \IPS\Db::i()->findInSet( 'dpt_staff', \IPS\nexus\Support\Department::staffDepartmentPerms() ) . ')' ) ) )
|
||||
{
|
||||
$myStream = \IPS\nexus\Support\Stream::myStream();
|
||||
$openSupportRequests = $myStream->count( \IPS\Member::loggedIn() );
|
||||
}
|
||||
Output::i()->cssFiles = array_merge( Output::i()->cssFiles, Theme::i()->css( 'widgets.css', 'nexus', 'front' ) );
|
||||
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'widgets.css', 'nexus', 'front' ) );
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'dashboard', 'nexus' )->pendingActions( $pendingTransactions, $pendingShipments, $pendingWithdrawals, $openSupportRequests, $pendingAdvertisements );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the block information
|
||||
*
|
||||
* @return array array( 'name' => 'Block title', 'key' => 'unique_key', 'size' => [1,2,3], 'by' => 'Author name' )
|
||||
*/
|
||||
public function getInfo()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the block data submitted. This method is only necessary if your block accepts some sort of submitted data to save (such as the 'admin notes' block).
|
||||
*
|
||||
* @return void
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function saveBlock()
|
||||
{
|
||||
return Theme::i()->getTemplate( 'dashboard', 'nexus' )->pendingActions( $pendingTransactions, $pendingWithdrawals, $pendingAdvertisements );
|
||||
}
|
||||
}
|
||||
@@ -12,48 +12,54 @@
|
||||
namespace IPS\nexus\extensions\core\EditorLocations;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use InvalidArgumentException;
|
||||
use IPS\Content;
|
||||
use IPS\Db;
|
||||
use IPS\Extensions\EditorLocationsAbstract;
|
||||
use IPS\Helpers\Form\Editor;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Customer;
|
||||
use IPS\nexus\extensions\nexus\Item\Package;
|
||||
use IPS\nexus\Package\Item;
|
||||
use IPS\nexus\Purchase;
|
||||
use IPS\Node\Model;
|
||||
use IPS\Request;
|
||||
use IPS\Settings;
|
||||
use IPS\Text\Parser;
|
||||
use LogicException;
|
||||
use OutOfRangeException;
|
||||
use function count;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Editor Extension: Admin
|
||||
*/
|
||||
class _Admin
|
||||
class Admin extends EditorLocationsAbstract
|
||||
{
|
||||
/**
|
||||
* Can we use HTML in this editor?
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
|
||||
*/
|
||||
public function canUseHtml( $member )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can we use attachments in this editor?
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @param \IPS\Helpers\Form\Editor $field The editor field
|
||||
* @param Member $member The member
|
||||
* @param Editor $field The editor field
|
||||
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
|
||||
*/
|
||||
public function canAttach( $member, $field )
|
||||
public function canAttach( Member $member, Editor $field ): ?bool
|
||||
{
|
||||
if ( mb_substr( $field->options['autoSaveKey'], -6 ) == '-email' )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Permission check for attachments
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @param Member $member The member
|
||||
* @param int|null $id1 Primary ID
|
||||
* @param int|null $id2 Secondary ID
|
||||
* @param string|null $id3 Arbitrary data
|
||||
@@ -61,7 +67,7 @@ class _Admin
|
||||
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
|
||||
* @return bool
|
||||
*/
|
||||
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
|
||||
public function attachmentPermissionCheck( Member $member, ?int $id1, ?int $id2, ?string $id3, array $attachment, bool $viewOnly=FALSE ): bool
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -70,28 +76,39 @@ class _Admin
|
||||
case 'pkg':
|
||||
case 'pkg-assoc':
|
||||
case 'pkg-email':
|
||||
return \IPS\nexus\Package\Item::load( $id1 )->canView( $member );
|
||||
return Item::load( $id1 )->canView( $member );
|
||||
|
||||
case 'custom-pg':
|
||||
try
|
||||
{
|
||||
$package = \IPS\nexus\Package::load( $id1 );
|
||||
return $package->custom == $member->member_id;
|
||||
}
|
||||
catch( OutOfRangeException )
|
||||
{
|
||||
throw new LogicException;
|
||||
}
|
||||
|
||||
case 'pkg-pg':
|
||||
$customer = \IPS\nexus\Customer::load( $member->member_id );
|
||||
if ( \count( \IPS\nexus\extensions\nexus\Item\Package::getPurchases( $customer, $id1, FALSE ) ) )
|
||||
$customer = Customer::load( $member->member_id );
|
||||
if ( count( Package::getPurchases( $customer, $id1, FALSE ) ) )
|
||||
{
|
||||
$options = array( 'type' => 'attach', 'id' => $attachment['attach_id'], 'name' => $attachment['attach_file'] );
|
||||
if ( \IPS\Request::i()->referrer() )
|
||||
if ( Request::i()->referrer() )
|
||||
{
|
||||
try
|
||||
{
|
||||
$purchase = \IPS\nexus\Purchase::loadFromUrl( \IPS\Request::i()->referrer() );
|
||||
$purchase = Purchase::loadFromUrl( Request::i()->referrer() );
|
||||
|
||||
if( !$purchase->can( 'view', $member ) )
|
||||
{
|
||||
throw new \LogicException;
|
||||
throw new LogicException;
|
||||
}
|
||||
|
||||
$options['ps_id'] = $purchase->id;
|
||||
$options['ps_name'] = $purchase->name;
|
||||
}
|
||||
catch ( \LogicException $e ) { }
|
||||
catch ( LogicException ) { }
|
||||
}
|
||||
|
||||
$customer->log( 'download', $options );
|
||||
@@ -108,10 +125,10 @@ class _Admin
|
||||
return TRUE;
|
||||
|
||||
case 'network_status_text':
|
||||
return (bool) \IPS\Settings::i()->network_status;
|
||||
};
|
||||
return (bool) Settings::i()->network_status;
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -125,10 +142,10 @@ class _Admin
|
||||
* @param int|null $id1 Primary ID
|
||||
* @param int|null $id2 Secondary ID
|
||||
* @param string|null $id3 Arbitrary data
|
||||
* @return \IPS\Http\Url|\IPS\Content|\IPS\Node\Model
|
||||
* @throws \LogicException
|
||||
* @return Url|Content|Model|Member|null
|
||||
* @throws LogicException
|
||||
*/
|
||||
public function attachmentLookup( $id1, $id2, $id3 )
|
||||
public function attachmentLookup( int $id1=NULL, int $id2=NULL, string $id3=NULL ): Model|Content|Url|Member|null
|
||||
{
|
||||
switch ( $id3 )
|
||||
{
|
||||
@@ -136,35 +153,19 @@ class _Admin
|
||||
case 'pkg-assoc':
|
||||
case 'pkg-pg':
|
||||
case 'pkg-email':
|
||||
return \IPS\Http\Url::internal( "app=nexus&module=store&controller=packages&subnode=1&do=form&id={$id1}", 'admin' );
|
||||
return Url::internal( "app=nexus&module=store&controller=packages&subnode=1&do=form&id={$id1}", 'admin' );
|
||||
|
||||
case 'pgroup':
|
||||
return \IPS\Http\Url::internal( "app=nexus&module=store&controller=packages&do=form&id={$id1}", 'admin' );
|
||||
return Url::internal( "app=nexus&module=store&controller=packages&do=form&id={$id1}", 'admin' );
|
||||
|
||||
case 'invoice-header';
|
||||
case 'invoice-footer':
|
||||
return \IPS\Http\Url::internal( 'app=nexus&module=payments&controller=invoices&do=settings', 'admin' );
|
||||
};
|
||||
}
|
||||
return Url::internal( 'app=nexus&module=payments&controller=invoices&do=settings', 'admin' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuild attachment images in non-content item areas
|
||||
*
|
||||
* @param int|null $offset Offset to start from
|
||||
* @param int|null $max Maximum to parse
|
||||
* @return int Number completed
|
||||
* @note This method is optional and will only be called if it exists
|
||||
*/
|
||||
public function rebuildAttachmentImages( $offset, $max )
|
||||
{
|
||||
return $this->performRebuild( $offset, $max, array( 'IPS\Text\Parser', 'rebuildAttachmentUrls' ) );
|
||||
throw new LogicException;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Use the cached image URL instead of the original URL
|
||||
*/
|
||||
protected $proxyUrl = FALSE;
|
||||
|
||||
/**
|
||||
* Rebuild content to add or remove image proxy
|
||||
*
|
||||
@@ -174,44 +175,25 @@ class _Admin
|
||||
* @return int Number completed
|
||||
* @note This method is optional and will only be called if it exists
|
||||
*/
|
||||
public function rebuildImageProxy( $offset, $max, $proxyUrl = FALSE )
|
||||
public function rebuildImageProxy( ?int $offset, ?int $max, bool $proxyUrl = FALSE ): int
|
||||
{
|
||||
$this->proxyUrl = $proxyUrl;
|
||||
return $this->performRebuild( $offset, $max, 'parseImageProxy' );
|
||||
$callback = function( $value ) use ( $proxyUrl ) {
|
||||
return Parser::removeImageProxy( $value, $proxyUrl );
|
||||
};
|
||||
return $this->performRebuild( $offset, $max, $callback );
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuild content post-upgrade
|
||||
*
|
||||
* @param int|null $offset Offset to start from
|
||||
* @param int|null $max Maximum to parse
|
||||
* @return int Number completed
|
||||
* @note This method is optional and will only be called if it exists
|
||||
*/
|
||||
public function rebuildContent( $offset, $max )
|
||||
{
|
||||
return $this->performRebuild( $offset, $max, array( 'IPS\Text\LegacyParser', 'parseStatic' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Store lazy loading status ( true = enabled )
|
||||
*/
|
||||
protected $_lazyLoadStatus = null;
|
||||
|
||||
/**
|
||||
* Rebuild content to add or remove lazy loading
|
||||
*
|
||||
* @param int|null $offset Offset to start from
|
||||
* @param int|null $max Maximum to parse
|
||||
* @param bool $status Enable/Disable lazy loading
|
||||
* @return int Number completed
|
||||
* @note This method is optional and will only be called if it exists
|
||||
*/
|
||||
public function rebuildLazyLoad( $offset, $max, $status=TRUE )
|
||||
public function rebuildLazyLoad( ?int $offset, ?int $max ): int
|
||||
{
|
||||
$this->_lazyLoadStatus = $status;
|
||||
|
||||
return $this->performRebuild( $offset, $max, 'parseLazyLoad' );
|
||||
return $this->performRebuild( $offset, $max, [ 'IPS\Text\Parser', 'parseLazyLoad' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -222,30 +204,23 @@ class _Admin
|
||||
* @param callable $callback Method to call to rebuild content
|
||||
* @return int Number completed
|
||||
*/
|
||||
protected function performRebuild( $offset, $max, $callback )
|
||||
protected function performRebuild( ?int $offset, ?int $max, callable $callback ): int
|
||||
{
|
||||
/* We will do everything except pages first */
|
||||
if( !$offset )
|
||||
{
|
||||
/* Language bits */
|
||||
foreach( \IPS\Db::i()->select( '*', 'core_sys_lang_words', \IPS\Db::i()->in( 'word_key', array( 'nexus_com_rules_val', 'network_status_text_val' ) ) . " OR word_key LIKE 'nexus_donategoal_%_desc' OR word_key LIKE 'nexus_gateway_%_ins' OR word_key LIKE 'nexus_pgroup_%_desc' OR word_key LIKE 'nexus_package_%_desc' OR word_key LIKE 'nexus_package_%_page' OR word_key LIKE 'nexus_department_%_desc'", 'word_id ASC', array( $offset, $max ) ) as $word )
|
||||
foreach( Db::i()->select( '*', 'core_sys_lang_words', Db::i()->in( 'word_key', array( 'nexus_com_rules_val', 'network_status_text_val' ) ) . " OR word_key LIKE 'nexus_donategoal_%_desc' OR word_key LIKE 'nexus_gateway_%_ins' OR word_key LIKE 'nexus_pgroup_%_desc' OR word_key LIKE 'nexus_package_%_desc' OR word_key LIKE 'nexus_package_%_page' OR word_key LIKE 'nexus_department_%_desc'", 'word_id ASC', array( $offset, $max ) ) as $word )
|
||||
{
|
||||
$rebuilt = FALSE;
|
||||
try
|
||||
{
|
||||
if( $callback == 'parseImageProxy' )
|
||||
{
|
||||
$rebuilt = \IPS\Text\Parser::removeImageProxy( $word['word_custom'], $this->proxyUrl );
|
||||
}
|
||||
elseif( $callback == 'parseLazyLoad' )
|
||||
{
|
||||
$rebuilt = \IPS\Text\Parser::parseLazyLoad( $word['word_custom'], $this->_lazyLoadStatus );
|
||||
}
|
||||
else
|
||||
if( !empty( $word['word_custom'] ) )
|
||||
{
|
||||
$rebuilt = $callback( $word['word_custom'] );
|
||||
}
|
||||
}
|
||||
catch( \InvalidArgumentException $e )
|
||||
catch( InvalidArgumentException $e )
|
||||
{
|
||||
if( $callback[1] == 'parseStatic' AND $e->getcode() == 103014 )
|
||||
{
|
||||
@@ -259,33 +234,26 @@ class _Admin
|
||||
|
||||
if( $rebuilt !== FALSE )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_sys_lang_words', array( 'word_custom' => $rebuilt ), 'word_id=' . $word['word_id'] );
|
||||
Db::i()->update( 'core_sys_lang_words', array( 'word_custom' => $rebuilt ), 'word_id=' . $word['word_id'] );
|
||||
}
|
||||
}
|
||||
|
||||
/* Settings */
|
||||
foreach ( array( 'nexus_invoice_header', 'nexus_invoice_footer' ) as $k )
|
||||
{
|
||||
$newMessage = FALSE;
|
||||
try
|
||||
{
|
||||
if( $callback == 'parseImageProxy' )
|
||||
if( !empty( Settings::i()->$k ) )
|
||||
{
|
||||
$newMessage = \IPS\Text\Parser::removeImageProxy( \IPS\Settings::i()->$k );
|
||||
}
|
||||
elseif( $callback == 'parseLazyLoad' )
|
||||
{
|
||||
$newMessage = \IPS\Text\Parser::parseLazyLoad( \IPS\Settings::i()->$k, $this->_lazyLoadStatus );
|
||||
}
|
||||
else
|
||||
{
|
||||
$newMessage = $callback( \IPS\Settings::i()->$k );
|
||||
$newMessage = $callback( Settings::i()->$k );
|
||||
}
|
||||
}
|
||||
catch( \InvalidArgumentException $e )
|
||||
catch( InvalidArgumentException $e )
|
||||
{
|
||||
if( $callback[1] == 'parseStatic' AND $e->getcode() == 103014 )
|
||||
{
|
||||
$newMessage = preg_replace( "#\[/?([^\]]+?)\]#", '', \IPS\Settings::i()->$k );
|
||||
$newMessage = preg_replace( "#\[/?([^\]]+?)\]#", '', Settings::i()->$k );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -295,7 +263,7 @@ class _Admin
|
||||
|
||||
if( $newMessage !== FALSE )
|
||||
{
|
||||
\IPS\Settings::i()->changeValues( array( $k => $newMessage ) );
|
||||
Settings::i()->changeValues( array( $k => $newMessage ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -303,27 +271,24 @@ class _Admin
|
||||
/* Now do packages */
|
||||
$did = 0;
|
||||
|
||||
foreach( \IPS\Db::i()->select( '*', 'nexus_packages', null, 'p_id ASC', array( $offset, $max ) ) as $package )
|
||||
foreach( Db::i()->select( '*', 'nexus_packages', null, 'p_id ASC', array( $offset, $max ) ) as $package )
|
||||
{
|
||||
$did++;
|
||||
$rebuilt = FALSE;
|
||||
|
||||
/* Update */
|
||||
try
|
||||
{
|
||||
if( $callback == 'parseImageProxy' )
|
||||
{
|
||||
$rebuilt = \IPS\Text\Parser::removeImageProxy( $package['p_page'] );
|
||||
}
|
||||
elseif( $callback == 'parseLazyLoad' )
|
||||
{
|
||||
$rebuilt = \IPS\Text\Parser::parseLazyLoad( $package['p_page'], $this->_lazyLoadStatus );
|
||||
}
|
||||
else
|
||||
if( is_string( $package['p_page'] ) AND $callback[1] == 'parseStatic' )
|
||||
{
|
||||
$rebuilt = $callback( $package['p_page'], NULL, FALSE, 'nexus_Admin', $package['p_id'], NULL, 'pkg-pg' );
|
||||
}
|
||||
elseif( is_string( $package['p_page'] ) )
|
||||
{
|
||||
$rebuilt = $callback( $package['p_page'] );
|
||||
}
|
||||
}
|
||||
catch( \InvalidArgumentException $e )
|
||||
catch( InvalidArgumentException $e )
|
||||
{
|
||||
if( $callback[1] == 'parseStatic' AND $e->getcode() == 103014 )
|
||||
{
|
||||
@@ -337,7 +302,7 @@ class _Admin
|
||||
|
||||
if( $rebuilt !== FALSE )
|
||||
{
|
||||
\IPS\Db::i()->update( 'nexus_packages', array( 'p_page' => $rebuilt ), array( 'p_id=?', $package['p_id'] ) );
|
||||
Db::i()->update( 'nexus_packages', array( 'p_page' => $rebuilt ), array( 'p_id=?', $package['p_id'] ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,13 +314,13 @@ class _Admin
|
||||
*
|
||||
* @return int Total Count
|
||||
*/
|
||||
public function contentCount()
|
||||
public function contentCount(): int
|
||||
{
|
||||
$count = 2;
|
||||
|
||||
$count += \IPS\Db::i()->select( 'COUNT(*) as count', 'core_sys_lang_words', \IPS\Db::i()->in( 'word_key', array( 'nexus_com_rules_val', 'network_status_text_val' ) ) . " OR word_key LIKE 'nexus_donategoal_%_desc' OR word_key LIKE 'nexus_gateway_%_ins' OR word_key LIKE 'nexus_pgroup_%_desc' OR word_key LIKE 'nexus_package_%_desc' OR word_key LIKE 'nexus_package_%_page' OR word_key LIKE 'nexus_department_%_desc'" )->first();
|
||||
$count += Db::i()->select( 'COUNT(*) as count', 'core_sys_lang_words', Db::i()->in( 'word_key', array( 'nexus_com_rules_val', 'network_status_text_val' ) ) . " OR word_key LIKE 'nexus_donategoal_%_desc' OR word_key LIKE 'nexus_gateway_%_ins' OR word_key LIKE 'nexus_pgroup_%_desc' OR word_key LIKE 'nexus_package_%_desc' OR word_key LIKE 'nexus_package_%_page' OR word_key LIKE 'nexus_department_%_desc'" )->first();
|
||||
|
||||
$count += \IPS\Db::i()->select( 'COUNT(*) as count', 'nexus_packages' )->first();
|
||||
$count += Db::i()->select( 'COUNT(*) as count', 'nexus_packages' )->first();
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
@@ -12,38 +12,43 @@
|
||||
namespace IPS\nexus\extensions\core\EditorLocations;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use InvalidArgumentException;
|
||||
use IPS\Content;
|
||||
use IPS\Db;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Extensions\EditorLocationsAbstract;
|
||||
use IPS\Helpers\Form\Editor;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Customer as NexusCustomer;
|
||||
use IPS\Node\Model;
|
||||
use IPS\Text\Parser;
|
||||
use LogicException;
|
||||
use function count;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Editor Extension: Customer Fields
|
||||
*/
|
||||
class _Customer
|
||||
class Customer extends EditorLocationsAbstract
|
||||
{
|
||||
/**
|
||||
* Can we use HTML in this editor?
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
|
||||
*/
|
||||
public function canUseHtml( $member )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can we use attachments in this editor?
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @param \IPS\Helpers\Form\Editor $editor The editor instance
|
||||
* @param Member $member The member
|
||||
* @param Editor $field The editor instance
|
||||
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
|
||||
*/
|
||||
public function canAttach( $member, $editor )
|
||||
public function canAttach( Member $member, Editor $field ): ?bool
|
||||
{
|
||||
if( !$editor->options['allowAttachments'] )
|
||||
if( !$field->options['allowAttachments'] )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -54,7 +59,7 @@ class _Customer
|
||||
/**
|
||||
* Permission check for attachments
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @param Member $member The member
|
||||
* @param int|null $id1 Primary ID
|
||||
* @param int|null $id2 Secondary ID
|
||||
* @param string|null $id3 Arbitrary data
|
||||
@@ -62,7 +67,7 @@ class _Customer
|
||||
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
|
||||
* @return bool
|
||||
*/
|
||||
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
|
||||
public function attachmentPermissionCheck( Member $member, ?int $id1, ?int $id2, ?string $id3, array $attachment, bool $viewOnly=FALSE ): bool
|
||||
{
|
||||
if ( ( $id3 !== 'note' and $member->member_id == $id1 ) or $member->hasAcpRestriction( 'nexus', 'customers', 'customers_view' ) )
|
||||
{
|
||||
@@ -77,33 +82,21 @@ class _Customer
|
||||
* @param int|null $id1 Primary ID
|
||||
* @param int|null $id2 Secondary ID
|
||||
* @param string|null $id3 Arbitrary data
|
||||
* @return \IPS\Http\Url|\IPS\Content|\IPS\Node\Model
|
||||
* @throws \LogicException
|
||||
* @return Url|Content|Model|Member|null
|
||||
* @throws LogicException
|
||||
*/
|
||||
public function attachmentLookup( $id1, $id2, $id3 )
|
||||
public function attachmentLookup( int $id1=NULL, int $id2=NULL, string $id3=NULL ): Model|Content|Url|Member|null
|
||||
{
|
||||
if ( \IPS\Dispatcher::i()->controllerLocation === 'admin' )
|
||||
if ( Dispatcher::i()->controllerLocation === 'admin' )
|
||||
{
|
||||
return \IPS\nexus\Customer::load( $id1 )->acpUrl();
|
||||
return NexusCustomer::load( $id1 )->acpUrl();
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\Http\Url::internal( 'app=nexus&module=clients&controller=info', 'front', 'clientsinfo' );
|
||||
return Url::internal( 'app=nexus&module=clients&controller=info', 'front', 'clientsinfo' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuild attachment images in non-content item areas
|
||||
*
|
||||
* @param int|null $offset Offset to start from
|
||||
* @param int|null $max Maximum to parse
|
||||
* @return int Number completed
|
||||
*/
|
||||
public function rebuildAttachmentImages( $offset, $max )
|
||||
{
|
||||
return $this->performRebuild( $offset, $max, array( 'IPS\Text\Parser', 'rebuildAttachmentUrls' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuild content post-upgrade
|
||||
*
|
||||
@@ -112,16 +105,11 @@ class _Customer
|
||||
* @return int Number completed
|
||||
* @note This method is optional and will only be called if it exists
|
||||
*/
|
||||
public function rebuildContent( $offset, $max )
|
||||
public function rebuildContent( ?int $offset, ?int $max ): int
|
||||
{
|
||||
return $this->performRebuild( $offset, $max, array( 'IPS\Text\LegacyParser', 'parseStatic' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Use the cached image URL instead of the original URL
|
||||
*/
|
||||
protected $proxyUrl = FALSE;
|
||||
|
||||
/**
|
||||
* Rebuild content to add or remove image proxy
|
||||
*
|
||||
@@ -131,31 +119,25 @@ class _Customer
|
||||
* @return int Number completed
|
||||
* @note This method is optional and will only be called if it exists
|
||||
*/
|
||||
public function rebuildImageProxy( $offset, $max, $proxyUrl = FALSE )
|
||||
public function rebuildImageProxy( ?int $offset, ?int $max, bool $proxyUrl = FALSE ): int
|
||||
{
|
||||
$this->proxyUrl = $proxyUrl;
|
||||
return $this->performRebuild( $offset, $max, 'parseImageProxy' );
|
||||
$callback = function( $value ) use ( $proxyUrl ) {
|
||||
return Parser::removeImageProxy( $value, $proxyUrl );
|
||||
};
|
||||
return $this->performRebuild( $offset, $max, $callback );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Store lazy loading status ( true = enabled )
|
||||
*/
|
||||
protected $_lazyLoadStatus = null;
|
||||
|
||||
/**
|
||||
* Rebuild content to add or remove lazy loading
|
||||
*
|
||||
* @param int|null $offset Offset to start from
|
||||
* @param int|null $max Maximum to parse
|
||||
* @param bool $status Enable/Disable lazy loading
|
||||
* @return int Number completed
|
||||
* @note This method is optional and will only be called if it exists
|
||||
*/
|
||||
public function rebuildLazyLoad( $offset, $max, $status=TRUE )
|
||||
public function rebuildLazyLoad( ?int $offset, ?int $max ): int
|
||||
{
|
||||
$this->_lazyLoadStatus = $status;
|
||||
|
||||
return $this->performRebuild( $offset, $max, 'parseLazyLoad' );
|
||||
return $this->performRebuild( $offset, $max, [ 'IPS\Text\Parser', 'parseLazyLoad' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -166,25 +148,25 @@ class _Customer
|
||||
* @param callable $callback Method to call to rebuild content
|
||||
* @return int Number completed
|
||||
*/
|
||||
protected function performRebuild( $offset, $max, $callback )
|
||||
protected function performRebuild( ?int $offset, ?int $max, callable $callback ): int
|
||||
{
|
||||
$did = 0;
|
||||
|
||||
/* Get editor fields */
|
||||
$editorFields = array();
|
||||
|
||||
foreach( \IPS\Db::i()->select( '*', 'nexus_customer_fields', "f_type='Editor'" ) as $field )
|
||||
foreach( Db::i()->select( '*', 'nexus_customer_fields', "f_type='Editor'" ) as $field )
|
||||
{
|
||||
$editorFields[] = 'field_' . $field['f_id'];
|
||||
}
|
||||
|
||||
if( !\count( $editorFields ) )
|
||||
if( !count( $editorFields ) )
|
||||
{
|
||||
return $did;
|
||||
}
|
||||
|
||||
/* Now update the content */
|
||||
foreach( \IPS\Db::i()->select( '*', 'nexus_customers', implode( " IS NOT NULL OR ", $editorFields ) . " IS NOT NULL", 'member_id ASC', array( $offset, $max ) ) as $member )
|
||||
foreach( Db::i()->select( '*', 'nexus_customers', implode( " IS NOT NULL OR ", $editorFields ) . " IS NOT NULL", 'member_id ASC', array( $offset, $max ) ) as $member )
|
||||
{
|
||||
$did++;
|
||||
|
||||
@@ -193,22 +175,19 @@ class _Customer
|
||||
|
||||
foreach( $editorFields as $fieldId )
|
||||
{
|
||||
$rebuilt = FALSE;
|
||||
try
|
||||
{
|
||||
if( $callback == 'parseImageProxy' )
|
||||
if( $callback[1] == 'parseStatic' )
|
||||
{
|
||||
$rebuilt = \IPS\Text\Parser::removeImageProxy( $member[ $fieldId ], $this->proxyUrl );
|
||||
}
|
||||
elseif( $callback == 'parseLazyLoad' )
|
||||
{
|
||||
$rebuilt = \IPS\Text\Parser::parseLazyLoad( $member[ $fieldId ], $this->_lazyLoadStatus );
|
||||
$rebuilt = $callback( $member[ $fieldId ], Member::load( $member['member_id'] ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$rebuilt = $callback( $member[ $fieldId ], \IPS\Member::load( $member['member_id'] ) );
|
||||
$rebuilt = $callback( $member[ $fieldId ] );
|
||||
}
|
||||
}
|
||||
catch( \InvalidArgumentException $e )
|
||||
catch( InvalidArgumentException $e )
|
||||
{
|
||||
if( $callback[1] == 'parseStatic' AND $e->getcode() == 103014 )
|
||||
{
|
||||
@@ -226,9 +205,9 @@ class _Customer
|
||||
}
|
||||
}
|
||||
|
||||
if( \count( $toUpdate ) )
|
||||
if( count( $toUpdate ) )
|
||||
{
|
||||
\IPS\Db::i()->update( 'nexus_customers', $toUpdate, array( 'member_id=?', $member['member_id'] ) );
|
||||
Db::i()->update( 'nexus_customers', $toUpdate, array( 'member_id=?', $member['member_id'] ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,21 +219,21 @@ class _Customer
|
||||
*
|
||||
* @return int Total Count
|
||||
*/
|
||||
public function contentCount()
|
||||
public function contentCount(): int
|
||||
{
|
||||
/* Get editor fields */
|
||||
$editorFields = array();
|
||||
|
||||
foreach( \IPS\Db::i()->select( '*', 'nexus_customer_fields', "f_type='Editor'" ) as $field )
|
||||
foreach( Db::i()->select( '*', 'nexus_customer_fields', "f_type='Editor'" ) as $field )
|
||||
{
|
||||
$editorFields[] = 'field_' . $field['f_id'];
|
||||
}
|
||||
|
||||
if( !\count( $editorFields ) )
|
||||
if( !count( $editorFields ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return \IPS\Db::i()->select( 'COUNT(*) as count', 'nexus_customers', implode( " IS NOT NULL OR ", $editorFields ) . " IS NOT NULL" )->first();
|
||||
return Db::i()->select( 'COUNT(*) as count', 'nexus_customers', implode( " IS NOT NULL OR ", $editorFields ) . " IS NOT NULL" )->first();
|
||||
}
|
||||
}
|
||||
@@ -12,36 +12,40 @@
|
||||
namespace IPS\nexus\extensions\core\EditorLocations;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Content;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Extensions\EditorLocationsAbstract;
|
||||
use IPS\Helpers\Form\Editor;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Invoice;
|
||||
use IPS\nexus\Purchase;
|
||||
use IPS\Node\Model;
|
||||
use LogicException;
|
||||
use OutOfRangeException;
|
||||
use function defined;
|
||||
use function intval;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Editor Extension: Support
|
||||
* Editor Extension: Purchases
|
||||
*/
|
||||
class _Purchases
|
||||
class Purchases extends EditorLocationsAbstract
|
||||
{
|
||||
/**
|
||||
* Can we use HTML in this editor?
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
|
||||
*/
|
||||
public function canUseHtml( $member )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can we use attachments in this editor?
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @param \IPS\Helpers\Form\Editor $field The editor field
|
||||
* @param Member $member The member
|
||||
* @param Editor $field The editor field
|
||||
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
|
||||
*/
|
||||
public function canAttach( $member, $field )
|
||||
public function canAttach( Member $member, Editor $field ): ?bool
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -49,7 +53,7 @@ class _Purchases
|
||||
/**
|
||||
* Permission check for attachments
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @param Member $member The member
|
||||
* @param int|null $id1 Primary ID
|
||||
* @param int|null $id2 Secondary ID
|
||||
* @param string|null $id3 Arbitrary data
|
||||
@@ -57,7 +61,7 @@ class _Purchases
|
||||
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
|
||||
* @return bool
|
||||
*/
|
||||
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
|
||||
public function attachmentPermissionCheck( Member $member, ?int $id1, ?int $id2, ?string $id3, array $attachment, bool $viewOnly=FALSE ): bool
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -72,19 +76,19 @@ class _Purchases
|
||||
/* If it's in an invoice, we can check that */
|
||||
if ( mb_substr( $id3, 0, 7 ) == 'invoice' )
|
||||
{
|
||||
return \IPS\nexus\Invoice::load( \intval( mb_substr( $id3, 7 ) ) )->canView( $member );
|
||||
return Invoice::load( intval( mb_substr( $id3, 7 ) ) )->canView( $member );
|
||||
}
|
||||
|
||||
/* If it's in an purchase, we can link to that */
|
||||
if ( $id3 == 'purchase' )
|
||||
{
|
||||
return \IPS\nexus\Purchase::load( $id1 )->canView( $member );
|
||||
return Purchase::load( $id1 )->canView( $member );
|
||||
}
|
||||
|
||||
/* Still here? Return false */
|
||||
return FALSE;
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -96,31 +100,31 @@ class _Purchases
|
||||
* @param int|null $id1 Primary ID
|
||||
* @param int|null $id2 Secondary ID
|
||||
* @param string|null $id3 Arbitrary data
|
||||
* @return \IPS\Http\Url|\IPS\Content|\IPS\Node\Model
|
||||
* @throws \LogicException
|
||||
* @return Url|Content|Model|Member|null
|
||||
* @throws LogicException
|
||||
*/
|
||||
public function attachmentLookup( $id1, $id2, $id3 )
|
||||
public function attachmentLookup( int $id1=NULL, int $id2=NULL, string $id3=NULL ): Model|Content|Url|Member|null
|
||||
{
|
||||
/* If it's in the cart, wer obviously can't link to that */
|
||||
if ( $id3 == 'cart' )
|
||||
{
|
||||
throw new \LogicException;
|
||||
throw new LogicException;
|
||||
}
|
||||
|
||||
/* If it's in an invoice, we can link to that */
|
||||
if ( mb_substr( $id3, 0, 8 ) == 'invoice-' )
|
||||
{
|
||||
$invoice = \IPS\nexus\Invoice::load( \intval( mb_substr( $id3, 8 ) ) );
|
||||
return \IPS\Dispatcher::i()->controllerLocation == 'admin' ? $invoice->acpUrl() : $invoice->url();
|
||||
$invoice = Invoice::load( intval( mb_substr( $id3, 8 ) ) );
|
||||
return Dispatcher::i()->controllerLocation == 'admin' ? $invoice->acpUrl() : $invoice->url();
|
||||
}
|
||||
|
||||
/* If it's in an purchase, we can link to that */
|
||||
if ( $id3 == 'purchase' )
|
||||
{
|
||||
return \IPS\nexus\Purchase::load( $id1 );
|
||||
return Purchase::load( $id1 );
|
||||
}
|
||||
|
||||
/* Still here? No idea */
|
||||
throw new \LogicException;
|
||||
throw new LogicException;
|
||||
}
|
||||
}
|
||||
@@ -12,36 +12,39 @@
|
||||
namespace IPS\nexus\extensions\core\EditorLocations;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Content;
|
||||
use IPS\Extensions\EditorLocationsAbstract;
|
||||
use IPS\Helpers\Form\Editor;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Package\Item;
|
||||
use IPS\nexus\Package\Review;
|
||||
use IPS\Node\Model;
|
||||
use LogicException;
|
||||
use OutOfRangeException;
|
||||
use RuntimeException;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Editor Extension: Product Reviews
|
||||
*/
|
||||
class _Store
|
||||
class Store extends EditorLocationsAbstract
|
||||
{
|
||||
/**
|
||||
* Can we use HTML in this editor?
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
|
||||
*/
|
||||
public function canUseHtml( $member )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can we use attachments in this editor?
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @param \IPS\Helpers\Form\Editor $field The editor field
|
||||
* @param Member $member The member
|
||||
* @param Editor $field The editor field
|
||||
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
|
||||
*/
|
||||
public function canAttach( $member, $field )
|
||||
public function canAttach( Member $member, Editor $field ): ?bool
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -50,11 +53,11 @@ class _Store
|
||||
* 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
|
||||
* @param Member $member The member
|
||||
* @param Editor $field The editor field
|
||||
* @return bool
|
||||
*/
|
||||
public function canBeModerated( $member, $field )
|
||||
public function canBeModerated( Member $member, Editor $field ): bool
|
||||
{
|
||||
/* Creating/editing a review */
|
||||
if ( preg_match( '/^(?:editComment|review)\-nexus\/store\-\d+/', $field->options['autoSaveKey'] ) )
|
||||
@@ -66,16 +69,17 @@ class _Store
|
||||
{
|
||||
if ( \IPS\IN_DEV )
|
||||
{
|
||||
throw new \RuntimeException( 'Unknown canBeModerated: ' . $field->options['autoSaveKey'] );
|
||||
throw new RuntimeException( 'Unknown canBeModerated: ' . $field->options['autoSaveKey'] );
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
return parent::canBeModerated( $member, $field );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Permission check for attachments
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @param Member $member The member
|
||||
* @param int|null $id1 Primary ID
|
||||
* @param int|null $id2 Secondary ID
|
||||
* @param string|null $id3 Arbitrary data
|
||||
@@ -83,13 +87,13 @@ class _Store
|
||||
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
|
||||
* @return bool
|
||||
*/
|
||||
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
|
||||
public function attachmentPermissionCheck( Member $member, ?int $id1, ?int $id2, ?string $id3, array $attachment, bool $viewOnly=FALSE ): bool
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\nexus\Package\Item::load( $id1 )->canView( $member );
|
||||
return Item::load( $id1 )->canView( $member );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -101,12 +105,12 @@ class _Store
|
||||
* @param int|null $id1 Primary ID
|
||||
* @param int|null $id2 Secondary ID
|
||||
* @param string|null $id3 Arbitrary data
|
||||
* @return \IPS\Http\Url|\IPS\Content|\IPS\Node\Model
|
||||
* @throws \LogicException
|
||||
* @return Url|Content|Model|Member|null
|
||||
* @throws LogicException
|
||||
*/
|
||||
public function attachmentLookup( $id1, $id2, $id3 )
|
||||
public function attachmentLookup( int $id1=NULL, int $id2=NULL, string $id3=NULL ): Model|Content|Url|Member|null
|
||||
{
|
||||
return \IPS\nexus\Package\Review::load( $id2 );
|
||||
return Review::load( $id2 );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Editor Extension: Support
|
||||
* @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 09 Apr 2014
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\extensions\core\EditorLocations;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Editor Extension: Support
|
||||
*/
|
||||
class _Support
|
||||
{
|
||||
/**
|
||||
* Can we use HTML in this editor?
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
|
||||
*/
|
||||
public function canUseHtml( $member )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can we use attachments in this editor?
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @param \IPS\Helpers\Form\Editor $field The editor field
|
||||
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
|
||||
*/
|
||||
public function canAttach( $member, $field )
|
||||
{
|
||||
if ( $field->options['autoSaveKey'] == 'default_content' )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if( !$field->options['allowAttachments'] )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Permission check for attachments
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @param int|null $id1 Primary ID
|
||||
* @param int|null $id2 Secondary ID
|
||||
* @param string|null $id3 Arbitrary data
|
||||
* @param array $attachment The attachment data
|
||||
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
|
||||
* @return bool
|
||||
*/
|
||||
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\nexus\Support\Request::load( $id1 )->canView( $member );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attachment lookup
|
||||
*
|
||||
* @param int|null $id1 Primary ID
|
||||
* @param int|null $id2 Secondary ID
|
||||
* @param string|null $id3 Arbitrary data
|
||||
* @return \IPS\Http\Url|\IPS\Content|\IPS\Node\Model
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function attachmentLookup( $id1, $id2, $id3 )
|
||||
{
|
||||
return \IPS\nexus\Support\Reply::load( $id2 );
|
||||
}
|
||||
}
|
||||
@@ -12,25 +12,34 @@
|
||||
namespace IPS\nexus\extensions\core\FileStorage;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use Exception;
|
||||
use IPS\Db;
|
||||
use IPS\Extensions\FileStorageAbstract;
|
||||
use IPS\File;
|
||||
use UnderflowException;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Editor Extension: Advertisement Images
|
||||
*/
|
||||
class _Ads
|
||||
class Ads extends FileStorageAbstract
|
||||
{
|
||||
/**
|
||||
* Count stored files
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
public function count(): int
|
||||
{
|
||||
return \IPS\Db::i()->select( 'COUNT(*)', 'core_advertisements', array( 'ad_member<>0 or ad_member IS NULL' ) )->first();
|
||||
return Db::i()->select( 'COUNT(*)', 'core_advertisements', array( 'ad_member<>0 or ad_member IS NULL' ) )->first();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,70 +48,47 @@ class _Ads
|
||||
* @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
|
||||
* @throws Underflowexception When file record doesn't exist. Indicating there are no more files to move
|
||||
* @return void
|
||||
*/
|
||||
public function move( $offset, $storageConfiguration, $oldConfiguration=NULL )
|
||||
public function move( int $offset, int $storageConfiguration, int $oldConfiguration=NULL ) : void
|
||||
{
|
||||
$record = \IPS\Db::i()->select( '*', 'core_advertisements', array( 'ad_member<>0 or ad_member IS NULL' ), 'ad_id', array( $offset, 1 ) )->first();
|
||||
$record = Db::i()->select( '*', 'core_advertisements', array( 'ad_member<>0 or ad_member IS NULL' ), 'ad_id', array( $offset, 1 ) )->first();
|
||||
|
||||
$images = json_decode( $record['ad_images'], TRUE );
|
||||
foreach ( $images as $key => $location )
|
||||
{
|
||||
try
|
||||
{
|
||||
$images[ $key ] = (string) \IPS\File::get( $oldConfiguration ?: 'nexus_Ads', $location )->move( $storageConfiguration );
|
||||
$images[ $key ] = (string) File::get( $oldConfiguration ?: 'nexus_Ads', $location )->move( $storageConfiguration );
|
||||
}
|
||||
catch( \Exception $e )
|
||||
catch( Exception )
|
||||
{
|
||||
/* Any issues are logged */
|
||||
}
|
||||
}
|
||||
\IPS\Db::i()->update( 'core_advertisements', array( 'ad_images' => json_encode( $images ) ), array( 'ad_id=?', $record['ad_id'] ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix all URLs
|
||||
*
|
||||
* @param int $offset This will be sent starting with 0, increasing to get all files stored by this extension
|
||||
* @return void
|
||||
*/
|
||||
public function fixUrls( $offset )
|
||||
{
|
||||
$record = \IPS\Db::i()->select( '*', 'core_advertisements', array( 'ad_member<>0 or ad_member IS NULL' ), 'ad_id', array( $offset, 1 ) )->first();
|
||||
|
||||
$images = json_decode( $record['ad_images'], TRUE );
|
||||
|
||||
foreach ( $images as $key => $location )
|
||||
{
|
||||
if ( $new = \IPS\File::repairUrl( $location ) )
|
||||
{
|
||||
$images[ $key ] = $new;
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Db::i()->update( 'core_advertisements', array( 'ad_images' => json_encode( $images ) ), array( 'ad_id=?', $record['ad_id'] ) );
|
||||
Db::i()->update( 'core_advertisements', array( 'ad_images' => json_encode( $images ) ), array( 'ad_id=?', $record['ad_id'] ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a file is valid
|
||||
*
|
||||
* @param string $file The file path to check
|
||||
* @param File|string $file The file path to check
|
||||
* @return bool
|
||||
*/
|
||||
public function isValidFile( $file )
|
||||
public function isValidFile( File|string $file ): bool
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_advertisements', array( 'ad_member<>0 or ad_member IS NULL' ) ) as $ad )
|
||||
foreach ( Db::i()->select( '*', 'core_advertisements', array( 'ad_member<>0 or ad_member IS NULL' ) ) as $ad )
|
||||
{
|
||||
if ( \in_array( (string) $file, json_decode( $ad['ad_images'], TRUE ) ) )
|
||||
if ( in_array( (string) $file, json_decode( $ad['ad_images'], TRUE ) ) )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( \UnderflowException $e ) { }
|
||||
catch ( UnderflowException ) { }
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@@ -112,17 +98,17 @@ class _Ads
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
public function delete() : void
|
||||
{
|
||||
foreach( \IPS\Db::i()->select( '*', 'core_advertisements', array( 'ad_member<>0 or ad_member IS NULL' ) ) as $ad )
|
||||
foreach( Db::i()->select( '*', 'core_advertisements', array( 'ad_member<>0 or ad_member IS NULL' ) ) as $ad )
|
||||
{
|
||||
foreach ( json_decode( $ad['ad_images'], TRUE ) as $key => $location )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\File::get( 'nexus_Products', $location )->delete();
|
||||
File::get( 'nexus_Products', $location )->delete();
|
||||
}
|
||||
catch( \Exception $e ){}
|
||||
catch( Exception ){}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,35 +12,45 @@
|
||||
namespace IPS\nexus\extensions\core\FileStorage;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use Exception;
|
||||
use IPS\Db;
|
||||
use IPS\Extensions\FileStorageAbstract;
|
||||
use IPS\File;
|
||||
use IPS\nexus\Customer\CustomField;
|
||||
use Underflowexception;
|
||||
use function count;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* File Storage Extension: Customer Fields
|
||||
*/
|
||||
class _Customer
|
||||
class Customer extends FileStorageAbstract
|
||||
{
|
||||
/**
|
||||
* Count stored files
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
public function count(): int
|
||||
{
|
||||
$where = array();
|
||||
foreach ( \IPS\nexus\Customer\CustomField::roots( NULL, NULL, array( 'f_type=?', 'Upload' ) ) as $field )
|
||||
foreach ( CustomField::roots( NULL, NULL, array( 'f_type=?', 'Upload' ) ) as $field )
|
||||
{
|
||||
$where[] = "field_{$field->id}<>''";
|
||||
}
|
||||
if ( !\count( $where ) )
|
||||
if ( !count( $where ) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return \IPS\Db::i()->select( 'COUNT(*)', 'nexus_customers', implode( ' OR ', $where ) )->first();
|
||||
return Db::i()->select( 'COUNT(*)', 'nexus_customers', implode( ' OR ', $where ) )->first();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -49,38 +59,38 @@ class _Customer
|
||||
* @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
|
||||
* @throws Underflowexception When file record doesn't exist. Indicating there are no more files to move
|
||||
* @return void
|
||||
*/
|
||||
public function move( $offset, $storageConfiguration, $oldConfiguration=NULL )
|
||||
public function move( int $offset, int $storageConfiguration, int $oldConfiguration=NULL ) : void
|
||||
{
|
||||
$ids = array();
|
||||
$where = array();
|
||||
foreach ( \IPS\nexus\Customer\CustomField::roots( NULL, NULL, array( 'f_type=?', 'Upload' ) ) as $field )
|
||||
foreach ( CustomField::roots( NULL, NULL, array( 'f_type=?', 'Upload' ) ) as $field )
|
||||
{
|
||||
$ids[] = $field->id;
|
||||
$where[] = "field_{$field->id}<>''";
|
||||
}
|
||||
if ( !\count( $where ) )
|
||||
if ( !count( $where ) )
|
||||
{
|
||||
throw new \Underflowexception;
|
||||
throw new Underflowexception;
|
||||
}
|
||||
|
||||
$customer = \IPS\Db::i()->select( '*', 'nexus_customers', implode( ' OR ', $where ) )->first();
|
||||
$customer = Db::i()->select( '*', 'nexus_customers', implode( ' OR ', $where ) )->first();
|
||||
$update = array();
|
||||
foreach ( $ids as $id )
|
||||
{
|
||||
try
|
||||
{
|
||||
$update[ 'field_' . $id ] = (string) \IPS\File::get( $oldConfiguration ?: 'nexus_Customer', $update[ 'field_' . $id ] )->move( $storageConfiguration );
|
||||
$update[ 'field_' . $id ] = (string) File::get( $oldConfiguration ?: 'nexus_Customer', $update[ 'field_' . $id ] )->move( $storageConfiguration );
|
||||
}
|
||||
catch( \Exception $e )
|
||||
catch( Exception )
|
||||
{
|
||||
/* Any issues are logged */
|
||||
}
|
||||
}
|
||||
|
||||
if ( \count( $update ) )
|
||||
if ( count( $update ) )
|
||||
{
|
||||
foreach( $update as $k => $v )
|
||||
{
|
||||
@@ -90,48 +100,9 @@ class _Customer
|
||||
}
|
||||
}
|
||||
|
||||
if ( \count( $update ) )
|
||||
if ( count( $update ) )
|
||||
{
|
||||
\IPS\Db::i()->update( 'nexus_customers', $update, array( 'member_id=?', $customer['member_id'] ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix all URLs
|
||||
*
|
||||
* @param int $offset This will be sent starting with 0, increasing to get all files stored by this extension
|
||||
* @return void
|
||||
*/
|
||||
public function fixUrls( $offset )
|
||||
{
|
||||
$ids = array();
|
||||
$where = array();
|
||||
foreach ( \IPS\nexus\Customer\CustomField::roots( NULL, NULL, array( 'f_type=?', 'Upload' ) ) as $field )
|
||||
{
|
||||
$ids[] = $field->id;
|
||||
$where[] = "field_{$field->id}<>''";
|
||||
}
|
||||
if ( !\count( $where ) )
|
||||
{
|
||||
throw new \Underflowexception;
|
||||
}
|
||||
|
||||
$customer = \IPS\Db::i()->select( '*', 'nexus_customers', implode( ' OR ', $where ) )->first();
|
||||
$update = array();
|
||||
foreach ( $ids as $id )
|
||||
{
|
||||
if ( $new = \IPS\File::repairUrl( $customer[ 'field_' . $id ] ) )
|
||||
{
|
||||
$update[ 'field_' . $id ] = $new;
|
||||
}
|
||||
}
|
||||
|
||||
if ( \count( $update ) )
|
||||
{
|
||||
if ( \count( $update ) )
|
||||
{
|
||||
\IPS\Db::i()->update( 'nexus_customers', $update, array( 'member_id=?', $customer['member_id'] ) );
|
||||
Db::i()->update( 'nexus_customers', $update, array( 'member_id=?', $customer['member_id'] ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -139,25 +110,25 @@ class _Customer
|
||||
/**
|
||||
* Check if a file is valid
|
||||
*
|
||||
* @param string $file The file path to check
|
||||
* @param File|string $file The file path to check
|
||||
* @return bool
|
||||
*/
|
||||
public function isValidFile( $file )
|
||||
public function isValidFile( File|string $file ): bool
|
||||
{
|
||||
$_where = array();
|
||||
foreach ( \IPS\nexus\Customer\CustomField::roots( NULL, NULL, array( 'f_type=?', 'Upload' ) ) as $field )
|
||||
foreach ( CustomField::roots( NULL, NULL, array( 'f_type=?', 'Upload' ) ) as $field )
|
||||
{
|
||||
$_where[] = "field_{$field->id}=?";
|
||||
}
|
||||
if ( !\count( $_where ) )
|
||||
if ( !count( $_where ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$where = array_fill( 0, \count( $_where ), (string) $file );
|
||||
$where = array_fill( 0, count( $_where ), (string) $file );
|
||||
array_unshift( $where, implode( ' OR ', $_where ) );
|
||||
|
||||
return (bool) \IPS\Db::i()->select( 'COUNT(*)', 'nexus_customers', $where )->first();
|
||||
return (bool) Db::i()->select( 'COUNT(*)', 'nexus_customers', $where )->first();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,29 +136,29 @@ class _Customer
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
public function delete() : void
|
||||
{
|
||||
$ids = array();
|
||||
$where = array();
|
||||
foreach ( \IPS\nexus\Customer\CustomField::roots( NULL, NULL, array( 'f_type=?', 'Upload' ) ) as $field )
|
||||
foreach ( CustomField::roots( NULL, NULL, array( 'f_type=?', 'Upload' ) ) as $field )
|
||||
{
|
||||
$ids[] = $field->id;
|
||||
$where[] = "field_{$field->id}<>''";
|
||||
}
|
||||
if ( !\count( $where ) )
|
||||
if ( !count( $where ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( \IPS\Db::i()->select( '*', 'nexus_customers', implode( ' OR ', $where ) ) as $customer )
|
||||
foreach ( Db::i()->select( '*', 'nexus_customers', implode( ' OR ', $where ) ) as $customer )
|
||||
{
|
||||
foreach ( $ids as $id )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\File::get( 'nexus_Customer', $customer[ 'field_' . $id ] )->delete();
|
||||
File::get( 'nexus_Customer', $customer[ 'field_' . $id ] )->delete();
|
||||
}
|
||||
catch( \Exception $e ){}
|
||||
catch( Exception ){}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,25 +12,33 @@
|
||||
namespace IPS\nexus\extensions\core\FileStorage;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use Exception;
|
||||
use IPS\Db;
|
||||
use IPS\Extensions\FileStorageAbstract;
|
||||
use IPS\File;
|
||||
use UnderflowException;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* File Storage Extension: Gateways
|
||||
*/
|
||||
class _Gateways
|
||||
class Gateways extends FileStorageAbstract
|
||||
{
|
||||
/**
|
||||
* Count stored files
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
public function count(): int
|
||||
{
|
||||
return \IPS\Db::i()->select( 'COUNT(*)', 'nexus_paymethods', array( 'm_validationfile<>?', '' ) )->first();
|
||||
return Db::i()->select( 'COUNT(*)', 'nexus_paymethods', array( 'm_validationfile<>?', '' ) )->first();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,23 +47,23 @@ class _Gateways
|
||||
* @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
|
||||
* @throws UnderflowException When file record doesn't exist. Indicating there are no more files to move
|
||||
* @return void
|
||||
*/
|
||||
public function move( $offset, $storageConfiguration, $oldConfiguration=NULL )
|
||||
public function move( int $offset, int $storageConfiguration, int $oldConfiguration=NULL ) : void
|
||||
{
|
||||
$record = \IPS\Db::i()->select( '*', 'nexus_paymethods', array( 'm_validationfile<>?', '' ), 'm_id', array( $offset, 1 ) )->first();
|
||||
$record = 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 );
|
||||
$file = 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'] ) );
|
||||
Db::i()->update( 'nexus_paymethods', array( 'm_validationfile' => (string) $file ), array( 'm_id=?', $record['m_id'] ) );
|
||||
}
|
||||
}
|
||||
catch( \Exception $e )
|
||||
catch( Exception )
|
||||
{
|
||||
/* Any issues are logged */
|
||||
}
|
||||
@@ -64,17 +72,17 @@ class _Gateways
|
||||
/**
|
||||
* Check if a file is valid
|
||||
*
|
||||
* @param string $file The file path to check
|
||||
* @param File|string $file The file path to check
|
||||
* @return bool
|
||||
*/
|
||||
public function isValidFile( $file )
|
||||
public function isValidFile( File|string $file ): bool
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\Db::i()->select( '*', 'nexus_paymethods', array( 'm_validationfile=?', (string) $file ) )->first();
|
||||
Db::i()->select( '*', 'nexus_paymethods', array( 'm_validationfile=?', $file ) )->first();
|
||||
return TRUE;
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
catch ( UnderflowException )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -85,15 +93,15 @@ class _Gateways
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
public function delete() : void
|
||||
{
|
||||
foreach( \IPS\Db::i()->select( '*', 'nexus_paymethods', array( 'm_validationfile<>?', '' ) ) as $product )
|
||||
foreach( Db::i()->select( '*', 'nexus_paymethods', array( 'm_validationfile<>?', '' ) ) as $product )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\File::get( 'nexus_Gateways', $product['m_validationfile'] )->delete();
|
||||
File::get( 'nexus_Gateways', $product['m_validationfile'] )->delete();
|
||||
}
|
||||
catch( \Exception $e ){}
|
||||
catch( Exception ){}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,25 +12,33 @@
|
||||
namespace IPS\nexus\extensions\core\FileStorage;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use Exception;
|
||||
use IPS\Db;
|
||||
use IPS\Extensions\FileStorageAbstract;
|
||||
use IPS\File;
|
||||
use UnderflowException;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* File Storage Extension: Package Groups
|
||||
*/
|
||||
class _PackageGroups
|
||||
class PackageGroups extends FileStorageAbstract
|
||||
{
|
||||
/**
|
||||
* Count stored files
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
public function count(): int
|
||||
{
|
||||
return \IPS\Db::i()->select( 'COUNT(*)', 'nexus_package_groups', array( 'pg_image<>?', '' ) )->first();
|
||||
return Db::i()->select( 'COUNT(*)', 'nexus_package_groups', array( 'pg_image<>?', '' ) )->first();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,58 +47,42 @@ class _PackageGroups
|
||||
* @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
|
||||
* @throws Underflowexception When file record doesn't exist. Indicating there are no more files to move
|
||||
* @return void
|
||||
*/
|
||||
public function move( $offset, $storageConfiguration, $oldConfiguration=NULL )
|
||||
public function move( int $offset, int $storageConfiguration, int $oldConfiguration=NULL ) : void
|
||||
{
|
||||
$record = \IPS\Db::i()->select( '*', 'nexus_package_groups', array( 'pg_image<>?', '' ), 'pg_id', array( $offset, 1 ) )->first();
|
||||
$record = Db::i()->select( '*', 'nexus_package_groups', array( 'pg_image<>?', '' ), 'pg_id', array( $offset, 1 ) )->first();
|
||||
|
||||
try
|
||||
{
|
||||
$file = \IPS\File::get( $oldConfiguration ?: 'nexus_PackageGroups', $record['pg_image'] )->move( $storageConfiguration );
|
||||
$file = File::get( $oldConfiguration ?: 'nexus_PackageGroups', $record['pg_image'] )->move( $storageConfiguration );
|
||||
|
||||
if ( (string) $file != $record['pg_image'] )
|
||||
{
|
||||
\IPS\Db::i()->update( 'nexus_package_groups', array( 'pg_image' => (string) $file ), array( 'pg_id=?', $record['pg_id'] ) );
|
||||
Db::i()->update( 'nexus_package_groups', array( 'pg_image' => (string) $file ), array( 'pg_id=?', $record['pg_id'] ) );
|
||||
}
|
||||
}
|
||||
catch( \Exception $e )
|
||||
catch( Exception )
|
||||
{
|
||||
/* Any issues are logged */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix all URLs
|
||||
*
|
||||
* @param int $offset This will be sent starting with 0, increasing to get all files stored by this extension
|
||||
* @return void
|
||||
*/
|
||||
public function fixUrls( $offset )
|
||||
{
|
||||
$record = \IPS\Db::i()->select( '*', 'nexus_package_groups', array( 'pg_image<>?', '' ), 'pg_id', array( $offset, 1 ) )->first();
|
||||
|
||||
if ( $new = \IPS\File::repairUrl( $record['pg_image'] ) )
|
||||
{
|
||||
\IPS\Db::i()->update( 'nexus_package_groups', array( 'pg_image' => $new ), array( 'pg_id=?', $record['pg_id'] ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a file is valid
|
||||
*
|
||||
* @param string $file The file path to check
|
||||
* @param File|string $file The file path to check
|
||||
* @return bool
|
||||
*/
|
||||
public function isValidFile( $file )
|
||||
public function isValidFile( File|string $file ): bool
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\Db::i()->select( '*', 'nexus_package_groups', array( 'pg_image=?', (string) $file ) )->first();
|
||||
Db::i()->select( '*', 'nexus_package_groups', array( 'pg_image=?', (string) $file ) )->first();
|
||||
return TRUE;
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
catch ( UnderflowException )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -101,15 +93,15 @@ class _PackageGroups
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
public function delete() : void
|
||||
{
|
||||
foreach( \IPS\Db::i()->select( '*', 'nexus_package_groups', array( 'pg_image<>?', '' ) ) as $product )
|
||||
foreach( Db::i()->select( '*', 'nexus_package_groups', array( 'pg_image<>?', '' ) ) as $product )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\File::get( 'nexus_PackageGroups', $product['pg_image'] )->delete();
|
||||
File::get( 'nexus_PackageGroups', $product['pg_image'] )->delete();
|
||||
}
|
||||
catch( \Exception $e ){}
|
||||
catch( Exception ){}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,25 +12,33 @@
|
||||
namespace IPS\nexus\extensions\core\FileStorage;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use Exception;
|
||||
use IPS\Db;
|
||||
use IPS\Extensions\FileStorageAbstract;
|
||||
use IPS\File;
|
||||
use UnderflowException;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* File Storage Extension: Package Images
|
||||
*/
|
||||
class _Products
|
||||
class Products extends FileStorageAbstract
|
||||
{
|
||||
/**
|
||||
* Count stored files
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
public function count(): int
|
||||
{
|
||||
return \IPS\Db::i()->select( 'COUNT(*)', 'nexus_package_images' )->first();
|
||||
return Db::i()->select( 'COUNT(*)', 'nexus_package_images' )->first();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,58 +47,42 @@ class _Products
|
||||
* @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
|
||||
* @throws Underflowexception When file record doesn't exist. Indicating there are no more files to move
|
||||
* @return void
|
||||
*/
|
||||
public function move( $offset, $storageConfiguration, $oldConfiguration=NULL )
|
||||
public function move( int $offset, int $storageConfiguration, int $oldConfiguration=NULL ) : void
|
||||
{
|
||||
$record = \IPS\Db::i()->select( '*', 'nexus_package_images', array(), 'image_id', array( $offset, 1 ) )->first();
|
||||
$record = Db::i()->select( '*', 'nexus_package_images', array(), 'image_id', array( $offset, 1 ) )->first();
|
||||
|
||||
try
|
||||
{
|
||||
$file = \IPS\File::get( $oldConfiguration ?: 'nexus_Products', $record['image_location'] )->move( $storageConfiguration );
|
||||
$file = File::get( $oldConfiguration ?: 'nexus_Products', $record['image_location'] )->move( $storageConfiguration );
|
||||
|
||||
if ( (string) $file != $record['image_location'] )
|
||||
{
|
||||
\IPS\Db::i()->update( 'nexus_package_images', array( 'image_location' => (string) $file ), array( 'image_id=?', $record['image_id'] ) );
|
||||
Db::i()->update( 'nexus_package_images', array( 'image_location' => (string) $file ), array( 'image_id=?', $record['image_id'] ) );
|
||||
}
|
||||
}
|
||||
catch( \Exception $e )
|
||||
catch( Exception )
|
||||
{
|
||||
/* Any issues are logged */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix all URLs
|
||||
*
|
||||
* @param int $offset This will be sent starting with 0, increasing to get all files stored by this extension
|
||||
* @return void
|
||||
*/
|
||||
public function fixUrls( $offset )
|
||||
{
|
||||
$record = \IPS\Db::i()->select( '*', 'nexus_package_images', array(), 'image_id', array( $offset, 1 ) )->first();
|
||||
|
||||
if ( $new = \IPS\File::repairUrl( $record['image_location'] ) )
|
||||
{
|
||||
\IPS\Db::i()->update( 'nexus_package_images', array( 'image_location' => $new ), array( 'image_id=?', $record['image_id'] ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a file is valid
|
||||
*
|
||||
* @param string $file The file path to check
|
||||
* @param File|string $file The file path to check
|
||||
* @return bool
|
||||
*/
|
||||
public function isValidFile( $file )
|
||||
public function isValidFile( File|string $file ): bool
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\Db::i()->select( '*', 'nexus_package_images', array( 'image_location=?', (string) $file ) )->first();
|
||||
Db::i()->select( '*', 'nexus_package_images', array( 'image_location=?', (string) $file ) )->first();
|
||||
return TRUE;
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
catch ( UnderflowException )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -101,15 +93,15 @@ class _Products
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
public function delete() : void
|
||||
{
|
||||
foreach( \IPS\Db::i()->select( '*', 'nexus_package_images', "image_location IS NOT NULL" ) as $product )
|
||||
foreach( Db::i()->select( '*', 'nexus_package_images', "image_location IS NOT NULL" ) as $product )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\File::get( 'nexus_Products', $product['image_location'] )->delete();
|
||||
File::get( 'nexus_Products', $product['image_location'] )->delete();
|
||||
}
|
||||
catch( \Exception $e ){}
|
||||
catch( Exception ){}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,25 +12,35 @@
|
||||
namespace IPS\nexus\extensions\core\FileStorage;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use Exception;
|
||||
use IPS\Db;
|
||||
use IPS\Extensions\FileStorageAbstract;
|
||||
use IPS\File;
|
||||
use IPS\nexus\Package\CustomField;
|
||||
use UnderflowException;
|
||||
use function count;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* File Storage Extension: Purchase Custom Fields
|
||||
*/
|
||||
class _PurchaseFields
|
||||
class PurchaseFields extends FileStorageAbstract
|
||||
{
|
||||
/**
|
||||
* Count stored files
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
public function count(): int
|
||||
{
|
||||
return \IPS\Db::i()->select( 'COUNT(*)', 'nexus_package_fields', array( 'cf_type=?', 'upload' ) )->first();
|
||||
return Db::i()->select( 'COUNT(*)', 'nexus_package_fields', array( 'cf_type=?', 'upload' ) )->first();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,13 +49,13 @@ class _PurchaseFields
|
||||
* @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
|
||||
* @throws Underflowexception When file record doesn't exist. Indicating there are no more files to move
|
||||
* @return void
|
||||
*/
|
||||
public function move( $offset, $storageConfiguration, $oldConfiguration=NULL )
|
||||
public function move( int $offset, int $storageConfiguration, int $oldConfiguration=NULL ) : void
|
||||
{
|
||||
$customFields = \IPS\nexus\Package\CustomField::roots( NULL, NULL, array( 'cf_type=?', 'upload' ) );
|
||||
if ( \count( $customFields ) )
|
||||
$customFields = CustomField::roots( NULL, NULL, array( 'cf_type=?', 'upload' ) );
|
||||
if ( count( $customFields ) )
|
||||
{
|
||||
$packages = array();
|
||||
foreach ( $customFields as $field )
|
||||
@@ -56,10 +66,10 @@ class _PurchaseFields
|
||||
}
|
||||
}
|
||||
|
||||
$purchase = \IPS\Db::i()->select( '*', 'nexus_purchases', array(
|
||||
$purchase = Db::i()->select( '*', 'nexus_purchases', array(
|
||||
array( 'ps_app=?', 'nexus' ),
|
||||
array( 'ps_type=?', 'package' ),
|
||||
array( \IPS\Db::i()->in( 'ps_item_id', array_unique( $packages ) ) )
|
||||
array( Db::i()->in( 'ps_item_id', array_unique( $packages ) ) )
|
||||
), 'ps_id', array( $offset, 1 ) )->first();
|
||||
|
||||
$fieldValues = json_decode( $purchase['ps_custom_fields'], TRUE );
|
||||
@@ -69,77 +79,33 @@ class _PurchaseFields
|
||||
{
|
||||
try
|
||||
{
|
||||
$fieldValues[ $k ] = \IPS\File::get( $oldConfiguration ?: 'nexus_PurchaseFields', $fieldValues[ $k ] )->move( $storageConfiguration );
|
||||
$fieldValues[ $k ] = File::get( $oldConfiguration ?: 'nexus_PurchaseFields', $fieldValues[ $k ] )->move( $storageConfiguration );
|
||||
}
|
||||
catch( \Exception $e )
|
||||
catch( Exception )
|
||||
{
|
||||
/* Any issues are logged */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Db::i()->update( 'nexus_purchases', array( 'ps_custom_fields' => json_encode( $fieldValues ) ), array( 'ps_id=?', $purchase['ps_id'] ) );
|
||||
Db::i()->update( 'nexus_purchases', array( 'ps_custom_fields' => json_encode( $fieldValues ) ), array( 'ps_id=?', $purchase['ps_id'] ) );
|
||||
}
|
||||
|
||||
throw new \UnderflowException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix all URLs
|
||||
*
|
||||
* @param int $offset This will be sent starting with 0, increasing to get all files stored by this extension
|
||||
* @return void
|
||||
*/
|
||||
public function fixUrls( $offset )
|
||||
{
|
||||
$customFields = \IPS\nexus\Package\CustomField::roots( NULL, NULL, array( 'cf_type=?', 'upload' ) );
|
||||
if ( \count( $customFields ) )
|
||||
{
|
||||
$packages = array();
|
||||
foreach ( $customFields as $field )
|
||||
{
|
||||
if ( $field->packages )
|
||||
{
|
||||
$packages = array_merge( $packages, explode( ',', $field->packages ) );
|
||||
}
|
||||
}
|
||||
|
||||
$purchase = \IPS\Db::i()->select( '*', 'nexus_purchases', array(
|
||||
array( 'ps_app=?', 'nexus' ),
|
||||
array( 'ps_type=?', 'package' ),
|
||||
array( \IPS\Db::i()->in( 'ps_item_id', array_unique( $packages ) ) )
|
||||
), 'ps_id', array( $offset, 1 ) )->first();
|
||||
|
||||
$fieldValues = json_decode( $purchase['ps_custom_fields'], TRUE );
|
||||
foreach ( $fieldValues as $k => $v )
|
||||
{
|
||||
if ( array_key_exists( $k, $customFields ) )
|
||||
{
|
||||
if ( $new = \IPS\File::repairUrl( $fieldValues[ $k ] ) )
|
||||
{
|
||||
$fieldValues[ $k ] = $new;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Db::i()->update( 'nexus_purchases', array( 'ps_custom_fields' => json_encode( $fieldValues ) ), array( 'ps_id=?', $purchase['ps_id'] ) );
|
||||
}
|
||||
|
||||
throw new \UnderflowException;
|
||||
throw new UnderflowException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a file is valid
|
||||
*
|
||||
* @param string $file The file path to check
|
||||
* @param File|string $file The file path to check
|
||||
* @return bool
|
||||
*/
|
||||
public function isValidFile( $file )
|
||||
public function isValidFile( File|string $file ): bool
|
||||
{
|
||||
$customFields = \IPS\nexus\Package\CustomField::roots( NULL, NULL, array( 'cf_type=?', 'upload' ) );
|
||||
if ( \count( $customFields ) )
|
||||
$customFields = CustomField::roots( NULL, NULL, array( 'cf_type=?', 'upload' ) );
|
||||
if ( count( $customFields ) )
|
||||
{
|
||||
foreach ( \IPS\Db::i()->select( '*', 'nexus_purchases', array( "ps_custom_fields LIKE ?", "%" . str_replace( '\\', '\\\\\\', trim( json_encode( (string) $file ), '"' ) . "%" ) ) ) as $purchase )
|
||||
foreach ( Db::i()->select( '*', 'nexus_purchases', array( "ps_custom_fields LIKE ?", "%" . str_replace( '\\', '\\\\\\', trim( json_encode( (string) $file ), '"' ) . "%" ) ) ) as $purchase )
|
||||
{
|
||||
$fieldValues = json_decode( $purchase['ps_custom_fields'], TRUE );
|
||||
foreach ( $customFields as $field )
|
||||
@@ -159,10 +125,10 @@ class _PurchaseFields
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
public function delete() : void
|
||||
{
|
||||
$customFields = \IPS\nexus\Package\CustomField::roots( NULL, NULL, array( 'cf_type=?', 'upload' ) );
|
||||
if ( \count( $customFields ) )
|
||||
$customFields = CustomField::roots( NULL, NULL, array( 'cf_type=?', 'upload' ) );
|
||||
if ( count( $customFields ) )
|
||||
{
|
||||
$packages = array();
|
||||
foreach ( $customFields as $field )
|
||||
@@ -176,10 +142,10 @@ class _PurchaseFields
|
||||
$where = array(
|
||||
array( 'ps_app=?', 'nexus' ),
|
||||
array( 'ps_type=?', 'package' ),
|
||||
array( \IPS\Db::i()->in( 'ps_item_id', array_unique( $packages ) ) )
|
||||
array( Db::i()->in( 'ps_item_id', array_unique( $packages ) ) )
|
||||
);
|
||||
|
||||
foreach( \IPS\Db::i()->select( '*', 'nexus_purchases', $where ) as $purchase )
|
||||
foreach( Db::i()->select( '*', 'nexus_purchases', $where ) as $purchase )
|
||||
{
|
||||
$fieldValues = json_decode( $purchase['ps_custom_fields'], TRUE );
|
||||
foreach ( $fieldValues as $k => $v )
|
||||
@@ -188,9 +154,9 @@ class _PurchaseFields
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\File::get( 'nexus_PurchaseFields', $fieldValues[ $k ] )->delete();
|
||||
File::get( 'nexus_PurchaseFields', $fieldValues[ $k ] )->delete();
|
||||
}
|
||||
catch( \Exception $e ){}
|
||||
catch( Exception ){}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,216 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief File Storage Extension: Support Custom Fields
|
||||
* @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 17 Apr 2014
|
||||
*/
|
||||
|
||||
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: Support Custom Fields
|
||||
*/
|
||||
class _Support
|
||||
{
|
||||
/**
|
||||
* Count stored files
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return \IPS\Db::i()->select( 'COUNT(*)', 'nexus_support_fields', array( 'sf_type=?', 'upload' ) )->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
|
||||
*/
|
||||
public function move( $offset, $storageConfiguration, $oldConfiguration=NULL )
|
||||
{
|
||||
$customFields = \IPS\nexus\Support\CustomField::roots( NULL, NULL, array( 'sf_type=?', 'upload' ) );
|
||||
if ( \count( $customFields ) )
|
||||
{
|
||||
$where = array();
|
||||
$departments = array();
|
||||
foreach ( $customFields as $field )
|
||||
{
|
||||
if ( $field->departments and $field->departments !== '*' )
|
||||
{
|
||||
$departments = array_merge( $departments, explode( ',', $field->departments ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$where = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( $where !== NULL )
|
||||
{
|
||||
$where = \IPS\Db::i()->in( 'r_department', array_unique( $departments ) );
|
||||
}
|
||||
|
||||
$request = \IPS\Db::i()->select( '*', 'nexus_support_requests', $where, 'r_id', array( $offset, 1 ) )->first();
|
||||
|
||||
$fieldValues = json_decode( $request['r_cfields'], TRUE );
|
||||
foreach ( $fieldValues as $k => $v )
|
||||
{
|
||||
if ( array_key_exists( $k, $customFields ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$fieldValues[ $k ] = \IPS\File::get( $oldConfiguration ?: 'nexus_Support', $fieldValues[ $k ] )->move( $storageConfiguration );
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
/* Any issues are logged */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Db::i()->update( 'nexus_support_requests', array( 'r_cfields' => json_encode( $fieldValues ) ), array( 'r_id=?', $request['r_id'] ) );
|
||||
}
|
||||
|
||||
throw new \UnderflowException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix all URLs
|
||||
*
|
||||
* @param int $offset This will be sent starting with 0, increasing to get all files stored by this extension
|
||||
* @return void
|
||||
*/
|
||||
public function fixUrls( $offset )
|
||||
{
|
||||
$customFields = \IPS\nexus\Support\CustomField::roots( NULL, NULL, array( 'sf_type=?', 'upload' ) );
|
||||
if ( \count( $customFields ) )
|
||||
{
|
||||
$where = array();
|
||||
$departments = array();
|
||||
foreach ( $customFields as $field )
|
||||
{
|
||||
if ( $field->departments and $field->departments !== '*' )
|
||||
{
|
||||
$departments = array_merge( $departments, explode( ',', $field->departments ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$where = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( $where !== NULL )
|
||||
{
|
||||
$where = \IPS\Db::i()->in( 'r_department', array_unique( $departments ) );
|
||||
}
|
||||
|
||||
$request = \IPS\Db::i()->select( '*', 'nexus_support_requests', $where, 'r_id', array( $offset, 1 ) )->first();
|
||||
|
||||
$fieldValues = json_decode( $request['r_cfields'], TRUE );
|
||||
foreach ( $fieldValues as $k => $v )
|
||||
{
|
||||
if ( array_key_exists( $k, $customFields ) )
|
||||
{
|
||||
if ( $new = \IPS\File::repairUrl( $fieldValues[ $k ] ) )
|
||||
{
|
||||
$fieldValues[ $k ] = $new;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Db::i()->update( 'nexus_support_requests', array( 'r_cfields' => json_encode( $fieldValues ) ), array( 'r_id=?', $request['r_id'] ) );
|
||||
}
|
||||
|
||||
throw new \UnderflowException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a file is valid
|
||||
*
|
||||
* @param string $file The file path to check
|
||||
* @return bool
|
||||
*/
|
||||
public function isValidFile( $file )
|
||||
{
|
||||
$customFields = \IPS\nexus\Support\CustomField::roots( NULL, NULL, array( 'sf_type=?', 'upload' ) );
|
||||
if ( \count( $customFields ) )
|
||||
{
|
||||
foreach ( \IPS\Db::i()->select( '*', 'nexus_support_requests', array( "r_cfields LIKE ?", "%" . str_replace( '\\', '\\\\\\', trim( json_encode( (string) $file ), '"' ) . "%" ) ) ) as $request )
|
||||
{
|
||||
$fieldValues = json_decode( $request['r_cfields'], TRUE );
|
||||
foreach ( $customFields as $field )
|
||||
{
|
||||
if ( $fieldValues[ $field->id ] == (string) $file )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all stored files
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
$customFields = \IPS\nexus\Support\CustomField::roots( NULL, NULL, array( 'sf_type=?', 'upload' ) );
|
||||
if ( \count( $customFields ) )
|
||||
{
|
||||
$where = array();
|
||||
$departments = array();
|
||||
foreach ( $customFields as $field )
|
||||
{
|
||||
if ( $field->departments and $field->departments !== '*' )
|
||||
{
|
||||
$departments = array_merge( $departments, explode( ',', $departments ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$where = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( $where !== NULL )
|
||||
{
|
||||
$where = \IPS\Db::i()->in( 'r_department', array_unique( $departments ) );
|
||||
}
|
||||
|
||||
foreach( \IPS\Db::i()->select( '*', 'nexus_support_requests', $where ) as $request )
|
||||
{
|
||||
$fieldValues = json_decode( $request['r_cfields'], TRUE );
|
||||
foreach ( $fieldValues as $k => $v )
|
||||
{
|
||||
if ( array_key_exists( $k, $customFields ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\File::get( 'nexus_Support', $fieldValues[ $k ] )->delete();
|
||||
}
|
||||
catch( \Exception $e ){}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,64 +12,77 @@
|
||||
namespace IPS\nexus\extensions\core\FrontNavigation;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Application\Module;
|
||||
use IPS\core\FrontNavigation\FrontNavigationAbstract;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Front Navigation Extension: Addresses
|
||||
*/
|
||||
class _Addresses extends \IPS\core\FrontNavigation\FrontNavigationAbstract
|
||||
{
|
||||
class Addresses extends FrontNavigationAbstract
|
||||
{
|
||||
/**
|
||||
* @var string Default icon
|
||||
*/
|
||||
public string $defaultIcon = '\f3c5';
|
||||
|
||||
/**
|
||||
* Get Type Title which will display in the AdminCP Menu Manager
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function typeTitle()
|
||||
public static function typeTitle(): string
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('client_addresses');
|
||||
return Member::loggedIn()->language()->addToStack('client_addresses');
|
||||
}
|
||||
|
||||
/**
|
||||
* Can the currently logged in user access the content this item links to?
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public function canAccessContent()
|
||||
public function canAccessContent(): bool
|
||||
{
|
||||
return ( \IPS\Member::loggedIn()->member_id AND \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'nexus', 'clients' ) ) );
|
||||
return ( Member::loggedIn()->member_id AND Member::loggedIn()->canAccessModule( Module::get( 'nexus', 'clients' ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Title
|
||||
*
|
||||
* @return string
|
||||
* @return string
|
||||
*/
|
||||
public function title()
|
||||
public function title(): string
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('client_addresses');
|
||||
return Member::loggedIn()->language()->addToStack('client_addresses');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Link
|
||||
*
|
||||
* @return \IPS\Http\Url
|
||||
* @return string|Url|null
|
||||
*/
|
||||
public function link()
|
||||
public function link(): Url|string|null
|
||||
{
|
||||
return \IPS\Http\Url::internal( "app=nexus&module=clients&controller=addresses", 'front', 'clientsaddresses' );
|
||||
return Url::internal( "app=nexus&module=clients&controller=addresses", 'front', 'clientsaddresses' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Active?
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public function active()
|
||||
public function active(): bool
|
||||
{
|
||||
return \IPS\Dispatcher::i()->application->directory === 'nexus' and \IPS\Dispatcher::i()->module and \IPS\Dispatcher::i()->module->key === 'clients' and \IPS\Dispatcher::i()->controller == 'addresses';
|
||||
return Dispatcher::i()->application->directory === 'nexus' and Dispatcher::i()->module and Dispatcher::i()->module->key === 'clients' and Dispatcher::i()->controller == 'addresses';
|
||||
}
|
||||
}
|
||||
@@ -12,64 +12,77 @@
|
||||
namespace IPS\nexus\extensions\core\FrontNavigation;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Application\Module;
|
||||
use IPS\core\FrontNavigation\FrontNavigationAbstract;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Front Navigation Extension: Alternative Contacts
|
||||
*/
|
||||
class _Alternatives extends \IPS\core\FrontNavigation\FrontNavigationAbstract
|
||||
{
|
||||
class Alternatives extends FrontNavigationAbstract
|
||||
{
|
||||
/**
|
||||
* @var string Default icon
|
||||
*/
|
||||
public string $defaultIcon = '\f2b9';
|
||||
|
||||
/**
|
||||
* Get Type Title which will display in the AdminCP Menu Manager
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function typeTitle()
|
||||
public static function typeTitle(): string
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('client_alternatives');
|
||||
return Member::loggedIn()->language()->addToStack('client_alternatives');
|
||||
}
|
||||
|
||||
/**
|
||||
* Can the currently logged in user access the content this item links to?
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public function canAccessContent()
|
||||
public function canAccessContent(): bool
|
||||
{
|
||||
return ( \IPS\Member::loggedIn()->member_id AND \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'nexus', 'clients' ) ) );
|
||||
return ( Member::loggedIn()->member_id AND Member::loggedIn()->canAccessModule( Module::get( 'nexus', 'clients' ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Title
|
||||
*
|
||||
* @return string
|
||||
* @return string
|
||||
*/
|
||||
public function title()
|
||||
public function title(): string
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('client_alternatives');
|
||||
return Member::loggedIn()->language()->addToStack('client_alternatives');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Link
|
||||
*
|
||||
* @return \IPS\Http\Url
|
||||
* @return string|Url|null
|
||||
*/
|
||||
public function link()
|
||||
public function link(): Url|string|null
|
||||
{
|
||||
return \IPS\Http\Url::internal( "app=nexus&module=clients&controller=alternatives", 'front', 'clientsalternatives' );
|
||||
return Url::internal( "app=nexus&module=clients&controller=alternatives", 'front', 'clientsalternatives' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Active?
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public function active()
|
||||
public function active(): bool
|
||||
{
|
||||
return \IPS\Dispatcher::i()->application->directory === 'nexus' and \IPS\Dispatcher::i()->module and \IPS\Dispatcher::i()->module->key === 'clients' and \IPS\Dispatcher::i()->controller == 'alternatives';
|
||||
return Dispatcher::i()->application->directory === 'nexus' and Dispatcher::i()->module and Dispatcher::i()->module->key === 'clients' and Dispatcher::i()->controller == 'alternatives';
|
||||
}
|
||||
}
|
||||
@@ -12,25 +12,34 @@
|
||||
namespace IPS\nexus\extensions\core\FrontNavigation;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Application\Module;
|
||||
use IPS\core\FrontNavigation\FrontNavigationAbstract;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\Settings;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Front Navigation Extension: Billing Agreements
|
||||
*/
|
||||
class _BillingAgreements extends \IPS\core\FrontNavigation\FrontNavigationAbstract
|
||||
class BillingAgreements extends FrontNavigationAbstract
|
||||
{
|
||||
/**
|
||||
* Get Type Title which will display in the AdminCP Menu Manager
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function typeTitle()
|
||||
public static function typeTitle(): string
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('client_billing_agreements');
|
||||
return Member::loggedIn()->language()->addToStack('client_billing_agreements');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -38,50 +47,50 @@ class _BillingAgreements extends \IPS\core\FrontNavigation\FrontNavigationAbstra
|
||||
* For example, if this will link to a particular feature which has been diabled, it should
|
||||
* not be available, even if the user has permission
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public static function isEnabled()
|
||||
public static function isEnabled() : bool
|
||||
{
|
||||
return \IPS\Settings::i()->billing_agreement_gateways;
|
||||
return Settings::i()->billing_agreement_gateways;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can the currently logged in user access the content this item links to?
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public function canAccessContent()
|
||||
public function canAccessContent(): bool
|
||||
{
|
||||
return ( \IPS\Member::loggedIn()->member_id AND \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'nexus', 'clients' ) ) );
|
||||
return ( Member::loggedIn()->member_id AND Member::loggedIn()->canAccessModule( Module::get( 'nexus', 'clients' ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Title
|
||||
*
|
||||
* @return string
|
||||
* @return string
|
||||
*/
|
||||
public function title()
|
||||
public function title(): string
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('client_billing_agreements');
|
||||
return Member::loggedIn()->language()->addToStack('client_billing_agreements');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Link
|
||||
*
|
||||
* @return \IPS\Http\Url
|
||||
* @return string|Url|null
|
||||
*/
|
||||
public function link()
|
||||
public function link(): Url|string|null
|
||||
{
|
||||
return \IPS\Http\Url::internal( "app=nexus&module=clients&controller=billingagreements", 'front', 'clientsbillingagreements' );
|
||||
return Url::internal( "app=nexus&module=clients&controller=billingagreements", 'front', 'clientsbillingagreements' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Active?
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public function active()
|
||||
public function active(): bool
|
||||
{
|
||||
return \IPS\Dispatcher::i()->application->directory === 'nexus' and \IPS\Dispatcher::i()->module and \IPS\Dispatcher::i()->module->key === 'clients' and \IPS\Dispatcher::i()->controller == 'billingagreements';
|
||||
return Dispatcher::i()->application->directory === 'nexus' and Dispatcher::i()->module and Dispatcher::i()->module->key === 'clients' and Dispatcher::i()->controller == 'billingagreements';
|
||||
}
|
||||
}
|
||||
@@ -12,25 +12,34 @@
|
||||
namespace IPS\nexus\extensions\core\FrontNavigation;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Application\Module;
|
||||
use IPS\core\FrontNavigation\FrontNavigationAbstract;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\Settings;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Front Navigation Extension: Cards
|
||||
*/
|
||||
class _Cards extends \IPS\core\FrontNavigation\FrontNavigationAbstract
|
||||
class Cards extends FrontNavigationAbstract
|
||||
{
|
||||
/**
|
||||
* Get Type Title which will display in the AdminCP Menu Manager
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function typeTitle()
|
||||
public static function typeTitle(): string
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('client_cards');
|
||||
return Member::loggedIn()->language()->addToStack('client_cards');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -38,50 +47,50 @@ class _Cards extends \IPS\core\FrontNavigation\FrontNavigationAbstract
|
||||
* For example, if this will link to a particular feature which has been diabled, it should
|
||||
* not be available, even if the user has permission
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public static function isEnabled()
|
||||
public static function isEnabled() : bool
|
||||
{
|
||||
return \IPS\Settings::i()->card_storage_gateways;
|
||||
return Settings::i()->card_storage_gateways;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can the currently logged in user access the content this item links to?
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public function canAccessContent()
|
||||
public function canAccessContent(): bool
|
||||
{
|
||||
return ( \IPS\Member::loggedIn()->member_id AND \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'nexus', 'clients' ) ) );
|
||||
return ( Member::loggedIn()->member_id AND Member::loggedIn()->canAccessModule( Module::get( 'nexus', 'clients' ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Title
|
||||
*
|
||||
* @return string
|
||||
* @return string
|
||||
*/
|
||||
public function title()
|
||||
public function title(): string
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('client_cards');
|
||||
return Member::loggedIn()->language()->addToStack('client_cards');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Link
|
||||
*
|
||||
* @return \IPS\Http\Url
|
||||
* @return string|Url|null
|
||||
*/
|
||||
public function link()
|
||||
public function link(): Url|string|null
|
||||
{
|
||||
return \IPS\Http\Url::internal( "app=nexus&module=clients&controller=cards", 'front', 'clientscards' );
|
||||
return Url::internal( "app=nexus&module=clients&controller=cards", 'front', 'clientscards' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Active?
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public function active()
|
||||
public function active(): bool
|
||||
{
|
||||
return \IPS\Dispatcher::i()->application->directory === 'nexus' and \IPS\Dispatcher::i()->module and \IPS\Dispatcher::i()->module->key === 'clients' and \IPS\Dispatcher::i()->controller == 'cards';
|
||||
return Dispatcher::i()->application->directory === 'nexus' and Dispatcher::i()->module and Dispatcher::i()->module->key === 'clients' and Dispatcher::i()->controller == 'cards';
|
||||
}
|
||||
}
|
||||
@@ -12,16 +12,27 @@
|
||||
namespace IPS\nexus\extensions\core\FrontNavigation;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Application\Module;
|
||||
use IPS\core\FrontNavigation\FrontNavigationAbstract;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\Settings;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function is_array;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Front Navigation Extension: Account Credit
|
||||
*/
|
||||
class _Credit extends \IPS\core\FrontNavigation\FrontNavigationAbstract
|
||||
class Credit extends FrontNavigationAbstract
|
||||
{
|
||||
|
||||
/**
|
||||
@@ -29,9 +40,9 @@ class _Credit extends \IPS\core\FrontNavigation\FrontNavigationAbstract
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function typeTitle()
|
||||
public static function typeTitle(): string
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('client_credit');
|
||||
return Member::loggedIn()->language()->addToStack('client_credit');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,50 +50,50 @@ class _Credit extends \IPS\core\FrontNavigation\FrontNavigationAbstract
|
||||
* For example, if this will link to a particular feature which has been diabled, it should
|
||||
* not be available, even if the user has permission
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public static function isEnabled()
|
||||
public static function isEnabled() : bool
|
||||
{
|
||||
return ( \IPS\Settings::i()->nexus_min_topup or ( \is_array( json_decode( \IPS\Settings::i()->nexus_payout, TRUE ) ) AND \count( json_decode( \IPS\Settings::i()->nexus_payout, TRUE ) ) ) );
|
||||
return ( Settings::i()->nexus_min_topup or ( is_array( json_decode( Settings::i()->nexus_payout, TRUE ) ) AND count( json_decode( Settings::i()->nexus_payout, TRUE ) ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Can the currently logged in user access the content this item links to?
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public function canAccessContent()
|
||||
public function canAccessContent(): bool
|
||||
{
|
||||
return ( \IPS\Member::loggedIn()->member_id AND \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'nexus', 'clients' ) ) );
|
||||
return ( Member::loggedIn()->member_id AND Member::loggedIn()->canAccessModule( Module::get( 'nexus', 'clients' ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Title
|
||||
*
|
||||
* @return string
|
||||
* @return string
|
||||
*/
|
||||
public function title()
|
||||
public function title(): string
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('client_credit');
|
||||
return Member::loggedIn()->language()->addToStack('client_credit');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Link
|
||||
*
|
||||
* @return \IPS\Http\Url
|
||||
* @return string|Url|null
|
||||
*/
|
||||
public function link()
|
||||
public function link(): Url|string|null
|
||||
{
|
||||
return \IPS\Http\Url::internal( "app=nexus&module=clients&controller=credit", 'front', 'clientscredit' );
|
||||
return Url::internal( "app=nexus&module=clients&controller=credit", 'front', 'clientscredit' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Active?
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public function active()
|
||||
public function active(): bool
|
||||
{
|
||||
return \IPS\Dispatcher::i()->application->directory === 'nexus' and \IPS\Dispatcher::i()->module and \IPS\Dispatcher::i()->module->key === 'clients' and \IPS\Dispatcher::i()->controller == 'credit';
|
||||
return Dispatcher::i()->application->directory === 'nexus' and Dispatcher::i()->module and Dispatcher::i()->module->key === 'clients' and Dispatcher::i()->controller == 'credit';
|
||||
}
|
||||
}
|
||||
@@ -12,25 +12,39 @@
|
||||
namespace IPS\nexus\extensions\core\FrontNavigation;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Application\Module;
|
||||
use IPS\core\FrontNavigation\FrontNavigationAbstract;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\Settings;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Front Navigation Extension: Donations
|
||||
*/
|
||||
class _Donations extends \IPS\core\FrontNavigation\FrontNavigationAbstract
|
||||
{
|
||||
class Donations extends FrontNavigationAbstract
|
||||
{
|
||||
/**
|
||||
* @var string Default icon
|
||||
*/
|
||||
public string $defaultIcon = '\f1cd';
|
||||
|
||||
/**
|
||||
* Get Type Title which will display in the AdminCP Menu Manager
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function typeTitle()
|
||||
public static function typeTitle(): string
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('client_donations');
|
||||
return Member::loggedIn()->language()->addToStack('client_donations');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -38,50 +52,50 @@ class _Donations extends \IPS\core\FrontNavigation\FrontNavigationAbstract
|
||||
* For example, if this will link to a particular feature which has been diabled, it should
|
||||
* not be available, even if the user has permission
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public static function isEnabled()
|
||||
public static function isEnabled(): bool
|
||||
{
|
||||
return \IPS\Settings::i()->donation_goals;
|
||||
return Settings::i()->donation_goals;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can the currently logged in user access the content this item links to?
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public function canAccessContent()
|
||||
public function canAccessContent(): bool
|
||||
{
|
||||
return \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'nexus', 'clients' ) );
|
||||
return Member::loggedIn()->canAccessModule( Module::get( 'nexus', 'clients' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Title
|
||||
*
|
||||
* @return string
|
||||
* @return string
|
||||
*/
|
||||
public function title()
|
||||
public function title(): string
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('client_donations');
|
||||
return Member::loggedIn()->language()->addToStack('client_donations');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Link
|
||||
*
|
||||
* @return \IPS\Http\Url
|
||||
* @return string|Url|null
|
||||
*/
|
||||
public function link()
|
||||
public function link(): Url|string|null
|
||||
{
|
||||
return \IPS\Http\Url::internal( "app=nexus&module=clients&controller=donations", 'front', 'clientsdonations' );
|
||||
return Url::internal( "app=nexus&module=clients&controller=donations", 'front', 'clientsdonations' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Active?
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public function active()
|
||||
public function active(): bool
|
||||
{
|
||||
return \IPS\Dispatcher::i()->application->directory === 'nexus' and \IPS\Dispatcher::i()->module and \IPS\Dispatcher::i()->module->key === 'clients' and \IPS\Dispatcher::i()->controller == 'donations';
|
||||
return Dispatcher::i()->application->directory === 'nexus' and Dispatcher::i()->module and Dispatcher::i()->module->key === 'clients' and Dispatcher::i()->controller == 'donations';
|
||||
}
|
||||
}
|
||||
@@ -12,25 +12,34 @@
|
||||
namespace IPS\nexus\extensions\core\FrontNavigation;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\core\FrontNavigation\FrontNavigationAbstract;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\Settings;
|
||||
use function count;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Front Navigation Extension: Gift Cards
|
||||
*/
|
||||
class _Gifts extends \IPS\core\FrontNavigation\FrontNavigationAbstract
|
||||
class Gifts extends FrontNavigationAbstract
|
||||
{
|
||||
/**
|
||||
* Get Type Title which will display in the AdminCP Menu Manager
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function typeTitle()
|
||||
public static function typeTitle(): string
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('gift_vouchers');
|
||||
return Member::loggedIn()->language()->addToStack('gift_vouchers');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -38,40 +47,40 @@ class _Gifts extends \IPS\core\FrontNavigation\FrontNavigationAbstract
|
||||
* For example, if this will link to a particular feature which has been diabled, it should
|
||||
* not be available, even if the user has permission
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public static function isEnabled()
|
||||
public static function isEnabled(): bool
|
||||
{
|
||||
return ( ( $giftVouchers = json_decode( \IPS\Settings::i()->nexus_gift_vouchers, TRUE ) and \count( $giftVouchers ) ) or \IPS\Settings::i()->nexus_gift_vouchers_free );
|
||||
return ( ( $giftVouchers = json_decode( Settings::i()->nexus_gift_vouchers, TRUE ) and count( $giftVouchers ) ) or Settings::i()->nexus_gift_vouchers_free );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Title
|
||||
*
|
||||
* @return string
|
||||
* @return string
|
||||
*/
|
||||
public function title()
|
||||
public function title(): string
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('gift_vouchers');
|
||||
return Member::loggedIn()->language()->addToStack('gift_vouchers');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Link
|
||||
*
|
||||
* @return \IPS\Http\Url
|
||||
* @return string|Url|null
|
||||
*/
|
||||
public function link()
|
||||
public function link(): Url|string|null
|
||||
{
|
||||
return \IPS\Http\Url::internal( "app=nexus&module=store&controller=gifts", 'front', 'store_giftvouchers' );
|
||||
return Url::internal( "app=nexus&module=store&controller=gifts", 'front', 'store_giftvouchers' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Active?
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public function active()
|
||||
public function active(): bool
|
||||
{
|
||||
return \IPS\Dispatcher::i()->application->directory === 'nexus' and \IPS\Dispatcher::i()->module and \IPS\Dispatcher::i()->module->key === 'store' and \IPS\Dispatcher::i()->controller == 'gifts';
|
||||
return Dispatcher::i()->application->directory === 'nexus' and Dispatcher::i()->module and Dispatcher::i()->module->key === 'store' and Dispatcher::i()->controller == 'gifts';
|
||||
}
|
||||
}
|
||||
@@ -12,64 +12,77 @@
|
||||
namespace IPS\nexus\extensions\core\FrontNavigation;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Application\Module;
|
||||
use IPS\core\FrontNavigation\FrontNavigationAbstract;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Front Navigation Extension: Personal Information
|
||||
*/
|
||||
class _Info extends \IPS\core\FrontNavigation\FrontNavigationAbstract
|
||||
{
|
||||
class Info extends FrontNavigationAbstract
|
||||
{
|
||||
/**
|
||||
* @var string Default icon
|
||||
*/
|
||||
public string $defaultIcon = '\f2c2';
|
||||
|
||||
/**
|
||||
* Get Type Title which will display in the AdminCP Menu Manager
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function typeTitle()
|
||||
public static function typeTitle(): string
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('client_info');
|
||||
return Member::loggedIn()->language()->addToStack('client_info');
|
||||
}
|
||||
|
||||
/**
|
||||
* Can the currently logged in user access the content this item links to?
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public function canAccessContent()
|
||||
public function canAccessContent(): bool
|
||||
{
|
||||
return ( \IPS\Member::loggedIn()->member_id AND \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'nexus', 'clients' ) ) );
|
||||
return ( Member::loggedIn()->member_id AND Member::loggedIn()->canAccessModule( Module::get( 'nexus', 'clients' ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Title
|
||||
*
|
||||
* @return string
|
||||
* @return string
|
||||
*/
|
||||
public function title()
|
||||
public function title(): string
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('client_info');
|
||||
return Member::loggedIn()->language()->addToStack('client_info');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Link
|
||||
*
|
||||
* @return \IPS\Http\Url
|
||||
* @return string|Url|null
|
||||
*/
|
||||
public function link()
|
||||
public function link(): Url|string|null
|
||||
{
|
||||
return \IPS\Http\Url::internal( "app=nexus&module=clients&controller=info", 'front', 'clientsinfo' );
|
||||
return Url::internal( "app=nexus&module=clients&controller=info", 'front', 'clientsinfo' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Active?
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public function active()
|
||||
public function active(): bool
|
||||
{
|
||||
return \IPS\Dispatcher::i()->application->directory === 'nexus' and \IPS\Dispatcher::i()->module and \IPS\Dispatcher::i()->module->key === 'clients' and \IPS\Dispatcher::i()->controller == 'info';
|
||||
return Dispatcher::i()->application->directory === 'nexus' and Dispatcher::i()->module and Dispatcher::i()->module->key === 'clients' and Dispatcher::i()->controller == 'info';
|
||||
}
|
||||
}
|
||||
@@ -12,64 +12,77 @@
|
||||
namespace IPS\nexus\extensions\core\FrontNavigation;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Application\Module;
|
||||
use IPS\core\FrontNavigation\FrontNavigationAbstract;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Front Navigation Extension: Orders
|
||||
*/
|
||||
class _Orders extends \IPS\core\FrontNavigation\FrontNavigationAbstract
|
||||
{
|
||||
class Orders extends FrontNavigationAbstract
|
||||
{
|
||||
/**
|
||||
* @var string Default icon
|
||||
*/
|
||||
public string $defaultIcon = '\f466';
|
||||
|
||||
/**
|
||||
* Get Type Title which will display in the AdminCP Menu Manager
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function typeTitle()
|
||||
public static function typeTitle(): string
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('client_invoices');
|
||||
return Member::loggedIn()->language()->addToStack('client_invoices');
|
||||
}
|
||||
|
||||
/**
|
||||
* Can the currently logged in user access the content this item links to?
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public function canAccessContent()
|
||||
public function canAccessContent(): bool
|
||||
{
|
||||
return ( \IPS\Member::loggedIn()->member_id AND \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'nexus', 'clients' ) ) );
|
||||
return ( Member::loggedIn()->member_id AND Member::loggedIn()->canAccessModule( Module::get( 'nexus', 'clients' ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Title
|
||||
*
|
||||
* @return string
|
||||
* @return string
|
||||
*/
|
||||
public function title()
|
||||
public function title(): string
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('client_invoices');
|
||||
return Member::loggedIn()->language()->addToStack('client_invoices');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Link
|
||||
*
|
||||
* @return \IPS\Http\Url
|
||||
* @return string|Url|null
|
||||
*/
|
||||
public function link()
|
||||
public function link(): Url|string|null
|
||||
{
|
||||
return \IPS\Http\Url::internal( "app=nexus&module=clients&controller=invoices", 'front', 'clientsinvoices' );
|
||||
return Url::internal( "app=nexus&module=clients&controller=invoices", 'front', 'clientsinvoices' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Active?
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public function active()
|
||||
public function active(): bool
|
||||
{
|
||||
return \IPS\Dispatcher::i()->application->directory === 'nexus' and \IPS\Dispatcher::i()->module and \IPS\Dispatcher::i()->module->key === 'clients' and ( !\IPS\Dispatcher::i()->controller or \IPS\Dispatcher::i()->controller == 'invoices' );
|
||||
return Dispatcher::i()->application->directory === 'nexus' and Dispatcher::i()->module and Dispatcher::i()->module->key === 'clients' and ( !Dispatcher::i()->controller or Dispatcher::i()->controller == 'invoices' );
|
||||
}
|
||||
}
|
||||
@@ -12,64 +12,78 @@
|
||||
namespace IPS\nexus\extensions\core\FrontNavigation;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Application\Module;
|
||||
use IPS\core\FrontNavigation\FrontNavigationAbstract;
|
||||
use IPS\Db;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Front Navigation Extension: Orders
|
||||
*/
|
||||
class _Purchases extends \IPS\core\FrontNavigation\FrontNavigationAbstract
|
||||
{
|
||||
class Purchases extends FrontNavigationAbstract
|
||||
{
|
||||
/**
|
||||
* @var string Default icon
|
||||
*/
|
||||
public string $defaultIcon = '\f571';
|
||||
|
||||
/**
|
||||
* Get Type Title which will display in the AdminCP Menu Manager
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function typeTitle()
|
||||
public static function typeTitle(): string
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('client_purchases');
|
||||
return Member::loggedIn()->language()->addToStack('client_purchases');
|
||||
}
|
||||
|
||||
/**
|
||||
* Can the currently logged in user access the content this item links to?
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public function canAccessContent()
|
||||
public function canAccessContent(): bool
|
||||
{
|
||||
return ( \IPS\Member::loggedIn()->member_id AND \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'nexus', 'clients' ) ) and \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_member=? AND ps_show=1', \IPS\Member::loggedIn()->member_id ) ) );
|
||||
return ( Member::loggedIn()->member_id AND Member::loggedIn()->canAccessModule( Module::get( 'nexus', 'clients' ) ) and Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_member=? AND ps_show=1', Member::loggedIn()->member_id ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Title
|
||||
*
|
||||
* @return string
|
||||
* @return string
|
||||
*/
|
||||
public function title()
|
||||
public function title(): string
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('client_purchases');
|
||||
return Member::loggedIn()->language()->addToStack('client_purchases');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Link
|
||||
*
|
||||
* @return \IPS\Http\Url
|
||||
* @return string|Url|null
|
||||
*/
|
||||
public function link()
|
||||
public function link(): Url|string|null
|
||||
{
|
||||
return \IPS\Http\Url::internal( "app=nexus&module=clients&controller=purchases", 'front', 'clientspurchases' );
|
||||
return Url::internal( "app=nexus&module=clients&controller=purchases", 'front', 'clientspurchases' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Active?
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public function active()
|
||||
public function active(): bool
|
||||
{
|
||||
return \IPS\Dispatcher::i()->application->directory === 'nexus' and \IPS\Dispatcher::i()->module and \IPS\Dispatcher::i()->module->key === 'clients' and \IPS\Dispatcher::i()->controller == 'purchases';
|
||||
return Dispatcher::i()->application->directory === 'nexus' and Dispatcher::i()->module and Dispatcher::i()->module->key === 'clients' and Dispatcher::i()->controller == 'purchases';
|
||||
}
|
||||
}
|
||||
@@ -12,64 +12,78 @@
|
||||
namespace IPS\nexus\extensions\core\FrontNavigation;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Application\Module;
|
||||
use IPS\core\FrontNavigation\FrontNavigationAbstract;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Front Navigation Extension: Store
|
||||
*/
|
||||
class _Store extends \IPS\core\FrontNavigation\FrontNavigationAbstract
|
||||
class Store extends FrontNavigationAbstract
|
||||
{
|
||||
/**
|
||||
* @var string Default icon
|
||||
*/
|
||||
public string $defaultIcon = '\f07a';
|
||||
|
||||
/**
|
||||
* Get Type Title which will display in the AdminCP Menu Manager
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function typeTitle()
|
||||
public static function typeTitle(): string
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('module__nexus_store');
|
||||
return Member::loggedIn()->language()->addToStack('module__nexus_store');
|
||||
}
|
||||
|
||||
/**
|
||||
* Can the currently logged in user access the content this item links to?
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public function canAccessContent()
|
||||
public function canAccessContent(): bool
|
||||
{
|
||||
return \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'nexus', 'store' ) );
|
||||
return Member::loggedIn()->canAccessModule( Module::get( 'nexus', 'store' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Title
|
||||
*
|
||||
* @return string
|
||||
* @return string
|
||||
*/
|
||||
public function title()
|
||||
public function title(): string
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('module__nexus_store');
|
||||
return Member::loggedIn()->language()->addToStack('module__nexus_store');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Link
|
||||
*
|
||||
* @return \IPS\Http\Url
|
||||
* @return string|Url|null
|
||||
*/
|
||||
public function link()
|
||||
public function link(): Url|string|null
|
||||
{
|
||||
return \IPS\Http\Url::internal( "app=nexus&module=store&controller=store", 'front', 'store' );
|
||||
return Url::internal( "app=nexus&module=store&controller=store", 'front', 'store' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Active?
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public function active()
|
||||
public function active(): bool
|
||||
{
|
||||
return \IPS\Dispatcher::i()->application->directory === 'nexus' and \IPS\Dispatcher::i()->module and \IPS\Dispatcher::i()->module->key === 'store' and \in_array( \IPS\Dispatcher::i()->controller, array( 'cart', 'product', 'store' ) );
|
||||
return Dispatcher::i()->application->directory === 'nexus' and Dispatcher::i()->module and Dispatcher::i()->module->key === 'store' and in_array( Dispatcher::i()->controller, array( 'cart', 'product', 'store' ) );
|
||||
}
|
||||
}
|
||||
@@ -12,25 +12,39 @@
|
||||
namespace IPS\nexus\extensions\core\FrontNavigation;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Application\Module;
|
||||
use IPS\core\FrontNavigation\FrontNavigationAbstract;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\Settings;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Front Navigation Extension: Subscriptions
|
||||
*/
|
||||
class _Subscriptions extends \IPS\core\FrontNavigation\FrontNavigationAbstract
|
||||
{
|
||||
class Subscriptions extends FrontNavigationAbstract
|
||||
{
|
||||
/**
|
||||
* @var string Default icon
|
||||
*/
|
||||
public string $defaultIcon = '\f021';
|
||||
|
||||
/**
|
||||
* Get Type Title which will display in the AdminCP Menu Manager
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function typeTitle()
|
||||
public static function typeTitle(): string
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('nexus_subscriptions');
|
||||
return Member::loggedIn()->language()->addToStack('nexus_subscriptions');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -38,50 +52,50 @@ class _Subscriptions extends \IPS\core\FrontNavigation\FrontNavigationAbstract
|
||||
* For example, if this will link to a particular feature which has been diabled, it should
|
||||
* not be available, even if the user has permission
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public static function isEnabled()
|
||||
public static function isEnabled() : bool
|
||||
{
|
||||
return \IPS\Settings::i()->nexus_subs_enabled;
|
||||
return Settings::i()->nexus_subs_enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can the currently logged in user access the content this item links to?
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public function canAccessContent()
|
||||
public function canAccessContent(): bool
|
||||
{
|
||||
return \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'nexus', 'subscriptions' ) );
|
||||
return Member::loggedIn()->canAccessModule( Module::get( 'nexus', 'subscriptions' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Title
|
||||
*
|
||||
* @return string
|
||||
* @return string
|
||||
*/
|
||||
public function title()
|
||||
public function title(): string
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('nexus_subscriptions');
|
||||
return Member::loggedIn()->language()->addToStack('nexus_subscriptions');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Link
|
||||
*
|
||||
* @return \IPS\Http\Url
|
||||
* @return string|Url|null
|
||||
*/
|
||||
public function link()
|
||||
public function link(): Url|string|null
|
||||
{
|
||||
return \IPS\Http\Url::internal( "app=nexus&module=subscriptions&controller=subscriptions", 'front', 'nexus_subscriptions' );
|
||||
return Url::internal( "app=nexus&module=subscriptions&controller=subscriptions", 'front', 'nexus_subscriptions' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Active?
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public function active()
|
||||
public function active(): bool
|
||||
{
|
||||
return \IPS\Dispatcher::i()->application->directory === 'nexus' and \IPS\Dispatcher::i()->module and \IPS\Dispatcher::i()->module->key === 'subscriptions' and \IPS\Dispatcher::i()->controller == 'subscriptions';
|
||||
return Dispatcher::i()->application->directory === 'nexus' and Dispatcher::i()->module and Dispatcher::i()->module->key === 'subscriptions' and Dispatcher::i()->controller == 'subscriptions';
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Front Navigation Extension: Support
|
||||
* @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 08 Apr 2014
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\extensions\core\FrontNavigation;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Front Navigation Extension: Support
|
||||
*/
|
||||
class _Support extends \IPS\core\FrontNavigation\FrontNavigationAbstract
|
||||
{
|
||||
/**
|
||||
* Get Type Title which will display in the AdminCP Menu Manager
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function typeTitle()
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'frontnavigation_support' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Can the currently logged in user access the content this item links to?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canAccessContent()
|
||||
{
|
||||
return ( \IPS\Member::loggedIn()->member_id AND \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'nexus', 'support' ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Title
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function title()
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'frontnavigation_support' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Link
|
||||
*
|
||||
* @return \IPS\Http\Url
|
||||
*/
|
||||
public function link()
|
||||
{
|
||||
return \IPS\Http\Url::internal( "app=nexus&module=support&controller=home", 'front', 'support' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Active?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function active()
|
||||
{
|
||||
return \IPS\Dispatcher::i()->application->directory === 'nexus' and \IPS\Dispatcher::i()->module and \IPS\Dispatcher::i()->module->key === 'support';
|
||||
}
|
||||
}
|
||||
@@ -12,25 +12,33 @@
|
||||
namespace IPS\nexus\extensions\core\GroupForm;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Db;
|
||||
use IPS\Extensions\GroupFormAbstract;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Member\Group;
|
||||
use UnderflowException;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Admin CP Group Form
|
||||
*/
|
||||
class _PreventDeletion
|
||||
class PreventDeletion extends GroupFormAbstract
|
||||
{
|
||||
/**
|
||||
* Process Form
|
||||
*
|
||||
* @param \IPS\Helpers\Form $form The form
|
||||
* @param \IPS\Member\Group $group Existing Group
|
||||
* @param Form $form The form
|
||||
* @param Group $group Existing Group
|
||||
* @return void
|
||||
*/
|
||||
public function process( &$form, $group )
|
||||
public function process( Form $form, Group $group ): void
|
||||
{
|
||||
|
||||
}
|
||||
@@ -39,10 +47,10 @@ class _PreventDeletion
|
||||
* Save
|
||||
*
|
||||
* @param array $values Values from form
|
||||
* @param \IPS\Member\Group $group The group
|
||||
* @param Group $group The group
|
||||
* @return void
|
||||
*/
|
||||
public function save( $values, &$group )
|
||||
public function save( array $values, Group $group ) : void
|
||||
{
|
||||
|
||||
}
|
||||
@@ -50,28 +58,28 @@ class _PreventDeletion
|
||||
/**
|
||||
* Can this group be deleted?
|
||||
*
|
||||
* @param \IPS\Member\Group $group The group
|
||||
* @return void
|
||||
* @param Group $group The group
|
||||
* @return bool
|
||||
*/
|
||||
public function canDelete( $group ) : bool
|
||||
public function canDelete( Group $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();
|
||||
Db::i()->select( '*', 'nexus_packages', ['p_primary_group=? OR ' . Db::i()->findInSet('p_secondary_group', [$group->g_id] ), $group->g_id ] )->first();
|
||||
return FALSE;
|
||||
}
|
||||
catch(\UnderflowException $e )
|
||||
catch(UnderflowException )
|
||||
{
|
||||
}
|
||||
|
||||
// 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();
|
||||
Db::i()->select( '*', 'nexus_member_subscription_packages', ['sp_primary_group=? OR ' . Db::i()->findInSet('sp_secondary_group', [$group->g_id] ), $group->g_id ] )->first();
|
||||
return FALSE;
|
||||
}
|
||||
catch(\UnderflowException $e )
|
||||
catch(UnderflowException )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -1,551 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Nexus Incoming Email Handler
|
||||
* @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 07 Mar 2014
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\extensions\core\IncomingEmail;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Community Enhancement
|
||||
*/
|
||||
class _Support
|
||||
{
|
||||
/**
|
||||
* Handle email
|
||||
*
|
||||
* @param \IPS\Email\Incoming\Email $email The email
|
||||
* @return bool
|
||||
*/
|
||||
public function process( \IPS\Email\Incoming\Email $email )
|
||||
{
|
||||
/* Is it from an actual member? */
|
||||
$member = \IPS\Member::load( $email->from, 'email' );
|
||||
|
||||
/* Replying? */
|
||||
$request = $this->_emailIsReplyForRequest( $email );
|
||||
$department = $this->_getDepartment( $email );
|
||||
|
||||
if ( $request )
|
||||
{
|
||||
/* IS this request locked? */
|
||||
if ( $request->status->is_locked )
|
||||
{
|
||||
/* Figure out what we are doing */
|
||||
switch( \IPS\Settings::i()->reply_request_resolved )
|
||||
{
|
||||
case 'reject': // The reply is rejected - let the customer know
|
||||
$this->_processLocked( $email, $member, $request );
|
||||
return TRUE;
|
||||
break;
|
||||
|
||||
case 'create': // We are accepting the reply, however we are creating a new request from it rather than opening a new one.
|
||||
$this->_processNewRequest( $email, $member, $department, $request );
|
||||
return TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Still here? Normal reply, or we are just re-opening the request regardless of resolved status - do that */
|
||||
$this->_processReply( $email, $member, $request );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Still here? Make sure the department is valid */
|
||||
if ( !$department )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Create request */
|
||||
$this->_processNewRequest( $email, $member, $department );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Track a property in the reply-to header for reference later
|
||||
*/
|
||||
protected $_lastMessageId = NULL;
|
||||
|
||||
/**
|
||||
* Is reply?
|
||||
*
|
||||
* @param \IPS\Email\Incoming\Email $email The email
|
||||
* @return \IPS\nexus\Support\Request|NULL
|
||||
* @note The key may come in as quoted printable
|
||||
*/
|
||||
protected function _emailIsReplyForRequest( \IPS\Email\Incoming\Email $email )
|
||||
{
|
||||
/* Figure out if this email belongs to an existing request */
|
||||
if (
|
||||
/* Look at the In-Reply-To header */
|
||||
( isset( $email->headers['in-reply-to'] ) and preg_match( '/^<?IPS\-\d+\-SR(\d+)\.(.+?)(\.(\d+))?-/', $email->headers['in-reply-to'], $matches ) ) or
|
||||
|
||||
/* Look for [SRXX.XXX] in the raw content */
|
||||
preg_match( '/\[SR(\d+?)\.(.+?)(\.(\d+))?\]/', $email->raw, $matches ) or
|
||||
|
||||
/* Look for the same in the message */
|
||||
preg_match( '/\[SR(\d+?)\.(.+?)(\.(\d+))?\]/', $email->message, $matches ) or
|
||||
|
||||
/* If neither of those are found, look for the quoted printable version */
|
||||
preg_match( '/\=5BSR(\d+?)\.(.+?)(\.(\d+))?\=5D/', $email->raw, $matches )
|
||||
)
|
||||
{
|
||||
/* We have to store this now so we can inspect it later in _processReply() */
|
||||
if( isset( $matches[4] ) AND $matches[4] )
|
||||
{
|
||||
$this->_lastMessageId = $matches[4];
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$request = \IPS\nexus\Support\Request::load( $matches[1] );
|
||||
if ( $request->email_key === quoted_printable_decode( $matches[2] ) )
|
||||
{
|
||||
return $request;
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
}
|
||||
|
||||
/* If the same email generated a new support request within the last 10 minutes and the department is the same, add this as a reply to that */
|
||||
try
|
||||
{
|
||||
$department = $this->_getDepartment( $email );
|
||||
$where = array();
|
||||
$where[] = array( 'r_email=?', $email->from );
|
||||
$where[] = array( 'r_started>?', time() - 600 );
|
||||
|
||||
if ( $department )
|
||||
{
|
||||
$where[] = array( 'r_department=?', $department->_id );
|
||||
}
|
||||
|
||||
$recentRequest = \IPS\Db::i()->select( '*', 'nexus_support_requests', $where )->first();
|
||||
return \IPS\nexus\Support\Request::constructFromData( $recentRequest );
|
||||
}
|
||||
catch ( \UnderflowException $e ) { }
|
||||
|
||||
/* Still here? It must be a new thing */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle reply to locked request
|
||||
*
|
||||
* @param \IPS\Email\Incoming\Email $email The email
|
||||
* @param \IPS\Member $member The member it's from
|
||||
* @param \IPS|nexus\Support\Request $request The support request
|
||||
* @return void
|
||||
*/
|
||||
protected function _processLocked( \IPS\Email\Incoming\Email $email, \IPS\Member $member, \IPS\nexus\Support\Request $request )
|
||||
{
|
||||
\IPS\Email::buildFromTemplate( 'nexus', 'replyRequestLocked', array( $request, $member ), \IPS\Email::TYPE_TRANSACTIONAL )->send( $member->member_id ? $member : $email->from );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle reply
|
||||
*
|
||||
* @param \IPS\Email\Incoming\Email $email The email
|
||||
* @param \IPS\Member $member The member it's from
|
||||
* @param \IPS\nexus\Support\Request $request The support request to make it a reply of
|
||||
* @return void
|
||||
*/
|
||||
protected function _processReply( \IPS\Email\Incoming\Email $email, \IPS\Member $member, \IPS\nexus\Support\Request $request )
|
||||
{
|
||||
$staff = array_key_exists( $member->member_id, \IPS\nexus\Support\Request::staff() );
|
||||
|
||||
$pending = FALSE;
|
||||
$newMessage = NULL;
|
||||
if ( $staff and $this->_lastMessageId )
|
||||
{
|
||||
$newMessage = $request->comments( 1, 0, 'date', 'desc' );
|
||||
if ( $newMessage and $this->_lastMessageId != $newMessage->id )
|
||||
{
|
||||
$pending = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
$request->status = \IPS\nexus\Support\Status::load( TRUE, $staff ? 'status_default_staff' : 'status_default_member' );
|
||||
$request->last_reply = time();
|
||||
$request->last_reply_by = (int) $member->member_id;
|
||||
$request->replies++;
|
||||
$request->save();
|
||||
|
||||
$reply = new \IPS\nexus\Support\Reply;
|
||||
$reply->request = $request->id;
|
||||
$reply->member = (int) $member->member_id;
|
||||
$reply->type = $staff ? ( $pending ? $reply::REPLY_PENDING : $reply::REPLY_STAFF ) : $reply::REPLY_EMAIL;
|
||||
$reply->post = $email->message;
|
||||
$reply->date = time();
|
||||
$reply->email = $email->from;
|
||||
$reply->cc = implode( ',', $email->cc );
|
||||
$reply->raw = $email->raw;
|
||||
$reply->save();
|
||||
static::makeAndClaimAttachments( $email->attachments, $reply, $member );
|
||||
static::storeAttachmentMappings( $email->mappedAttachments, $reply, $member );
|
||||
|
||||
if ( $pending )
|
||||
{
|
||||
$notifyEmail = \IPS\Email::buildFromTemplate( 'nexus', 'staffReplyPending', array( $reply, $newMessage ), \IPS\Email::TYPE_TRANSACTIONAL );
|
||||
$notifyEmail->send( $member );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( $staff )
|
||||
{
|
||||
$defaultRecipients = $request->getDefaultRecipients();
|
||||
$reply->sendCustomerNotifications( $defaultRecipients['to'], $defaultRecipients['cc'], $defaultRecipients['bcc'] );
|
||||
}
|
||||
$reply->sendNotifications();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get department
|
||||
*
|
||||
* @param \IPS\Email\Incoming\Email $email The email
|
||||
* @return \IPS\nexus\Support\Department
|
||||
*/
|
||||
protected function _getDepartment( \IPS\Email\Incoming\Email $email )
|
||||
{
|
||||
foreach ( $email->to as $to )
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\nexus\Support\Department::load( $to, 'dpt_email' );
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
}
|
||||
|
||||
foreach ( $email->cc as $to )
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\nexus\Support\Department::load( $to, 'dpt_email' );
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle new requst
|
||||
*
|
||||
* @param \IPS\Email\Incoming\Email $email The email
|
||||
* @param \IPS\Member $member The member it's from
|
||||
* @param \IPS\nexus\Support\Department $department The department to put it in
|
||||
* @param \IPS\nexus\Support\Request|NULL $request If this is from a previous request, the request, otherwise NULL
|
||||
* @return void
|
||||
*/
|
||||
protected function _processNewRequest( \IPS\Email\Incoming\Email $email, \IPS\Member $member, \IPS\nexus\Support\Department $department, \IPS\nexus\Support\Request $previousRequest = NULL )
|
||||
{
|
||||
/* Make sure we're looking at the right department. */
|
||||
if ( !\is_null( $previousRequest ) )
|
||||
{
|
||||
/* Use the existing requests department instead. */
|
||||
$department = $previousRequest->department;
|
||||
}
|
||||
|
||||
/* Forwarded by a staff member? */
|
||||
if (
|
||||
preg_match( '/^FWD?: (.*)$/i', $email->subject, $matches ) // Was forwarded
|
||||
and $member->member_id and array_key_exists( $member->member_id, \IPS\nexus\Support\Request::staff() ) // By a staff member
|
||||
and $originallyFromEmail = $this->_originalSenderOfForwardedMessage( $email ) // And we can get the email address of the original sender
|
||||
) {
|
||||
list( $request, $reply ) = $this->_createRequestFromStaffForward( $email, $member, $department, $originallyFromEmail );
|
||||
}
|
||||
|
||||
/* Nope, normal request */
|
||||
else
|
||||
{
|
||||
list( $request, $reply ) = $this->_createNormalNewRequest( $email, $member, $department );
|
||||
}
|
||||
|
||||
/* Send staff notifications */
|
||||
$request->afterCreateLog( $reply );
|
||||
|
||||
if ( $previousRequest )
|
||||
{
|
||||
$request->log( 'previous_request', $previousRequest, NULL, ( $member->member_id ) ? $member : FALSE );
|
||||
$previousRequest->log( 'previous_request', NULL, $request, ( $member->member_id ) ? $member : FALSE );
|
||||
}
|
||||
|
||||
$request->sendNotifications();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle new request for an email that was forwarded by a staff member
|
||||
*
|
||||
* @param \IPS\Email\Incoming\Email $email The email
|
||||
* @param \IPS\Member $member The member it's from
|
||||
* @param \IPS\nexus\Support\Department $department The department to put it in
|
||||
* @param string $originallyFromEmail The email address of the original sender
|
||||
* @return [ \IPS\nexus\Support\Request, \IPS\nexus\Support\Reply ]
|
||||
*/
|
||||
protected function _createRequestFromStaffForward( \IPS\Email\Incoming\Email $email, \IPS\Member $member, \IPS\nexus\Support\Department $department, $originallyFromEmail )
|
||||
{
|
||||
/* Get the member for the original email */
|
||||
$originallyFrom = \IPS\Member::load( $originallyFromEmail, 'email' );
|
||||
|
||||
/* Init request */
|
||||
$request = $this->_initRequest( $member, $department );
|
||||
preg_match( '/^FWD?: (.*)$/i', $email->subject, $matches );
|
||||
$request->title = $matches[1];
|
||||
$request->member = (int) $originallyFrom->member_id;
|
||||
$request->email = $originallyFromEmail;
|
||||
$request->save();
|
||||
|
||||
/* Strip any headers from the forwarded message */
|
||||
$quoted = $email->quote;
|
||||
$haveInitialHeader = FALSE;
|
||||
$exploded = explode( '<br>', $quoted );
|
||||
foreach ( $exploded as $k => $line )
|
||||
{
|
||||
if ( $line )
|
||||
{
|
||||
if ( !$haveInitialHeader and preg_match( '/^.*:/', $line ) )
|
||||
{
|
||||
$haveInitialHeader = TRUE;
|
||||
}
|
||||
elseif ( !preg_match( '/^.*:.*$/', $line ) )
|
||||
{
|
||||
$quoted = implode( '<br>', array_splice( $exploded, $k ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$quoted = \IPS\Text\Parser::parseStatic( '<div>' . $quoted . '</div>' );
|
||||
|
||||
/* Create the reply */
|
||||
$reply = $this->_createReply( $email, $request, $member, $quoted, $originallyFromEmail );
|
||||
|
||||
/* Create a hidden note */
|
||||
if ( trim( $email->message ) or \count( $email->attachments ) )
|
||||
{
|
||||
$note = new \IPS\nexus\Support\Reply;
|
||||
$note->request = $request->id;
|
||||
$note->member = (int) $member->member_id;
|
||||
$note->type = $reply::REPLY_HIDDEN;
|
||||
$note->post = $email->message;
|
||||
$note->date = time();
|
||||
$note->email = $email->from;
|
||||
$note->save();
|
||||
|
||||
static::makeAndClaimAttachments( $email->attachments, $note, $member );
|
||||
static::storeAttachmentMappings( $email->mappedAttachments, $note, $member );
|
||||
}
|
||||
|
||||
/* Return */
|
||||
return array( $request, $reply );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle new request from a normal email
|
||||
*
|
||||
* @param \IPS\Email\Incoming\Email $email The email
|
||||
* @param \IPS\Member $member The member it's from
|
||||
* @param \IPS\nexus\Support\Department $department The department to put it in
|
||||
* @return [ \IPS\nexus\Support\Request, \IPS\nexus\Support\Reply ]
|
||||
*/
|
||||
protected function _createNormalNewRequest( \IPS\Email\Incoming\Email $email, \IPS\Member $member, \IPS\nexus\Support\Department $department )
|
||||
{
|
||||
/* Init request */
|
||||
$request = $this->_initRequest( $member, $department );
|
||||
$request->title = $email->subject;
|
||||
$request->member = (int) $member->member_id;
|
||||
$request->email = $email->from;
|
||||
|
||||
/* Figure out who to notify for replies */
|
||||
$notify = array();
|
||||
foreach( $email->to as $to )
|
||||
{
|
||||
if ( $to !== $department->email )
|
||||
{
|
||||
$notify[] = array( 'type' => 'e', 'value' => $to );
|
||||
}
|
||||
}
|
||||
foreach( $email->cc as $cc )
|
||||
{
|
||||
if ( $cc !== $department->email )
|
||||
{
|
||||
$notify[] = array( 'type' => 'e', 'value' => $cc );
|
||||
}
|
||||
}
|
||||
|
||||
$request->notify = $notify;
|
||||
$request->save();
|
||||
|
||||
/* Create the reply */
|
||||
$reply = $this->_createReply( $email, $request, $member, $email->message . $email->quote, $email->from );
|
||||
static::makeAndClaimAttachments( $email->attachments, $reply, $member );
|
||||
static::storeAttachmentMappings( $email->mappedAttachments, $reply, $member );
|
||||
|
||||
/* Send confirmation email */
|
||||
if ( \IPS\Settings::i()->nexus_sout_autoreply )
|
||||
{
|
||||
$confirmationEmail = \IPS\Email::buildFromTemplate( 'nexus', 'emailConfirmation', array( $request ), \IPS\Email::TYPE_TRANSACTIONAL );
|
||||
switch ( \IPS\Settings::i()->nexus_sout_from )
|
||||
{
|
||||
case 'staff':
|
||||
case 'dpt':
|
||||
$fromName = $member->language()->get( 'nexus_department_' . $request->department->_id );
|
||||
break;
|
||||
default:
|
||||
$fromName = \IPS\Settings::i()->nexus_sout_from;
|
||||
break;
|
||||
}
|
||||
$confirmationEmail->send( $member->member_id ? $member : $email->from, [], [], $request->department->email, $fromName, [ 'Message-ID' => "<IPS-0-SR{$request->id}.{$request->email_key}-{$request->department->email}>" ] );
|
||||
}
|
||||
|
||||
/* Return */
|
||||
return array( $request, $reply );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a basic support request object
|
||||
*
|
||||
* @param \IPS\Member $member The member it's from
|
||||
* @param \IPS\nexus\Support\Department $department The department to put it in
|
||||
* @return \IPS\nexus\Support\Request
|
||||
*/
|
||||
protected function _initRequest( \IPS\Member $member, \IPS\nexus\Support\Department $department )
|
||||
{
|
||||
$request = new \IPS\nexus\Support\Request;
|
||||
$request->department = $department;
|
||||
$request->status = \IPS\nexus\Support\Status::load( TRUE, 'status_default_member' );
|
||||
$request->severity = \IPS\nexus\Support\Severity::load( TRUE, 'sev_default' );
|
||||
$request->started = time();
|
||||
$request->last_reply = time();
|
||||
$request->last_reply_by = (int) $member->member_id;
|
||||
$request->last_new_reply = time();
|
||||
$request->replies = 1;
|
||||
return $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a basic support reply object
|
||||
*
|
||||
* @param \IPS\Email\Incoming\Email $email The email
|
||||
* @param \IPS\nexus\Support\Request $request The request it's for
|
||||
* @param \IPS\Member $member The member it's from
|
||||
* @param string $message The message body
|
||||
* @param string $emailFrom The email address it is from
|
||||
* @return \IPS\nexus\Support\Reply
|
||||
*/
|
||||
protected function _createReply( \IPS\Email\Incoming\Email $email, \IPS\nexus\Support\Request $request, \IPS\Member $member, $message, $emailFrom )
|
||||
{
|
||||
$reply = new \IPS\nexus\Support\Reply;
|
||||
$reply->request = $request->id;
|
||||
$reply->member = (int) $member->member_id;
|
||||
$reply->type = $reply::REPLY_EMAIL;
|
||||
$reply->post = $message;
|
||||
$reply->date = time();
|
||||
$reply->email = $emailFrom;
|
||||
$reply->cc = implode( ',', $email->cc );
|
||||
$reply->raw = $email->raw;
|
||||
$reply->save();
|
||||
return $reply;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this message was forwarded by a staff member, get the
|
||||
* email address it was sent to that staff member from (i.e.
|
||||
* the user who should show as creating the support request)
|
||||
*
|
||||
* @param \IPS\Email\Incoming\Email $email The email
|
||||
* @return bool
|
||||
*/
|
||||
protected function _originalSenderOfForwardedMessage( \IPS\Email\Incoming\Email $email )
|
||||
{
|
||||
$originallyFrom = NULL;
|
||||
if ( isset( $email->headers['original-recipient'] ) )
|
||||
{
|
||||
$originallyFrom = preg_replace( '/^.*;(.*)$/', '$1', $email->headers['original-recipient'] );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( preg_match( '/From:.+?(\b[A-Z0-9\._%+\-\']+@[A-Z0-9\.\-]+\.[A-Z]{2,9}\b)/i', $email->quote, $_matches ) )
|
||||
{
|
||||
$originallyFrom = $_matches[1];
|
||||
}
|
||||
}
|
||||
|
||||
return $originallyFrom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make and claim attachments
|
||||
*
|
||||
* @param array $files \IPS\File objects
|
||||
* @param \IPS\nexus\Support\Reply $reply The support request reply
|
||||
* @param \IPS\Member $member The member it's from
|
||||
* @return void
|
||||
*/
|
||||
public static function makeAndClaimAttachments( array $files, \IPS\nexus\Support\Reply $reply, \IPS\Member $member )
|
||||
{
|
||||
$replacements = array();
|
||||
foreach ( $files as $file )
|
||||
{
|
||||
$attachment = $file->makeAttachment('', $member);
|
||||
if ( !$file->isImage() )
|
||||
{
|
||||
$replacements["<fileStore.core_Attachment>/{$file}"] = \IPS\Settings::i()->base_url . "applications/core/interface/file/attachment.php?id={$attachment['attach_id']}";
|
||||
if ( $attachment['attach_security_key'] )
|
||||
{
|
||||
$replacements["<fileStore.core_Attachment>/{$file}"] .= "&key={$attachment['attach_security_key']}";
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Db::i()->insert( 'core_attachments_map', array(
|
||||
'attachment_id' => $attachment['attach_id'],
|
||||
'location_key' => 'nexus_Support',
|
||||
'id1' => $reply->request,
|
||||
'id2' => $reply->id,
|
||||
) );
|
||||
}
|
||||
|
||||
if ( \count( $replacements ) )
|
||||
{
|
||||
foreach ( $replacements as $find => $replace )
|
||||
{
|
||||
$reply->post = str_replace( $find, $replace, $reply->post );
|
||||
}
|
||||
$reply->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store attachment mappings if a previous attachment was reused in this email
|
||||
*
|
||||
* @param array $attachments Attachment IDs
|
||||
* @param \IPS\nexus\Support\Reply $reply The support request reply
|
||||
* @param \IPS\Member $member The member it's from
|
||||
* @return void
|
||||
*/
|
||||
public static function storeAttachmentMappings( array $attachments, \IPS\nexus\Support\Reply $reply, \IPS\Member $member )
|
||||
{
|
||||
foreach ( $attachments as $id )
|
||||
{
|
||||
\IPS\Db::i()->insert( 'core_attachments_map', array(
|
||||
'attachment_id' => $id,
|
||||
'location_key' => 'nexus_Support',
|
||||
'id1' => $reply->request,
|
||||
'id2' => $reply->id,
|
||||
) );
|
||||
}
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -12,28 +12,26 @@
|
||||
namespace IPS\nexus\extensions\core\IpAddresses;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Db;
|
||||
use IPS\Db\Select;
|
||||
use IPS\Extensions\IpAddressesAbstract;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Payout;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* IP Address Lookup extension
|
||||
*/
|
||||
class _Payouts
|
||||
class Payouts extends IpAddressesAbstract
|
||||
{
|
||||
/**
|
||||
* Supported in the ACP IP address lookup tool?
|
||||
*
|
||||
* @return bool
|
||||
* @note If the method does not exist in an extension, the result is presumed to be TRUE
|
||||
*/
|
||||
public function supportedInAcp()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Supported in the ModCP IP address lookup tool?
|
||||
*
|
||||
@@ -49,18 +47,18 @@ class _Payouts
|
||||
* Find Records by IP
|
||||
*
|
||||
* @param string $ip The IP Address
|
||||
* @param \IPS\Http\Url $baseUrl URL table will be displayed on or NULL to return a count
|
||||
* @return \IPS\Helpers\Table|null
|
||||
* @param Url|null $baseUrl URL table will be displayed on or NULL to return a count
|
||||
* @return string|int|null
|
||||
*/
|
||||
public function findByIp( $ip, \IPS\Http\Url $baseUrl = NULL )
|
||||
public function findByIp( string $ip, ?Url $baseUrl = NULL ): string|int|null
|
||||
{
|
||||
/* Return count */
|
||||
if ( $baseUrl === NULL )
|
||||
{
|
||||
return \IPS\Db::i()->select( 'COUNT(*)', 'nexus_payouts', array( "po_ip LIKE ?", $ip ) )->first();
|
||||
return Db::i()->select( 'COUNT(*)', 'nexus_payouts', array( "po_ip LIKE ?", $ip ) )->first();
|
||||
}
|
||||
|
||||
$table = \IPS\nexus\Payout::table( array( "po_ip LIKE ?", $ip ), $baseUrl );
|
||||
$table = Payout::table( array( "po_ip LIKE ?", $ip ), $baseUrl );
|
||||
$table->include[] = 'po_ip';
|
||||
|
||||
return (string) $table;
|
||||
@@ -80,11 +78,11 @@ class _Payouts
|
||||
...
|
||||
);
|
||||
* @endcode
|
||||
* @param \IPS\Member $member The member
|
||||
* @return array|NULL
|
||||
* @param Member $member The member
|
||||
* @return array|Select
|
||||
*/
|
||||
public function findByMember( $member )
|
||||
public function findByMember( Member $member ): array|Select
|
||||
{
|
||||
return \IPS\Db::i()->select( "po_ip AS ip, count(*) AS count, MIN(po_date) AS first, MAX(po_date) AS last", 'nexus_payouts', array( "po_member=?", $member->member_id ), NULL, NULL, "po_ip" )->setKeyField( 'ip' );
|
||||
return Db::i()->select( "po_ip AS ip, count(*) AS count, MIN(po_date) AS first, MAX(po_date) AS last", 'nexus_payouts', array( "po_member=?", $member->member_id ), NULL, NULL, "po_ip" )->setKeyField( 'ip' );
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief IP Address Lookup 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/
|
||||
* @package Invision Community
|
||||
* @subpackage Nexus
|
||||
* @since 18 Sep 2014
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\extensions\core\IpAddresses;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* IP Address Lookup extension
|
||||
*/
|
||||
class _Support
|
||||
{
|
||||
/**
|
||||
* Supported in the ACP IP address lookup tool?
|
||||
*
|
||||
* @return bool
|
||||
* @note If the method does not exist in an extension, the result is presumed to be TRUE
|
||||
*/
|
||||
public function supportedInAcp()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Supported in the ModCP IP address lookup tool?
|
||||
*
|
||||
* @return bool
|
||||
* @note If the method does not exist in an extension, the result is presumed to be TRUE
|
||||
*/
|
||||
public function supportedInModCp(): bool
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find Records by IP
|
||||
*
|
||||
* @param string $ip The IP Address
|
||||
* @param \IPS\Http\Url $baseUrl URL table will be displayed on or NULL to return a count
|
||||
* @return \IPS\Helpers\Table|null
|
||||
*/
|
||||
public function findByIp( $ip, \IPS\Http\Url $baseUrl = NULL )
|
||||
{
|
||||
/* Return count */
|
||||
if ( $baseUrl === NULL )
|
||||
{
|
||||
return \IPS\Db::i()->select( 'COUNT(*)', 'nexus_support_replies', array( "reply_ip_address LIKE ?", $ip ) )->first();
|
||||
}
|
||||
|
||||
$class = new \IPS\core\extensions\core\IpAddresses\Content;
|
||||
$class->class = 'IPS\nexus\Support\Reply';
|
||||
return $class->findByIp( $ip, $baseUrl );
|
||||
}
|
||||
|
||||
/**
|
||||
* Find IPs by Member
|
||||
*
|
||||
* @code
|
||||
return array(
|
||||
'::1' => array(
|
||||
'ip' => '::1'// string (IP Address)
|
||||
'count' => ... // int (number of times this member has used this IP)
|
||||
'first' => ... // int (timestamp of first use)
|
||||
'last' => ... // int (timestamp of most recent use)
|
||||
),
|
||||
...
|
||||
);
|
||||
* @endcode
|
||||
* @param \IPS\Member $member The member
|
||||
* @return array|NULL
|
||||
*/
|
||||
public function findByMember( $member )
|
||||
{
|
||||
$class = new \IPS\core\extensions\core\IpAddresses\Content;
|
||||
$class->class = 'IPS\nexus\Support\Reply';
|
||||
return $class->findByMember( $member );
|
||||
}
|
||||
}
|
||||
@@ -12,28 +12,26 @@
|
||||
namespace IPS\nexus\extensions\core\IpAddresses;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Db;
|
||||
use IPS\Db\Select;
|
||||
use IPS\Extensions\IpAddressesAbstract;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Transaction;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* IP Address Lookup extension
|
||||
*/
|
||||
class _Transactions
|
||||
class Transactions extends IpAddressesAbstract
|
||||
{
|
||||
/**
|
||||
* Supported in the ACP IP address lookup tool?
|
||||
*
|
||||
* @return bool
|
||||
* @note If the method does not exist in an extension, the result is presumed to be TRUE
|
||||
*/
|
||||
public function supportedInAcp()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Supported in the ModCP IP address lookup tool?
|
||||
*
|
||||
@@ -49,18 +47,18 @@ class _Transactions
|
||||
* Find Records by IP
|
||||
*
|
||||
* @param string $ip The IP Address
|
||||
* @param \IPS\Http\Url $baseUrl URL table will be displayed on or NULL to return a count
|
||||
* @return \IPS\Helpers\Table|null
|
||||
* @param Url|null $baseUrl URL table will be displayed on or NULL to return a count
|
||||
* @return string|int|null
|
||||
*/
|
||||
public function findByIp( $ip, \IPS\Http\Url $baseUrl = NULL )
|
||||
public function findByIp( string $ip, ?Url $baseUrl = NULL ): string|int|null
|
||||
{
|
||||
/* Return count */
|
||||
if ( $baseUrl === NULL )
|
||||
{
|
||||
return \IPS\Db::i()->select( 'COUNT(*)', 'nexus_transactions', array( "t_ip LIKE ?", $ip ) )->first();
|
||||
return Db::i()->select( 'COUNT(*)', 'nexus_transactions', array( "t_ip LIKE ?", $ip ) )->first();
|
||||
}
|
||||
|
||||
$table = \IPS\nexus\Transaction::table( array( array( "t_ip LIKE ?", $ip ) ), $baseUrl );
|
||||
$table = Transaction::table( array( array( "t_ip LIKE ?", $ip ) ), $baseUrl );
|
||||
$table->include[] = 't_ip';
|
||||
|
||||
return (string) $table;
|
||||
@@ -80,11 +78,11 @@ class _Transactions
|
||||
...
|
||||
);
|
||||
* @endcode
|
||||
* @param \IPS\Member $member The member
|
||||
* @return array|NULL
|
||||
* @param Member $member The member
|
||||
* @return array|Select
|
||||
*/
|
||||
public function findByMember( $member )
|
||||
public function findByMember( Member $member ): array|Select
|
||||
{
|
||||
return \IPS\Db::i()->select( "t_ip AS ip, count(*) AS count, MIN(t_date) AS first, MAX(t_date) AS last", 'nexus_transactions', array( "t_member=?", $member->member_id ), NULL, NULL, "t_ip" )->setKeyField( 'ip' );
|
||||
return Db::i()->select( "t_ip AS ip, count(*) AS count, MIN(t_date) AS first, MAX(t_date) AS last", 'nexus_transactions', array( "t_member=?", $member->member_id ), NULL, NULL, "t_ip" )->setKeyField( 'ip' );
|
||||
}
|
||||
}
|
||||
@@ -12,30 +12,46 @@
|
||||
namespace IPS\nexus\extensions\core\LiveSearch;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\core\extensions\core\LiveSearch\Members;
|
||||
use IPS\Db;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Extensions\LiveSearchAbstract;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Customer;
|
||||
use IPS\nexus\Invoice;
|
||||
use IPS\nexus\Purchase;
|
||||
use IPS\nexus\Purchase\LicenseKey;
|
||||
use IPS\nexus\Transaction;
|
||||
use IPS\Patterns\ActiveRecordIterator;
|
||||
use IPS\Theme;
|
||||
use OutOfRangeException;
|
||||
use function defined;
|
||||
use function is_numeric;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ACP Live Search Extension
|
||||
*/
|
||||
class _Nexus
|
||||
class Nexus extends LiveSearchAbstract
|
||||
{
|
||||
/**
|
||||
* Check we have access
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasAccess()
|
||||
public function hasAccess(): bool
|
||||
{
|
||||
return \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'invoices_manage' )
|
||||
or \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'transactions_manage' )
|
||||
or \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'purchases_view' )
|
||||
or \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'support', 'requests_manage' )
|
||||
or \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customers_view' )
|
||||
or \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'lkeys_view' );
|
||||
return Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'invoices_manage' )
|
||||
or Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'transactions_manage' )
|
||||
or Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'purchases_view' )
|
||||
or Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customers_view' )
|
||||
or Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'lkeys_view' );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,69 +60,55 @@ class _Nexus
|
||||
* @param string $searchTerm Search Term
|
||||
* @return array Array of results
|
||||
*/
|
||||
public function getResults( $searchTerm )
|
||||
public function getResults( string $searchTerm ): array
|
||||
{
|
||||
$results = array();
|
||||
|
||||
/* Numeric */
|
||||
if ( \is_numeric( $searchTerm ) )
|
||||
if ( is_numeric( $searchTerm ) )
|
||||
{
|
||||
/* Invoice */
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'invoices_manage' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'invoices_manage' ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$results[] = \IPS\Theme::i()->getTemplate('livesearch', 'nexus')->invoice( \IPS\nexus\Invoice::load( $searchTerm ) );
|
||||
$results[] = Theme::i()->getTemplate('livesearch', 'nexus')->invoice( Invoice::load( $searchTerm ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
catch ( OutOfRangeException ) { }
|
||||
}
|
||||
|
||||
/* Transaction */
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'transactions_manage' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'transactions_manage' ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$results[] = \IPS\Theme::i()->getTemplate('livesearch', 'nexus')->transaction( \IPS\nexus\Transaction::load( $searchTerm ) );
|
||||
$results[] = Theme::i()->getTemplate('livesearch', 'nexus')->transaction( Transaction::load( $searchTerm ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
catch ( OutOfRangeException ) { }
|
||||
}
|
||||
|
||||
/* Purchase */
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'purchases_view' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'purchases_view' ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$results[] = \IPS\Theme::i()->getTemplate('livesearch', 'nexus')->purchase( \IPS\nexus\Purchase::load( $searchTerm ) );
|
||||
$results[] = Theme::i()->getTemplate('livesearch', 'nexus')->purchase( Purchase::load( $searchTerm ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
}
|
||||
|
||||
/* Support */
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'support', 'requests_manage' ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$supportRequest = \IPS\nexus\Support\Request::load( $searchTerm );
|
||||
if ( $supportRequest->canView() )
|
||||
{
|
||||
$results[] = \IPS\Theme::i()->getTemplate('livesearch', 'nexus')->support( $supportRequest );
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
catch ( OutOfRangeException ) { }
|
||||
}
|
||||
|
||||
/* Customer */
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customers_view' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customers_view' ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$customer = \IPS\nexus\Customer::load( $searchTerm );
|
||||
$customer = Customer::load( $searchTerm );
|
||||
if ( $customer->member_id )
|
||||
{
|
||||
$results[] = \IPS\Theme::i()->getTemplate('livesearch', 'nexus')->customer( $customer );
|
||||
$results[] = Theme::i()->getTemplate('livesearch', 'nexus')->customer( $customer );
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
catch ( OutOfRangeException ) { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,38 +116,38 @@ class _Nexus
|
||||
else
|
||||
{
|
||||
/* License Key */
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'lkeys_view' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'lkeys_view' ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$results[] = \IPS\Theme::i()->getTemplate('livesearch', 'nexus')->licensekey( \IPS\nexus\Purchase\LicenseKey::load( $searchTerm ) );
|
||||
$results[] = Theme::i()->getTemplate('livesearch', 'nexus')->licensekey( LicenseKey::load( $searchTerm ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
catch ( OutOfRangeException ) { }
|
||||
}
|
||||
|
||||
/* Customers */
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customers_view' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customers_view' ) )
|
||||
{
|
||||
if( \IPS\core\extensions\core\LiveSearch\Members::canPerformInlineSearch() )
|
||||
if( Members::canPerformInlineSearch() )
|
||||
{
|
||||
$query = \IPS\Db::i()->select( '*', 'nexus_customers', array( \IPS\Db::i()->like( array( 'core_members.name', 'core_members.email', "CONCAT( LOWER( nexus_customers.cm_first_name ), ' ', LOWER( nexus_customers.cm_last_name ) )" ), $searchTerm, TRUE, TRUE, TRUE ) ), NULL, 50 )->join( 'core_members', 'core_members.member_id=nexus_customers.member_id' );
|
||||
$query = Db::i()->select( '*', 'nexus_customers', array( Db::i()->like( array( 'core_members.name', 'core_members.email', "CONCAT( LOWER( nexus_customers.cm_first_name ), ' ', LOWER( nexus_customers.cm_last_name ) )" ), $searchTerm, TRUE, TRUE, TRUE ) ), NULL, 50 )->join( 'core_members', 'core_members.member_id=nexus_customers.member_id' );
|
||||
}
|
||||
else
|
||||
{
|
||||
$query = \IPS\Db::i()->select( '*', 'nexus_customers', array( \IPS\Db::i()->like( array( 'core_members.name', 'core_members.email', 'nexus_customers.cm_first_name', 'nexus_customers.cm_last_name', "CONCAT( LOWER( nexus_customers.cm_first_name ), ' ', LOWER( nexus_customers.cm_last_name ) )" ), $searchTerm, TRUE, TRUE, FALSE ) ), NULL, 50 )->join( 'core_members', 'core_members.member_id=nexus_customers.member_id' );
|
||||
$query = Db::i()->select( '*', 'nexus_customers', array( Db::i()->like( array( 'core_members.name', 'core_members.email', 'nexus_customers.cm_first_name', 'nexus_customers.cm_last_name', "CONCAT( LOWER( nexus_customers.cm_first_name ), ' ', LOWER( nexus_customers.cm_last_name ) )" ), $searchTerm ) ), NULL, 50 )->join( 'core_members', 'core_members.member_id=nexus_customers.member_id' );
|
||||
}
|
||||
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( $query, 'IPS\nexus\Customer' ) as $customer )
|
||||
foreach ( new ActiveRecordIterator( $query, 'IPS\nexus\Customer' ) as $customer )
|
||||
{
|
||||
$results[] = \IPS\Theme::i()->getTemplate('livesearch', 'nexus')->customer( $customer );
|
||||
$results[] = Theme::i()->getTemplate('livesearch', 'nexus')->customer( $customer );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* For either, search for transaction gateway IDs */
|
||||
foreach ( \IPS\Db::i()->select( '*', 'nexus_transactions', array( 't_gw_id=?', $searchTerm ) ) as $transactionData )
|
||||
foreach ( Db::i()->select( '*', 'nexus_transactions', array( 't_gw_id=?', $searchTerm ) ) as $transactionData )
|
||||
{
|
||||
$results[] = \IPS\Theme::i()->getTemplate( 'livesearch', 'nexus' )->transaction( \IPS\nexus\Transaction::constructFromData( $transactionData ) );
|
||||
$results[] = Theme::i()->getTemplate( 'livesearch', 'nexus' )->transaction( Transaction::constructFromData( $transactionData ) );
|
||||
}
|
||||
|
||||
/* Return */
|
||||
@@ -157,8 +159,8 @@ class _Nexus
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isDefault()
|
||||
public function isDefault(): bool
|
||||
{
|
||||
return \IPS\Dispatcher::i()->application->directory == 'nexus';
|
||||
return Dispatcher::i()->application->directory == 'nexus';
|
||||
}
|
||||
}
|
||||
@@ -12,24 +12,30 @@
|
||||
namespace IPS\nexus\extensions\core\MFAArea;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Extensions\MFAAreaAbstract;
|
||||
use IPS\Settings;
|
||||
use function count;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multi-Factor Authentication Area
|
||||
*/
|
||||
class _AccountCredit
|
||||
class AccountCredit extends MFAAreaAbstract
|
||||
{
|
||||
/**
|
||||
* Is this area available and should show in the ACP configuration?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEnabled()
|
||||
public function isEnabled(): bool
|
||||
{
|
||||
return ( \IPS\Settings::i()->nexus_min_topup or \count( json_decode( \IPS\Settings::i()->nexus_payout, TRUE ) ) );
|
||||
return ( Settings::i()->nexus_min_topup or count( json_decode( Settings::i()->nexus_payout, TRUE ) ) );
|
||||
}
|
||||
}
|
||||
@@ -12,23 +12,27 @@
|
||||
namespace IPS\nexus\extensions\core\MFAArea;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Extensions\MFAAreaAbstract;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multi-Factor Authentication Area
|
||||
*/
|
||||
class _Addresses
|
||||
class Addresses extends MFAAreaAbstract
|
||||
{
|
||||
/**
|
||||
* Is this area available and should show in the ACP configuration?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEnabled()
|
||||
public function isEnabled(): bool
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -12,23 +12,27 @@
|
||||
namespace IPS\nexus\extensions\core\MFAArea;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Extensions\MFAAreaAbstract;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multi-Factor Authentication Area
|
||||
*/
|
||||
class _Alternatives
|
||||
class Alternatives extends MFAAreaAbstract
|
||||
{
|
||||
/**
|
||||
* Is this area available and should show in the ACP configuration?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEnabled()
|
||||
public function isEnabled(): bool
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -12,24 +12,29 @@
|
||||
namespace IPS\nexus\extensions\core\MFAArea;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Extensions\MFAAreaAbstract;
|
||||
use IPS\Settings;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multi-Factor Authentication Area
|
||||
*/
|
||||
class _BillingAgreements
|
||||
class BillingAgreements extends MFAAreaAbstract
|
||||
{
|
||||
/**
|
||||
* Is this area available and should show in the ACP configuration?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEnabled()
|
||||
public function isEnabled(): bool
|
||||
{
|
||||
return \IPS\Settings::i()->billing_agreement_gateways;
|
||||
return Settings::i()->billing_agreement_gateways;
|
||||
}
|
||||
}
|
||||
@@ -12,23 +12,27 @@
|
||||
namespace IPS\nexus\extensions\core\MFAArea;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Extensions\MFAAreaAbstract;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multi-Factor Authentication Area
|
||||
*/
|
||||
class _BillingInfo
|
||||
class BillingInfo extends MFAAreaAbstract
|
||||
{
|
||||
/**
|
||||
* Is this area available and should show in the ACP configuration?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEnabled()
|
||||
public function isEnabled(): bool
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -12,24 +12,29 @@
|
||||
namespace IPS\nexus\extensions\core\MFAArea;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Extensions\MFAAreaAbstract;
|
||||
use IPS\Settings;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multi-Factor Authentication Area
|
||||
*/
|
||||
class _Cards
|
||||
class Cards extends MFAAreaAbstract
|
||||
{
|
||||
/**
|
||||
* Is this area available and should show in the ACP configuration?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEnabled()
|
||||
public function isEnabled(): bool
|
||||
{
|
||||
return \IPS\Settings::i()->card_storage_gateways;
|
||||
return Settings::i()->card_storage_gateways;
|
||||
}
|
||||
}
|
||||
@@ -12,38 +12,65 @@
|
||||
namespace IPS\nexus\extensions\core\MemberACPProfileBlocks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DateInterval;
|
||||
use Exception;
|
||||
use IPS\core\MemberACPProfile\TabbedBlock;
|
||||
use IPS\DateTime;
|
||||
use IPS\Helpers\Chart;
|
||||
use IPS\Helpers\Table\Custom;
|
||||
use IPS\Helpers\Table\Db;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Customer;
|
||||
use IPS\nexus\Gateway;
|
||||
use IPS\nexus\Money;
|
||||
use IPS\nexus\Purchase;
|
||||
use IPS\nexus\Subscription;
|
||||
use IPS\nexus\Transaction;
|
||||
use IPS\Patterns\ActiveRecordIterator;
|
||||
use IPS\Request;
|
||||
use IPS\Settings;
|
||||
use IPS\Theme;
|
||||
use OutOfRangeException;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function is_null;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ACP Member Profile Block
|
||||
*
|
||||
* @property Customer $member
|
||||
*/
|
||||
class _AccountInformation extends \IPS\core\MemberACPProfile\TabbedBlock
|
||||
class AccountInformation extends TabbedBlock
|
||||
{
|
||||
/**
|
||||
* Get Tab Names
|
||||
*
|
||||
* @return string
|
||||
* @return array
|
||||
*/
|
||||
public function tabs()
|
||||
public function tabs(): array
|
||||
{
|
||||
$tabs = array(
|
||||
'overview' => array(
|
||||
'icon' => 'ellipsis-h',
|
||||
'icon' => 'address-card',
|
||||
'count' => 0
|
||||
)
|
||||
);
|
||||
if ( \count( \IPS\nexus\Gateway::cardStorageGateways() ) )
|
||||
if ( count( Gateway::cardStorageGateways() ) )
|
||||
{
|
||||
$tabs['cards'] = array(
|
||||
'icon' => 'credit-card',
|
||||
'count' => \IPS\Db::i()->select( 'COUNT(*)', 'nexus_customer_cards', array( 'card_member=?', $this->member->member_id ) )->first()
|
||||
);
|
||||
}
|
||||
if ( \count( \IPS\nexus\Gateway::billingAgreementGateways() ) )
|
||||
if ( count( Gateway::billingAgreementGateways() ) )
|
||||
{
|
||||
$tabs['paypal'] = array(
|
||||
'icon' => 'paypal',
|
||||
@@ -61,44 +88,44 @@ class _AccountInformation extends \IPS\core\MemberACPProfile\TabbedBlock
|
||||
/**
|
||||
* Get output: OVERVIEW
|
||||
*
|
||||
* @return string
|
||||
* @return mixed
|
||||
*/
|
||||
protected function _overview()
|
||||
protected function _overview(): mixed
|
||||
{
|
||||
/* Sparkline */
|
||||
$sparkline = NULL;
|
||||
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customers_view_statistics' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customers_view_statistics' ) )
|
||||
{
|
||||
$rows = array();
|
||||
$oneYearAgo = \IPS\DateTime::create()->sub( new \DateInterval( 'P1Y' ) );
|
||||
$oneYearAgo = DateTime::create()->sub( new DateInterval( 'P1Y' ) );
|
||||
$date = clone $oneYearAgo;
|
||||
$endOfLastMonth = mktime( 23, 59, 59, date( 'n' ) - 1, date( 't' ), date( 'Y' ) );
|
||||
while ( $date->getTimestamp() < $endOfLastMonth )
|
||||
{
|
||||
foreach ( \IPS\nexus\Money::currencies() as $currency )
|
||||
foreach ( Money::currencies() as $currency )
|
||||
{
|
||||
$rows[$date->format( 'n Y' )][$currency] = 0;
|
||||
}
|
||||
$date->add( new \DateInterval( 'P1M' ) );
|
||||
$date->add( new DateInterval( 'P1M' ) );
|
||||
}
|
||||
$sparkline = new \IPS\Helpers\Chart;
|
||||
foreach ( \IPS\Db::i()->select( 'DATE_FORMAT( FROM_UNIXTIME(t_date), \'%c %Y\' ) AS time, SUM(t_amount)-SUM(t_partial_refund) AS amount, t_currency', 'nexus_transactions', array(array("t_member=? AND ( t_status=? OR t_status=? ) AND t_method>0 AND t_date>? AND t_date<?", $this->member->member_id, \IPS\nexus\Transaction::STATUS_PAID, \IPS\nexus\Transaction::STATUS_PART_REFUNDED, $oneYearAgo->getTimestamp(), time())), NULL, NULL, array('time', 't_currency') ) as $row )
|
||||
$sparkline = new Chart;
|
||||
foreach ( \IPS\Db::i()->select( 'DATE_FORMAT( FROM_UNIXTIME(t_date), \'%c %Y\' ) AS time, SUM(t_amount)-SUM(t_partial_refund) AS amount, t_currency', 'nexus_transactions', array(array("t_member=? AND ( t_status=? OR t_status=? ) AND t_method>0 AND t_date>? AND t_date<?", $this->member->member_id, Transaction::STATUS_PAID, Transaction::STATUS_PART_REFUNDED, $oneYearAgo->getTimestamp(), time())), NULL, NULL, array('time', 't_currency') ) as $row )
|
||||
{
|
||||
if ( isset( $rows[$row['time']][$row['t_currency']] ) ) // Currency may no longer exist
|
||||
{
|
||||
$rows[$row['time']][$row['t_currency']] += $row['amount'];
|
||||
}
|
||||
}
|
||||
$sparkline->addHeader( \IPS\Member::loggedIn()->language()->addToStack( 'date' ), 'date' );
|
||||
foreach ( \IPS\nexus\Money::currencies() as $currency )
|
||||
$sparkline->addHeader( Member::loggedIn()->language()->addToStack( 'date' ), 'date' );
|
||||
foreach ( Money::currencies() as $currency )
|
||||
{
|
||||
$sparkline->addHeader( $currency, 'number' );
|
||||
}
|
||||
foreach ( $rows as $time => $row )
|
||||
{
|
||||
$datetime = new \IPS\DateTime;
|
||||
$datetime->setTime( 0, 0, 0 );
|
||||
$datetime = new DateTime;
|
||||
$datetime->setTime( 0, 0 );
|
||||
$exploded = explode( ' ', $time );
|
||||
$datetime->setDate( $exploded[1], $exploded[0], 1 );
|
||||
|
||||
@@ -145,20 +172,21 @@ class _AccountInformation extends \IPS\core\MemberACPProfile\TabbedBlock
|
||||
$addressCount = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_customer_addresses', array( '`member`=?', $this->member->member_id ) )->first();
|
||||
|
||||
/* Display */
|
||||
return \IPS\Theme::i()->getTemplate( 'customers', 'nexus' )->accountInformationOverview( $this->member, $sparkline, $primaryBillingAddress, $addressCount );
|
||||
return Theme::i()->getTemplate( 'customers', 'nexus' )->accountInformationOverview( $this->member, $sparkline, $primaryBillingAddress, $addressCount );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get output: STORED PAYMENT METHODS
|
||||
*
|
||||
* @param bool $edit Edit view?
|
||||
* @return string
|
||||
* @return mixed
|
||||
*/
|
||||
protected function _cards( $edit = FALSE )
|
||||
protected function _cards( bool $edit = FALSE ): mixed
|
||||
{
|
||||
$cards = array();
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_customer_cards', array( 'card_member=?', $this->member->member_id ), NULL, $edit ? NULL : 10 ), 'IPS\nexus\Customer\CreditCard' ) as $card )
|
||||
foreach ( new ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_customer_cards', array( 'card_member=?', $this->member->member_id ), NULL, $edit ? NULL : 10 ), 'IPS\nexus\Customer\CreditCard' ) as $card )
|
||||
{
|
||||
/* @var Customer\CreditCard $card */
|
||||
try
|
||||
{
|
||||
$cardData = $card->card;
|
||||
@@ -167,21 +195,21 @@ class _AccountInformation extends \IPS\core\MemberACPProfile\TabbedBlock
|
||||
'card_type' => $cardData->type,
|
||||
'card_member' => $card->member->member_id,
|
||||
'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
|
||||
'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 ) { }
|
||||
catch ( Exception ) { }
|
||||
}
|
||||
$cards = new \IPS\Helpers\Table\Custom( $cards, $this->member->acpUrl()->setQueryString( 'view', 'cards' ) );
|
||||
$cards = new Custom( $cards, $this->member->acpUrl()->setQueryString( 'view', 'cards' ) );
|
||||
|
||||
if ( \IPS\nexus\Gateway::cardStorageGateways( TRUE ) )
|
||||
if ( Gateway::cardStorageGateways( TRUE ) )
|
||||
{
|
||||
$cards->rootButtons = array(
|
||||
'add' => array(
|
||||
'link' => \IPS\Http\Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( 'do', 'addCard' ),
|
||||
'link' => Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( 'do', 'addCard' ),
|
||||
'title' => 'add',
|
||||
'icon' => 'plus',
|
||||
'data' => array( 'ipsDialog' => true, 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('add_card') )
|
||||
'data' => array( 'ipsDialog' => true, 'ipsDialog-title' => Member::loggedIn()->language()->addToStack('add_card') )
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -189,7 +217,7 @@ class _AccountInformation extends \IPS\core\MemberACPProfile\TabbedBlock
|
||||
{
|
||||
return array(
|
||||
'delete' => array(
|
||||
'link' => \IPS\Http\Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( array( 'do' => 'deleteCard', 'card_id' => $row['id'] ) ),
|
||||
'link' => Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( array( 'do' => 'deleteCard', 'card_id' => $row['id'] ) ),
|
||||
'title' => 'delete',
|
||||
'icon' => 'times-circle',
|
||||
'data' => array( 'delete' => '' )
|
||||
@@ -199,18 +227,18 @@ class _AccountInformation extends \IPS\core\MemberACPProfile\TabbedBlock
|
||||
|
||||
if ( $edit )
|
||||
{
|
||||
$cards->tableTemplate = array( \IPS\Theme::i()->getTemplate( 'customers', 'nexus' ), 'cardsTable' );
|
||||
$cards->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'customers', 'nexus' ), 'cardsTableRows' );
|
||||
$cards->tableTemplate = array( Theme::i()->getTemplate( 'customers', 'nexus' ), 'cardsTable' );
|
||||
$cards->rowsTemplate = array( Theme::i()->getTemplate( 'customers', 'nexus' ), 'cardsTableRows' );
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'customers', 'nexus' )->customerPopup( $cards );
|
||||
return Theme::i()->getTemplate( 'customers', 'nexus' )->customerPopup( $cards );
|
||||
}
|
||||
else
|
||||
{
|
||||
$cards->tableTemplate = array( \IPS\Theme::i()->getTemplate( 'customers', 'nexus' ), 'cardsOverview' );
|
||||
$cards->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'customers', 'nexus' ), 'cardsOverviewRows' );
|
||||
$cards->tableTemplate = array( Theme::i()->getTemplate( 'customers', 'nexus' ), 'cardsOverview' );
|
||||
$cards->rowsTemplate = array( Theme::i()->getTemplate( 'customers', 'nexus' ), 'cardsOverviewRows' );
|
||||
|
||||
$cardCount = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_customer_cards', array( 'card_member=?', $this->member->member_id ) )->first();
|
||||
return \IPS\Theme::i()->getTemplate( 'customers', 'nexus' )->accountInformationTablePreview( $this->member, $cards, \IPS\Member::loggedIn()->language()->addToStack( 'num_credit_card', FALSE, array( 'pluralize' => array( $cardCount ) ) ), 'cards' );
|
||||
return Theme::i()->getTemplate( 'customers', 'nexus' )->accountInformationTablePreview( $this->member, $cards, Member::loggedIn()->language()->addToStack( 'num_credit_card', FALSE, array( 'pluralize' => array( $cardCount ) ) ), 'cards' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,9 +246,9 @@ class _AccountInformation extends \IPS\core\MemberACPProfile\TabbedBlock
|
||||
* Get output: BILLING AGREEMENTS
|
||||
*
|
||||
* @param bool $edit Edit view?
|
||||
* @return string
|
||||
* @return mixed
|
||||
*/
|
||||
protected function _paypal( $edit = FALSE )
|
||||
protected function _paypal( bool $edit = FALSE ): mixed
|
||||
{
|
||||
$billingAgreementCount = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_billing_agreements', array( 'ba_member=? AND ba_canceled=0', $this->member->member_id ) )->first();
|
||||
$billingAgreements = array();
|
||||
@@ -233,20 +261,20 @@ class _AccountInformation extends \IPS\core\MemberACPProfile\TabbedBlock
|
||||
'next_cycle' => $billingAgreement['ba_next_cycle'],
|
||||
);
|
||||
}
|
||||
$billingAgreements = new \IPS\Helpers\Table\Custom( $billingAgreements, $this->member->acpUrl()->setQueryString( 'view', 'billingagreements' ) );
|
||||
$billingAgreements = new Custom( $billingAgreements, $this->member->acpUrl()->setQueryString( 'view', 'billingagreements' ) );
|
||||
$billingAgreements->parsers = array(
|
||||
'started' => function( $val ) {
|
||||
return $val ? \IPS\DateTime::ts( $val )->relative() : null;
|
||||
return $val ? DateTime::ts( $val )->relative() : null;
|
||||
},
|
||||
'next_cycle' => function( $val ) {
|
||||
return $val ? \IPS\DateTime::ts( $val )->relative() : null;
|
||||
return $val ? DateTime::ts( $val )->relative() : null;
|
||||
},
|
||||
);
|
||||
$billingAgreements->rowButtons = function( $row, $id )
|
||||
{
|
||||
return array(
|
||||
'view' => array(
|
||||
'link' => \IPS\Http\Url::internal("app=nexus&module=payments&controller=billingagreements&id={$id}"),
|
||||
'link' => Url::internal("app=nexus&module=payments&controller=billingagreements&id={$id}"),
|
||||
'title' => 'view',
|
||||
'icon' => 'search',
|
||||
)
|
||||
@@ -256,14 +284,14 @@ class _AccountInformation extends \IPS\core\MemberACPProfile\TabbedBlock
|
||||
{
|
||||
$billingAgreements->exclude = array( 'id', 'last_transaction_currency' );
|
||||
$billingAgreements->langPrefix = 'ba_';
|
||||
return \IPS\Theme::i()->getTemplate( 'customers', 'nexus' )->customerPopup( $billingAgreements );
|
||||
return Theme::i()->getTemplate( 'customers', 'nexus' )->customerPopup( $billingAgreements );
|
||||
}
|
||||
else
|
||||
{
|
||||
$billingAgreements->tableTemplate = array( \IPS\Theme::i()->getTemplate( 'customers', 'nexus' ), 'billingAgreementsOverview' );
|
||||
$billingAgreements->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'customers', 'nexus' ), 'billingAgreementsOverviewRows' );
|
||||
$billingAgreements->tableTemplate = array( Theme::i()->getTemplate( 'customers', 'nexus' ), 'billingAgreementsOverview' );
|
||||
$billingAgreements->rowsTemplate = array( Theme::i()->getTemplate( 'customers', 'nexus' ), 'billingAgreementsOverviewRows' );
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'customers', 'nexus' )->accountInformationTablePreview( $this->member, $billingAgreements, \IPS\Member::loggedIn()->language()->addToStack( 'num_billing_agreements', FALSE, array( 'pluralize' => array( $billingAgreementCount ) ) ), 'paypal' );
|
||||
return Theme::i()->getTemplate( 'customers', 'nexus' )->accountInformationTablePreview( $this->member, $billingAgreements, Member::loggedIn()->language()->addToStack( 'num_billing_agreements', FALSE, array( 'pluralize' => array( $billingAgreementCount ) ) ), 'paypal' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,24 +299,24 @@ class _AccountInformation extends \IPS\core\MemberACPProfile\TabbedBlock
|
||||
* Get output: ALTERNATE CONTACTS
|
||||
*
|
||||
* @param bool $edit Edit view?
|
||||
* @return string
|
||||
* @return mixed
|
||||
*/
|
||||
protected function _alts( $edit = FALSE )
|
||||
protected function _alts( bool $edit = FALSE ): mixed
|
||||
{
|
||||
$altContactCount = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_alternate_contacts', array( 'main_id=?', $this->member->member_id ) )->first();
|
||||
$alternativeContacts = new \IPS\Helpers\Table\Db( 'nexus_alternate_contacts', $this->member->acpUrl()->setQueryString( 'view', 'alternatives' ), array( 'main_id=?', $this->member->member_id ) );
|
||||
$alternativeContacts = new Db( 'nexus_alternate_contacts', $this->member->acpUrl()->setQueryString( 'view', 'alternatives' ), array( 'main_id=?', $this->member->member_id ) );
|
||||
$alternativeContacts->langPrefix = 'altcontactTable_';
|
||||
$alternativeContacts->include = array( 'alt_id', 'purchases', 'billing', 'support' );
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customers_edit_details' ) )
|
||||
$alternativeContacts->include = array( 'alt_id', 'purchases', 'billing' );
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customers_edit_details' ) )
|
||||
{
|
||||
$alternativeContacts->parsers = array(
|
||||
'alt_id' => function( $val )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'nexus' )->userLink( \IPS\nexus\Customer::load( $val ) );
|
||||
return Theme::i()->getTemplate( 'global', 'nexus' )->userLink( Customer::load( $val ) );
|
||||
},
|
||||
'email' => function ( $val, $row )
|
||||
{
|
||||
return htmlspecialchars( \IPS\nexus\Customer::load( $row['alt_id'] )->email, ENT_DISALLOWED, 'UTF-8', FALSE );
|
||||
return htmlspecialchars( Customer::load( $row['alt_id'] )->email, ENT_DISALLOWED, 'UTF-8', FALSE );
|
||||
},
|
||||
'purchases' => function( $val )
|
||||
{
|
||||
@@ -296,9 +324,9 @@ class _AccountInformation extends \IPS\core\MemberACPProfile\TabbedBlock
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'purchases', 'nexus' )->link( \IPS\nexus\Purchase::load( $id ) );
|
||||
return Theme::i()->getTemplate( 'purchases', 'nexus' )->link( Purchase::load( $id ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
return '';
|
||||
}
|
||||
@@ -306,33 +334,29 @@ class _AccountInformation extends \IPS\core\MemberACPProfile\TabbedBlock
|
||||
},
|
||||
'billing' => function( $val )
|
||||
{
|
||||
return $val ? "<i class='fa fa-check'></i>" : "<i class='fa fa-times'></i>";
|
||||
},
|
||||
'support' => function( $val )
|
||||
{
|
||||
return $val ? "<i class='fa fa-check'></i>" : "<i class='fa fa-times'></i>";
|
||||
return $val ? "<i class='fa-solid fa-check'></i>" : "<i class='fa-solid fa-xmark'></i>";
|
||||
}
|
||||
);
|
||||
|
||||
$alternativeContacts->rootButtons = array(
|
||||
'add' => array(
|
||||
'link' => \IPS\Http\Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( 'do', 'alternativeContactForm' ),
|
||||
'link' => Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( 'do', 'alternativeContactForm' ),
|
||||
'title' => 'add',
|
||||
'icon' => 'plus',
|
||||
'data' => array( 'ipsDialog' => true, 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('altcontact_add') )
|
||||
'data' => array( 'ipsDialog' => true, 'ipsDialog-title' => Member::loggedIn()->language()->addToStack('altcontact_add') )
|
||||
)
|
||||
);
|
||||
$alternativeContacts->rowButtons = function( $row )
|
||||
{
|
||||
return array(
|
||||
'edit' => array(
|
||||
'link' => \IPS\Http\Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( array( 'do' => 'alternativeContactForm', 'alt_id' => $row['alt_id'] ) ),
|
||||
'link' => Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( array( 'do' => 'alternativeContactForm', 'alt_id' => $row['alt_id'] ) ),
|
||||
'title' => 'edit',
|
||||
'icon' => 'pencil',
|
||||
'data' => array( 'ipsDialog' => true )
|
||||
),
|
||||
'delete' => array(
|
||||
'link' => \IPS\Http\Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( array( 'do' => 'deleteAlternativeContact', 'alt_id' => $row['alt_id'] ) ),
|
||||
'link' => Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( array( 'do' => 'deleteAlternativeContact', 'alt_id' => $row['alt_id'] ) ),
|
||||
'title' => 'delete',
|
||||
'icon' => 'times-circle',
|
||||
'data' => array( 'delete' => '' )
|
||||
@@ -342,25 +366,26 @@ class _AccountInformation extends \IPS\core\MemberACPProfile\TabbedBlock
|
||||
}
|
||||
if ( $edit )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'customers', 'nexus' )->customerPopup( $alternativeContacts );
|
||||
return Theme::i()->getTemplate( 'customers', 'nexus' )->customerPopup( $alternativeContacts );
|
||||
}
|
||||
else
|
||||
{
|
||||
$alternativeContacts->include[] = 'email';
|
||||
$alternativeContacts->limit = 2;
|
||||
$alternativeContacts->tableTemplate = array( \IPS\Theme::i()->getTemplate( 'customers', 'nexus' ), 'altContactsOverview' );
|
||||
$alternativeContacts->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'customers', 'nexus' ), 'altContactsOverviewRows' );
|
||||
$alternativeContacts->tableTemplate = array( Theme::i()->getTemplate( 'customers', 'nexus' ), 'altContactsOverview' );
|
||||
$alternativeContacts->rowsTemplate = array( Theme::i()->getTemplate( 'customers', 'nexus' ), 'altContactsOverviewRows' );
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'customers', 'nexus' )->accountInformationTablePreview( $this->member, $alternativeContacts, \IPS\Member::loggedIn()->language()->addToStack( 'num_alternate_contacts', FALSE, array( 'pluralize' => array( $altContactCount ) ) ), 'alts' );
|
||||
return Theme::i()->getTemplate( 'customers', 'nexus' )->accountInformationTablePreview( $this->member, $alternativeContacts, Member::loggedIn()->language()->addToStack( 'num_alternate_contacts', FALSE, array( 'pluralize' => array( $altContactCount ) ) ), 'alts' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get output
|
||||
*
|
||||
* @return string
|
||||
* @param string $tab
|
||||
* @return mixed
|
||||
*/
|
||||
public function tabOutput( $tab )
|
||||
public function tabOutput( string $tab ): mixed
|
||||
{
|
||||
$method = "_{$tab}";
|
||||
return $this->$method();
|
||||
@@ -371,11 +396,11 @@ class _AccountInformation extends \IPS\core\MemberACPProfile\TabbedBlock
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function edit()
|
||||
public function edit(): string
|
||||
{
|
||||
if ( array_key_exists( \IPS\Request::i()->type, $this->tabs() ) )
|
||||
if ( array_key_exists( Request::i()->type, $this->tabs() ) )
|
||||
{
|
||||
$method = "_" . \IPS\Request::i()->type;
|
||||
$method = "_" . Request::i()->type;
|
||||
return $this->$method( TRUE );
|
||||
}
|
||||
return parent::edit();
|
||||
@@ -386,22 +411,22 @@ class _AccountInformation extends \IPS\core\MemberACPProfile\TabbedBlock
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function output()
|
||||
public function output(): string
|
||||
{
|
||||
$tabs = $this->tabs();
|
||||
if ( !\count( $tabs ) )
|
||||
if ( !count( $tabs ) )
|
||||
{
|
||||
return '';
|
||||
}
|
||||
$tabKeys = array_keys( $tabs );
|
||||
$activeTabKey = ( isset( \IPS\Request::i()->block['nexus_AccountInformation'] ) and array_key_exists( \IPS\Request::i()->block['nexus_AccountInformation'], $tabs ) ) ? \IPS\Request::i()->block['nexus_AccountInformation'] : array_shift( $tabKeys );
|
||||
$activeTabKey = ( isset( Request::i()->block['nexus_AccountInformation'] ) and array_key_exists( Request::i()->block['nexus_AccountInformation'], $tabs ) ) ? Request::i()->block['nexus_AccountInformation'] : array_shift( $tabKeys );
|
||||
|
||||
$activeSubscription = FALSE;
|
||||
if ( \IPS\Settings::i()->nexus_subs_enabled )
|
||||
if ( Settings::i()->nexus_subs_enabled )
|
||||
{
|
||||
$activeSubscription = \IPS\nexus\Subscription::loadActiveByMember( $this->member );
|
||||
$activeSubscription = Subscription::loadByMember( $this->member, TRUE );
|
||||
}
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'customers', 'nexus' )->accountInformation( $this->member, $tabs, $activeTabKey, $this->tabOutput( $activeTabKey ), $activeSubscription );
|
||||
return (string) Theme::i()->getTemplate( 'customers', 'nexus' )->accountInformation( $this->member, $tabs, $activeTabKey, $this->tabOutput( $activeTabKey ), $activeSubscription );
|
||||
}
|
||||
}
|
||||
@@ -11,40 +11,49 @@
|
||||
namespace IPS\nexus\extensions\core\MemberACPProfileBlocks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\core\MemberACPProfile\Block;
|
||||
use IPS\Db;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Invoice;
|
||||
use IPS\Theme;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ACP Member Profile: Invoices
|
||||
*/
|
||||
class _Invoices extends \IPS\core\MemberACPProfile\Block
|
||||
class Invoices extends Block
|
||||
{
|
||||
/**
|
||||
* Get output
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function output()
|
||||
public function output(): string
|
||||
{
|
||||
$invoiceCount = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_invoices', array( 'i_member=?', $this->member->member_id ) )->first();
|
||||
$invoices = \IPS\nexus\Invoice::table( array( 'i_member=?', $this->member->member_id ), $this->member->acpUrl()->setQueryString( 'tab', 'invoices' ), 'c' );
|
||||
$invoiceCount = Db::i()->select( 'COUNT(*)', 'nexus_invoices', array( 'i_member=?', $this->member->member_id ) )->first();
|
||||
$invoices = Invoice::table( array( 'i_member=?', $this->member->member_id ), $this->member->acpUrl()->setQueryString( 'tab', 'invoices' ), 'c' );
|
||||
$invoices->limit = 15;
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'invoices_add' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'invoices_add' ) )
|
||||
{
|
||||
$invoices->rootButtons = array(
|
||||
'add' => array(
|
||||
'link' => \IPS\Http\Url::internal( "app=nexus&module=payments&controller=invoices&do=generate&member={$this->member->member_id}" ),
|
||||
'link' => Url::internal( "app=nexus&module=payments&controller=invoices&do=generate&member={$this->member->member_id}" ),
|
||||
'title' => 'add',
|
||||
'icon' => 'plus',
|
||||
)
|
||||
);
|
||||
}
|
||||
$invoices->tableTemplate = array( \IPS\Theme::i()->getTemplate( 'customers', 'nexus' ), 'invoicesTable' );
|
||||
$invoices->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'customers', 'nexus' ), 'invoicesTableRows' );
|
||||
$invoices->tableTemplate = array( Theme::i()->getTemplate( 'customers', 'nexus' ), 'invoicesTable' );
|
||||
$invoices->rowsTemplate = array( Theme::i()->getTemplate( 'customers', 'nexus' ), 'invoicesTableRows' );
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'customers', 'nexus' )->invoices( $this->member, $invoices, $invoiceCount );
|
||||
return (string) Theme::i()->getTemplate( 'customers', 'nexus' )->invoices( $this->member, $invoices, $invoiceCount );
|
||||
}
|
||||
}
|
||||
@@ -11,51 +11,59 @@
|
||||
namespace IPS\nexus\extensions\core\MemberACPProfileBlocks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\core\MemberACPProfile\Block;
|
||||
use IPS\Helpers\Table\Db;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\Theme;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ACP Member Profile: Notes
|
||||
*/
|
||||
class _Notes extends \IPS\core\MemberACPProfile\Block
|
||||
class Notes extends Block
|
||||
{
|
||||
/**
|
||||
* @brief Notes
|
||||
*/
|
||||
protected $notes;
|
||||
protected ?Db $notes = NULL;
|
||||
|
||||
/**
|
||||
* @brief Note Count
|
||||
*/
|
||||
protected $noteCount;
|
||||
protected ?int $noteCount = NULL;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param \IPS\Member $member Member
|
||||
* @param Member $member Member
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( \IPS\Member $member )
|
||||
public function __construct( Member $member )
|
||||
{
|
||||
parent::__construct( $member );
|
||||
|
||||
$this->notes = NULL;
|
||||
$this->noteCount = 0;
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customer_notes_view' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customer_notes_view' ) )
|
||||
{
|
||||
$this->noteCount = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_notes', array( 'note_member=?', $this->member->member_id ) )->first();
|
||||
|
||||
$this->notes = new \IPS\Helpers\Table\Db( 'nexus_notes', $this->member->acpUrl()->setQueryString( array( 'view' => 'notes', 'support' => isset( \IPS\Request::i()->support ) ? \IPS\Request::i()->support : 0 ) ), array( 'note_member=?', $this->member->member_id ) );
|
||||
$this->notes->tableTemplate = array( \IPS\Theme::i()->getTemplate( 'customers', 'nexus' ), 'notes' );
|
||||
$this->notes = new Db( 'nexus_notes', $this->member->acpUrl()->setQueryString( array( 'view' => 'notes' ) ), array( 'note_member=?', $this->member->member_id ) );
|
||||
$this->notes->tableTemplate = array( Theme::i()->getTemplate( 'customers', 'nexus' ), 'notes' );
|
||||
$this->notes->sortBy = 'note_date';
|
||||
|
||||
$this->notes->parsers = array(
|
||||
'note_member' => function( $val )
|
||||
{
|
||||
return \IPS\Member::load( $val );
|
||||
return Member::load( $val );
|
||||
},
|
||||
'note_text' => function( $val )
|
||||
{
|
||||
@@ -66,30 +74,19 @@ class _Notes extends \IPS\core\MemberACPProfile\Block
|
||||
$this->notes->rowButtons = function( $row )
|
||||
{
|
||||
$return = array();
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customer_notes_edit' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customer_notes_edit' ) )
|
||||
{
|
||||
if ( !isset( \IPS\Request::i()->support ) or !\IPS\Request::i()->support )
|
||||
{
|
||||
$return['edit'] = array(
|
||||
'link' => \IPS\Http\Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( array( 'do' => 'noteForm', 'note_id' => $row['note_id'], 'support' => isset( \IPS\Request::i()->support ) ? \IPS\Request::i()->support : 0 ) ),
|
||||
'title' => 'edit',
|
||||
'icon' => 'pencil',
|
||||
'data' => array( 'ipsDialog' => true, 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('edit_note') )
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$return['edit'] = array(
|
||||
'link' => \IPS\Http\Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( array( 'do' => 'noteForm', 'note_id' => $row['note_id'], 'support' => isset( \IPS\Request::i()->support ) ? \IPS\Request::i()->support : 0 ) ),
|
||||
'title' => 'edit',
|
||||
'icon' => 'pencil',
|
||||
);
|
||||
}
|
||||
$return['edit'] = array(
|
||||
'link' => Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( array( 'do' => 'noteForm', 'note_id' => $row['note_id'] ) ),
|
||||
'title' => 'edit',
|
||||
'icon' => 'pencil',
|
||||
'data' => array( 'ipsDialog' => true, 'ipsDialog-title' => Member::loggedIn()->language()->addToStack('edit_note') )
|
||||
);
|
||||
}
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customer_notes_delete' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customer_notes_delete' ) )
|
||||
{
|
||||
$return['delete'] = array(
|
||||
'link' => \IPS\Http\Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( array( 'do' => 'deleteNote', 'note_id' => $row['note_id'], 'support' => isset( \IPS\Request::i()->support ) ? \IPS\Request::i()->support : 0 ) )->csrf(),
|
||||
'link' => Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( array( 'do' => 'deleteNote', 'note_id' => $row['note_id'] ) )->csrf(),
|
||||
'title' => 'delete',
|
||||
'icon' => 'times-circle',
|
||||
'data' => array( 'confirm' => '' )
|
||||
@@ -98,14 +95,14 @@ class _Notes extends \IPS\core\MemberACPProfile\Block
|
||||
return $return;
|
||||
};
|
||||
|
||||
if ( ( !isset( \IPS\Request::i()->support ) or !\IPS\Request::i()->support ) and \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customer_notes_add' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customer_notes_add' ) )
|
||||
{
|
||||
$this->notes->rootButtons = array(
|
||||
'add' => array(
|
||||
'link' => \IPS\Http\Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( array( 'do' => 'noteForm', 'support' => isset( \IPS\Request::i()->support ) ? \IPS\Request::i()->support : 0 ) ),
|
||||
'link' => Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( array( 'do' => 'noteForm' ) ),
|
||||
'title' => 'add',
|
||||
'icon' => 'plus',
|
||||
'data' => array( 'ipsDialog' => true, 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('add_note') )
|
||||
'data' => array( 'ipsDialog' => true, 'ipsDialog-title' => Member::loggedIn()->language()->addToStack('add_note') )
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -117,13 +114,13 @@ class _Notes extends \IPS\core\MemberACPProfile\Block
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function output()
|
||||
public function output(): string
|
||||
{
|
||||
$this->notes->limit = 2;
|
||||
$this->notes->tableTemplate = array( \IPS\Theme::i()->getTemplate( 'customers', 'nexus' ), 'notesOverview' );
|
||||
$this->notes->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'customers', 'nexus' ), 'notesOverviewRows' );
|
||||
$this->notes->tableTemplate = array( Theme::i()->getTemplate( 'customers', 'nexus' ), 'notesOverview' );
|
||||
$this->notes->rowsTemplate = array( Theme::i()->getTemplate( 'customers', 'nexus' ), 'notesOverviewRows' );
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'customers', 'nexus' )->notesBlock( $this->member, $this->noteCount, $this->notes );
|
||||
return (string) Theme::i()->getTemplate( 'customers', 'nexus' )->notesBlock( $this->member, $this->noteCount, $this->notes );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,8 +128,8 @@ class _Notes extends \IPS\core\MemberACPProfile\Block
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function lazyOutput()
|
||||
public function lazyOutput(): string
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'customers', 'nexus' )->customerPopup( $this->notes );
|
||||
return (string) Theme::i()->getTemplate( 'customers', 'nexus' )->customerPopup( $this->notes );
|
||||
}
|
||||
}
|
||||
@@ -11,33 +11,43 @@
|
||||
namespace IPS\nexus\extensions\core\MemberACPProfileBlocks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\core\MemberACPProfile\Block;
|
||||
use IPS\Db;
|
||||
use IPS\nexus\Customer;
|
||||
use IPS\Theme;
|
||||
use function count;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ACP Member Profile: Customer Statistics Block
|
||||
*/
|
||||
class _ParentAccounts extends \IPS\core\MemberACPProfile\Block
|
||||
class ParentAccounts extends Block
|
||||
{
|
||||
/**
|
||||
* Get output
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function output()
|
||||
public function output(): string
|
||||
{
|
||||
$parents = array();
|
||||
foreach ( \IPS\Db::i()->select( 'main_id', 'nexus_alternate_contacts', array( 'alt_id=?', $this->member->member_id ) ) as $row )
|
||||
foreach ( Db::i()->select( 'main_id', 'nexus_alternate_contacts', array( 'alt_id=?', $this->member->member_id ) ) as $row )
|
||||
{
|
||||
$parents[] = \IPS\nexus\Customer::load( $row );
|
||||
$parents[] = Customer::load( $row );
|
||||
}
|
||||
|
||||
if ( \count( $parents ) )
|
||||
if ( count( $parents ) )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'customers', 'nexus' )->parentAccounts( $parents );
|
||||
return (string) Theme::i()->getTemplate( 'customers', 'nexus' )->parentAccounts( $parents );
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
@@ -11,44 +11,55 @@
|
||||
namespace IPS\nexus\extensions\core\MemberACPProfileBlocks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\core\MemberACPProfile\TabbedBlock;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Helpers\Tree\Tree;
|
||||
use IPS\nexus\Purchase;
|
||||
use IPS\Request;
|
||||
use IPS\Theme;
|
||||
use function count;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ACP Member Profile: Purchases
|
||||
*/
|
||||
class _Purchases extends \IPS\core\MemberACPProfile\TabbedBlock
|
||||
class Purchases extends TabbedBlock
|
||||
{
|
||||
/**
|
||||
* Purchase tree
|
||||
*/
|
||||
protected $_purchases = NULL;
|
||||
protected ?Tree $_purchases = NULL;
|
||||
|
||||
/**
|
||||
* Get Tab Names
|
||||
*
|
||||
* @return string
|
||||
* @return array
|
||||
*/
|
||||
public function tabs()
|
||||
public function tabs(): array
|
||||
{
|
||||
$tabs = array();
|
||||
|
||||
$activeCount = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_member=? AND ps_show=1 AND ps_active=1 AND ps_parent = 0', $this->member->member_id ) )->first();
|
||||
$activeCount = Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_member=? AND ps_show=1 AND ps_active=1 AND ps_parent = 0', $this->member->member_id ) )->first();
|
||||
$tabs['active'] = array(
|
||||
'icon' => 'credit-card',
|
||||
'count' => $activeCount,
|
||||
);
|
||||
|
||||
$expiredCount = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_member=? AND ps_active = 0 AND ps_cancelled = 0 AND ps_parent = 0 AND ps_expire <?', $this->member->member_id, \IPS\DateTime::create()->getTimestamp() ) )->first();
|
||||
$expiredCount = Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_member=? AND ps_active = 0 AND ps_cancelled = 0 AND ps_parent = 0 AND ps_expire <?', $this->member->member_id, DateTime::create()->getTimestamp() ) )->first();
|
||||
$tabs['expired'] = array(
|
||||
'icon' => 'credit-card',
|
||||
'count' => $expiredCount,
|
||||
);
|
||||
|
||||
$canceledCount = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_member=? AND ps_cancelled=1 AND ps_parent = 0', $this->member->member_id ) )->first();
|
||||
$canceledCount = Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_member=? AND ps_cancelled=1 AND ps_parent = 0', $this->member->member_id ) )->first();
|
||||
$tabs['canceled'] = array(
|
||||
'icon' => 'credit-card',
|
||||
'count' => $canceledCount,
|
||||
@@ -62,32 +73,33 @@ class _Purchases extends \IPS\core\MemberACPProfile\TabbedBlock
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function output()
|
||||
public function output(): string
|
||||
{
|
||||
$tabs = $this->tabs();
|
||||
if ( !\count( $tabs ) )
|
||||
if ( !count( $tabs ) )
|
||||
{
|
||||
return '';
|
||||
}
|
||||
$tabKeys = array_keys( $tabs );
|
||||
$activeTabKey = ( isset( \IPS\Request::i()->block['nexus_Purchase'] ) and array_key_exists( \IPS\Request::i()->block['nexus_Purchases'], $tabs ) ) ? \IPS\Request::i()->block['nexus_Purchases'] : array_shift( $tabKeys );
|
||||
$activeTabKey = ( isset( Request::i()->block['nexus_Purchase'] ) and array_key_exists( Request::i()->block['nexus_Purchases'], $tabs ) ) ? Request::i()->block['nexus_Purchases'] : array_shift( $tabKeys );
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'customers', 'nexus' )->purchases( $this->member, $tabs, $activeTabKey, $this->tabOutput( $activeTabKey ) );
|
||||
return (string) Theme::i()->getTemplate( 'customers', 'nexus' )->purchases( $this->member, $tabs, $activeTabKey, $this->tabOutput( $activeTabKey ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get output
|
||||
*
|
||||
* @return string
|
||||
* @param string $tab
|
||||
* @return mixed
|
||||
*/
|
||||
public function tabOutput( $activeTabKey )
|
||||
public function tabOutput(string $tab ): mixed
|
||||
{
|
||||
if ( $this->_purchases === NULL )
|
||||
{
|
||||
$where = array();
|
||||
$where[] = array( 'ps_member=?', $this->member->member_id );
|
||||
|
||||
switch ( $activeTabKey )
|
||||
switch ( $tab )
|
||||
{
|
||||
case 'active':
|
||||
$where[] = array( 'ps_active=1' );
|
||||
@@ -96,11 +108,11 @@ class _Purchases extends \IPS\core\MemberACPProfile\TabbedBlock
|
||||
$where[] = array( 'ps_cancelled=1' );
|
||||
break;
|
||||
case 'expired':
|
||||
$where[] = array( 'ps_active = 0 and ps_cancelled = 0 and ps_expire <?', \IPS\DateTime::create()->getTimestamp() );
|
||||
$where[] = array( 'ps_active = 0 and ps_cancelled = 0 and ps_expire <?', DateTime::create()->getTimestamp() );
|
||||
break;
|
||||
}
|
||||
|
||||
$this->_purchases = \IPS\nexus\Purchase::tree( $this->member->acpUrl()->setQueryString( 'blockKey', 'nexus_Purchases' ), $where );
|
||||
$this->_purchases = Purchase::tree( $this->member->acpUrl()->setQueryString( 'blockKey', 'nexus_Purchases' ), $where );
|
||||
$this->_purchases->getTotalRoots = function()
|
||||
{
|
||||
return NULL;
|
||||
|
||||
@@ -11,36 +11,48 @@
|
||||
namespace IPS\nexus\extensions\core\MemberACPProfileBlocks;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\core\MemberACPProfile\LazyLoadingBlock;
|
||||
use IPS\Db;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Invoice;
|
||||
use IPS\nexus\Money;
|
||||
use IPS\nexus\Transaction;
|
||||
use IPS\Theme;
|
||||
use UnderflowException;
|
||||
use function defined;
|
||||
use function floatval;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ACP Member Profile: Customer Statistics Block
|
||||
*/
|
||||
class _Statistics extends \IPS\core\MemberACPProfile\LazyLoadingBlock
|
||||
class Statistics extends LazyLoadingBlock
|
||||
{
|
||||
/**
|
||||
* Get output
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function lazyOutput()
|
||||
public function lazyOutput(): string
|
||||
{
|
||||
$standing = array();
|
||||
$time = time();
|
||||
foreach ( \IPS\nexus\Money::currencies() as $currency )
|
||||
foreach ( Money::currencies() as $currency )
|
||||
{
|
||||
/* Total spent */
|
||||
$comparisons = \IPS\Db::i()->select( 'AVG(xval) AS avg, MAX(xval) AS max, MIN(xval) AS min', \IPS\Db::i()->select( "(SUM(t_amount)-SUM(t_partial_refund)) as xval", 'nexus_transactions', array( '( t_status=? OR t_status=? ) AND t_method>0 AND t_currency=? AND t_member<>0', \IPS\nexus\Transaction::STATUS_PAID, \IPS\nexus\Transaction::STATUS_PART_REFUNDED, $currency ), NULL, NULL, 't_member' ), 'xval>0' )->first();
|
||||
$val = \IPS\Db::i()->select( 'SUM(t_amount)-SUM(t_partial_refund)', 'nexus_transactions', array( 't_member=? AND ( t_status=? OR t_status=? ) AND t_method>0 AND t_currency=?', $this->member->member_id, \IPS\nexus\Transaction::STATUS_PAID, \IPS\nexus\Transaction::STATUS_PART_REFUNDED, $currency ) )->first();
|
||||
$standing[ \IPS\Member::loggedIn()->language()->addToStack( 'total_spent_currency', FALSE, array( 'sprintf' => array( $currency ) ) ) ] = array(
|
||||
'value' => new \IPS\nexus\Money( $val ?: '0', $currency ),
|
||||
'avg' => new \IPS\nexus\Money( $comparisons['avg'], $currency ),
|
||||
'highest' => new \IPS\nexus\Money( $comparisons['max'], $currency ),
|
||||
'lowest' => new \IPS\nexus\Money( $comparisons['min'], $currency ),
|
||||
$comparisons = Db::i()->select( 'AVG(xval) AS avg, MAX(xval) AS max, MIN(xval) AS min', Db::i()->select( "(SUM(t_amount)-SUM(t_partial_refund)) as xval", 'nexus_transactions', array( '( t_status=? OR t_status=? ) AND t_method>0 AND t_currency=? AND t_member<>0', Transaction::STATUS_PAID, Transaction::STATUS_PART_REFUNDED, $currency ), NULL, NULL, 't_member' ), 'xval>0' )->first();
|
||||
$val = Db::i()->select( 'SUM(t_amount)-SUM(t_partial_refund)', 'nexus_transactions', array( 't_member=? AND ( t_status=? OR t_status=? ) AND t_method>0 AND t_currency=?', $this->member->member_id, Transaction::STATUS_PAID, Transaction::STATUS_PART_REFUNDED, $currency ) )->first();
|
||||
$standing[ Member::loggedIn()->language()->addToStack( 'total_spent_currency', FALSE, array( 'sprintf' => array( $currency ) ) ) ] = array(
|
||||
'value' => new Money( $val ?: '0', $currency ),
|
||||
'avg' => new Money( $comparisons['avg'] ?: 0, $currency ),
|
||||
'highest' => new Money( $comparisons['max'] ?: 0, $currency ),
|
||||
'lowest' => new Money( $comparisons['min'] ?: 0, $currency ),
|
||||
'lowval' => $comparisons['min'],
|
||||
'highval' => $comparisons['max'],
|
||||
'avgval' => $comparisons['avg'],
|
||||
@@ -52,21 +64,21 @@ class _Statistics extends \IPS\core\MemberACPProfile\LazyLoadingBlock
|
||||
|
||||
/* Average monthly spend */
|
||||
$sum = "( SUM(t_amount) / ( ( {$time} - core_members.joined ) / 2592000 ) )";
|
||||
$where = array( array( "( t_status=? OR t_status=? ) AND ({$time} - core_members.joined > 2592000) AND t_currency=?", \IPS\nexus\Transaction::STATUS_PAID, \IPS\nexus\Transaction::STATUS_PART_REFUNDED, $currency ) );
|
||||
$where = array( array( "( t_status=? OR t_status=? ) AND ({$time} - core_members.joined > 2592000) AND t_currency=?", Transaction::STATUS_PAID, Transaction::STATUS_PART_REFUNDED, $currency ) );
|
||||
try
|
||||
{
|
||||
$val = \IPS\Db::i()->select( "{$sum} as sum", 'nexus_transactions', array_merge( $where, array( array( 't_member=?', $this->member->member_id ) ) ), 'joined', NULL, 'joined' )->join( 'core_members', 'member_id=t_member' )->first();
|
||||
$val = Db::i()->select( "{$sum} as sum", 'nexus_transactions', array_merge( $where, array( array( 't_member=?', $this->member->member_id ) ) ), 'joined', NULL, 'joined' )->join( 'core_members', 'member_id=t_member' )->first();
|
||||
}
|
||||
catch( \UnderflowException $e )
|
||||
catch( UnderflowException )
|
||||
{
|
||||
$val = 0;
|
||||
}
|
||||
$comparisons = \IPS\Db::i()->select( 'AVG(xval) AS avg, MAX(xval) AS max, MIN(xval) AS min', \IPS\Db::i()->select( "{$sum} as xval", 'nexus_transactions', array_merge( $where, array( array( 't_member<>0' ) ) ), NULL, NULL, array( 't_member', 'joined' ) ), 'xval>0' )->join( 'core_members', 'member_id=t_member' )->first();
|
||||
$standing[ \IPS\Member::loggedIn()->language()->addToStack( 'average_spend_currency', FALSE, array( 'sprintf' => array( $currency ) ) ) ] = array(
|
||||
'value' => new \IPS\nexus\Money( $val, $currency ),
|
||||
'avg' => new \IPS\nexus\Money( $comparisons['avg'], $currency ),
|
||||
'highest' => new \IPS\nexus\Money( $comparisons['max'], $currency ),
|
||||
'lowest' => new \IPS\nexus\Money( $comparisons['min'], $currency ),
|
||||
$comparisons = Db::i()->select( 'AVG(xval) AS avg, MAX(xval) AS max, MIN(xval) AS min', Db::i()->select( "{$sum} as xval", 'nexus_transactions', array_merge( $where, array( array( 't_member<>0' ) ) ), NULL, NULL, array( 't_member', 'joined' ) ), 'xval>0' )->join( 'core_members', 'member_id=t_member' )->first();
|
||||
$standing[ Member::loggedIn()->language()->addToStack( 'average_spend_currency', FALSE, array( 'sprintf' => array( $currency ) ) ) ] = array(
|
||||
'value' => new Money( $val ?: 0, $currency ),
|
||||
'avg' => new Money( $comparisons['avg'] ?: 0, $currency ),
|
||||
'highest' => new Money( $comparisons['max'] ?: 0, $currency ),
|
||||
'lowest' => new Money( $comparisons['min'] ?: 0, $currency ),
|
||||
'lowval' => $comparisons['min'],
|
||||
'highval' => $comparisons['max'],
|
||||
'avgval' => $comparisons['avg'],
|
||||
@@ -78,47 +90,24 @@ class _Statistics extends \IPS\core\MemberACPProfile\LazyLoadingBlock
|
||||
}
|
||||
|
||||
$sum = "ROUND( ( AVG( i_paid - i_date ) / 86400 ), 2 )";
|
||||
$where = array( array( "i_status=? AND i_date>0 AND i_paid>0", \IPS\nexus\Invoice::STATUS_PAID ) );
|
||||
$val = \IPS\Db::i()->select( "{$sum} as sum", 'nexus_invoices', array_merge( $where, array( array( 'i_member=?', $this->member->member_id ) ) ) )->join( 'core_members', 'member_id=i_member' )->first();
|
||||
$comparisons = \IPS\Db::i()->select( 'AVG(xval) AS avg, MAX(xval) AS max, MIN(xval) AS min', \IPS\Db::i()->select( "{$sum} as xval", 'nexus_invoices', array_merge( $where, array( array( 'i_member<>0' ) ) ), NULL, NULL, array( 'i_member', 'joined' ) ), 'xval>0' )->join( 'core_members', 'member_id=i_member' )->first();
|
||||
$standing[ \IPS\Member::loggedIn()->language()->addToStack( 'average_time_to_pay' ) ] = array(
|
||||
'value' => \IPS\Member::loggedIn()->language()->formatNumber( $val, 2 ) . ' ' . \IPS\Member::loggedIn()->language()->addToStack('days'),
|
||||
'avg' => \IPS\Member::loggedIn()->language()->formatNumber( $comparisons['avg'], 2 ) . ' ' . \IPS\Member::loggedIn()->language()->addToStack('days'),
|
||||
'highest' => \IPS\Member::loggedIn()->language()->formatNumber( $comparisons['max'], 2 ) . ' ' . \IPS\Member::loggedIn()->language()->addToStack('days'),
|
||||
'lowest' => \IPS\Member::loggedIn()->language()->formatNumber( $comparisons['min'], 2 ) . ' ' . \IPS\Member::loggedIn()->language()->addToStack('days'),
|
||||
$where = array( array( "i_status=? AND i_date>0 AND i_paid>0", Invoice::STATUS_PAID ) );
|
||||
$val = Db::i()->select( "{$sum} as sum", 'nexus_invoices', array_merge( $where, array( array( 'i_member=?', $this->member->member_id ) ) ) )->join( 'core_members', 'member_id=i_member' )->first();
|
||||
$comparisons = Db::i()->select( 'AVG(xval) AS avg, MAX(xval) AS max, MIN(xval) AS min', Db::i()->select( "{$sum} as xval", 'nexus_invoices', array_merge( $where, array( array( 'i_member<>0' ) ) ), NULL, NULL, array( 'i_member', 'joined' ) ), 'xval>0' )->join( 'core_members', 'member_id=i_member' )->first();
|
||||
$standing[ Member::loggedIn()->language()->addToStack( 'average_time_to_pay' ) ] = array(
|
||||
'value' => Member::loggedIn()->language()->formatNumber( $val, 2 ) . ' ' . Member::loggedIn()->language()->addToStack('days'),
|
||||
'avg' => Member::loggedIn()->language()->formatNumber( $comparisons['avg'], 2 ) . ' ' . Member::loggedIn()->language()->addToStack('days'),
|
||||
'highest' => Member::loggedIn()->language()->formatNumber( $comparisons['max'], 2 ) . ' ' . Member::loggedIn()->language()->addToStack('days'),
|
||||
'lowest' => Member::loggedIn()->language()->formatNumber( $comparisons['min'], 2 ) . ' ' . Member::loggedIn()->language()->addToStack('days'),
|
||||
'lowval' => $comparisons['min'],
|
||||
'highval' => $comparisons['max'],
|
||||
'avgval' => $comparisons['avg'],
|
||||
'thisval' => $val,
|
||||
'avgpct' => \floatval( $comparisons['max'] ) ? round( ( ( $comparisons['avg'] - $comparisons['min'] ) / $comparisons['max'] ) * 100, 1 ) : 0,
|
||||
'thispct' => \floatval( $comparisons['max'] ) ? round( ( ( $val - $comparisons['min'] ) / $comparisons['max'] ) * 100, 1 ) : 0,
|
||||
'avgpct' => floatval( $comparisons['max'] ) ? round( ( ( $comparisons['avg'] - $comparisons['min'] ) / $comparisons['max'] ) * 100, 1 ) : 0,
|
||||
'thispct' => floatval( $comparisons['max'] ) ? round( ( ( $val - $comparisons['min'] ) / $comparisons['max'] ) * 100, 1 ) : 0,
|
||||
'type' => 'timetopay'
|
||||
);
|
||||
|
||||
$sum = "LEAST( ( count(*) / ( ( {$time} - core_members.joined ) / 2592000 ) ), count(*) )";
|
||||
try
|
||||
{
|
||||
$val = \IPS\Db::i()->select( "{$sum} as sum", 'nexus_support_requests', array( 'r_member=?', $this->member->member_id ), 'joined', NULL, 'joined' )->join( 'core_members', 'member_id=r_member' )->first();
|
||||
}
|
||||
catch( \UnderflowException $e )
|
||||
{
|
||||
$val = 0;
|
||||
}
|
||||
$comparisons = \IPS\Db::i()->select( 'AVG(xval) AS avg, MAX(xval) AS max, MIN(xval) AS min', \IPS\Db::i()->select( "{$sum} as xval", 'nexus_support_requests', 'r_member<>0', NULL, NULL, 'joined' ) )->join( 'core_members', 'member_id=r_member' )->first();
|
||||
$standing[ \IPS\Member::loggedIn()->language()->addToStack( 'average_monthly_support_requests' ) ] = array(
|
||||
'value' => \IPS\Member::loggedIn()->language()->formatNumber( $val, 2 ),
|
||||
'avg' => \IPS\Member::loggedIn()->language()->formatNumber( $comparisons['avg'], 2 ),
|
||||
'highest' => \IPS\Member::loggedIn()->language()->formatNumber( $comparisons['max'], 2 ),
|
||||
'lowest' => \IPS\Member::loggedIn()->language()->formatNumber( $comparisons['min'], 2 ),
|
||||
'lowval' => $comparisons['min'],
|
||||
'highval' => $comparisons['max'],
|
||||
'avgval' => $comparisons['avg'],
|
||||
'thisval' => $val,
|
||||
'avgpct' => $comparisons['max'] ? round( ( ( $comparisons['avg'] - $comparisons['min'] ) / $comparisons['max'] ) * 100, 1 ) : 0,
|
||||
'thispct' => $comparisons['max'] ? round( ( ( $val - $comparisons['min'] ) / $comparisons['max'] ) * 100, 1 ) : 0,
|
||||
'type' => 'support'
|
||||
);
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'customers', 'nexus' )->standing( $standing );
|
||||
return (string) Theme::i()->getTemplate( 'customers', 'nexus' )->standing( $standing );
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief ACP Member Profile: Support
|
||||
* @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
|
||||
* @since 5 Dec 2017
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\extensions\core\MemberACPProfileBlocks;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ACP Member Profile: Support
|
||||
*/
|
||||
class _Support extends \IPS\core\MemberACPProfile\Block
|
||||
{
|
||||
/**
|
||||
* Get output
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function output()
|
||||
{
|
||||
$customerStream = \IPS\nexus\Support\Stream::customer( $this->member );
|
||||
$supportCount = $customerStream->count( \IPS\Member::loggedIn() );
|
||||
$results = $customerStream->results( \IPS\Member::loggedIn(), 'r_started DESC', 1, 15 );
|
||||
$supportRequestsInView = array_keys( iterator_to_array( $results ) );
|
||||
$tracked = iterator_to_array( \IPS\Db::i()->select( array( 'request_id', 'notify' ), 'nexus_support_tracker', array( array( 'member_id=?', \IPS\Member::loggedIn()->member_id ), array( \IPS\Db::i()->in( 'request_id', $supportRequestsInView ) ) ) )->setKeyField( 'request_id' )->setValueField( 'notify' ) );
|
||||
$participatedIn = iterator_to_array( \IPS\Db::i()->select( 'DISTINCT reply_request', 'nexus_support_replies', array( array( 'reply_member=?', \IPS\Member::loggedIn()->member_id ), array( \IPS\Db::i()->in( 'reply_request', $supportRequestsInView ) ) ) ) );
|
||||
$support = \IPS\Theme::i()->getTemplate( 'support', 'nexus' )->requestsTableResults( $results, NULL, FALSE, $tracked, $participatedIn, FALSE );
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'customers', 'nexus' )->support( $this->member, $support, $supportCount );
|
||||
}
|
||||
}
|
||||
@@ -11,26 +11,34 @@
|
||||
namespace IPS\nexus\extensions\core\MemberACPProfileTabs;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\core\MemberACPProfile\MainTab;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Customer;
|
||||
use IPS\Output;
|
||||
use IPS\Theme;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ACP Member Profile: Customer Tab
|
||||
*/
|
||||
class _Main extends \IPS\core\MemberACPProfile\MainTab
|
||||
class Main extends MainTab
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param \IPS\Member $member Member
|
||||
* @param Member $member Member
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( \IPS\Member $member )
|
||||
public function __construct( Member $member )
|
||||
{
|
||||
$this->member = \IPS\nexus\Customer::load( $member->member_id );
|
||||
$this->member = Customer::load( $member->member_id );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -38,9 +46,9 @@ class _Main extends \IPS\core\MemberACPProfile\MainTab
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canView()
|
||||
public function canView(): bool
|
||||
{
|
||||
return (bool) \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customers_view' );
|
||||
return (bool) Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customers_view' );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,7 +56,7 @@ class _Main extends \IPS\core\MemberACPProfile\MainTab
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function leftColumnBlocks()
|
||||
public function leftColumnBlocks(): array
|
||||
{
|
||||
return array(
|
||||
'IPS\nexus\extensions\core\MemberACPProfileBlocks\AccountInformation',
|
||||
@@ -60,37 +68,32 @@ class _Main extends \IPS\core\MemberACPProfile\MainTab
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function mainColumnBlocks()
|
||||
public function mainColumnBlocks(): array
|
||||
{
|
||||
$return = array();
|
||||
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customers_view_statistics' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customers_view_statistics' ) )
|
||||
{
|
||||
$return[] = 'IPS\nexus\extensions\core\MemberACPProfileBlocks\Statistics';
|
||||
}
|
||||
|
||||
$return[] = 'IPS\nexus\extensions\core\MemberACPProfileBlocks\ParentAccounts';
|
||||
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customer_notes_view' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customer_notes_view' ) )
|
||||
{
|
||||
$return[] = 'IPS\nexus\extensions\core\MemberACPProfileBlocks\Notes';
|
||||
}
|
||||
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'purchases_view' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'purchases_view' ) )
|
||||
{
|
||||
$return[] = 'IPS\nexus\extensions\core\MemberACPProfileBlocks\Purchases';
|
||||
}
|
||||
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'invoices_manage' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'invoices_manage' ) )
|
||||
{
|
||||
$return[] = 'IPS\nexus\extensions\core\MemberACPProfileBlocks\Invoices';
|
||||
}
|
||||
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'support', 'requests_manage' ) )
|
||||
{
|
||||
$return[] = 'IPS\nexus\extensions\core\MemberACPProfileBlocks\Support';
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
@@ -99,17 +102,10 @@ class _Main extends \IPS\core\MemberACPProfile\MainTab
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function output()
|
||||
public function output(): string
|
||||
{
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'customer.css', 'nexus', 'admin' ) );
|
||||
|
||||
if ( \IPS\Theme::i()->settings['responsive'] )
|
||||
{
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'customer_responsive.css', 'nexus', 'admin' ) );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'support.css', 'nexus', 'admin' ) );
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'admin_customer.js', 'nexus', 'admin' ) );
|
||||
Output::i()->cssFiles = array_merge( Output::i()->cssFiles, Theme::i()->css( 'customer.css', 'nexus', 'admin' ) );
|
||||
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js( 'admin_customer.js', 'nexus', 'admin' ) );
|
||||
|
||||
return parent::output();
|
||||
}
|
||||
|
||||
@@ -11,30 +11,43 @@
|
||||
namespace IPS\nexus\extensions\core\MemberExportPersonalInformation;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use Exception;
|
||||
use IPS\Db;
|
||||
use IPS\Extensions\MemberExportPiiAbstract;
|
||||
use IPS\GeoLocation;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Customer as NexusCustomer;
|
||||
use IPS\nexus\Customer\CustomField;
|
||||
use IPS\Patterns\ActiveRecordIterator;
|
||||
use OutOfRangeException;
|
||||
use function defined;
|
||||
use function is_null;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ACP Export Personal Information
|
||||
*/
|
||||
class _Customer
|
||||
class Customer extends MemberExportPiiAbstract
|
||||
{
|
||||
/**
|
||||
* Return data
|
||||
* @param \IPS\Member $member The member
|
||||
* @param Member $member The member
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getData( \IPS\Member $member )
|
||||
public function getData( Member $member ): array
|
||||
{
|
||||
$return = array();
|
||||
|
||||
try
|
||||
{
|
||||
$customer = \IPS\nexus\Customer::load( $member->member_id );
|
||||
$customer = NexusCustomer::load( $member->member_id );
|
||||
|
||||
/* Name and addresses */
|
||||
$return['customer'] = array(
|
||||
@@ -42,13 +55,13 @@ class _Customer
|
||||
'last_name' => $customer->cm_last_name
|
||||
);
|
||||
|
||||
foreach( \IPS\Db::i()->select( '*', 'nexus_customer_addresses', array( '`member`=?', $member->member_id ) ) as $address )
|
||||
foreach( Db::i()->select( '*', 'nexus_customer_addresses', array( '`member`=?', $member->member_id ) ) as $address )
|
||||
{
|
||||
$return['addresses'][] = \IPS\GeoLocation::buildFromJson( $address['address'] )->toString( "," );
|
||||
$return['addresses'][] = GeoLocation::buildFromJson( $address['address'] )->toString( "," );
|
||||
}
|
||||
|
||||
/* Customer custom fields */
|
||||
foreach ( \IPS\nexus\Customer\CustomField::roots() as $field )
|
||||
foreach ( CustomField::roots() as $field )
|
||||
{
|
||||
$column = $field->column;
|
||||
if ( $column )
|
||||
@@ -58,7 +71,7 @@ class _Customer
|
||||
}
|
||||
|
||||
/* Credit cards */
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_customer_cards', array( 'card_member=?', $member->member_id ) ), 'IPS\nexus\Customer\CreditCard' ) as $card )
|
||||
foreach ( new ActiveRecordIterator( Db::i()->select( '*', 'nexus_customer_cards', array( 'card_member=?', $member->member_id ) ), 'IPS\nexus\Customer\CreditCard' ) as $card )
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -66,13 +79,13 @@ class _Customer
|
||||
$return['credit_cards'][ $card->id ] = array(
|
||||
'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
|
||||
'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 ) {}
|
||||
catch ( Exception ) {}
|
||||
}
|
||||
}
|
||||
catch( \OutOfRangeException $ex )
|
||||
catch( OutOfRangeException )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Member Filter 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/
|
||||
* @package Invision Community
|
||||
* @subpackage Commerce
|
||||
* @since 30 Jan 2024
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\extensions\core\MemberFilter;
|
||||
|
||||
use IPS\Db;
|
||||
use IPS\Db\Select;
|
||||
use IPS\Extensions\MemberFilterAbstract;
|
||||
use IPS\Helpers\Form\Custom;
|
||||
use IPS\Helpers\Form\Node;
|
||||
use IPS\Helpers\Form\Select as FormSelect;
|
||||
use IPS\nexus\Donation\Goal;
|
||||
use IPS\nexus\Money;
|
||||
use IPS\Theme;
|
||||
use LogicException;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Member Filter Extension
|
||||
*/
|
||||
class Donations extends MemberFilterAbstract
|
||||
{
|
||||
/**
|
||||
* Determine if the filter is available in a given area
|
||||
*
|
||||
* @param string $area Area to check (bulkmail, group_promotions, automatic_moderation, passwordreset)
|
||||
* @return bool
|
||||
*/
|
||||
public function availableIn( string $area ): bool
|
||||
{
|
||||
return in_array( $area, array( 'bulkmail', 'group_promotions' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Setting Field
|
||||
*
|
||||
* @param array $criteria Value returned from the save() method
|
||||
* @return array Array of form elements
|
||||
*/
|
||||
public function getSettingField( array $criteria ): array
|
||||
{
|
||||
return array(
|
||||
$this->_combine( 'nexus_bm_filters_total_donate', 'IPS\nexus\Form\Money', $criteria ),
|
||||
new Node( 'nexus_bm_filters_donate_goals', $criteria['donate_goals'] ?? 0, false, array( 'class' => Goal::class, 'multiple' => true, 'zeroVal' => 'any' ) )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the filter data
|
||||
*
|
||||
* @param array $post Form values
|
||||
* @return array False, or an array of data to use later when filtering the members
|
||||
* @throws LogicException
|
||||
*/
|
||||
public function save( array $post ): array
|
||||
{
|
||||
$amounts = array();
|
||||
|
||||
foreach( $post['nexus_bm_filters_total_donate'][1] as $amount )
|
||||
{
|
||||
$amounts[$amount->currency] = $amount->amount;
|
||||
}
|
||||
|
||||
return array(
|
||||
'total_donate_operator' => $post['nexus_bm_filters_total_donate'][0],
|
||||
'total_donate_amounts' => json_encode( $amounts ),
|
||||
'donate_goals' => ( is_array( $post['nexus_bm_filters_donate_goals'] ) and count( $post['nexus_bm_filters_donate_goals'] ) ) ? array_keys( $post['nexus_bm_filters_donate_goals'] ) : 0
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get where clause to add to the member retrieval database query
|
||||
*
|
||||
* @param array $data The array returned from the save() method
|
||||
* @return array|null Where clause
|
||||
*/
|
||||
public function getQueryWhereClause( array $data ): ?array
|
||||
{
|
||||
$where = array();
|
||||
|
||||
if ( ( isset( $data['total_donate_operator'] ) and $data['total_donate_operator'] !== 'any' ) and isset( $data['total_donate_amounts'] ) )
|
||||
{
|
||||
foreach( json_decode( $data['total_donate_amounts'], true ) as $currency => $amount )
|
||||
{
|
||||
switch ( $data['total_donate_operator'] )
|
||||
{
|
||||
case 'gt':
|
||||
$operator = ">";
|
||||
break;
|
||||
case 'lt':
|
||||
$operator = "<";
|
||||
break;
|
||||
}
|
||||
|
||||
$where[] = "(nexus_donate_logs.dl_amount{$operator}'{$amount}')";
|
||||
}
|
||||
|
||||
$where[] = array( implode( ' OR ', $where ) );
|
||||
}
|
||||
|
||||
if( isset( $data['donate_goals'] ) and $data['donate_goals'] !== 0 )
|
||||
{
|
||||
$where[] = array( Db::i()->in( 'dl_goal', $data['donate_goals'] ) );
|
||||
}
|
||||
|
||||
return count( $where ) ? $where : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for member retrieval database query
|
||||
* Can be used to set joins
|
||||
*
|
||||
* @param array $data The array returned from the save() method
|
||||
* @param Select $query The query
|
||||
* @return void
|
||||
*/
|
||||
public function queryCallback( array $data, Select $query ) : void
|
||||
{
|
||||
$currencies = Money::currencies();
|
||||
$defaultCurrency = array_shift( $currencies );
|
||||
|
||||
if (
|
||||
( ( isset( $data['total_donate_operator'] ) and $data['total_donate_operator'] !== 'any' ) and isset( $data['total_donate_amounts'] ) ) OR
|
||||
( isset( $data['donate_goals'] ) and $data['donate_goals'] !== 0 )
|
||||
)
|
||||
{
|
||||
$query->join( 'nexus_donate_logs', "core_members.member_id=nexus_donate_logs.dl_member" );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine two fields
|
||||
*
|
||||
* @param string $name Field name
|
||||
* @param string $field2Class Classname for second field
|
||||
* @param array $criteria Value returned from the save() method
|
||||
* @return Custom
|
||||
*/
|
||||
public function _combine( string $name, string $field2Class, array $criteria ) : Custom
|
||||
{
|
||||
$validate = NULL;
|
||||
|
||||
$options = array(
|
||||
'options' => array(
|
||||
'any' => 'any_value',
|
||||
'gt' => 'gt',
|
||||
'lt' => 'lt'
|
||||
),
|
||||
'toggles' => array(
|
||||
'gt' => array( $name . '_unit' ),
|
||||
'lt' => array( $name . '_unit' ),
|
||||
)
|
||||
);
|
||||
|
||||
$field1 = new FormSelect( $name . '_type', $criteria['total_donate_operator'] ?? '', FALSE, $options, NULL, NULL, NULL );
|
||||
$field2 = new $field2Class( $name . '_unit', $criteria['total_donate_amounts'] ?? NULL, FALSE, array() );
|
||||
|
||||
return new Custom( $name, array( "gt", NULL ), FALSE, array(
|
||||
'getHtml' => function() use ( $name, $field1, $field2 )
|
||||
{
|
||||
return Theme::i()->getTemplate( 'forms', 'nexus', 'global' )->combined( $name, $field1, $field2 );
|
||||
},
|
||||
'formatValue' => function() use ( $field1, $field2 )
|
||||
{
|
||||
return array( $field1->value, $field2->value );
|
||||
}
|
||||
) );
|
||||
}
|
||||
}
|
||||
@@ -12,58 +12,83 @@
|
||||
namespace IPS\nexus\extensions\core\MemberFilter;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DateInterval;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Db\Select;
|
||||
use IPS\Extensions\MemberFilterAbstract;
|
||||
use IPS\Helpers\Form\CheckboxSet;
|
||||
use IPS\Helpers\Form\Custom;
|
||||
use IPS\Helpers\Form\DateRange;
|
||||
use IPS\Helpers\Form\Node;
|
||||
use IPS\nexus\Package;
|
||||
use IPS\nexus\Package\Group;
|
||||
use IPS\Theme;
|
||||
use LogicException;
|
||||
use OutOfRangeException;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
use function intval;
|
||||
use function is_array;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Member filter extension
|
||||
*/
|
||||
class _Purchases
|
||||
class Purchases extends MemberFilterAbstract
|
||||
{
|
||||
/**
|
||||
* Determine if the filter is available in a given area
|
||||
*
|
||||
* @param string $area Area to check
|
||||
* @param string $area Area to check (bulkmail, group_promotions, automatic_moderation)
|
||||
* @return bool
|
||||
*/
|
||||
public function availableIn( $area )
|
||||
public function availableIn( string $area ): bool
|
||||
{
|
||||
return \in_array( $area, array( 'bulkmail' ) );
|
||||
return in_array( $area, array( 'bulkmail' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Setting Field
|
||||
*
|
||||
* @param mixed $criteria Value returned from the save() method
|
||||
* @param array $criteria Value returned from the save() method
|
||||
* @return array Array of form elements
|
||||
*/
|
||||
public function getSettingField( $criteria )
|
||||
public function getSettingField( array $criteria ): array
|
||||
{
|
||||
return array(
|
||||
new \IPS\Helpers\Form\Node( 'nexus_bm_filters_packages', isset( $criteria['nexus_bm_filters_packages'] ) ? array_filter( array_map( function( $val )
|
||||
new Node( 'nexus_bm_filters_packages', isset( $criteria['nexus_bm_filters_packages'] ) ? array_filter( array_map( function( $val )
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\nexus\Package::load( $val );
|
||||
return Package::load( $val );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}, explode( ',', $criteria['nexus_bm_filters_packages'] ) ) ) : 0, FALSE, array( 'zeroVal' => 'nexus_bm_filters_packages_none', 'multiple' => TRUE, 'class' => 'IPS\nexus\Package\Group', 'zeroValTogglesOff' => array( 'nexus_bm_filters_pkg_active', 'nexus_bm_filters_pkg_expired', 'nexus_bm_filters_pkg_canceled' ), 'permissionCheck' => function( $node )
|
||||
{
|
||||
return !( $node instanceof \IPS\nexus\Package\Group );
|
||||
return !( $node instanceof Group );
|
||||
} ) ),
|
||||
new \IPS\Helpers\Form\CheckboxSet( 'nexus_bm_filters_type', isset( $criteria['nexus_bm_filters_type'] ) ? $criteria['nexus_bm_filters_type'] : array( 'active' ), FALSE, array( 'toggles' => array( 'expired' => array( 'nexus_bm_filters_pkg_expired' ) ), 'options' => array( 'active' => 'nexus_bm_filters_type_active', 'expired' => 'nexus_bm_filters_type_expired', 'canceled' => 'nexus_bm_filters_type_canceled' ) ), NULL, NULL, NULL, 'nexus_bm_filters_types' ),
|
||||
new \IPS\Helpers\Form\Custom( 'nexus_bm_filters_pkg_expired', array( 0 => isset( $criteria['nexus_bm_filters_pkg_expired']['range'] ) ? $criteria['nexus_bm_filters_pkg_expired']['range'] : '', 1 => isset( $criteria['nexus_bm_filters_pkg_expired']['days'] ) ? $criteria['nexus_bm_filters_pkg_expired']['days'] : NULL, 3 => isset( $criteria['nexus_bm_filters_pkg_expired']['days_lt'] ) ? $criteria['nexus_bm_filters_pkg_expired']['days_lt'] : NULL ), FALSE, array(
|
||||
new CheckboxSet( 'nexus_bm_filters_type', $criteria['nexus_bm_filters_type'] ?? array('active'), FALSE, array( 'toggles' => array( 'expired' => array( 'nexus_bm_filters_pkg_expired' ) ), 'options' => array( 'active' => 'nexus_bm_filters_type_active', 'expired' => 'nexus_bm_filters_type_expired', 'canceled' => 'nexus_bm_filters_type_canceled' ) ), NULL, NULL, NULL, 'nexus_bm_filters_types' ),
|
||||
new Custom( 'nexus_bm_filters_pkg_expired', array(
|
||||
0 => $criteria['nexus_bm_filters_pkg_expired']['range'] ?? '',
|
||||
1 => $criteria['nexus_bm_filters_pkg_expired']['days'] ?? NULL,
|
||||
3 => $criteria['nexus_bm_filters_pkg_expired']['days_lt'] ?? NULL
|
||||
), FALSE, array(
|
||||
'getHtml' => function( $element )
|
||||
{
|
||||
$dateRange = new \IPS\Helpers\Form\DateRange( "{$element->name}[0]", $element->value[0], FALSE );
|
||||
$dateRange = new DateRange( "{$element->name}[0]", $element->value[0], FALSE );
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'members', 'core', 'global' )->dateFilters( $dateRange, $element );
|
||||
return Theme::i()->getTemplate( 'members', 'core', 'global' )->dateFilters( $dateRange, $element );
|
||||
}
|
||||
), NULL, NULL, NULL, 'nexus_bm_filters_pkg_expired' ),
|
||||
);
|
||||
@@ -73,14 +98,14 @@ class _Purchases
|
||||
* Save the filter data
|
||||
*
|
||||
* @param array $post Form values
|
||||
* @return mixed False, or an array of data to use later when filtering the members
|
||||
* @throws \LogicException
|
||||
* @return array|bool False, or an array of data to use later when filtering the members
|
||||
* @throws LogicException
|
||||
*/
|
||||
public function save( $post )
|
||||
public function save( array $post ): array|bool
|
||||
{
|
||||
$return = array();
|
||||
|
||||
if ( \is_array( $post['nexus_bm_filters_packages'] ) )
|
||||
if ( is_array( $post['nexus_bm_filters_packages'] ) )
|
||||
{
|
||||
$ids = array();
|
||||
foreach ( $post['nexus_bm_filters_packages'] as $package )
|
||||
@@ -94,17 +119,16 @@ class _Purchases
|
||||
if( isset( $post['nexus_bm_filters_type'] ) )
|
||||
{
|
||||
$return['nexus_bm_filters_type'] = $post['nexus_bm_filters_type'];
|
||||
$return['nexus_bm_filters_pkg_active'] = (bool) ( \in_array( "active", $post['nexus_bm_filters_type'] ) );
|
||||
$return['nexus_bm_filters_pkg_canceled'] = (bool) ( \in_array( "canceled", $post['nexus_bm_filters_type'] ) );
|
||||
$return['nexus_bm_filters_pkg_expired'] = NULL;
|
||||
$return['nexus_bm_filters_pkg_active'] = ( in_array( "active", $post['nexus_bm_filters_type'] ) );
|
||||
$return['nexus_bm_filters_pkg_canceled'] = ( in_array( "canceled", $post['nexus_bm_filters_type'] ) );
|
||||
|
||||
if( isset( $post['nexus_bm_filters_pkg_expired'][2] ) AND $post['nexus_bm_filters_pkg_expired'][2] == 'days' )
|
||||
{
|
||||
$return['nexus_bm_filters_pkg_expired'] = $post['nexus_bm_filters_pkg_expired'][1] ? array( 'days' => \intval( $post['nexus_bm_filters_pkg_expired'][1] ) ) : FALSE;
|
||||
$return['nexus_bm_filters_pkg_expired'] = $post['nexus_bm_filters_pkg_expired'][1] ? array( 'days' => intval( $post['nexus_bm_filters_pkg_expired'][1] ) ) : FALSE;
|
||||
}
|
||||
elseif( isset( $post['nexus_bm_filters_pkg_expired'][2] ) AND $post['nexus_bm_filters_pkg_expired'][2] == 'days_lt' )
|
||||
{
|
||||
$return['nexus_bm_filters_pkg_expired'] = $post['nexus_bm_filters_pkg_expired'][3] ? array( 'days_lt' => \intval( $post['nexus_bm_filters_pkg_expired'][3] ) ) : FALSE;
|
||||
$return['nexus_bm_filters_pkg_expired'] = $post['nexus_bm_filters_pkg_expired'][3] ? array( 'days_lt' => intval( $post['nexus_bm_filters_pkg_expired'][3] ) ) : FALSE;
|
||||
}
|
||||
elseif( isset( $post['nexus_bm_filters_pkg_expired'][2] ) AND $post['nexus_bm_filters_pkg_expired'][2] == 'range' )
|
||||
{
|
||||
@@ -116,16 +140,16 @@ class _Purchases
|
||||
}
|
||||
}
|
||||
|
||||
return \count( $return ) ? $return : FALSE;
|
||||
return count( $return ) ? $return : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get where clause to add to the member retrieval database query
|
||||
*
|
||||
* @param mixed $data The array returned from the save() method
|
||||
* @param array $data The array returned from the save() method
|
||||
* @return array|NULL Where clause - must be a single array( "clause" )
|
||||
*/
|
||||
public function getQueryWhereClause( $data )
|
||||
public function getQueryWhereClause( array $data ): ?array
|
||||
{
|
||||
if ( isset( $data['nexus_bm_filters_packages'] ) and $data['nexus_bm_filters_packages'] )
|
||||
{
|
||||
@@ -138,11 +162,11 @@ class _Purchases
|
||||
* Callback for member retrieval database query
|
||||
* Can be used to set joins
|
||||
*
|
||||
* @param mixed $data The array returned from the save() method
|
||||
* @param \IPS\Db\Query $query The query
|
||||
* @param array $data The array returned from the save() method
|
||||
* @param Select $query The query
|
||||
* @return void
|
||||
*/
|
||||
public function queryCallback( $data, &$query )
|
||||
public function queryCallback( array $data, Select $query ) : void
|
||||
{
|
||||
if ( isset( $data['nexus_bm_filters_packages'] ) and $data['nexus_bm_filters_packages'] )
|
||||
{
|
||||
@@ -160,26 +184,26 @@ class _Purchases
|
||||
|
||||
if ( !empty( $data[ 'nexus_bm_filters_pkg_expired' ][ 'range' ] ) AND !empty( $data[ 'nexus_bm_filters_pkg_expired' ][ 'range' ][ 'end' ] ) )
|
||||
{
|
||||
$start = ( $data[ 'nexus_bm_filters_pkg_expired' ][ 'range' ][ 'start' ] ) ? new \IPS\DateTime( $data[ 'nexus_bm_filters_pkg_expired' ][ 'range' ][ 'start' ] ) : NULL;
|
||||
$end = ( $data[ 'nexus_bm_filters_pkg_expired' ][ 'range' ][ 'end' ] ) ? new \IPS\DateTime( $data[ 'nexus_bm_filters_pkg_expired' ][ 'range' ][ 'end' ] ) : NULL;
|
||||
$start = ( $data[ 'nexus_bm_filters_pkg_expired' ][ 'range' ][ 'start' ] ) ? new DateTime( $data[ 'nexus_bm_filters_pkg_expired' ][ 'range' ][ 'start' ] ) : NULL;
|
||||
$end = new DateTime( $data[ 'nexus_bm_filters_pkg_expired' ][ 'range' ][ 'end' ] );
|
||||
|
||||
if ( $start and $end )
|
||||
if ( $start )
|
||||
{
|
||||
$types[] = "( purchase.ps_active=0 AND purchase.ps_cancelled=0 AND purchase.ps_expire BETWEEN {$start->getTimestamp()} AND {$end->getTimestamp()})";
|
||||
}
|
||||
}
|
||||
elseif ( !empty( $data[ 'nexus_bm_filters_pkg_expired' ][ 'days' ] ) )
|
||||
{
|
||||
$date = \IPS\DateTime::create()->sub( new \DateInterval( 'P' . $data[ 'nexus_bm_filters_pkg_expired' ][ 'days' ] . 'D' ) );
|
||||
$date = DateTime::create()->sub( new DateInterval( 'P' . $data[ 'nexus_bm_filters_pkg_expired' ][ 'days' ] . 'D' ) );
|
||||
$types[] = "( purchase.ps_active=0 AND purchase.ps_cancelled=0 AND purchase.ps_expire < {$date->getTimestamp()})";
|
||||
}
|
||||
elseif( !empty( $data[ 'nexus_bm_filters_pkg_expired' ][ 'days_lt' ] ) AND (int) $data[ 'nexus_bm_filters_pkg_expired' ][ 'days_lt' ] )
|
||||
{
|
||||
$date = \IPS\DateTime::create()->sub( new \DateInterval( 'P' . (int) $data[ 'nexus_bm_filters_pkg_expired' ][ 'days_lt' ] . 'D' ) );
|
||||
$date = DateTime::create()->sub( new DateInterval( 'P' . (int) $data[ 'nexus_bm_filters_pkg_expired' ][ 'days_lt' ] . 'D' ) );
|
||||
|
||||
$types[] = "( purchase.ps_active=0 AND purchase.ps_cancelled=0 AND purchase.ps_expire > {$date->getTimestamp()})";
|
||||
}
|
||||
elseif( isset( $data['nexus_bm_filters_type'] ) AND \in_array( 'expired', $data['nexus_bm_filters_type'] ) )
|
||||
elseif( isset( $data['nexus_bm_filters_type'] ) AND in_array( 'expired', $data['nexus_bm_filters_type'] ) )
|
||||
{
|
||||
$types[] = "(purchase.ps_expire < " . time() . ")";
|
||||
}
|
||||
@@ -189,7 +213,7 @@ class _Purchases
|
||||
$types = implode( ' OR ', $types );
|
||||
}
|
||||
|
||||
$query->join( ['nexus_purchases', 'purchase'], "purchase.ps_app='nexus' AND purchase.ps_type='package' AND purchase.ps_member=core_members.member_id AND " . \IPS\Db::i()->in( 'purchase.ps_item_id', explode( ',', $data['nexus_bm_filters_packages'] ) ) . ( $types ? " AND ( {$types} )" : '' ) );
|
||||
$query->join( ['nexus_purchases', 'purchase'], "purchase.ps_app='nexus' AND purchase.ps_type='package' AND purchase.ps_member=core_members.member_id AND " . Db::i()->in( 'purchase.ps_item_id', explode( ',', $data['nexus_bm_filters_packages'] ) ) . ( $types ? " AND ( {$types} )" : '' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,57 +12,79 @@
|
||||
namespace IPS\nexus\extensions\core\MemberFilter;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DateInterval;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Db\Select;
|
||||
use IPS\Extensions\MemberFilterAbstract;
|
||||
use IPS\Helpers\Form\CheckboxSet;
|
||||
use IPS\Helpers\Form\Custom;
|
||||
use IPS\Helpers\Form\DateRange;
|
||||
use IPS\Helpers\Form\Node;
|
||||
use IPS\nexus\Subscription\Package;
|
||||
use IPS\Theme;
|
||||
use LogicException;
|
||||
use OutOfRangeException;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
use function intval;
|
||||
use function is_array;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Member filter extension
|
||||
*/
|
||||
class _Subscriptions
|
||||
class Subscriptions extends MemberFilterAbstract
|
||||
{
|
||||
/**
|
||||
* Determine if the filter is available in a given area
|
||||
*
|
||||
* @param string $area Area to check
|
||||
* @param string $area Area to check (bulkmail, group_promotions, automatic_moderation)
|
||||
* @return bool
|
||||
*/
|
||||
public function availableIn( $area )
|
||||
public function availableIn( string $area ): bool
|
||||
{
|
||||
return \in_array( $area, array( 'bulkmail' ) );
|
||||
return in_array( $area, array( 'bulkmail' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Setting Field
|
||||
*
|
||||
* @param mixed $criteria Value returned from the save() method
|
||||
* @param array $criteria Value returned from the save() method
|
||||
* @return array Array of form elements
|
||||
*/
|
||||
public function getSettingField( $criteria )
|
||||
public function getSettingField( array $criteria ): array
|
||||
{
|
||||
return array(
|
||||
new \IPS\Helpers\Form\Node( 'nexus_bm_filters_subscription_pkgs', isset( $criteria['nexus_bm_filters_subscription_pkgs'] ) ? array_filter( array_map( function( $val )
|
||||
new Node( 'nexus_bm_filters_subscription_pkgs', isset( $criteria['nexus_bm_filters_subscription_pkgs'] ) ? array_filter( array_map( function( $val )
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\nexus\Subscription\Package::load( $val );
|
||||
return Package::load( $val );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}, explode( ',', $criteria['nexus_bm_filters_subscription_pkgs'] ) ) ) : 0, FALSE, array( 'zeroVal' => 'nexus_bm_filters_subscription_none', 'multiple' => TRUE, 'class' => 'IPS\nexus\Subscription\Package', 'zeroValTogglesOff' => array( 'nexus_bm_filters_subscription_type' ) ) ),
|
||||
|
||||
new \IPS\Helpers\Form\CheckboxSet( 'nexus_bm_filters_subscription_type', isset( $criteria['nexus_bm_filters_subscription_type'] ) ? explode( ',', $criteria['nexus_bm_filters_subscription_type'] ) : array( 'active' ), FALSE, array( 'toggles' => array( 'expired' => array( 'nexus_bm_filters_type_expired_date' ) ), 'options' => array( 'active' => 'nexus_bm_filters_type_active', 'expired' => 'nexus_bm_filters_type_expired' ) ), NULL, NULL, NULL, 'nexus_bm_filters_subscription_type' ),
|
||||
new CheckboxSet( 'nexus_bm_filters_subscription_type', isset( $criteria['nexus_bm_filters_subscription_type'] ) ? explode( ',', $criteria['nexus_bm_filters_subscription_type'] ) : array( 'active' ), FALSE, array( 'toggles' => array( 'expired' => array( 'nexus_bm_filters_type_expired_date' ) ), 'options' => array( 'active' => 'nexus_bm_filters_type_active', 'expired' => 'nexus_bm_filters_type_expired' ) ), NULL, NULL, NULL, 'nexus_bm_filters_subscription_type' ),
|
||||
|
||||
new \IPS\Helpers\Form\Custom( 'nexus_bm_filters_type_expired_date', array( 0 => isset( $criteria['nexus_bm_filters_type_expired_date']['range'] ) ? $criteria['nexus_bm_filters_type_expired_date']['range'] : '', 1 => isset( $criteria['nexus_bm_filters_type_expired_date']['days'] ) ? $criteria['nexus_bm_filters_type_expired_date']['days'] : NULL ), FALSE, array(
|
||||
new Custom( 'nexus_bm_filters_type_expired_date', array(
|
||||
0 => $criteria['nexus_bm_filters_type_expired_date']['range'] ?? '',
|
||||
1 => $criteria['nexus_bm_filters_type_expired_date']['days'] ?? NULL
|
||||
), FALSE, array(
|
||||
'getHtml' => function( $element )
|
||||
{
|
||||
$dateRange = new \IPS\Helpers\Form\DateRange( "{$element->name}[0]", $element->value[0], FALSE );
|
||||
$dateRange = new DateRange( "{$element->name}[0]", $element->value[0], FALSE );
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'members', 'core', 'global' )->dateFilters( $dateRange, $element );
|
||||
return Theme::i()->getTemplate( 'members', 'core', 'global' )->dateFilters( $dateRange, $element );
|
||||
}
|
||||
), NULL, NULL, NULL, 'nexus_bm_filters_type_expired_date' ),
|
||||
);
|
||||
@@ -72,12 +94,12 @@ class _Subscriptions
|
||||
* Save the filter data
|
||||
*
|
||||
* @param array $post Form values
|
||||
* @return mixed False, or an array of data to use later when filtering the members
|
||||
* @throws \LogicException
|
||||
* @return array|bool False, or an array of data to use later when filtering the members
|
||||
* @throws LogicException
|
||||
*/
|
||||
public function save( $post )
|
||||
public function save( array $post ): array|bool
|
||||
{
|
||||
if ( \is_array( $post['nexus_bm_filters_subscription_pkgs'] ) )
|
||||
if ( is_array( $post['nexus_bm_filters_subscription_pkgs'] ) )
|
||||
{
|
||||
$ids = array();
|
||||
foreach ( $post['nexus_bm_filters_subscription_pkgs'] as $package )
|
||||
@@ -87,13 +109,13 @@ class _Subscriptions
|
||||
|
||||
$return = array(
|
||||
'nexus_bm_filters_subscription_pkgs' => implode( ',', $ids ),
|
||||
'nexus_bm_filters_subscription_active' => (bool) ( \in_array( "active", $post['nexus_bm_filters_subscription_type'] ) ),
|
||||
'nexus_bm_filters_subscription_canceled' => (bool) ( \in_array( "expired", $post['nexus_bm_filters_subscription_type'] ) ),
|
||||
'nexus_bm_filters_subscription_active' => ( in_array( "active", $post['nexus_bm_filters_subscription_type'] ) ),
|
||||
'nexus_bm_filters_subscription_canceled' => ( in_array( "expired", $post['nexus_bm_filters_subscription_type'] ) ),
|
||||
);
|
||||
|
||||
if( isset( $post['nexus_bm_filters_type_expired_date'][2] ) AND $post['nexus_bm_filters_type_expired_date'][2] == 'days' )
|
||||
{
|
||||
$return['nexus_bm_filters_type_expired_date'] = $post['nexus_bm_filters_type_expired_date'][1] ? array( 'days' => \intval( $post['nexus_bm_filters_type_expired_date'][1] ) ) : FALSE;
|
||||
$return['nexus_bm_filters_type_expired_date'] = $post['nexus_bm_filters_type_expired_date'][1] ? array( 'days' => intval( $post['nexus_bm_filters_type_expired_date'][1] ) ) : FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -111,10 +133,10 @@ class _Subscriptions
|
||||
/**
|
||||
* Get where clause to add to the member retrieval database query
|
||||
*
|
||||
* @param mixed $data The array returned from the save() method
|
||||
* @param array $data The array returned from the save() method
|
||||
* @return array|NULL Where clause - must be a single array( "clause" )
|
||||
*/
|
||||
public function getQueryWhereClause( $data )
|
||||
public function getQueryWhereClause( array $data ): ?array
|
||||
{
|
||||
if ( isset( $data['nexus_bm_filters_subscription_pkgs'] ) and $data['nexus_bm_filters_subscription_pkgs'] )
|
||||
{
|
||||
@@ -127,11 +149,11 @@ class _Subscriptions
|
||||
* Callback for member retrieval database query
|
||||
* Can be used to set joins
|
||||
*
|
||||
* @param mixed $data The array returned from the save() method
|
||||
* @param \IPS\Db\Query $query The query
|
||||
* @param array $data The array returned from the save() method
|
||||
* @param Select $query The query
|
||||
* @return void
|
||||
*/
|
||||
public function queryCallback( $data, &$query )
|
||||
public function queryCallback( array $data, Select $query ) : void
|
||||
{
|
||||
if ( isset( $data['nexus_bm_filters_subscription_pkgs'] ) and $data['nexus_bm_filters_subscription_pkgs'] )
|
||||
{
|
||||
@@ -149,24 +171,24 @@ class _Subscriptions
|
||||
|
||||
if ( !empty( $data[ 'nexus_bm_filters_type_expired_date' ][ 'range' ] ) AND !empty( $data[ 'nexus_bm_filters_type_expired_date' ][ 'range' ][ 'end' ] ) )
|
||||
{
|
||||
$start = ( $data[ 'nexus_bm_filters_type_expired_date' ][ 'range' ][ 'start' ] ) ? new \IPS\DateTime( $data[ 'nexus_bm_filters_type_expired_date' ][ 'range' ][ 'start' ] ) : NULL;
|
||||
$end = ( $data[ 'nexus_bm_filters_type_expired_date' ][ 'range' ][ 'end' ] ) ? new \IPS\DateTime( $data[ 'nexus_bm_filters_type_expired_date' ][ 'range' ][ 'end' ] ) : NULL;
|
||||
$start = ( $data[ 'nexus_bm_filters_type_expired_date' ][ 'range' ][ 'start' ] ) ? new DateTime( $data[ 'nexus_bm_filters_type_expired_date' ][ 'range' ][ 'start' ] ) : NULL;
|
||||
$end = new DateTime( $data[ 'nexus_bm_filters_type_expired_date' ][ 'range' ][ 'end' ] );
|
||||
|
||||
if ( $start and $end )
|
||||
if ( $start )
|
||||
{
|
||||
$types[] = "( nexus_purchases.ps_active=0 AND nexus_purchases.ps_cancelled=0 AND nexus_purchases.ps_expire BETWEEN {$start->getTimestamp()} AND {$end->getTimestamp()})";
|
||||
}
|
||||
}
|
||||
elseif ( !empty( $data[ 'nexus_bm_filters_type_expired_date' ][ 'days' ] ) )
|
||||
{
|
||||
$date = \IPS\DateTime::create()->sub( new \DateInterval( 'P' . $data[ 'nexus_bm_filters_type_expired_date' ][ 'days' ] . 'D' ) );
|
||||
$date = DateTime::create()->sub( new DateInterval( 'P' . $data[ 'nexus_bm_filters_type_expired_date' ][ 'days' ] . 'D' ) );
|
||||
$types[] = "( nexus_purchases.ps_active=0 AND nexus_purchases.ps_cancelled=0 AND nexus_purchases.ps_expire < {$date->getTimestamp()})";
|
||||
}
|
||||
|
||||
if ( !empty( $types ) )
|
||||
{
|
||||
$types = implode( ' OR ', $types );
|
||||
$query->join( 'nexus_purchases', "nexus_purchases.ps_app='nexus' AND nexus_purchases.ps_type='subscription' AND nexus_purchases.ps_member=core_members.member_id AND " . \IPS\Db::i()->in( 'nexus_purchases.ps_item_id', explode( ',', $data['nexus_bm_filters_subscription_pkgs'] ) ) . " AND ( {$types} )" );
|
||||
$query->join( 'nexus_purchases', "nexus_purchases.ps_app='nexus' AND nexus_purchases.ps_type='subscription' AND nexus_purchases.ps_member=core_members.member_id AND " . Db::i()->in( 'nexus_purchases.ps_item_id', explode( ',', $data['nexus_bm_filters_subscription_pkgs'] ) ) . " AND ( {$types} )" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,35 +12,46 @@
|
||||
namespace IPS\nexus\extensions\core\MemberFilter;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Db\Select;
|
||||
use IPS\Extensions\MemberFilterAbstract;
|
||||
use IPS\Helpers\Form\Custom;
|
||||
use IPS\Helpers\Form\Select as FormSelect;
|
||||
use IPS\nexus\Money;
|
||||
use IPS\Theme;
|
||||
use LogicException;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Member filter extension
|
||||
*/
|
||||
class _TotalSpend
|
||||
class TotalSpend extends MemberFilterAbstract
|
||||
{
|
||||
/**
|
||||
* Determine if the filter is available in a given area
|
||||
*
|
||||
* @param string $area Area to check
|
||||
* @param string $area Area to check (bulkmail, group_promotions, automatic_moderation)
|
||||
* @return bool
|
||||
*/
|
||||
public function availableIn( $area )
|
||||
public function availableIn( string $area ): bool
|
||||
{
|
||||
return \in_array( $area, array( 'bulkmail' ) );
|
||||
return in_array( $area, array( 'bulkmail' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Setting Field
|
||||
*
|
||||
* @param mixed $criteria Value returned from the save() method
|
||||
* @param array $criteria Value returned from the save() method
|
||||
* @return array Array of form elements
|
||||
*/
|
||||
public function getSettingField( $criteria )
|
||||
public function getSettingField( array $criteria ): array
|
||||
{
|
||||
return array( $this->_combine( 'nexus_bm_filters_total_spend', 'IPS\nexus\Form\Money', $criteria ) );
|
||||
}
|
||||
@@ -49,10 +60,10 @@ class _TotalSpend
|
||||
* Save the filter data
|
||||
*
|
||||
* @param array $post Form values
|
||||
* @return mixed False, or an array of data to use later when filtering the members
|
||||
* @throws \LogicException
|
||||
* @return array False, or an array of data to use later when filtering the members
|
||||
* @throws LogicException
|
||||
*/
|
||||
public function save( $post )
|
||||
public function save( array $post ): array
|
||||
{
|
||||
$amounts = array();
|
||||
|
||||
@@ -67,10 +78,10 @@ class _TotalSpend
|
||||
/**
|
||||
* Get where clause to add to the member retrieval database query
|
||||
*
|
||||
* @param mixed $data The array returned from the save() method
|
||||
* @return string|array|NULL Where clause
|
||||
* @param array $data The array returned from the save() method
|
||||
* @return array|null Where clause
|
||||
*/
|
||||
public function getQueryWhereClause( $data )
|
||||
public function getQueryWhereClause( array $data ): ?array
|
||||
{
|
||||
if ( ( isset( $data['total_spend_operator'] ) and $data['total_spend_operator'] !== 'any' ) and isset( $data['total_spend_amounts'] ) )
|
||||
{
|
||||
@@ -100,13 +111,13 @@ class _TotalSpend
|
||||
* Callback for member retrieval database query
|
||||
* Can be used to set joins
|
||||
*
|
||||
* @param mixed $data The array returned from the save() method
|
||||
* @param \IPS\Db\Query $query The query
|
||||
* @param array $data The array returned from the save() method
|
||||
* @param Select $query The query
|
||||
* @return void
|
||||
*/
|
||||
public function queryCallback( $data, &$query )
|
||||
public function queryCallback( array $data, Select $query ) : void
|
||||
{
|
||||
$currencies = \IPS\nexus\Money::currencies();
|
||||
$currencies = Money::currencies();
|
||||
$defaultCurrency = array_shift( $currencies );
|
||||
|
||||
if ( ( isset( $data['total_spend_operator'] ) and $data['total_spend_operator'] !== 'any' ) and isset( $data['total_spend_amounts'] ) )
|
||||
@@ -119,11 +130,11 @@ class _TotalSpend
|
||||
* Combine two fields
|
||||
*
|
||||
* @param string $name Field name
|
||||
* @param bool $field2Class Classname for second field
|
||||
* @param mixed $criteria Value returned from the save() method
|
||||
* @return \IPS\Helpers\Form\Custom
|
||||
* @param string $field2Class Classname for second field
|
||||
* @param array $criteria Value returned from the save() method
|
||||
* @return Custom
|
||||
*/
|
||||
public function _combine( $name, $field2Class, $criteria )
|
||||
public function _combine( string $name, string $field2Class, array $criteria ) : Custom
|
||||
{
|
||||
$validate = NULL;
|
||||
|
||||
@@ -139,13 +150,13 @@ class _TotalSpend
|
||||
)
|
||||
);
|
||||
|
||||
$field1 = new \IPS\Helpers\Form\Select( $name . '_type', isset($criteria['total_spend_operator']) ? $criteria['total_spend_operator'] : '', FALSE, $options, NULL, NULL, NULL );
|
||||
$field2 = new $field2Class( $name . '_unit', isset( $criteria['total_spend_amounts'] ) ? $criteria['total_spend_amounts'] : NULL, FALSE, array() );
|
||||
$field1 = new FormSelect( $name . '_type', $criteria['total_spend_operator'] ?? '', FALSE, $options, NULL, NULL, NULL );
|
||||
$field2 = new $field2Class( $name . '_unit', $criteria['total_spend_amounts'] ?? NULL, FALSE, array() );
|
||||
|
||||
return new \IPS\Helpers\Form\Custom( $name, array( "gt", NULL ), FALSE, array(
|
||||
return new Custom( $name, array( "gt", NULL ), FALSE, array(
|
||||
'getHtml' => function() use ( $name, $field1, $field2 )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'forms', 'nexus', 'global' )->combined( $name, $field1, $field2 );
|
||||
return Theme::i()->getTemplate( 'forms', 'nexus', 'global' )->combined( $name, $field1, $field2 );
|
||||
},
|
||||
'formatValue' => function() use ( $field1, $field2 )
|
||||
{
|
||||
|
||||
@@ -12,28 +12,50 @@
|
||||
namespace IPS\nexus\extensions\core\MemberHistory;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use BadFunctionCallException;
|
||||
use DateInterval;
|
||||
use IPS\Application;
|
||||
use IPS\downloads\File;
|
||||
use IPS\Extensions\MemberHistoryAbstract;
|
||||
use IPS\GeoLocation;
|
||||
use IPS\Math\Number;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Customer;
|
||||
use IPS\nexus\Invoice;
|
||||
use IPS\nexus\Money;
|
||||
use IPS\nexus\Payout;
|
||||
use IPS\nexus\Purchase;
|
||||
use IPS\nexus\Purchase\RenewalTerm;
|
||||
use IPS\nexus\Subscription\Package;
|
||||
use IPS\nexus\Transaction;
|
||||
use IPS\Settings;
|
||||
use IPS\Theme;
|
||||
use OutOfRangeException;
|
||||
use function defined;
|
||||
use function is_array;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Member History: Nexus
|
||||
*/
|
||||
class _Nexus
|
||||
class Nexus extends MemberHistoryAbstract
|
||||
{
|
||||
/**
|
||||
* Return the valid member history log types
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getTypes()
|
||||
public function getTypes(): array
|
||||
{
|
||||
return array(
|
||||
'invoice',
|
||||
'transaction',
|
||||
'shipping',
|
||||
'purchase',
|
||||
'comission',
|
||||
'giftvoucher',
|
||||
@@ -44,7 +66,6 @@ class _Nexus
|
||||
'payout',
|
||||
'lkey',
|
||||
'download',
|
||||
'support',
|
||||
'custom',
|
||||
'billingagreement',
|
||||
'note',
|
||||
@@ -59,7 +80,7 @@ class _Nexus
|
||||
* @param array $row entire log row
|
||||
* @return string
|
||||
*/
|
||||
public function parseLogData( $value, $row )
|
||||
public function parseLogData( string $value, array $row ): string
|
||||
{
|
||||
$val = json_decode( $value, TRUE );
|
||||
|
||||
@@ -69,10 +90,10 @@ class _Nexus
|
||||
{
|
||||
if ( $row['log_by'] === $row['log_member'] )
|
||||
{
|
||||
$byCustomer = \IPS\Member::loggedIn()->language()->addToStack('history_by_customer');
|
||||
$byCustomer = Member::loggedIn()->language()->addToStack('history_by_customer');
|
||||
}
|
||||
|
||||
$byStaff = \IPS\Member::loggedIn()->language()->addToStack('history_by_staff', FALSE, array( 'sprintf' => array( \IPS\Member::load( $row['log_by'] )->name ) ) );
|
||||
$byStaff = Member::loggedIn()->language()->addToStack('history_by_staff', FALSE, array( 'sprintf' => array( Member::load( $row['log_by'] )->name ) ) );
|
||||
}
|
||||
|
||||
switch ( $row['log_type'] )
|
||||
@@ -80,9 +101,9 @@ class _Nexus
|
||||
case 'invoice':
|
||||
try
|
||||
{
|
||||
$invoice = \IPS\Theme::i()->getTemplate('invoices', 'nexus')->link( \IPS\nexus\Invoice::load( $val['id'] ) );
|
||||
$invoice = Theme::i()->getTemplate('invoices', 'nexus')->link( Invoice::load( $val['id'] ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
$invoice = $val['title'];
|
||||
}
|
||||
@@ -92,27 +113,27 @@ class _Nexus
|
||||
switch ( $val['type'] )
|
||||
{
|
||||
case 'status':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_invoice_status', FALSE, array( 'htmlsprintf' => array( $invoice, mb_strtolower( \IPS\Member::loggedIn()->language()->addToStack( 'istatus_' . $val['new'] ) ), $byStaff ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_invoice_status', FALSE, array( 'htmlsprintf' => array( $invoice, mb_strtolower( Member::loggedIn()->language()->addToStack( 'istatus_' . $val['new'] ) ), $byStaff ) ) );
|
||||
|
||||
case 'resend':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_invoice_resend', FALSE, array( 'htmlsprintf' => array( $invoice, $byStaff, isset( $val['email'] ) ? \IPS\Member::loggedIn()->language()->addToStack( $val['email'] ? 'history_invoice_resend_email' : 'history_invoice_resend_no_email' ) : '' ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_invoice_resend', FALSE, array( 'htmlsprintf' => array( $invoice, $byStaff, isset( $val['email'] ) ? Member::loggedIn()->language()->addToStack( $val['email'] ? 'history_invoice_resend_email' : 'history_invoice_resend_no_email' ) : '' ) ) );
|
||||
|
||||
case 'delete':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_invoice_delete', FALSE, array( 'htmlsprintf' => array( $invoice, $byStaff ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_invoice_delete', FALSE, array( 'htmlsprintf' => array( $invoice, $byStaff ) ) );
|
||||
|
||||
case 'expire':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_invoice_expired', FALSE, array( 'htmlsprintf' => array( $invoice ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_invoice_expired', FALSE, array( 'htmlsprintf' => array( $invoice ) ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isset( $val['system'] ) and $val['system'] )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_invoice_generated', FALSE, array( 'htmlsprintf' => array( $invoice, '' ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_invoice_generated', FALSE, array( 'htmlsprintf' => array( $invoice, '' ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_invoice_generated', FALSE, array( 'htmlsprintf' => array( $invoice, $byCustomer ?: $byStaff ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_invoice_generated', FALSE, array( 'htmlsprintf' => array( $invoice, $byCustomer ?: $byStaff ) ) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -120,11 +141,11 @@ class _Nexus
|
||||
case 'transaction':
|
||||
try
|
||||
{
|
||||
$transaction = \IPS\Theme::i()->getTemplate('transactions', 'nexus')->link( \IPS\nexus\Transaction::load( $val['id'] ) );
|
||||
$transaction = Theme::i()->getTemplate('transactions', 'nexus')->link( Transaction::load( $val['id'] ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
$transaction = \IPS\Member::loggedIn()->language()->addToStack( 'transaction_number', FALSE, array( 'htmlsprintf' => array( $val['id'] ) ) );
|
||||
$transaction = Member::loggedIn()->language()->addToStack( 'transaction_number', FALSE, array( 'htmlsprintf' => array( $val['id'] ) ) );
|
||||
}
|
||||
|
||||
switch ( $val['type'] )
|
||||
@@ -133,116 +154,67 @@ class _Nexus
|
||||
|
||||
try
|
||||
{
|
||||
$invoice = \IPS\Theme::i()->getTemplate('invoices', 'nexus')->link( \IPS\nexus\Invoice::load( $val['invoice_id'] ), TRUE );
|
||||
$invoice = Theme::i()->getTemplate('invoices', 'nexus')->link( Invoice::load( $val['invoice_id'] ), TRUE );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
$invoice = \IPS\Member::loggedIn()->language()->addToStack( 'invoice_number', FALSE, array( 'sprintf' => array( $val['id'] ) ) );
|
||||
$invoice = Member::loggedIn()->language()->addToStack( 'invoice_number', FALSE, array( 'sprintf' => array( $val['id'] ) ) );
|
||||
}
|
||||
|
||||
if ( isset( $val['automatic'] ) and $val['automatic'] )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_transaction_auto', FALSE, array( 'htmlsprintf' => array( $transaction, $invoice, \IPS\Member::loggedIn()->language()->addToStack( 'history_transaction_status_' . $val['status'] ) ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_transaction_auto', FALSE, array( 'htmlsprintf' => array( $transaction, $invoice, Member::loggedIn()->language()->addToStack( 'history_transaction_status_' . $val['status'] ) ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_transaction_paid', FALSE, array( 'htmlsprintf' => array( $transaction, $invoice, $byStaff, \IPS\Member::loggedIn()->language()->addToStack( 'history_transaction_status_' . $val['status'] ) ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_transaction_paid', FALSE, array( 'htmlsprintf' => array( $transaction, $invoice, $byStaff, Member::loggedIn()->language()->addToStack( 'history_transaction_status_' . $val['status'] ) ) ) );
|
||||
}
|
||||
|
||||
case 'status':
|
||||
if ( $val['status'] === \IPS\nexus\Transaction::STATUS_REFUNDED or $val['status'] === \IPS\nexus\Transaction::STATUS_PART_REFUNDED )
|
||||
if ( $val['status'] === Transaction::STATUS_REFUNDED or $val['status'] === Transaction::STATUS_PART_REFUNDED )
|
||||
{
|
||||
if ( $val['refund'] === 'gateway' )
|
||||
{
|
||||
if ( isset( $val['amount'] ) and $val['amount'] )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_transaction_part_refunded', FALSE, array( 'htmlsprintf' => array( new \IPS\nexus\Money( $val['amount'], $val['currency'] ), $transaction, $byStaff ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_transaction_part_refunded', FALSE, array( 'htmlsprintf' => array( new Money( $val['amount'], $val['currency'] ), $transaction, $byStaff ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_transaction_refunded', FALSE, array( 'htmlsprintf' => array( $transaction, $byStaff ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_transaction_refunded', FALSE, array( 'htmlsprintf' => array( $transaction, $byStaff ) ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isset( $val['amount'] ) and $val['amount'] )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_transaction_part_credited', FALSE, array( 'htmlsprintf' => array( new \IPS\nexus\Money( $val['amount'], $val['currency'] ), $transaction, $byStaff ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_transaction_part_credited', FALSE, array( 'htmlsprintf' => array( new Money( $val['amount'], $val['currency'] ), $transaction, $byStaff ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_transaction_credited', FALSE, array( 'htmlsprintf' => array( $transaction, $byStaff ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_transaction_credited', FALSE, array( 'htmlsprintf' => array( $transaction, $byStaff ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $val['status'] === \IPS\nexus\Transaction::STATUS_REFUNDED )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_transaction_refunded', FALSE, array( 'htmlsprintf' => array( $transaction, $refundedTo, $byStaff ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_transaction_part_refunded', FALSE, array( 'htmlsprintf' => array( new \IPS\nexus\Money( $val['amount'], $val['currency'] ), $transaction, $refundedTo, $byStaff ) ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_transaction_status', FALSE, array( 'htmlsprintf' => array( $transaction, \IPS\Member::loggedIn()->language()->addToStack( 'history_transaction_status_' . $val['status'] ), $byStaff ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_transaction_status', FALSE, array( 'htmlsprintf' => array( $transaction, Member::loggedIn()->language()->addToStack( 'history_transaction_status_' . $val['status'] ), $byStaff ) ) );
|
||||
}
|
||||
|
||||
case 'undo_credit':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_transaction_undo_credit', FALSE, array( 'htmlsprintf' => array( new \IPS\nexus\Money( $val['amount'], $val['currency'] ), $transaction, $byStaff ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_transaction_undo_credit', FALSE, array( 'htmlsprintf' => array( new Money( $val['amount'], $val['currency'] ), $transaction, $byStaff ) ) );
|
||||
|
||||
case 'delete':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_transaction_delete', FALSE, array( 'htmlsprintf' => array( $transaction, $byStaff ) ) );
|
||||
}
|
||||
break;
|
||||
|
||||
case 'shipping':
|
||||
try
|
||||
{
|
||||
$shipment = \IPS\Theme::i()->getTemplate('shiporders', 'nexus')->link( \IPS\nexus\Shipping\Order::load( $val['id'] ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
$shipment = \IPS\Member::loggedIn()->language()->addToStack( 'shipment_number', FALSE, array( 'sprintf' => array( $val['id'] ) ) );
|
||||
}
|
||||
|
||||
if ( isset( $val['type'] ) )
|
||||
{
|
||||
if ( $val['type'] === 'new' )
|
||||
{
|
||||
try
|
||||
{
|
||||
$invoice = \IPS\Theme::i()->getTemplate('invoices', 'nexus')->link( \IPS\nexus\Invoice::load( $val['invoice_id'] ), TRUE );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
$invoice = \IPS\Member::loggedIn()->language()->addToStack('invoice_number', FALSE, array( 'sprintf' => array( $val['id'] ) ) );
|
||||
}
|
||||
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_shipping_new', FALSE, array( 'htmlsprintf' => array( $shipment, $invoice ) ) );
|
||||
}
|
||||
elseif ( $val['type'] === 'canc' )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_shipping_canc', FALSE, array( 'htmlsprintf' => array( $shipment, $byStaff ) ) );
|
||||
}
|
||||
}
|
||||
elseif ( isset( $val['deleted'] ) and $val['deleted'] )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_shipping_deleted', FALSE, array( 'htmlsprintf' => array( $shipment, $byStaff ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_shipping_ship', FALSE, array( 'htmlsprintf' => array( $shipment, $byStaff ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_transaction_delete', FALSE, array( 'htmlsprintf' => array( $transaction, $byStaff ) ) );
|
||||
}
|
||||
break;
|
||||
|
||||
case 'purchase':
|
||||
try
|
||||
{
|
||||
$purchase = \IPS\Theme::i()->getTemplate('purchases', 'nexus')->link( \IPS\nexus\Purchase::load( $val['id'] ), $val['type'] === 'change' );
|
||||
$purchase = Theme::i()->getTemplate('purchases', 'nexus')->link( Purchase::load( $val['id'] ), $val['type'] === 'change' );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
$purchase = $val['name'];
|
||||
}
|
||||
@@ -253,22 +225,21 @@ class _Nexus
|
||||
case 'renew':
|
||||
try
|
||||
{
|
||||
$invoice = \IPS\Theme::i()->getTemplate('invoices', 'nexus')->link( \IPS\nexus\Invoice::load( $val['invoice_id'] ), TRUE );
|
||||
$invoice = Theme::i()->getTemplate('invoices', 'nexus')->link( Invoice::load( $val['invoice_id'] ), TRUE );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
$invoice = \IPS\Member::loggedIn()->language()->addToStack('invoice_number', FALSE, array( 'sprintf' => array( $val['invoice_id'] ) ) );
|
||||
$invoice = Member::loggedIn()->language()->addToStack('invoice_number', FALSE, array( 'sprintf' => array( $val['invoice_id'] ) ) );
|
||||
}
|
||||
|
||||
if ( $val['type'] === 'new' )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_purchase_created', FALSE, array( 'htmlsprintf' => array( $purchase, $invoice ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_purchase_created', FALSE, array( 'htmlsprintf' => array( $purchase, $invoice ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_purchase_renewed', FALSE, array( 'htmlsprintf' => array( $purchase, $invoice ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_purchase_renewed', FALSE, array( 'htmlsprintf' => array( $purchase, $invoice ) ) );
|
||||
}
|
||||
break;
|
||||
|
||||
case 'info':
|
||||
if ( isset( $val['info'] ) )
|
||||
@@ -281,79 +252,79 @@ class _Nexus
|
||||
{
|
||||
foreach ( $val['to']['cost'] as $currency => $amount )
|
||||
{
|
||||
$to = new \IPS\nexus\Purchase\RenewalTerm( new \IPS\nexus\Money( $amount['amount'], $currency ), new \DateInterval( 'P' . $val['to']['term'] . mb_strtoupper( $val['to']['unit'] ) ) );
|
||||
$to = new RenewalTerm( new Money( $amount['amount'], $currency ), new DateInterval( 'P' . $val['to']['term'] . mb_strtoupper( $val['to']['unit'] ) ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* This is the correct way */
|
||||
else
|
||||
{
|
||||
$to = new \IPS\nexus\Purchase\RenewalTerm( new \IPS\nexus\Money( $val['to']['cost'], $val['to']['currency'] ), new \DateInterval( 'P' . $val['to']['term']['term'] . mb_strtoupper( $val['to']['term']['unit'] ) ) );
|
||||
$to = new RenewalTerm( new Money( $val['to']['cost'], $val['to']['currency'] ), new DateInterval( 'P' . $val['to']['term']['term'] . mb_strtoupper( $val['to']['term']['unit'] ) ) );
|
||||
}
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_purchase_renewals_changed', FALSE, array( 'htmlsprintf' => array( $purchase, ( isset( $val['system'] ) and $val['system'] ) ? '' : $byStaff, $to ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_purchase_renewals_changed', FALSE, array( 'htmlsprintf' => array( $purchase, ( isset( $val['system'] ) and $val['system'] ) ? '' : $byStaff, $to ?? '' ) ) );
|
||||
|
||||
case 'remove_renewals':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_purchase_renewals_removed', FALSE, array( 'htmlsprintf' => array( $purchase, ( isset( $val['system'] ) and $val['system'] ) ? '' : $byStaff ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_purchase_renewals_removed', FALSE, array( 'htmlsprintf' => array( $purchase, ( isset( $val['system'] ) and $val['system'] ) ? '' : $byStaff ) ) );
|
||||
|
||||
case 'never_expire':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_purchase_never_expire', FALSE, array( 'htmlsprintf' => array( $purchase, $byStaff ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_purchase_never_expire', FALSE, array( 'htmlsprintf' => array( $purchase, $byStaff ) ) );
|
||||
|
||||
case 'restored_expire':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_purchase_restored_expire', FALSE, array( 'htmlsprintf' => array( $purchase, $byStaff ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_purchase_restored_expire', FALSE, array( 'htmlsprintf' => array( $purchase, $byStaff ) ) );
|
||||
}
|
||||
}
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_purchase_edited', FALSE, array( 'htmlsprintf' => array( $purchase, ( isset( $val['system'] ) and $val['system'] ) ? '' : $byStaff ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_purchase_edited', FALSE, array( 'htmlsprintf' => array( $purchase, ( isset( $val['system'] ) and $val['system'] ) ? '' : $byStaff ) ) );
|
||||
|
||||
case 'transfer_from':
|
||||
try
|
||||
{
|
||||
$to = \IPS\Theme::i()->getTemplate('global', 'nexus')->userLink( \IPS\nexus\Customer::load( $val['to'] ) );
|
||||
$to = Theme::i()->getTemplate('global', 'nexus')->userLink( Customer::load( $val['to'] ) );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
catch( OutOfRangeException )
|
||||
{
|
||||
$to = \IPS\Member::loggedIn()->language()->addToStack( 'deleted_member' );
|
||||
$to = Member::loggedIn()->language()->addToStack( 'deleted_member' );
|
||||
}
|
||||
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_purchase_transfer_from', FALSE, array( 'htmlsprintf' => array( $purchase, $to, $byStaff ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_purchase_transfer_from', FALSE, array( 'htmlsprintf' => array( $purchase, $to, $byStaff ) ) );
|
||||
|
||||
case 'transfer_to':
|
||||
try
|
||||
{
|
||||
$from = \IPS\Theme::i()->getTemplate('global', 'nexus')->userLink( \IPS\nexus\Customer::load( $val['from'] ) );
|
||||
$from = Theme::i()->getTemplate('global', 'nexus')->userLink( Customer::load( $val['from'] ) );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
catch( OutOfRangeException )
|
||||
{
|
||||
$from = \IPS\Member::loggedIn()->language()->addToStack( 'deleted_member' );
|
||||
$from = Member::loggedIn()->language()->addToStack( 'deleted_member' );
|
||||
}
|
||||
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_purchase_transfer_to', FALSE, array( 'htmlsprintf' => array( $purchase, $from, $byStaff ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_purchase_transfer_to', FALSE, array( 'htmlsprintf' => array( $purchase, $from, $byStaff ) ) );
|
||||
|
||||
case 'cancel':
|
||||
if( isset( $val['by'] ) AND $val['by'] == 'api' )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_purchase_canceled_api', FALSE, array( 'htmlsprintf' => array( $purchase, $byStaff ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_purchase_canceled_api', FALSE, array( 'htmlsprintf' => array( $purchase, $byStaff ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_purchase_canceled', FALSE, array( 'htmlsprintf' => array( $purchase, $byStaff ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_purchase_canceled', FALSE, array( 'htmlsprintf' => array( $purchase, $byStaff ) ) );
|
||||
}
|
||||
case 'uncancel':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_purchase_reactivated', FALSE, array( 'htmlsprintf' => array( $purchase, $byStaff ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_purchase_reactivated', FALSE, array( 'htmlsprintf' => array( $purchase, $byStaff ) ) );
|
||||
|
||||
case 'delete':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_purchase_deleted', FALSE, array( 'htmlsprintf' => array( $purchase, $byStaff ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_purchase_deleted', FALSE, array( 'htmlsprintf' => array( $purchase, $byStaff ) ) );
|
||||
|
||||
case 'expire':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_purchase_expired', FALSE, array( 'htmlsprintf' => array( $purchase ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_purchase_expired', FALSE, array( 'htmlsprintf' => array( $purchase ) ) );
|
||||
|
||||
case 'change':
|
||||
$by = ( isset( $val['system'] ) and $val['system'] ) ? '' : $byCustomer;
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_purchase_changed', FALSE, array( 'htmlsprintf' => array( $purchase, $val['old'], $val['name'], $by ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_purchase_changed', FALSE, array( 'htmlsprintf' => array( $purchase, $val['old'], $val['name'], $by ) ) );
|
||||
|
||||
case 'group':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_purchase_grouped', FALSE, array( 'htmlsprintf' => array( $purchase, $byStaff ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_purchase_grouped', FALSE, array( 'htmlsprintf' => array( $purchase, $byStaff ) ) );
|
||||
case 'ungroup':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_purchase_ungrouped', FALSE, array( 'htmlsprintf' => array( $purchase, $byStaff ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_purchase_ungrouped', FALSE, array( 'htmlsprintf' => array( $purchase, $byStaff ) ) );
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -365,42 +336,43 @@ class _Nexus
|
||||
case 'purchase_refund':
|
||||
try
|
||||
{
|
||||
$purchase = \IPS\Theme::i()->getTemplate('purchases', 'nexus')->link( \IPS\nexus\Purchase::load( $val['id'] ) );
|
||||
$purchase = Theme::i()->getTemplate('purchases', 'nexus')->link( Purchase::load( $val['id'] ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
$purchase = $val['name'];
|
||||
}
|
||||
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( "history_commission_{$val['type']}", FALSE, array( 'htmlsprintf' => array( new \IPS\nexus\Money( $val['amount'], $val['currency'] ), $purchase ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( "history_commission_{$val['type']}", FALSE, array( 'htmlsprintf' => array( new Money( $val['amount'], $val['currency'] ), $purchase ) ) );
|
||||
|
||||
case 'invoice':
|
||||
case 'invoice_refund':
|
||||
try
|
||||
{
|
||||
$invoice = \IPS\Theme::i()->getTemplate('invoices', 'nexus')->link( \IPS\nexus\Invoice::load( $val['invoice_id'] ), TRUE );
|
||||
$invoice = Theme::i()->getTemplate('invoices', 'nexus')->link( Invoice::load( $val['invoice_id'] ), TRUE );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
$invoice = \IPS\Member::loggedIn()->language()->addToStack('invoice_number', FALSE, array( 'sprintf' => array( $val['invoice_id'] ) ) );
|
||||
$invoice = Member::loggedIn()->language()->addToStack('invoice_number', FALSE, array( 'sprintf' => array( $val['invoice_id'] ) ) );
|
||||
}
|
||||
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( "history_commission_{$val['type']}", FALSE, array( 'htmlsprintf' => array( new \IPS\nexus\Money( $val['amount'], $val['currency'] ), $invoice ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( "history_commission_{$val['type']}", FALSE, array( 'htmlsprintf' => array( new Money( $val['amount'], $val['currency'] ), $invoice ) ) );
|
||||
|
||||
case 'bought':
|
||||
try
|
||||
{
|
||||
$invoice = \IPS\Theme::i()->getTemplate('invoices', 'nexus')->link( \IPS\nexus\Invoice::load( $val['invoice_id'] ), TRUE );
|
||||
$invoice = Theme::i()->getTemplate('invoices', 'nexus')->link( Invoice::load( $val['invoice_id'] ), TRUE );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
$invoice = \IPS\Member::loggedIn()->language()->addToStack( 'invoice_number', FALSE, array( 'sprintf' => array( $val['invoice_id'] ) ) );
|
||||
$invoice = Member::loggedIn()->language()->addToStack( 'invoice_number', FALSE, array( 'sprintf' => array( $val['invoice_id'] ) ) );
|
||||
}
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_commission_bought', FALSE, array( 'htmlsprintf' => array( new \IPS\nexus\Money( $val['new_amount'], $val['currency'] ), $invoice, new \IPS\nexus\Money( $val['amount'], $val['currency'] ) ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_commission_bought', FALSE, array( 'htmlsprintf' => array( new Money( $val['new_amount'], $val['currency'] ), $invoice, new Money( $val['amount'], $val['currency'] ) ) ) );
|
||||
|
||||
case 'manual':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_commission_manual', FALSE, array( 'sprintf' => array( $byStaff, new \IPS\nexus\Money( $val['new'], $val['currency'] ), new \IPS\nexus\Money( $val['old'], $val['currency'] ) ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_commission_manual', FALSE, array( 'sprintf' => array( $byStaff, new Money( $val['new'], $val['currency'] ), new Money( $val['old'], $val['currency'] ) ) ) );
|
||||
}
|
||||
break;
|
||||
|
||||
case 'giftvoucher':
|
||||
switch ( $val['type'] )
|
||||
@@ -409,20 +381,20 @@ class _Nexus
|
||||
/* If the customer who used this gift card no longer exists, then we need to load up a guest customer object to avoid an OutOfRangeException */
|
||||
try
|
||||
{
|
||||
$customer = \IPS\nexus\Customer::load( $val['by'] );
|
||||
$customer = Customer::load( $val['by'] );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
catch( OutOfRangeException )
|
||||
{
|
||||
$customer = new \IPS\nexus\Customer;
|
||||
$customer = new Customer;
|
||||
}
|
||||
|
||||
$currency = isset( $val['currency'] ) ? $val['currency'] : $customer->defaultCurrency();
|
||||
$currency = $val['currency'] ?? $customer->defaultCurrency();
|
||||
|
||||
return
|
||||
\IPS\Member::loggedIn()->language()->addToStack( 'history_giftvoucher_used', FALSE, array( 'htmlsprintf' => array(
|
||||
new \IPS\nexus\Money( $val['amount'], $currency ),
|
||||
Member::loggedIn()->language()->addToStack( 'history_giftvoucher_used', FALSE, array( 'htmlsprintf' => array(
|
||||
new Money( $val['amount'], $currency ),
|
||||
$val['code'],
|
||||
\IPS\Theme::i()->getTemplate('global', 'nexus')->userLink( $customer )
|
||||
Theme::i()->getTemplate('global', 'nexus')->userLink( $customer )
|
||||
) ) );
|
||||
break;
|
||||
|
||||
@@ -430,33 +402,33 @@ class _Nexus
|
||||
/* If the customer who redeemed this gift card no longer exists, then we need to load up a guest customer object to avoid an OutOfRangeException */
|
||||
try
|
||||
{
|
||||
$customer = \IPS\nexus\Customer::load( $val['ps_member'] );
|
||||
$customer = Customer::load( $val['ps_member'] );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
catch( OutOfRangeException )
|
||||
{
|
||||
$customer = new \IPS\nexus\Customer;
|
||||
$customer = new Customer;
|
||||
}
|
||||
|
||||
$currency = isset( $val['currency'] ) ? $val['currency'] : $customer->defaultCurrency();
|
||||
$currency = $val['currency'] ?? $customer->defaultCurrency();
|
||||
|
||||
return
|
||||
\IPS\Member::loggedIn()->language()->addToStack( 'history_giftvoucher_redeemed', FALSE, array( 'htmlsprintf' => array(
|
||||
new \IPS\nexus\Money( $val['amount'], $currency ),
|
||||
Member::loggedIn()->language()->addToStack( 'history_giftvoucher_redeemed', FALSE, array( 'htmlsprintf' => array(
|
||||
new Money( $val['amount'], $currency ),
|
||||
$val['code'],
|
||||
\IPS\Theme::i()->getTemplate('global', 'nexus')->userLink( $customer ),
|
||||
new \IPS\nexus\Money( $val['newCreditAmount'], $currency )
|
||||
Theme::i()->getTemplate('global', 'nexus')->userLink( $customer ),
|
||||
new Money( $val['newCreditAmount'], $currency )
|
||||
) ) );
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'info':
|
||||
$changes = array( \IPS\Member::loggedIn()->language()->addToStack('history_info_change', FALSE, array( 'sprintf' => array( $byCustomer ?: $byStaff ) ) ) );
|
||||
$changes = array( Member::loggedIn()->language()->addToStack('history_info_change', FALSE, array( 'sprintf' => array( $byCustomer ?: $byStaff ) ) ) );
|
||||
|
||||
if ( isset( $val['name'] ) )
|
||||
{
|
||||
$name = \is_array( $val['name'] ) ? implode( ' ', array_values( $val['name'] ) ) : $val['name'];
|
||||
$changes[] = \IPS\Member::loggedIn()->language()->addToStack('history_name_changed_from', FALSE, array( 'sprintf' => array( $name ) ) );
|
||||
$name = is_array( $val['name'] ) ? implode( ' ', array_values( $val['name'] ) ) : $val['name'];
|
||||
$changes[] = Member::loggedIn()->language()->addToStack('history_name_changed_from', FALSE, array( 'sprintf' => array( $name ) ) );
|
||||
}
|
||||
|
||||
if ( isset( $val['other'] ) )
|
||||
@@ -464,30 +436,30 @@ class _Nexus
|
||||
foreach ( $val['other'] as $change )
|
||||
{
|
||||
/* Older versions may not have stored the display value, so we need to account for that */
|
||||
if( mb_strpos( $change['name'], 'nexus_ccfield_' ) !== FALSE AND \is_array( $change['value'] ) )
|
||||
if( mb_strpos( $change['name'], 'nexus_ccfield_' ) !== FALSE AND is_array( $change['value'] ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
/* If it's an array, we will start first by assuming it is probably an address */
|
||||
$value = \IPS\GeoLocation::buildFromJson( json_encode( $change['value'] ) )->toString( ', ' );
|
||||
$value = GeoLocation::buildFromJson( json_encode( $change['value'] ) )->toString();
|
||||
|
||||
/* A bad address will return an empty string */
|
||||
if( !$value )
|
||||
{
|
||||
throw new \BadFunctionCallException;
|
||||
throw new BadFunctionCallException;
|
||||
}
|
||||
|
||||
$change['value'] = $value;
|
||||
}
|
||||
/* Maybe it wasn't an address or geoip support is disabled */
|
||||
catch( \BadFunctionCallException $e )
|
||||
catch( BadFunctionCallException )
|
||||
{
|
||||
$_value = array();
|
||||
|
||||
/* We will just loop and implode so we have a string */
|
||||
foreach( $change['value'] as $k => $v )
|
||||
{
|
||||
if( \is_array( $v ) )
|
||||
if( is_array( $v ) )
|
||||
{
|
||||
foreach( $v as $_k => $_v )
|
||||
{
|
||||
@@ -508,11 +480,11 @@ class _Nexus
|
||||
|
||||
if ( isset( $change['old'] ) )
|
||||
{
|
||||
$changes[] = \IPS\Member::loggedIn()->language()->addToStack('history_field_changed_from', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( $change['name'] ), $change['old'], $change['value'] ) ) );
|
||||
$changes[] = Member::loggedIn()->language()->addToStack('history_field_changed_from', FALSE, array( 'sprintf' => array( Member::loggedIn()->language()->addToStack( $change['name'] ), $change['old'], $change['value'] ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$changes[] = \IPS\Member::loggedIn()->language()->addToStack('history_field_changed', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( $change['name'] ), $change['value'] ) ) );
|
||||
$changes[] = Member::loggedIn()->language()->addToStack('history_field_changed', FALSE, array( 'sprintf' => array( Member::loggedIn()->language()->addToStack( $change['name'] ), $change['value'] ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -523,15 +495,13 @@ class _Nexus
|
||||
switch ( $val['type'] )
|
||||
{
|
||||
case 'add':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('history_address_add', FALSE, array( 'sprintf' => array( (string) \IPS\GeoLocation::buildFromJson( $val['details'] ), $byCustomer ) ) );
|
||||
return Member::loggedIn()->language()->addToStack('history_address_add', FALSE, array( 'sprintf' => array( (string) GeoLocation::buildFromJson( $val['details'] ), $byCustomer ) ) );
|
||||
case 'edit':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('history_address_edit', FALSE, array( 'sprintf' => array( (string) \IPS\GeoLocation::buildFromJson( $val['old'] ), (string) \IPS\GeoLocation::buildFromJson( $val['new'] ), $byCustomer ) ) );
|
||||
return Member::loggedIn()->language()->addToStack('history_address_edit', FALSE, array( 'sprintf' => array( (string) GeoLocation::buildFromJson( $val['old'] ), (string) GeoLocation::buildFromJson( $val['new'] ), $byCustomer ) ) );
|
||||
case 'primary_billing':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('history_address_primary_billing', FALSE, array( 'sprintf' => array( (string) \IPS\GeoLocation::buildFromJson( $val['details'] ), $byCustomer ) ) );
|
||||
case 'primary_shipping':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('history_address_primary_shipping', FALSE, array( 'sprintf' => array( (string) \IPS\GeoLocation::buildFromJson( $val['details'] ), $byCustomer ) ) );
|
||||
return Member::loggedIn()->language()->addToStack('history_address_primary_billing', FALSE, array( 'sprintf' => array( (string) GeoLocation::buildFromJson( $val['details'] ), $byCustomer ) ) );
|
||||
case 'delete':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('history_address_delete', FALSE, array( 'sprintf' => array( (string) \IPS\GeoLocation::buildFromJson( $val['details'] ), $byCustomer ) ) );
|
||||
return Member::loggedIn()->language()->addToStack('history_address_delete', FALSE, array( 'sprintf' => array( (string) GeoLocation::buildFromJson( $val['details'] ), $byCustomer ) ) );
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -540,20 +510,20 @@ class _Nexus
|
||||
switch ( $val['type'] )
|
||||
{
|
||||
case 'add':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('history_card_add', FALSE, array( 'sprintf' => array( $val['number'], $byCustomer ) ) );
|
||||
return Member::loggedIn()->language()->addToStack('history_card_add', FALSE, array( 'sprintf' => array( $val['number'], $byCustomer ) ) );
|
||||
case 'delete':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('history_card_delete', FALSE, array( 'sprintf' => array( $val['number'], $byCustomer ) ) );
|
||||
return Member::loggedIn()->language()->addToStack('history_card_delete', FALSE, array( 'sprintf' => array( $val['number'], $byCustomer ) ) );
|
||||
}
|
||||
break;
|
||||
|
||||
case 'alternative':
|
||||
try
|
||||
{
|
||||
$altContact = \IPS\nexus\Customer::load( $val['alt_id'] );
|
||||
$altContact = Customer::load( $val['alt_id'] );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
catch( OutOfRangeException )
|
||||
{
|
||||
$altContact = new \IPS\nexus\Customer;
|
||||
$altContact = new Customer;
|
||||
}
|
||||
|
||||
$altContact = $altContact->member_id ? $altContact->link() : htmlspecialchars( $val['alt_name'], ENT_DISALLOWED, 'UTF-8', FALSE );
|
||||
@@ -561,11 +531,11 @@ class _Nexus
|
||||
switch ( $val['type'] )
|
||||
{
|
||||
case 'add':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('history_altcontact_add', FALSE, array( 'htmlsprintf' => array( $altContact, $byCustomer ) ) );
|
||||
return Member::loggedIn()->language()->addToStack('history_altcontact_add', FALSE, array( 'htmlsprintf' => array( $altContact, $byCustomer ) ) );
|
||||
case 'edit':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('history_altcontact_edit', FALSE, array( 'htmlsprintf' => array( $altContact, $byCustomer ) ) );
|
||||
return Member::loggedIn()->language()->addToStack('history_altcontact_edit', FALSE, array( 'htmlsprintf' => array( $altContact, $byCustomer ) ) );
|
||||
case 'delete':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('history_altcontact_delete', FALSE, array( 'htmlsprintf' => array( $altContact, $byCustomer ) ) );
|
||||
return Member::loggedIn()->language()->addToStack('history_altcontact_delete', FALSE, array( 'htmlsprintf' => array( $altContact, $byCustomer ) ) );
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -575,15 +545,16 @@ class _Nexus
|
||||
{
|
||||
if ( !isset( $val['payout_id'] ) )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
throw new OutOfRangeException;
|
||||
}
|
||||
$payout = \IPS\Theme::i()->getTemplate('payouts', 'nexus')->link( \IPS\nexus\Payout::load( $val['payout_id'] ) );
|
||||
|
||||
$payout = Theme::i()->getTemplate('payouts', 'nexus')->link( Payout::load( $val['payout_id'] ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
if ( isset( $va['currency'] ) )
|
||||
if ( isset( $val['currency'] ) )
|
||||
{
|
||||
$payout = new \IPS\nexus\Money( $val['amount'], $val['currency'] );
|
||||
$payout = new Money( new Number( (string)$val['amount'] ), $val['currency'] );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -594,15 +565,15 @@ class _Nexus
|
||||
switch ( $val['type'] )
|
||||
{
|
||||
case 'autoprocess':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('history_payout_autoprocess', FALSE, array( 'htmlsprintf' => array( $payout ) ) );
|
||||
return Member::loggedIn()->language()->addToStack('history_payout_autoprocess', FALSE, array( 'htmlsprintf' => array( $payout ) ) );
|
||||
case 'request':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('history_payout_request', FALSE, array( 'htmlsprintf' => array( $payout ) ) );
|
||||
return Member::loggedIn()->language()->addToStack('history_payout_request', FALSE, array( 'htmlsprintf' => array( $payout ) ) );
|
||||
case 'cancel':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('history_payout_cancel', FALSE, array( 'htmlsprintf' => array( $payout, $byCustomer ?: $byStaff ) ) );
|
||||
return Member::loggedIn()->language()->addToStack('history_payout_cancel', FALSE, array( 'htmlsprintf' => array( $payout, $byCustomer ?: $byStaff ) ) );
|
||||
case 'processed':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('history_payout_processed', FALSE, array( 'htmlsprintf' => array( $payout, $byStaff ) ) );
|
||||
return Member::loggedIn()->language()->addToStack('history_payout_processed', FALSE, array( 'htmlsprintf' => array( $payout, $byStaff ) ) );
|
||||
case 'dismissed':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('history_payout_dismissed', FALSE, array( 'htmlsprintf' => array( $payout, $byStaff ) ) );
|
||||
return Member::loggedIn()->language()->addToStack('history_payout_dismissed', FALSE, array( 'htmlsprintf' => array( $payout, $byStaff ) ) );
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -610,9 +581,9 @@ class _Nexus
|
||||
|
||||
try
|
||||
{
|
||||
$purchase = \IPS\Theme::i()->getTemplate('purchases', 'nexus')->link( \IPS\nexus\Purchase::load( $val['ps_id'] ) );
|
||||
$purchase = Theme::i()->getTemplate('purchases', 'nexus')->link( Purchase::load( $val['ps_id'] ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
if ( isset( $val['ps_name'] ) )
|
||||
{
|
||||
@@ -620,16 +591,16 @@ class _Nexus
|
||||
}
|
||||
else
|
||||
{
|
||||
$purchase = \IPS\Member::loggedIn()->language()->addToStack( 'purchase_number', FALSE, array( 'sprintf' => array( $val['ps_id'] ) ) );
|
||||
$purchase = Member::loggedIn()->language()->addToStack( 'purchase_number', FALSE, array( 'sprintf' => array( $val['ps_id'] ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
switch ( $val['type'] )
|
||||
{
|
||||
case 'activated':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('history_lkey_activated', FALSE, array( 'htmlsprintf' => array( $purchase ) ) );
|
||||
return Member::loggedIn()->language()->addToStack('history_lkey_activated', FALSE, array( 'htmlsprintf' => array( $purchase ) ) );
|
||||
case 'reset':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('history_lkey_reset', FALSE, array( 'htmlsprintf' => array( $purchase, $byStaff, $val['new'], $val['key'] ) ) );
|
||||
return Member::loggedIn()->language()->addToStack('history_lkey_reset', FALSE, array( 'htmlsprintf' => array( $purchase, $byStaff, $val['new'], $val['key'] ) ) );
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -641,66 +612,44 @@ class _Nexus
|
||||
case 'idm':
|
||||
try
|
||||
{
|
||||
if ( !\IPS\Application::appIsEnabled('downloads') )
|
||||
if ( !Application::appIsEnabled('downloads') )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
throw new OutOfRangeException;
|
||||
}
|
||||
|
||||
$options = array( 'htmlsprintf' => array( \IPS\Theme::i()->getTemplate( 'customers', 'nexus' )->downloadsLink( \IPS\downloads\File::load( $val['id'] ) ) ) );
|
||||
$options = array( 'htmlsprintf' => array( Theme::i()->getTemplate( 'customers', 'nexus' )->downloadsLink( File::load( $val['id'] ) ) ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
$options = array( 'sprintf' => array( $val['name'] ) );
|
||||
}
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_download', FALSE, $options );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_download', FALSE, $options );
|
||||
case 'attach':
|
||||
|
||||
$file = \IPS\Theme::i()->getTemplate( 'editor', 'core', 'global' )->attachedFile( \IPS\Settings::i()->base_url . "applications/core/interface/file/attachment.php?id=" . $val['id'], $val['name'], FALSE );
|
||||
$file = Theme::i()->getTemplate( 'editor', 'core', 'global' )->attachedFile( Settings::i()->base_url . "applications/core/interface/file/attachment.php?id=" . $val['id'], $val['name'], FALSE );
|
||||
if ( isset( $val['ps_id'] ) and $val['ps_id'] )
|
||||
{
|
||||
try
|
||||
{
|
||||
$options = array( 'htmlsprintf' => array( $file, \IPS\Theme::i()->getTemplate('purchases', 'nexus')->link( \IPS\nexus\Purchase::load( $val['ps_id'] ) ) ) );
|
||||
$options = array( 'htmlsprintf' => array( $file, Theme::i()->getTemplate('purchases', 'nexus')->link( Purchase::load( $val['ps_id'] ) ) ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
$options = array( 'htmlsprintf' => array( $file, htmlspecialchars( $val['ps_name'], ENT_QUOTES | ENT_DISALLOWED, 'UTF-8', FALSE ) ) );
|
||||
}
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_download_with_purchase', FALSE, $options );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_download_with_purchase', FALSE, $options );
|
||||
}
|
||||
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_download', FALSE, array( 'htmlsprintf' => $file ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_download', FALSE, array( 'htmlsprintf' => $file ) );
|
||||
}
|
||||
break;
|
||||
|
||||
case 'support':
|
||||
|
||||
if ( isset( $val['type'] ) and $val['type'] == 'email' )
|
||||
{
|
||||
$by = \IPS\Member::loggedIn()->language()->addToStack( 'history_support_by_email' );
|
||||
}
|
||||
else
|
||||
{
|
||||
$by = $byCustomer ?: $byStaff;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$options = array( 'htmlsprintf' => array( \IPS\Theme::i()->getTemplate( 'support', 'nexus' )->link( \IPS\nexus\Support\Request::load( $val['id'] ), FALSE ), $by ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
$options = array( 'sprintf' => array( $val['title'] ), 'htmlsprintf' => array( $by ) );
|
||||
}
|
||||
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_support', FALSE, $options );
|
||||
|
||||
case 'billingagreement':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_billingagreement_' . $val['type'], FALSE, array( 'sprintf' => array( $val['id'], $val['gw_id'], $byCustomer ?: $byStaff ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_billingagreement_' . $val['type'], FALSE, array( 'sprintf' => array( $val['id'], $val['gw_id'], $byCustomer ?: $byStaff ) ) );
|
||||
break;
|
||||
|
||||
case 'note':
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'history_' . $val . '_note', FALSE, array( 'sprintf' => $byStaff ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'history_' . $val . '_note', FALSE, array( 'sprintf' => $byStaff ) );
|
||||
break;
|
||||
|
||||
case 'custom':
|
||||
@@ -714,22 +663,22 @@ class _Nexus
|
||||
case 'cancelrenewals':
|
||||
try
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'nexus_history_cancelrenewals_with_name', FALSE, array( 'sprintf' => array( \IPS\nexus\Subscription\Package::load( $val['id'] )->_title, $byCustomer ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'nexus_history_cancelrenewals_with_name', FALSE, array( 'sprintf' => array( Package::load( $val['id'] )->_title, $byCustomer ) ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'nexus_history_cancelrenewals', FALSE, array( 'sprintf' => array( $byCustomer ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'nexus_history_cancelrenewals', FALSE, array( 'sprintf' => array( $byCustomer ) ) );
|
||||
}
|
||||
break;
|
||||
|
||||
case 'change':
|
||||
try
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'nexus_history_subscription_changed_with_name', FALSE, array( 'sprintf' => array( $val['old'], ( isset( $val['system'] ) and $val['system'] ) ? '' : $byStaff, $val['name'] ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'nexus_history_subscription_changed_with_name', FALSE, array( 'sprintf' => array( $val['old'], ( isset( $val['system'] ) and $val['system'] ) ? '' : $byStaff, $val['name'] ) ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'nexus_history_subscription_changed', FALSE, array( 'sprintf' => array( ( isset( $val['system'] ) and $val['system'] ) ? '' : $byStaff ) ) );
|
||||
return Member::loggedIn()->language()->addToStack( 'nexus_history_subscription_changed', FALSE, array( 'sprintf' => array( ( isset( $val['system'] ) and $val['system'] ) ? '' : $byStaff ) ) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -743,13 +692,13 @@ class _Nexus
|
||||
/**
|
||||
* Parse LogMember column
|
||||
*
|
||||
* @param string $value column value
|
||||
* @param array $row entire log row
|
||||
* @param string $value column value
|
||||
* @param array $row entire log row
|
||||
* @return string
|
||||
*/
|
||||
public function parseLogMember( $value, $row )
|
||||
public function parseLogMember( string $value, array $row ): string
|
||||
{
|
||||
\IPS\nexus\Customer::load( $value )->link();
|
||||
return Customer::load( $value )->link();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -759,8 +708,8 @@ class _Nexus
|
||||
* @param array $row entire log row
|
||||
* @return string
|
||||
*/
|
||||
public function parseLogType( $value, $row )
|
||||
public function parseLogType( string $value, array $row ): string
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'customers', 'nexus' )->logType( $value );
|
||||
return Theme::i()->getTemplate( 'customers', 'nexus' )->logType( $value );
|
||||
}
|
||||
}
|
||||
@@ -1,221 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Member Sync
|
||||
* @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 31 Mar 2014
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\extensions\core\MemberSync;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Member Sync
|
||||
*/
|
||||
class _Nexus
|
||||
{
|
||||
/**
|
||||
* Account Created
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @return void
|
||||
*/
|
||||
public function onCreateAccount( $member )
|
||||
{
|
||||
if ( $member->email )
|
||||
{
|
||||
\IPS\Db::i()->update( 'nexus_support_requests', array( 'r_member' => $member->member_id ), array( 'r_email=? AND r_member=0', $member->email ) );
|
||||
\IPS\Db::i()->update( 'nexus_support_replies', array( 'reply_member' => $member->member_id ), array( 'reply_email=? AND reply_member=0', $member->email ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Member has logged on
|
||||
*
|
||||
* @param \IPS\Member $member Member that logged in
|
||||
* @return void
|
||||
*/
|
||||
public function onLogin( $member )
|
||||
{
|
||||
if ( isset( \IPS\Request::i()->cookie['cm_reg'] ) and \IPS\Request::i()->cookie['cm_reg'] )
|
||||
{
|
||||
try
|
||||
{
|
||||
$invoice = \IPS\nexus\Invoice::load( \IPS\Request::i()->cookie['cm_reg'] );
|
||||
|
||||
\IPS\Request::i()->setCookie( 'cm_reg', 0 );
|
||||
|
||||
if ( !$invoice->member->member_id )
|
||||
{
|
||||
$invoice->member = $member;
|
||||
$invoice->save();
|
||||
}
|
||||
|
||||
if ( $invoice->member->member_id === $member->member_id )
|
||||
{
|
||||
\IPS\Output::i()->redirect( $invoice->checkoutUrl() );
|
||||
}
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
\IPS\Request::i()->setCookie( 'cm_reg', 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Member is merged with another member
|
||||
*
|
||||
* @param \IPS\Member $member Member being kept
|
||||
* @param \IPS\Member $member2 Member being removed
|
||||
* @return void
|
||||
*/
|
||||
public function onMerge( $member, $member2 )
|
||||
{
|
||||
\IPS\Db::i()->update( 'nexus_customer_addresses', array( 'member' => $member->member_id ), array( '`member`=?', $member2->member_id ) );
|
||||
\IPS\Db::i()->update( 'nexus_customer_cards', array( 'card_member' => $member->member_id ), array( 'card_member=?', $member2->member_id ) );
|
||||
\IPS\Db::i()->update( 'nexus_invoices', array( 'i_member' => $member->member_id ), array( 'i_member=?', $member2->member_id ) );
|
||||
\IPS\Db::i()->update( 'nexus_purchases', array( 'ps_member' => $member->member_id ), array( 'ps_member=?', $member2->member_id ) );
|
||||
\IPS\Db::i()->update( 'nexus_purchases', array( 'ps_pay_to' => $member->member_id ), array( 'ps_pay_to=?', $member2->member_id ) );
|
||||
\IPS\Db::i()->update( 'nexus_transactions', array( 't_member' => $member->member_id ), array( 't_member=?', $member2->member_id ) );
|
||||
\IPS\Db::i()->update( 'nexus_alternate_contacts', array( 'main_id' => $member->member_id ), array( 'main_id=?', $member2->member_id ) );
|
||||
\IPS\Db::i()->update( 'nexus_alternate_contacts', array( 'alt_id' => $member->member_id ), array( 'alt_id=?', $member2->member_id ) );
|
||||
\IPS\Db::i()->update( 'nexus_support_streams', array( 'stream_owner' => $member->member_id ), array( 'stream_owner=?', $member2->member_id ) );
|
||||
\IPS\Db::i()->update( 'nexus_billing_agreements', array( 'ba_member' => $member->member_id ), array( 'ba_member=?', $member2->member_id ) );
|
||||
\IPS\Db::i()->update( 'nexus_support_requests', array( 'r_member' => $member->member_id ), array( 'r_member=?', $member2->member_id ) );
|
||||
\IPS\Db::i()->update( 'nexus_support_requests', array( 'r_last_reply_by' => $member->member_id ), array( 'r_last_reply_by=?', $member2->member_id ) );
|
||||
\IPS\Db::i()->update( 'nexus_support_replies', array( 'reply_member' => $member->member_id ), array( 'reply_member=?', $member2->member_id ) );
|
||||
\IPS\Db::i()->update( 'nexus_support_ratings', array( 'rating_from' => $member->member_id ), array( 'rating_from=?', $member2->member_id ) );
|
||||
\IPS\Db::i()->update( 'nexus_support_ratings', array( 'rating_staff' => $member->member_id ), array( 'rating_staff=?', $member2->member_id ) );
|
||||
|
||||
\IPS\Db::i()->delete( 'nexus_customer_spend', array( 'spend_member_id=?', $member2->member_id ) );
|
||||
|
||||
\IPS\Db::i()->delete( 'nexus_alternate_contacts', array( 'main_id = alt_id' ) );
|
||||
|
||||
/* Account Credit */
|
||||
$customerToKeep = \IPS\nexus\Customer::load( $member->member_id );
|
||||
$creditToKeep = $customerToKeep->cm_credits;
|
||||
$creditToMerge = \IPS\nexus\Customer::load( $member2->member_id )->cm_credits;
|
||||
|
||||
foreach( \IPS\nexus\Money::currencies() as $currency )
|
||||
{
|
||||
if( isset( $creditToMerge[$currency] ) )
|
||||
{
|
||||
if( isset( $creditToKeep[$currency] ) )
|
||||
{
|
||||
$creditToKeep[$currency]->amount = $creditToKeep[$currency]->amount->add( $creditToMerge[$currency]->amount );
|
||||
}
|
||||
else
|
||||
{
|
||||
$creditToKeep[$currency] = $creditToMerge[$currency];
|
||||
}
|
||||
}
|
||||
}
|
||||
$customerToKeep->cm_credits = $creditToKeep;
|
||||
$customerToKeep->save();
|
||||
|
||||
/* Subscription packages */
|
||||
if ( $keepSub = \IPS\nexus\Subscription::loadActiveByMember( $member ) )
|
||||
{
|
||||
if ( $dropSub = \IPS\nexus\Subscription::loadActiveByMember( $member2 ) AND $package = \IPS\nexus\Subscription\Package::load( $dropSub->package_id ) )
|
||||
{
|
||||
$package->removeMember( \IPS\nexus\Customer::load( $member2->member_id ) );
|
||||
}
|
||||
}
|
||||
|
||||
/* Recount total spend */
|
||||
$customerToKeep->recountTotalSpend();
|
||||
}
|
||||
|
||||
/**
|
||||
* Member is deleted
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @return void
|
||||
*/
|
||||
public function onDelete( $member )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'nexus_customer_addresses', array( '`member`=?', $member->member_id ) );
|
||||
\IPS\Db::i()->delete( 'nexus_customer_cards', array( 'card_member=?', $member->member_id ) );
|
||||
\IPS\Db::i()->delete( 'nexus_customers', array( 'member_id=?', $member->member_id ) );
|
||||
\IPS\Db::i()->delete( 'nexus_alternate_contacts', array( 'main_id=?', $member->member_id ) );
|
||||
\IPS\Db::i()->delete( 'nexus_alternate_contacts', array( 'alt_id =?', $member->member_id ) );
|
||||
\IPS\Db::i()->delete( 'nexus_support_request_log', array( "rlog_member=?", $member->member_id ) );
|
||||
\IPS\Db::i()->update( 'nexus_support_requests', array( 'r_staff' => 0 ), array( "r_staff=?", $member->member_id ) );
|
||||
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_purchases', array( 'ps_member=?', $member->member_id ) ), 'IPS\nexus\Purchase' ) as $purchase )
|
||||
{
|
||||
$purchase->delete();
|
||||
}
|
||||
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_billing_agreements', array( 'ba_member=?', $member->member_id ) ), '\IPS\nexus\Customer\BillingAgreement' ) as $agreement )
|
||||
{
|
||||
try
|
||||
{
|
||||
$agreement->cancel();
|
||||
}
|
||||
catch ( \Exception $e ) {}
|
||||
}
|
||||
|
||||
\IPS\Db::i()->update( 'nexus_purchases', array( 'ps_pay_to' => 0 ), array( 'ps_pay_to=?', $member->member_id ) );
|
||||
\IPS\Db::i()->delete( 'nexus_support_streams', array( 'stream_owner=?', $member->member_id ) );
|
||||
|
||||
/* Subscriptions (mop up orphaned members) */
|
||||
\IPS\Db::i()->delete( 'nexus_member_subscriptions', array( "sub_member_id=?", $member->member_id ) );
|
||||
|
||||
\IPS\Db::i()->delete( 'nexus_customer_spend', array( 'spend_member_id=?', $member->member_id ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Member account has been updated
|
||||
*
|
||||
* @param $member \IPS\Member Member updating profile
|
||||
* @param $changes array The changes
|
||||
* @return void
|
||||
*/
|
||||
public function onProfileUpdate( $member, $changes )
|
||||
{
|
||||
$refresh = FALSE;
|
||||
$adminGroups = array_keys( \IPS\Member::administrators()['g'] );
|
||||
|
||||
if ( $member->inGroup( $adminGroups ) )
|
||||
{
|
||||
$refresh = TRUE;
|
||||
}
|
||||
|
||||
/* Moving out of an admin group? */
|
||||
if ( $refresh === FALSE AND ( isset( $changes['member_group_id'] ) OR isset( $changes['mgroup_others'] ) ) )
|
||||
{
|
||||
if ( isset( $changes['member_group_id'] ) AND \in_array( $changes['member_group_id'], $adminGroups ) )
|
||||
{
|
||||
$refresh = TRUE;
|
||||
}
|
||||
|
||||
if ( isset( $changes['mgroup_others'] ) )
|
||||
{
|
||||
foreach( explode( ',', $changes['mgroup_others'] ) AS $group )
|
||||
{
|
||||
if ( \in_array( $group, $adminGroups ) )
|
||||
{
|
||||
$refresh = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $refresh === TRUE and isset( \IPS\Data\Store::i()->supportStaff ) )
|
||||
{
|
||||
unset( \IPS\Data\Store::i()->supportStaff );
|
||||
}
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -1,45 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Template Plugin - Length
|
||||
* @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 20 Oct 2014
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\extensions\core\OutputPlugins;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Template Plugin - Length
|
||||
*/
|
||||
class _Length
|
||||
{
|
||||
/**
|
||||
* @brief Can be used when compiling CSS
|
||||
*/
|
||||
public static $canBeUsedInCss = FALSE;
|
||||
|
||||
/**
|
||||
* Run the plug-in
|
||||
*
|
||||
* @param string $data The initial data from the tag
|
||||
* @param array $options Array of options
|
||||
* @return array|string array( 'pre' => Code to eval before 'return', 'return' => Code to eval to return desired value )
|
||||
*/
|
||||
public static function runPlugin( $data, $options )
|
||||
{
|
||||
return array(
|
||||
'pre' => '$length = new \IPS\nexus\Shipping\Length( ' . $data . " );",
|
||||
'return' => '$length->string()'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -12,30 +12,34 @@
|
||||
namespace IPS\nexus\extensions\core\OutputPlugins;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Extensions\OutputPluginsAbstract;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Template Plugin - Money
|
||||
*/
|
||||
class _Money
|
||||
class Money extends OutputPluginsAbstract
|
||||
{
|
||||
/**
|
||||
* @brief Can be used when compiling CSS
|
||||
*/
|
||||
public static $canBeUsedInCss = FALSE;
|
||||
public static bool $canBeUsedInCss = FALSE;
|
||||
|
||||
/**
|
||||
* Run the plug-in
|
||||
*
|
||||
* @param string $data The initial data from the tag
|
||||
* @param array $options Array of options
|
||||
* @return array array( 'pre' => Code to eval before 'return', 'return' => Code to eval to return desired value )
|
||||
* @return array|string array( 'pre' => Code to eval before 'return', 'return' => Code to eval to return desired value )
|
||||
*/
|
||||
public static function runPlugin( $data, $options )
|
||||
public static function runPlugin( string $data, array $options ): string|array
|
||||
{
|
||||
if ( isset( $options['currency'] ) )
|
||||
{
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Template Plugin - Weight
|
||||
* @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 20 Oct 2014
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\extensions\core\OutputPlugins;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Template Plugin - Length
|
||||
*/
|
||||
class _Weight
|
||||
{
|
||||
/**
|
||||
* @brief Can be used when compiling CSS
|
||||
*/
|
||||
public static $canBeUsedInCss = FALSE;
|
||||
|
||||
/**
|
||||
* Run the plug-in
|
||||
*
|
||||
* @param string $data The initial data from the tag
|
||||
* @param array $options Array of options
|
||||
* @return array array( 'pre' => Code to eval before 'return', 'return' => Code to eval to return desired value )
|
||||
*/
|
||||
public static function runPlugin( $data, $options )
|
||||
{
|
||||
return array(
|
||||
'pre' => '$weight = new \IPS\nexus\Shipping\Weight( ' . $data . " );",
|
||||
'return' => '$weight->string()'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -12,21 +12,32 @@
|
||||
namespace IPS\nexus\extensions\core\OverviewStatistics;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Extensions\OverviewStatisticsAbstract;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Package;
|
||||
use IPS\Theme;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function is_array;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Overview statistics extension: Products
|
||||
*/
|
||||
class _Products
|
||||
class Products extends OverviewStatisticsAbstract
|
||||
{
|
||||
/**
|
||||
* @brief Which statistics page (activity or user)
|
||||
*/
|
||||
public $page = 'user';
|
||||
public string $page = 'user';
|
||||
|
||||
/**
|
||||
* Return the sub-block keys
|
||||
@@ -34,7 +45,7 @@ class _Products
|
||||
* @note This is designed to allow one class to support multiple blocks, for instance using the ContentRouter to generate blocks.
|
||||
* @return array
|
||||
*/
|
||||
public function getBlocks()
|
||||
public function getBlocks(): array
|
||||
{
|
||||
return array( 'products' );
|
||||
}
|
||||
@@ -45,7 +56,7 @@ class _Products
|
||||
* @param string|NULL $subBlock The subblock we are loading as returned by getBlocks()
|
||||
* @return array
|
||||
*/
|
||||
public function getBlockDetails( $subBlock = NULL )
|
||||
public function getBlockDetails( string $subBlock = NULL ): array
|
||||
{
|
||||
/* Description can be null and will not be shown if so */
|
||||
return array( 'app' => 'nexus', 'title' => 'stats_overview_products', 'description' => null, 'refresh' => 60 );
|
||||
@@ -54,11 +65,11 @@ class _Products
|
||||
/**
|
||||
* Return the block HTML to show
|
||||
*
|
||||
* @param array|NULL $dateRange NULL for all time, or an array with 'start' and 'end' \IPS\DateTime objects to restrict to
|
||||
* @param array|string|null $dateRange String for a fixed time period in days, NULL for all time, or an array with 'start' and 'end' \IPS\DateTime objects to restrict to
|
||||
* @param string|NULL $subBlock The subblock we are loading as returned by getBlocks()
|
||||
* @return string
|
||||
*/
|
||||
public function getBlock( $dateRange = NULL, $subBlock = NULL )
|
||||
public function getBlock( array|string $dateRange = NULL, string $subBlock = NULL ): string
|
||||
{
|
||||
/* Init Chart */
|
||||
$pieBarData = array();
|
||||
@@ -67,61 +78,37 @@ class _Products
|
||||
$where = array( array( 'ps_app=?', 'nexus' ), array( 'ps_type=?', 'package' ) );
|
||||
$previousCount = NULL;
|
||||
|
||||
if( \is_array( $dateRange ) )
|
||||
if( is_array( $dateRange ) )
|
||||
{
|
||||
$where[] = array( 'ps_start > ?', $dateRange['start']->getTimestamp() );
|
||||
$where[] = array( 'ps_start < ?', $dateRange['end']->getTimestamp() );
|
||||
}
|
||||
elseif( $dateRange !== NULL )
|
||||
{
|
||||
$currentDate = new \IPS\DateTime;
|
||||
$interval = NULL;
|
||||
|
||||
switch( $dateRange )
|
||||
{
|
||||
case '7':
|
||||
$interval = new \DateInterval( 'P7D' );
|
||||
break;
|
||||
|
||||
case '30':
|
||||
$interval = new \DateInterval( 'P1M' );
|
||||
break;
|
||||
|
||||
case '90':
|
||||
$interval = new \DateInterval( 'P3M' );
|
||||
break;
|
||||
|
||||
case '180':
|
||||
$interval = new \DateInterval( 'P6M' );
|
||||
break;
|
||||
|
||||
case '365':
|
||||
$interval = new \DateInterval( 'P1Y' );
|
||||
break;
|
||||
}
|
||||
|
||||
$currentDate = new DateTime;
|
||||
$interval = static::getInterval( $dateRange );
|
||||
$initialTimestamp = $currentDate->sub( $interval )->getTimestamp();
|
||||
$where[] = array( 'ps_start > ?', $initialTimestamp );
|
||||
|
||||
$previousCount = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( array( 'ps_app=?', 'nexus' ), array( 'ps_type=?', 'package' ), array( 'ps_start BETWEEN ? AND ?', $currentDate->sub( $interval )->getTimestamp(), $initialTimestamp ) ) )->first();
|
||||
$previousCount = Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( array( 'ps_app=?', 'nexus' ), array( 'ps_type=?', 'package' ), array( 'ps_start BETWEEN ? AND ?', $currentDate->sub( $interval )->getTimestamp(), $initialTimestamp ) ) )->first();
|
||||
}
|
||||
|
||||
$total = 0;
|
||||
$chart = NULL;
|
||||
|
||||
foreach( \IPS\nexus\Package::roots() as $package )
|
||||
foreach( Package::roots() as $package )
|
||||
{
|
||||
$filter = $where;
|
||||
$filter[] = array( 'ps_item_id=?', $package->id );
|
||||
|
||||
$value = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', $filter )->first();
|
||||
$value = Db::i()->select( 'COUNT(*)', 'nexus_purchases', $filter )->first();
|
||||
|
||||
if( $value > 0 )
|
||||
{
|
||||
$total += $value;
|
||||
|
||||
$pieBarData[] = array(
|
||||
'name' => \IPS\Member::loggedIn()->language()->addToStack('nexus_package_' . $package->id ),
|
||||
'name' => Member::loggedIn()->language()->addToStack('nexus_package_' . $package->id ),
|
||||
'value' => $value,
|
||||
'percentage' => 0
|
||||
);
|
||||
@@ -133,11 +120,11 @@ class _Products
|
||||
$package['percentage'] = round( ( $package['value'] / $total ) * 100, 2 );
|
||||
}
|
||||
|
||||
if( \count( $pieBarData ) )
|
||||
if( count( $pieBarData ) )
|
||||
{
|
||||
$chart = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->applePieChart( $pieBarData );
|
||||
$chart = Theme::i()->getTemplate( 'global', 'core', 'global' )->applePieChart( $pieBarData );
|
||||
}
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'stats' )->overviewComparisonCount( $total, $previousCount, $chart );
|
||||
return Theme::i()->getTemplate( 'stats' )->overviewComparisonCount( $total, $previousCount, $chart );
|
||||
}
|
||||
}
|
||||
@@ -12,21 +12,33 @@
|
||||
namespace IPS\nexus\extensions\core\OverviewStatistics;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Extensions\OverviewStatisticsAbstract;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Subscription\Package;
|
||||
use IPS\Settings;
|
||||
use IPS\Theme;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function is_array;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Overview statistics extension: Subscriptions
|
||||
*/
|
||||
class _Subscriptions
|
||||
class Subscriptions extends OverviewStatisticsAbstract
|
||||
{
|
||||
/**
|
||||
* @brief Which statistics page (activity or user)
|
||||
*/
|
||||
public $page = 'user';
|
||||
public string $page = 'user';
|
||||
|
||||
/**
|
||||
* Return the sub-block keys
|
||||
@@ -34,7 +46,7 @@ class _Subscriptions
|
||||
* @note This is designed to allow one class to support multiple blocks, for instance using the ContentRouter to generate blocks.
|
||||
* @return array
|
||||
*/
|
||||
public function getBlocks()
|
||||
public function getBlocks(): array
|
||||
{
|
||||
return array( 'subscriptions' );
|
||||
}
|
||||
@@ -45,20 +57,20 @@ class _Subscriptions
|
||||
* @param string|NULL $subBlock The subblock we are loading as returned by getBlocks()
|
||||
* @return array
|
||||
*/
|
||||
public function getBlockDetails( $subBlock = NULL )
|
||||
public function getBlockDetails( string $subBlock = NULL ): array
|
||||
{
|
||||
/* Description can be null and will not be shown if so */
|
||||
return \IPS\Settings::i()->nexus_subs_enabled ? array( 'app' => 'nexus', 'title' => 'stats_overview_subscriptions', 'description' => null, 'refresh' => 60 ) : NULL;
|
||||
return Settings::i()->nexus_subs_enabled ? array( 'app' => 'nexus', 'title' => 'stats_overview_subscriptions', 'description' => null, 'refresh' => 60 ) : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the block HTML to show
|
||||
*
|
||||
* @param array|NULL $dateRange NULL for all time, or an array with 'start' and 'end' \IPS\DateTime objects to restrict to
|
||||
* @param array|string|null $dateRange String for a fixed time period in days, NULL for all time, or an array with 'start' and 'end' \IPS\DateTime objects to restrict to
|
||||
* @param string|NULL $subBlock The subblock we are loading as returned by getBlocks()
|
||||
* @return string
|
||||
*/
|
||||
public function getBlock( $dateRange = NULL, $subBlock = NULL )
|
||||
public function getBlock( array|string $dateRange = NULL, string $subBlock = NULL ): string
|
||||
{
|
||||
/* Init Chart */
|
||||
$pieBarData = array();
|
||||
@@ -67,61 +79,37 @@ class _Subscriptions
|
||||
$where = array( array( 'ps_app=?', 'nexus' ), array( 'ps_type=?', 'subscription' ) );
|
||||
$previousCount = NULL;
|
||||
|
||||
if( \is_array( $dateRange ) )
|
||||
if( is_array( $dateRange ) )
|
||||
{
|
||||
$where[] = array( 'ps_start > ?', $dateRange['start']->getTimestamp() );
|
||||
$where[] = array( 'ps_start < ?', $dateRange['end']->getTimestamp() );
|
||||
}
|
||||
elseif( $dateRange !== NULL )
|
||||
{
|
||||
$currentDate = new \IPS\DateTime;
|
||||
$interval = NULL;
|
||||
|
||||
switch( $dateRange )
|
||||
{
|
||||
case '7':
|
||||
$interval = new \DateInterval( 'P7D' );
|
||||
break;
|
||||
|
||||
case '30':
|
||||
$interval = new \DateInterval( 'P1M' );
|
||||
break;
|
||||
|
||||
case '90':
|
||||
$interval = new \DateInterval( 'P3M' );
|
||||
break;
|
||||
|
||||
case '180':
|
||||
$interval = new \DateInterval( 'P6M' );
|
||||
break;
|
||||
|
||||
case '365':
|
||||
$interval = new \DateInterval( 'P1Y' );
|
||||
break;
|
||||
}
|
||||
|
||||
$currentDate = new DateTime;
|
||||
$interval = static::getInterval( $dateRange );
|
||||
$initialTimestamp = $currentDate->sub( $interval )->getTimestamp();
|
||||
$where = array( array( 'ps_start > ?', $initialTimestamp ) );
|
||||
|
||||
$previousCount = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( array( 'ps_app=?', 'nexus' ), array( 'ps_type=?', 'subscription' ), array( 'ps_start BETWEEN ? AND ?', $currentDate->sub( $interval )->getTimestamp(), $initialTimestamp ) ) )->first();
|
||||
$previousCount = Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( array( 'ps_app=?', 'nexus' ), array( 'ps_type=?', 'subscription' ), array( 'ps_start BETWEEN ? AND ?', $currentDate->sub( $interval )->getTimestamp(), $initialTimestamp ) ) )->first();
|
||||
}
|
||||
|
||||
$total = 0;
|
||||
$chart = NULL;
|
||||
|
||||
foreach( \IPS\nexus\Subscription\Package::roots() as $package )
|
||||
foreach( Package::roots() as $package )
|
||||
{
|
||||
$filter = $where;
|
||||
$filter[] = array( 'ps_item_id=?', $package->id );
|
||||
|
||||
$value = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', $filter )->first();
|
||||
$value = Db::i()->select( 'COUNT(*)', 'nexus_purchases', $filter )->first();
|
||||
|
||||
if( $value > 0 )
|
||||
{
|
||||
$total += $value;
|
||||
|
||||
$pieBarData[] = array(
|
||||
'name' => \IPS\Member::loggedIn()->language()->addToStack('nexus_subs_' . $package->id ),
|
||||
'name' => Member::loggedIn()->language()->addToStack('nexus_subs_' . $package->id ),
|
||||
'value' => $value,
|
||||
'percentage' => 0
|
||||
);
|
||||
@@ -133,11 +121,11 @@ class _Subscriptions
|
||||
$package['percentage'] = round( ( $package['value'] / $total ) * 100, 2 );
|
||||
}
|
||||
|
||||
if( \count( $pieBarData ) )
|
||||
if( count( $pieBarData ) )
|
||||
{
|
||||
$chart = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->applePieChart( $pieBarData );
|
||||
$chart = Theme::i()->getTemplate( 'global', 'core', 'global' )->applePieChart( $pieBarData );
|
||||
}
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'stats' )->overviewComparisonCount( $total, $previousCount, $chart );
|
||||
return Theme::i()->getTemplate( 'stats' )->overviewComparisonCount( $total, $previousCount, $chart );
|
||||
}
|
||||
}
|
||||
@@ -11,27 +11,45 @@
|
||||
namespace IPS\nexus\extensions\core\ProfileSteps;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use Exception;
|
||||
use IPS\Db;
|
||||
use IPS\Extensions\ProfileStepsAbstract;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\Editor;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\Member\ProfileStep;
|
||||
use IPS\nexus\Customer\CustomField;
|
||||
use IPS\Output;
|
||||
use IPS\Theme;
|
||||
use OutOfRangeException;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
use function substr;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Profile fields extension
|
||||
*/
|
||||
class _CustomerFields
|
||||
class CustomerFields extends ProfileStepsAbstract
|
||||
{
|
||||
/**
|
||||
* Available parent actions to complete steps
|
||||
*
|
||||
* @return array array( 'key' => 'lang_string' )
|
||||
*/
|
||||
public static function actions()
|
||||
public static function actions(): array
|
||||
{
|
||||
$return = array();
|
||||
|
||||
if ( \IPS\Db::i()->select( 'COUNT(*)', 'nexus_customer_fields' )->first() )
|
||||
if ( Db::i()->select( 'COUNT(*)', 'nexus_customer_fields' )->first() )
|
||||
{
|
||||
$return['customer_fields'] = 'complete_profile_app__nexus_CustomerFields';
|
||||
}
|
||||
@@ -44,13 +62,13 @@ class _CustomerFields
|
||||
*
|
||||
* @return array array( 'key' => 'lang_string' )
|
||||
*/
|
||||
public static function subActions()
|
||||
public static function subActions(): array
|
||||
{
|
||||
$return = array();
|
||||
|
||||
foreach( \IPS\Db::i()->select( '*', 'nexus_customer_fields' ) as $field )
|
||||
foreach( Db::i()->select( '*', 'nexus_customer_fields' ) as $field )
|
||||
{
|
||||
$field = \IPS\nexus\Customer\CustomField::constructFromData( $field );
|
||||
$field = CustomField::constructFromData( $field );
|
||||
$return['customer_fields'][ 'nexus_ccfield_' . $field->_id ] = 'nexus_ccfield_' . $field->_id;
|
||||
}
|
||||
|
||||
@@ -61,9 +79,9 @@ class _CustomerFields
|
||||
* Can the actions have multiple choices?
|
||||
*
|
||||
* @param string $action Action key (basic_profile, etc)
|
||||
* @return boolean
|
||||
* @return bool|null
|
||||
*/
|
||||
public static function actionMultipleChoice( $action )
|
||||
public static function actionMultipleChoice( string $action ): ?bool
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@@ -74,7 +92,7 @@ class _CustomerFields
|
||||
* @return array
|
||||
* @note This is intended for items which have their own independent settings and dedicated enable pages, such as MFA and Social Login integration
|
||||
*/
|
||||
public static function canBeRequired()
|
||||
public static function canBeRequired(): array
|
||||
{
|
||||
return array( 'customer_fields' );
|
||||
}
|
||||
@@ -82,13 +100,13 @@ class _CustomerFields
|
||||
/**
|
||||
* Has a specific step been completed?
|
||||
*
|
||||
* @param \IPS\Member\ProfileStep $step The step to check
|
||||
* @param \IPS\Member|NULL $member The member to check, or NULL for currently logged in
|
||||
* @param ProfileStep $step The step to check
|
||||
* @param Member|NULL $member The member to check, or NULL for currently logged in
|
||||
* @return bool
|
||||
*/
|
||||
public function completed( \IPS\Member\ProfileStep $step, \IPS\Member $member = NULL )
|
||||
public function completed( ProfileStep $step, Member $member = NULL ): bool
|
||||
{
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
$member = $member ?: Member::loggedIn();
|
||||
|
||||
if ( !$member->member_id )
|
||||
{
|
||||
@@ -96,14 +114,14 @@ class _CustomerFields
|
||||
}
|
||||
try
|
||||
{
|
||||
$profileFields = iterator_to_array( \IPS\Db::i()->select( '*', 'nexus_customers', array( 'member_id=?', $member->member_id ) ) );
|
||||
$profileFields = iterator_to_array( Db::i()->select( '*', 'nexus_customers', array( 'member_id=?', $member->member_id ) ) );
|
||||
}
|
||||
catch( \Exception $e )
|
||||
catch( Exception )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( ! \count( $profileFields ) )
|
||||
if ( ! count( $profileFields ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -111,13 +129,13 @@ class _CustomerFields
|
||||
$done = 0;
|
||||
foreach( $step->subcompletion_act as $item )
|
||||
{
|
||||
$fieldId = \substr( $item, 14 );
|
||||
$fieldId = substr( $item, 14 );
|
||||
|
||||
foreach( $profileFields AS $key => $value )
|
||||
{
|
||||
if ( $key == 'field_' . $fieldId )
|
||||
{
|
||||
if ( (bool) $value )
|
||||
if ( $value )
|
||||
{
|
||||
$done++;
|
||||
}
|
||||
@@ -125,38 +143,38 @@ class _CustomerFields
|
||||
}
|
||||
}
|
||||
|
||||
return ( $done === \count( $step->subcompletion_act ) );
|
||||
return ( $done === count( $step->subcompletion_act ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Action URL
|
||||
*
|
||||
* @param string $action The action
|
||||
* @param \IPS\Member|NULL $member The member, or NULL for currently logged in
|
||||
* @return \IPS\Http\Url
|
||||
* @param Member|NULL $member The member, or NULL for currently logged in
|
||||
* @return Url|null
|
||||
*/
|
||||
public function url( $action, \IPS\Member $member = NULL )
|
||||
public function url( string $action, Member $member = NULL ): ?Url
|
||||
{
|
||||
return \IPS\Http\Url::internal( "app=core&module=members&controller=profile&do=edit&id={$member->member_id}", 'front', 'edit_profile', $member->members_seo_name );
|
||||
return Url::internal( "app=core&module=members&controller=profile&do=edit&id={$member->member_id}", 'front', 'edit_profile', $member->members_seo_name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Post ACP Save
|
||||
*
|
||||
* @param \IPS\Member\ProfileStep $step The step
|
||||
* @param ProfileStep $step The step
|
||||
* @param array $values Form Values
|
||||
* @return void
|
||||
*/
|
||||
public function postAcpSave( \IPS\Member\ProfileStep $step, array $values )
|
||||
public function postAcpSave( ProfileStep $step, array $values ) : void
|
||||
{
|
||||
$subActions = static::subActions()['customer_fields'];
|
||||
|
||||
/* If we are going to add a profile field to a step, or even require it, we need to make sure the actual field is updated */
|
||||
foreach( $subActions AS $key )
|
||||
{
|
||||
if ( \in_array( $key, $values['step_subcompletion_act'] ) )
|
||||
if ( in_array( $key, $values['step_subcompletion_act'] ) )
|
||||
{
|
||||
$fieldId = \substr( $key, 14 );
|
||||
$fieldId = substr( $key, 14 );
|
||||
$update = array();
|
||||
$update['f_reg_show'] = 1;
|
||||
if ( $step->required )
|
||||
@@ -164,7 +182,7 @@ class _CustomerFields
|
||||
$update['f_reg_require'] = 1;
|
||||
}
|
||||
|
||||
\IPS\Db::i()->update( 'nexus_customer_fields', $update, array( "f_id=?", $fieldId ) );
|
||||
Db::i()->update( 'nexus_customer_fields', $update, array( "f_id=?", $fieldId ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -173,44 +191,42 @@ class _CustomerFields
|
||||
* Format Form Values
|
||||
*
|
||||
* @param array $values The form values
|
||||
* @param \IPS\Member $member The member
|
||||
* @param \IPS\Helpers\Form $form The form object
|
||||
* @param Member $member The member
|
||||
* @param Form $form The form object
|
||||
* @return void
|
||||
*/
|
||||
public static function formatFormValues( $values, &$member, &$form )
|
||||
public static function formatFormValues( array $values, Member $member, Form $form ) : void
|
||||
{
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
|
||||
$profileFields = array();
|
||||
foreach ( \IPS\nexus\Customer\CustomField::roots() as $field )
|
||||
foreach ( CustomField::roots() as $field )
|
||||
{
|
||||
if ( isset( $values[ "nexus_ccfield_{$field->_id}"] ) )
|
||||
{
|
||||
if( $field->required and ( $values[ "nexus_ccfield_{$field->_id}" ] === NULL or !isset( $values[ "nexus_ccfield_{$field->_id}" ] ) ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'reg_required_fields', '1C223/5', 403, '' );
|
||||
Output::i()->error( 'reg_required_fields', '1C223/5', 403, '' );
|
||||
}
|
||||
|
||||
$helper = $field->buildHelper();
|
||||
$profileFields[ "field_{$field->_id}" ] = $helper::stringValue( $values[ "nexus_ccfield_{$field->_id}" ] );
|
||||
|
||||
if ( $helper instanceof \IPS\Helpers\Form\Editor )
|
||||
if ( $helper instanceof Editor )
|
||||
{
|
||||
$field->claimAttachments( $member->member_id );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( \count( $profileFields ) )
|
||||
if ( count( $profileFields ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\Db::i()->select( 'member_id', 'nexus_customers', array( "member_id=?", $member->member_id ) )->first();
|
||||
\IPS\Db::i()->update( 'nexus_customers', $profileFields, array( "member_id=?", $member->member_id ) );
|
||||
Db::i()->select( 'member_id', 'nexus_customers', array( "member_id=?", $member->member_id ) )->first();
|
||||
Db::i()->update( 'nexus_customers', $profileFields, array( "member_id=?", $member->member_id ) );
|
||||
}
|
||||
catch( \Exception $e )
|
||||
catch( Exception )
|
||||
{
|
||||
\IPS\Db::i()->insert( 'nexus_customers', array_merge( array( 'member_id' => $member->member_id ), array_merge( array( 'member_id' => $member->member_id ), $profileFields ) ) );
|
||||
Db::i()->insert( 'nexus_customers', array_merge( array( 'member_id' => $member->member_id ), $profileFields ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -218,26 +234,26 @@ class _CustomerFields
|
||||
/**
|
||||
* Wizard Steps
|
||||
*
|
||||
* @param \IPS\Member|NULL $member The member completing the wizard, or NULL for currently logged in member
|
||||
* @return array
|
||||
* @param Member|NULL $member The member completing the wizard, or NULL for currently logged in member
|
||||
* @return array|string
|
||||
*/
|
||||
public static function wizard( \IPS\Member $member = NULL )
|
||||
public static function wizard( Member $member = NULL ): array|string
|
||||
{
|
||||
$include = array();
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
$member = $member ?: Member::loggedIn();
|
||||
$wizards = array();
|
||||
|
||||
foreach( \IPS\Member\ProfileStep::loadAll() AS $step )
|
||||
foreach( ProfileStep::loadAll() AS $step )
|
||||
{
|
||||
if ( $step->completion_act === 'customer_fields' AND ! $step->completed( $member ) )
|
||||
{
|
||||
$wizards[ $step->key ] = function( $data ) use ( $member, $include, $step ) {
|
||||
$form = new \IPS\Helpers\Form( 'customer_profile_fields_' . $step->id, 'profile_complete_next' );
|
||||
$form = new Form( 'customer_profile_fields_' . $step->id, 'profile_complete_next' );
|
||||
|
||||
foreach( $step->subcompletion_act as $item )
|
||||
{
|
||||
$id = \substr( $item, 14 );
|
||||
$field = \IPS\nexus\Customer\CustomField::load( $id );
|
||||
$id = substr( $item, 14 );
|
||||
$field = CustomField::load( $id );
|
||||
$form->add( $field->buildHelper() );
|
||||
}
|
||||
|
||||
@@ -249,47 +265,49 @@ class _CustomerFields
|
||||
return $values;
|
||||
}
|
||||
|
||||
return $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'profileCompleteTemplate' ), $step );
|
||||
return $form->customTemplate( array( Theme::i()->getTemplate( 'forms', 'core' ), 'profileCompleteTemplate' ), $step );
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if ( \count( $wizards ) )
|
||||
if ( count( $wizards ) )
|
||||
{
|
||||
return $wizards;
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Resyncs when something external happens
|
||||
*
|
||||
* @param \IPS\Member\ProfileStep $step The step
|
||||
* @param ProfileStep $step The step
|
||||
* @return void
|
||||
*/
|
||||
public function resync( \IPS\Member\ProfileStep $step )
|
||||
public function resync( ProfileStep $step ) : void
|
||||
{
|
||||
$subActions = array();
|
||||
|
||||
foreach( $step->subcompletion_act as $item )
|
||||
{
|
||||
$fieldId = \substr( $item, 12 );
|
||||
$fieldId = substr( $item, 12 );
|
||||
try
|
||||
{
|
||||
\IPS\nexus\Customer\CustomField::load( $fieldId );
|
||||
CustomField::load( $fieldId );
|
||||
$subActions[] = $item;
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
catch( OutOfRangeException )
|
||||
{
|
||||
/* No longer exists.. */
|
||||
}
|
||||
}
|
||||
|
||||
if ( \count( $subActions ) and \count( $subActions ) != $step->subcompletion_act )
|
||||
if ( count( $subActions ) and count( $subActions ) != $step->subcompletion_act )
|
||||
{
|
||||
$step->subcompletion_act = $subActions;
|
||||
$step->save();
|
||||
}
|
||||
else if ( ! \count( $subActions ) )
|
||||
else if ( ! count( $subActions ) )
|
||||
{
|
||||
/* No fields left, so delete this */
|
||||
$step->delete();
|
||||
|
||||
@@ -12,31 +12,45 @@
|
||||
namespace IPS\nexus\extensions\core\Queue;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use Exception;
|
||||
use IPS\core\AdminNotification;
|
||||
use IPS\Db;
|
||||
use IPS\Extensions\QueueAbstract;
|
||||
use IPS\Log;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Customer\BillingAgreement;
|
||||
use IPS\nexus\Gateway;
|
||||
use OutOfRangeException;
|
||||
use function count;
|
||||
use function defined;
|
||||
use const IPS\REBUILD_SLOW;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel billing agreements before removing the payment method
|
||||
*/
|
||||
class _DeletePaymentMethod
|
||||
class DeletePaymentMethod extends QueueAbstract
|
||||
{
|
||||
/**
|
||||
* @brief Number of records to process per cycle
|
||||
*/
|
||||
public $perCycle = \IPS\REBUILD_SLOW;
|
||||
public int $perCycle = REBUILD_SLOW;
|
||||
|
||||
/**
|
||||
* Parse data before queuing
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
* @return array|null
|
||||
*/
|
||||
public function preQueueData( $data )
|
||||
public function preQueueData( array $data ): ?array
|
||||
{
|
||||
$data['count'] = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_billing_agreements', array( 'ba_method=? AND ba_canceled=?', $data['id'], 0 ) )->first();
|
||||
$data['count'] = Db::i()->select( 'COUNT(*)', 'nexus_billing_agreements', array( 'ba_method=? AND ba_canceled=?', $data['id'], 0 ) )->first();
|
||||
|
||||
if( $data['count'] == 0 )
|
||||
{
|
||||
@@ -57,23 +71,23 @@ class _DeletePaymentMethod
|
||||
* @return int New offset
|
||||
* @throws \IPS\Task\Queue\OutOfRangeException Indicates offset doesn't exist and thus task is complete
|
||||
*/
|
||||
public function run( &$data, $offset )
|
||||
public function run( mixed &$data, int $offset ): int
|
||||
{
|
||||
$agreements = \IPS\Db::i()->select( '*', 'nexus_billing_agreements', array( 'ba_method=? AND ba_id>?', $data['id'], (int) $offset ), 'ba_id ASC', $this->perCycle );
|
||||
$agreements = Db::i()->select( '*', 'nexus_billing_agreements', array( 'ba_method=? AND ba_id>?', $data['id'], $offset ), 'ba_id ASC', $this->perCycle );
|
||||
$lastId = 0;
|
||||
|
||||
foreach( $agreements as $billingAgreement )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\nexus\Customer\BillingAgreement::constructFromData( $billingAgreement )->cancel();
|
||||
BillingAgreement::constructFromData( $billingAgreement )->cancel();
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
catch ( Exception $e )
|
||||
{
|
||||
/* Store the billing agreement ID so we can notify the admin once we're done */
|
||||
$data['failures'][] = $billingAgreement['ba_id'];
|
||||
|
||||
\IPS\Log::log( $e, 'delete-nexus-ba' );
|
||||
Log::log( $e, 'delete-nexus-ba' );
|
||||
}
|
||||
|
||||
$lastId = $billingAgreement['ba_id'];
|
||||
@@ -95,30 +109,31 @@ class _DeletePaymentMethod
|
||||
* @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
|
||||
* @throws OutOfRangeException Indicates offset doesn't exist and thus task is complete
|
||||
*/
|
||||
public function getProgress( $data, $offset )
|
||||
public function getProgress( mixed $data, int $offset ): array
|
||||
{
|
||||
return array( 'text' => \IPS\Member::loggedIn()->language()->addToStack('delete_gateway_with_bas'), 'complete' => $data['done'] ? ( round( 100 / $data['done'] * $data['count'], 2 ) ) : 0 );
|
||||
return array( 'text' => Member::loggedIn()->language()->addToStack('delete_gateway_with_bas'), 'complete' => $data['done'] ? ( round( 100 / $data['done'] * $data['count'], 2 ) ) : 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform post-completion processing
|
||||
*
|
||||
* @param array $data
|
||||
* @param array $data
|
||||
* @param bool $processed
|
||||
* @return void
|
||||
*/
|
||||
public function postComplete( $data )
|
||||
public function postComplete( array $data, bool $processed = TRUE ) : void
|
||||
{
|
||||
$_data = json_decode( $data['data'], true );
|
||||
|
||||
/* Send notification about any failures */
|
||||
if( \count( $_data['failures'] ) )
|
||||
if( count( $_data['failures'] ) )
|
||||
{
|
||||
\IPS\core\AdminNotification::send( 'nexus', 'ConfigurationError', json_encode( $_data['failures'] ), FALSE );
|
||||
AdminNotification::send( 'nexus', 'ConfigurationError', json_encode( $_data['failures'] ), FALSE );
|
||||
}
|
||||
|
||||
/* And delete the gateway itself */
|
||||
\IPS\nexus\Gateway::load( $_data['id'] )->delete();
|
||||
Gateway::load( $_data['id'] )->delete();
|
||||
}
|
||||
}
|
||||
@@ -12,30 +12,41 @@
|
||||
namespace IPS\nexus\extensions\core\Queue;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use Exception;
|
||||
use IPS\Db;
|
||||
use IPS\Extensions\QueueAbstract;
|
||||
use IPS\Member;
|
||||
use IPS\Patterns\ActiveRecordIterator;
|
||||
use OutOfRangeException;
|
||||
use function count;
|
||||
use function defined;
|
||||
use const IPS\REBUILD_SLOW;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Background Task
|
||||
*/
|
||||
class _DeleteSubscriptions
|
||||
class DeleteSubscriptions extends QueueAbstract
|
||||
{
|
||||
/**
|
||||
* Parse data before queuing
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
* @return array|null
|
||||
*/
|
||||
public function preQueueData( $data )
|
||||
public function preQueueData( array $data ): ?array
|
||||
{
|
||||
try
|
||||
{
|
||||
$data['count'] = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_member_subscriptions', [ 'sub_package_id=?', $data['id'] ] )->first();
|
||||
$data['count'] = Db::i()->select( 'COUNT(*)', 'nexus_member_subscriptions', [ 'sub_package_id=?', $data['id'] ] )->first();
|
||||
}
|
||||
catch( \Exception $ex )
|
||||
catch( Exception )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -53,15 +64,15 @@ class _DeleteSubscriptions
|
||||
* @return int New offset
|
||||
* @throws \IPS\Task\Queue\OutOfRangeException Indicates offset doesn't exist and thus task is complete
|
||||
*/
|
||||
public function run( $data, $offset )
|
||||
public function run( array &$data, int $offset ): int
|
||||
{
|
||||
$query = \IPS\Db::i()->select( '*', 'nexus_member_subscriptions', [ 'sub_id>? AND sub_package_id=?', $data['lastId'], $data['id'] ], 'sub_id ASC', \IPS\REBUILD_SLOW );
|
||||
if ( !\count( $query ) )
|
||||
$query = Db::i()->select( '*', 'nexus_member_subscriptions', [ 'sub_id>? AND sub_package_id=?', $data['lastId'], $data['id'] ], 'sub_id ASC', REBUILD_SLOW );
|
||||
if ( !count( $query ) )
|
||||
{
|
||||
throw new \IPS\Task\Queue\OutOfRangeException;
|
||||
}
|
||||
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( $query, 'IPS\nexus\Subscription' ) as $sub )
|
||||
foreach ( new ActiveRecordIterator( $query, 'IPS\nexus\Subscription' ) as $sub )
|
||||
{
|
||||
$data['completed']++;
|
||||
$data['lastId'] = $sub->id;
|
||||
@@ -77,11 +88,11 @@ class _DeleteSubscriptions
|
||||
* @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
|
||||
* @throws OutOfRangeException Indicates offset doesn't exist and thus task is complete
|
||||
*/
|
||||
public function getProgress( $data, $offset )
|
||||
public function getProgress( mixed $data, int $offset ): array
|
||||
{
|
||||
return array( 'text' => \IPS\Member::loggedIn()->language()->addToStack('removing_subscriptions'), 'complete' => $data['count'] ? ( round( 100 / $data['count'] * $data['completed'], 2 ) ) : 100 );
|
||||
return array( 'text' => Member::loggedIn()->language()->addToStack('removing_subscriptions'), 'complete' => $data['count'] ? ( round( 100 / $data['count'] * $data['completed'], 2 ) ) : 100 );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -91,7 +102,7 @@ class _DeleteSubscriptions
|
||||
* @param bool $processed Was anything processed or not? If preQueueData returns NULL, this will be FALSE.
|
||||
* @return void
|
||||
*/
|
||||
public function postComplete( $data, $processed = TRUE )
|
||||
public function postComplete( array $data, bool $processed = TRUE ) : void
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Background task to fix refunded transactions following the 4.3.5 change to treat refunds and credits separately
|
||||
* @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 10 Apr 2019
|
||||
*/
|
||||
|
||||
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 to fix refunded transactions following the 4.3.5 change to treat refunds and credits separately
|
||||
*/
|
||||
class _FixMissingAddresses
|
||||
{
|
||||
/**
|
||||
* @brief Number of records to process per cycle
|
||||
*/
|
||||
public $perCycle = \IPS\REBUILD_QUICK;
|
||||
|
||||
/**
|
||||
* Parse data before queuing
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function preQueueData( $data )
|
||||
{
|
||||
$data['count'] = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_invoices', array( 'i_status=? AND i_billaddress IS NULL', \IPS\nexus\Invoice::STATUS_PAID ) )->first();
|
||||
|
||||
if( $data['count'] == 0 )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
$data['done'] = 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 )
|
||||
{
|
||||
$invoices = \IPS\Db::i()->select( '*', 'nexus_invoices', array( array( 'i_id>?', $offset ), array( 'i_status=? AND i_billaddress IS NULL', \IPS\nexus\Invoice::STATUS_PAID ) ), 'i_id ASC', $this->perCycle );
|
||||
$lastId = 0;
|
||||
|
||||
foreach( $invoices as $invoiceData )
|
||||
{
|
||||
$invoice = \IPS\nexus\Invoice::constructFromData( $invoiceData );
|
||||
|
||||
try
|
||||
{
|
||||
$invoice->billaddress = \IPS\nexus\Customer\Address::constructFromData( \IPS\Db::i()->select( '*', 'nexus_customer_addresses', array( '`member`=? AND primary_billing=1', $invoiceData['i_member'] ) )->first() )->address;
|
||||
$invoice->save();
|
||||
}
|
||||
catch ( \UnderflowException $e ) { }
|
||||
|
||||
$lastId = $invoiceData['i_id'];
|
||||
}
|
||||
|
||||
if( $lastId == 0 )
|
||||
{
|
||||
throw new \IPS\Task\Queue\OutOfRangeException;
|
||||
}
|
||||
|
||||
$data['done'] += $this->perCycle;
|
||||
|
||||
return $lastId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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('upgrade_fix_missing_addresses'), 'complete' => $data['done'] ? ( round( 100 / $data['done'] * $data['count'], 2 ) ) : 0 );
|
||||
}
|
||||
}
|
||||
@@ -12,37 +12,49 @@
|
||||
namespace IPS\nexus\extensions\core\Queue;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Db;
|
||||
use IPS\Extensions\QueueAbstract;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Customer;
|
||||
use IPS\nexus\Purchase;
|
||||
use IPS\nexus\Subscription\Package;
|
||||
use OutOfRangeException;
|
||||
use UnderflowException;
|
||||
use function defined;
|
||||
use const IPS\REBUILD_NORMAL;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Background Task
|
||||
*/
|
||||
class _FixMissingSubscriptionPurchases
|
||||
class FixMissingSubscriptionPurchases extends QueueAbstract
|
||||
{
|
||||
/**
|
||||
* @brief Number of subscriptions to check per cycle
|
||||
*/
|
||||
public $batch = \IPS\REBUILD_NORMAL;
|
||||
public int $batch = REBUILD_NORMAL;
|
||||
|
||||
/**
|
||||
* Parse data before queuing
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
* @return array|null
|
||||
*/
|
||||
public function preQueueData( $data )
|
||||
public function preQueueData( array $data ): ?array
|
||||
{
|
||||
try
|
||||
{
|
||||
$data['count'] = \IPS\Db::i()->select( 'count(sub_id)', 'nexus_member_subscriptions' )->first();
|
||||
$data['count'] = Db::i()->select( 'count(sub_id)', 'nexus_member_subscriptions' )->first();
|
||||
}
|
||||
catch( \UnderflowException $e )
|
||||
catch( UnderflowException )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
throw new OutOfRangeException;
|
||||
}
|
||||
|
||||
if( $data['count'] == 0 )
|
||||
@@ -63,39 +75,39 @@ class _FixMissingSubscriptionPurchases
|
||||
* @return int New offset
|
||||
* @throws \IPS\Task\Queue\OutOfRangeException Indicates offset doesn't exist and thus task is complete
|
||||
*/
|
||||
public function run( &$data, $offset )
|
||||
public function run( mixed &$data, int $offset ): int
|
||||
{
|
||||
$last = null;
|
||||
|
||||
foreach( \IPS\Db::i()->select( '*', 'nexus_member_subscriptions', [ 'sub_id>?', $offset ], NULL, $this->batch ) as $subscription )
|
||||
foreach( 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' ] );
|
||||
Purchase::load( $subscription['sub_purchase_id' ] );
|
||||
|
||||
/* Nothing to do here */
|
||||
$data['completed']++;
|
||||
$last = $subscription['sub_id'];
|
||||
continue;
|
||||
}
|
||||
catch( \OutOfRangeException $e ) { }
|
||||
catch( OutOfRangeException ) { }
|
||||
}
|
||||
try
|
||||
{
|
||||
$package = \IPS\nexus\Subscription\Package::load( $subscription['sub_package_id'] );
|
||||
$package = 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() );
|
||||
$term = $package->renewalTerm( 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', [
|
||||
$purchaseId = 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_name' => 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'],
|
||||
@@ -112,9 +124,9 @@ class _FixMissingSubscriptionPurchases
|
||||
]);
|
||||
|
||||
/* update sub with purchase id */
|
||||
\IPS\Db::i()->update( 'nexus_member_subscriptions', [ 'sub_purchase_id' => $purchaseId ], [ 'sub_id=?', $subscription['sub_id'] ] );
|
||||
Db::i()->update( 'nexus_member_subscriptions', [ 'sub_purchase_id' => $purchaseId ], [ 'sub_id=?', $subscription['sub_id'] ] );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{}
|
||||
|
||||
|
||||
@@ -136,10 +148,10 @@ class _FixMissingSubscriptionPurchases
|
||||
* @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
|
||||
* @throws OutOfRangeException Indicates offset doesn't exist and thus task is complete
|
||||
*/
|
||||
public function getProgress( $data, $offset )
|
||||
public function getProgress( mixed $data, int $offset ): array
|
||||
{
|
||||
return array( 'text' => \IPS\Member::loggedIn()->language()->addToStack( 'nexus_queue_missing_sub_purchases' ), 'complete' => $data['count'] ? ( round( 100 / $data['count'] * $data['completed'], 2 ) ) : 100 );
|
||||
return array( 'text' => Member::loggedIn()->language()->addToStack( 'nexus_queue_missing_sub_purchases' ), 'complete' => $data['count'] ? ( round( 100 / $data['count'] * $data['completed'], 2 ) ) : 100 );
|
||||
}
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Background task to fix refunded transactions following the 4.3.5 change to treat refunds and credits separately
|
||||
* @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 20 June 2018
|
||||
*/
|
||||
|
||||
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 to fix refunded transactions following the 4.3.5 change to treat refunds and credits separately
|
||||
*/
|
||||
class _FixRefundTransactions
|
||||
{
|
||||
/**
|
||||
* @brief Number of records to process per cycle
|
||||
*/
|
||||
public $perCycle = \IPS\REBUILD_QUICK;
|
||||
|
||||
/**
|
||||
* Parse data before queuing
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function preQueueData( $data )
|
||||
{
|
||||
$data['count'] = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_transactions', array( \IPS\Db::i()->in( 't_status', array( \IPS\nexus\Transaction::STATUS_REFUNDED, \IPS\nexus\Transaction::STATUS_PART_REFUNDED ) ) ) )->first();
|
||||
|
||||
if( $data['count'] == 0 )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
$data['done'] = 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 )
|
||||
{
|
||||
$transactions = \IPS\Db::i()->select( '*', 'nexus_transactions', array( array( 't_id>?', $offset ), array( \IPS\Db::i()->in( 't_status', array( \IPS\nexus\Transaction::STATUS_REFUNDED, \IPS\nexus\Transaction::STATUS_PART_REFUNDED ) ) ) ), 't_id ASC', $this->perCycle );
|
||||
$lastId = 0;
|
||||
|
||||
foreach( $transactions as $transaction )
|
||||
{
|
||||
$extra = json_decode( $transaction['t_extra'], TRUE );
|
||||
if ( $extra and isset( $extra['history'] ) )
|
||||
{
|
||||
$credit = new \IPS\Math\Number('0');
|
||||
$totalRefunded = new \IPS\Math\Number('0');
|
||||
|
||||
$update = array();
|
||||
$updateHistory = FALSE;
|
||||
foreach ( $extra['history'] as $i => $history )
|
||||
{
|
||||
if ( ( $history['s'] === 'rfnd' or $history['s'] === 'prfd' ) )
|
||||
{
|
||||
if ( $history['to'] === 'credit' )
|
||||
{
|
||||
if ( $history['s'] === 'rfnd' )
|
||||
{
|
||||
$updateHistory = TRUE;
|
||||
$extra['history'][ $i ]['s'] = 'prfd';
|
||||
}
|
||||
|
||||
if ( isset( $history['amount'] ) )
|
||||
{
|
||||
$credit = $credit->add( new \IPS\Math\Number( (string) $history['amount'] ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$credit = $credit->add( new \IPS\Math\Number( (string) $transaction['t_amount'] ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isset( $history['amount'] ) )
|
||||
{
|
||||
$totalRefunded = $totalRefunded->add( new \IPS\Math\Number( (string) $history['amount'] ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$totalRefunded = $totalRefunded->add( new \IPS\Math\Number( (string) $transaction['t_amount'] ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $updateHistory )
|
||||
{
|
||||
$update['t_extra'] = json_encode( $extra );
|
||||
}
|
||||
if ( $credit->isGreaterThanZero() )
|
||||
{
|
||||
$update['t_credit'] = (string) $credit;
|
||||
}
|
||||
if ( $transaction['t_status'] === \IPS\nexus\Transaction::STATUS_PART_REFUNDED and $totalRefunded->compare( new \IPS\Math\Number( (string) $transaction['t_partial_refund'] ) ) !== 0 )
|
||||
{
|
||||
$update['t_partial_refund'] = (string) $totalRefunded;
|
||||
}
|
||||
if ( $transaction['t_status'] === \IPS\nexus\Transaction::STATUS_REFUNDED and $totalRefunded->compare( new \IPS\Math\Number( (string) $transaction['t_amount'] ) ) !== 0 )
|
||||
{
|
||||
$update['t_status'] = \IPS\nexus\Transaction::STATUS_PART_REFUNDED;
|
||||
}
|
||||
if ( $update )
|
||||
{
|
||||
\IPS\Db::i()->update( 'nexus_transactions', $update, array( 't_id=?', $transaction['t_id'] ) );
|
||||
}
|
||||
}
|
||||
|
||||
$lastId = $transaction['t_id'];
|
||||
}
|
||||
|
||||
if( $lastId == 0 )
|
||||
{
|
||||
throw new \IPS\Task\Queue\OutOfRangeException;
|
||||
}
|
||||
|
||||
$data['done'] += $this->perCycle;
|
||||
|
||||
return $lastId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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('upgrade_fix_refund_transactions'), 'complete' => $data['done'] ? ( round( 100 / $data['done'] * $data['count'], 2 ) ) : 0 );
|
||||
}
|
||||
}
|
||||
@@ -12,26 +12,37 @@
|
||||
namespace IPS\nexus\extensions\core\Queue;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Db;
|
||||
use IPS\Extensions\QueueAbstract;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Package;
|
||||
use IPS\Patterns\ActiveRecordIterator;
|
||||
use OutOfRangeException;
|
||||
use function count;
|
||||
use function defined;
|
||||
use const IPS\REBUILD_SLOW;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Background Task
|
||||
*/
|
||||
class _MassChangePurchases
|
||||
class MassChangePurchases extends QueueAbstract
|
||||
{
|
||||
/**
|
||||
* Parse data before queuing
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
* @return array|null
|
||||
*/
|
||||
public function preQueueData( $data )
|
||||
public function preQueueData( array $data ): ?array
|
||||
{
|
||||
$data['count'] = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=?', 'nexus', 'package', $data['id'] ) )->first();
|
||||
$data['count'] = Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=?', 'nexus', 'package', $data['id'] ) )->first();
|
||||
|
||||
return $data;
|
||||
}
|
||||
@@ -44,30 +55,30 @@ class _MassChangePurchases
|
||||
* @return int New offset
|
||||
* @throws \IPS\Task\Queue\OutOfRangeException Indicates offset doesn't exist and thus task is complete
|
||||
*/
|
||||
public function run( $data, $offset )
|
||||
public function run( array &$data, int $offset ): int
|
||||
{
|
||||
try
|
||||
{
|
||||
$package = \IPS\nexus\Package::load( $data['id'] );
|
||||
$package = Package::load( $data['id'] );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
catch( OutOfRangeException )
|
||||
{
|
||||
throw new \IPS\Task\Queue\OutOfRangeException;
|
||||
}
|
||||
|
||||
$admin = \IPS\Member::load( $data['admin'] );
|
||||
$admin = Member::load( $data['admin'] );
|
||||
if ( $data['cancel_type'] == 'change' )
|
||||
{
|
||||
$newPackage = \IPS\nexus\Package::load( $data['mass_change_purchases_to'] );
|
||||
$newPackage = Package::load( $data['mass_change_purchases_to'] );
|
||||
}
|
||||
|
||||
$query = \IPS\Db::i()->select( '*', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=?', 'nexus', 'package', $data['id'] ), 'ps_id ASC', ( $data['cancel_type'] == 'change' ) ? NULL : array( $offset, \IPS\REBUILD_SLOW ) );
|
||||
if ( !\count( $query ) )
|
||||
$query = Db::i()->select( '*', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=?', 'nexus', 'package', $data['id'] ), 'ps_id ASC', ( $data['cancel_type'] == 'change' ) ? NULL : array( $offset, REBUILD_SLOW ) );
|
||||
if ( !count( $query ) )
|
||||
{
|
||||
throw new \IPS\Task\Queue\OutOfRangeException;
|
||||
}
|
||||
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( $query, 'IPS\nexus\Purchase' ) as $purchase )
|
||||
foreach ( new ActiveRecordIterator( $query, 'IPS\nexus\Purchase' ) as $purchase )
|
||||
{
|
||||
if ( $data['cancel_type'] == 'change' )
|
||||
{
|
||||
@@ -107,7 +118,7 @@ class _MassChangePurchases
|
||||
}
|
||||
}
|
||||
|
||||
return $offset + \IPS\REBUILD_SLOW;
|
||||
return $offset + REBUILD_SLOW;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -116,11 +127,11 @@ class _MassChangePurchases
|
||||
* @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
|
||||
* @throws OutOfRangeException Indicates offset doesn't exist and thus task is complete
|
||||
*/
|
||||
public function getProgress( $data, $offset )
|
||||
public function getProgress( mixed $data, int $offset ): array
|
||||
{
|
||||
return array( 'text' => \IPS\Member::loggedIn()->language()->addToStack( 'mass_change_purchases_in_progress_text', FALSE, array( 'sprintf' => \IPS\nexus\Package::load( $data['id'] )->_title ) ), 'complete' => floor( 100 / $data['count'] * $offset ) );
|
||||
return array( 'text' => Member::loggedIn()->language()->addToStack( 'mass_change_purchases_in_progress_text', FALSE, array( 'sprintf' => Package::load( $data['id'] )->_title ) ), 'complete' => floor( 100 / $data['count'] * $offset ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,7 +141,7 @@ class _MassChangePurchases
|
||||
* @param bool $processed Was anything processed or not? If preQueueData returns NULL, this will be FALSE.
|
||||
* @return void
|
||||
*/
|
||||
public function postComplete( $data, $processed = TRUE )
|
||||
public function postComplete( array $data, bool $processed = TRUE ) : void
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -1,122 +0,0 @@
|
||||
<?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 03 Aug 2017
|
||||
*/
|
||||
|
||||
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 _MoveCustomerHistory
|
||||
{
|
||||
/**
|
||||
* @brief Number of records to process per cycle
|
||||
*/
|
||||
public $perCycle = \IPS\REBUILD_QUICK;
|
||||
|
||||
/**
|
||||
* Parse data before queuing
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function preQueueData( $data )
|
||||
{
|
||||
/* Task is not needed if this table doesn't exist */
|
||||
if( !\IPS\Db::i()->checkForTable( 'nexus_customer_history' ) )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
$data['count'] = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_customer_history' )->first();
|
||||
|
||||
if( $data['count'] == 0 )
|
||||
{
|
||||
\IPS\Db::i()->dropTable( 'nexus_customer_history' );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
$data['done'] = 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 )
|
||||
{
|
||||
$logs = \IPS\Db::i()->select( '*', 'nexus_customer_history', array( 'log_id>?', $offset ), 'log_id ASC', $this->perCycle );
|
||||
$lastId = 0;
|
||||
|
||||
foreach( $logs as $log )
|
||||
{
|
||||
$lastId = $log['log_id'];
|
||||
unset( $log['log_id'] );
|
||||
|
||||
/* Set log app */
|
||||
$log['log_app'] = 'nexus';
|
||||
|
||||
/* Convert nexus info into member history format */
|
||||
if( $log['log_data'] == 'info' )
|
||||
{
|
||||
$json = json_decode( $log['log_data'], TRUE );
|
||||
|
||||
if( isset( $json['email'] ) )
|
||||
{
|
||||
$log['log_app'] = 'core';
|
||||
$log['log_data'] = json_encode( array( 'old' => $data['email'], 'new' => '' ) );
|
||||
}
|
||||
elseif( isset( $data['password'] ) )
|
||||
{
|
||||
$log['log_app'] = 'core';
|
||||
$log['log_data'] = json_encode( array( 'password' => '' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/* Insert into member history */
|
||||
\IPS\Db::i()->insert( 'core_member_history', $log );
|
||||
}
|
||||
|
||||
if( $lastId == 0 )
|
||||
{
|
||||
\IPS\Db::i()->dropTable( 'nexus_customer_history' );
|
||||
throw new \IPS\Task\Queue\OutOfRangeException;
|
||||
}
|
||||
|
||||
$data['done'] += $this->perCycle;
|
||||
|
||||
return $lastId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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('moving_customer_history'), 'complete' => $data['done'] ? ( round( 100 / $data['done'] * $data['count'], 2 ) ) : 0 );
|
||||
}
|
||||
}
|
||||
@@ -12,32 +12,42 @@
|
||||
namespace IPS\nexus\extensions\core\Queue;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use Exception;
|
||||
use IPS\Db;
|
||||
use IPS\Extensions\QueueAbstract;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Customer;
|
||||
use OutOfRangeException;
|
||||
use function defined;
|
||||
use const IPS\REBUILD_QUICK;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Background Task
|
||||
*/
|
||||
class _RecountTotalSpend
|
||||
class RecountTotalSpend extends QueueAbstract
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief Number of records to process per cycle
|
||||
*/
|
||||
public $perCycle = \IPS\REBUILD_QUICK;
|
||||
public int $perCycle = REBUILD_QUICK;
|
||||
|
||||
/**
|
||||
* Parse data before queuing
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
* @return array|null
|
||||
*/
|
||||
public function preQueueData( $data )
|
||||
public function preQueueData( array $data ): ?array
|
||||
{
|
||||
$data['count'] = (int) \IPS\Db::i()->select( 'count(*)', 'nexus_customers' )->first();
|
||||
$data['count'] = (int) Db::i()->select( 'count(*)', 'nexus_customers' )->first();
|
||||
|
||||
if( $data['count'] == 0 )
|
||||
{
|
||||
@@ -57,22 +67,22 @@ class _RecountTotalSpend
|
||||
* @return int New offset
|
||||
* @throws \IPS\Task\Queue\OutOfRangeException Indicates offset doesn't exist and thus task is complete
|
||||
*/
|
||||
public function run( &$data, $offset )
|
||||
public function run( mixed &$data, int $offset ): int
|
||||
{
|
||||
$last = null;
|
||||
|
||||
/* Loop over members to fix them */
|
||||
foreach( \IPS\Db::i()->select( '*', 'nexus_customers', array( 'member_id > ?', $offset ), 'member_id ASC', array( 0, $this->perCycle ) ) as $customer )
|
||||
foreach( Db::i()->select( '*', 'nexus_customers', array( 'member_id > ?', $offset ), 'member_id ASC', array( 0, $this->perCycle ) ) as $customer )
|
||||
{
|
||||
$last = $customer['member_id'];
|
||||
$data['completed']++;
|
||||
|
||||
try
|
||||
{
|
||||
$customer = \IPS\nexus\Customer::load( $customer['member_id'] );
|
||||
$customer = Customer::load( $customer['member_id'] );
|
||||
$customer->recountTotalSpend();
|
||||
}
|
||||
catch( \Exception $ex ) { }
|
||||
catch( Exception ) { }
|
||||
}
|
||||
|
||||
if( $last === NULL )
|
||||
@@ -89,10 +99,10 @@ class _RecountTotalSpend
|
||||
* @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
|
||||
* @throws OutOfRangeException Indicates offset doesn't exist and thus task is complete
|
||||
*/
|
||||
public function getProgress( $data, $offset )
|
||||
public function getProgress( mixed $data, int $offset ): array
|
||||
{
|
||||
return array( 'text' => \IPS\Member::loggedIn()->language()->addToStack( 'recounting_total_spend' ), 'complete' => $data['count'] ? ( round( 100 / $data['count'] * $data['completed'], 2 ) ) : 100 );
|
||||
return array( 'text' => Member::loggedIn()->language()->addToStack( 'recounting_total_spend' ), 'complete' => $data['count'] ? ( round( 100 / $data['count'] * $data['completed'], 2 ) ) : 100 );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief SearchContent extension: Packages
|
||||
* @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 10 Jul 2023
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\extensions\core\SearchContent;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
|
||||
use DateInterval;
|
||||
use IPS\Content\Search\SearchContentAbstract;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Lang;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Customer;
|
||||
use IPS\nexus\Money;
|
||||
use IPS\nexus\Package;
|
||||
use IPS\nexus\Package\Item;
|
||||
use IPS\nexus\Tax;
|
||||
use IPS\Request;
|
||||
use IPS\Theme;
|
||||
use UnderflowException;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchContent extension: Packages
|
||||
*/
|
||||
class Packages extends SearchContentAbstract
|
||||
{
|
||||
/**
|
||||
* Return all searchable classes in your application,
|
||||
* including comments and/or reviews
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function supportedClasses() : array
|
||||
{
|
||||
return array(
|
||||
Item::class
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Title for search index
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function searchIndexTitle(): string
|
||||
{
|
||||
$titles = array();
|
||||
foreach ( Lang::languages() as $lang )
|
||||
{
|
||||
try
|
||||
{
|
||||
$titles[] = $lang->get( "nexus_package_{$this->object->id}" );
|
||||
}
|
||||
catch( UnderflowException ){}
|
||||
}
|
||||
return implode( ' ', $titles );
|
||||
}
|
||||
|
||||
/**
|
||||
* Content for search index
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function searchIndexContent(): string
|
||||
{
|
||||
$descriptions = array();
|
||||
foreach ( Lang::languages() as $lang )
|
||||
{
|
||||
try
|
||||
{
|
||||
$descriptions[] = $lang->get("nexus_package_{$this->object->id}_desc");
|
||||
}
|
||||
catch ( UnderflowException ) { }
|
||||
}
|
||||
return implode( ' ', $descriptions );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTML for search result display
|
||||
*
|
||||
* @param array $indexData Data from the search index
|
||||
* @param array $authorData Basic data about the author. Only includes columns returned by \IPS\Member::columnsForPhoto()
|
||||
* @param array $itemData Basic data about the item. Only includes columns returned by item::basicDataColumns()
|
||||
* @param array|NULL $containerData Basic data about the container. Only includes columns returned by container::basicDataColumns()
|
||||
* @param array $reputationData Array of people who have given reputation and the reputation they gave
|
||||
* @param int|NULL $reviewRating If this is a review, the rating
|
||||
* @param bool $iPostedIn If the user has posted in the item
|
||||
* @param string $view 'expanded' or 'condensed'
|
||||
* @param bool $asItem Displaying results as items?
|
||||
* @param bool $canIgnoreComments Can ignore comments in the result stream? Activity stream can, but search results cannot.
|
||||
* @param array|null $template Optional custom template
|
||||
* @param array $reactions Reaction Data
|
||||
* @return string
|
||||
*/
|
||||
public static function searchResult( array $indexData, array $authorData, array $itemData, array|null $containerData, array $reputationData, int|null $reviewRating, bool $iPostedIn, string $view, bool $asItem, bool $canIgnoreComments=FALSE, array|null $template=null, array $reactions=array() ): string
|
||||
{
|
||||
$indexData['index_title'] = Member::loggedIn()->language()->addToStack( 'nexus_package_' . $indexData['index_item_id'] );
|
||||
return parent::searchResult( $indexData, $authorData, $itemData, $containerData, $reputationData, $reviewRating, $iPostedIn, $view, $asItem, $canIgnoreComments, $template, $reactions );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get snippet HTML for search result display
|
||||
*
|
||||
* @param array $indexData Data from the search index
|
||||
* @param array $authorData Basic data about the author. Only includes columns returned by \IPS\Member::columnsForPhoto()
|
||||
* @param array $itemData Basic data about the item. Only includes columns returned by item::basicDataColumns()
|
||||
* @param array|NULL $containerData Basic data about the container. Only includes columns returned by container::basicDataColumns()
|
||||
* @param array $reputationData Array of people who have given reputation and the reputation they gave
|
||||
* @param int|NULL $reviewRating If this is a review, the rating
|
||||
* @param string $view 'expanded' or 'condensed'
|
||||
* @return callable
|
||||
*/
|
||||
public static function searchResultSnippet( array $indexData, array $authorData, array $itemData, array|null $containerData, array $reputationData, int|null $reviewRating, string $view ): string
|
||||
{
|
||||
$url = static::urlFromIndexData( $indexData, $itemData );
|
||||
|
||||
/* Work out the price to display */
|
||||
$customer = Customer::loggedIn();
|
||||
$currency = ( isset( Request::i()->cookie['currency'] ) and in_array( Request::i()->cookie['currency'], Money::currencies() ) ) ? Request::i()->cookie['currency'] : $customer->defaultCurrency();
|
||||
$renewOptions = $itemData['p_renew_options'] ? json_decode( $itemData['p_renew_options'], TRUE ) : array();
|
||||
$priceInfo = Package::fullPriceInfoFromData( $customer, $currency, $indexData['index_item_id'], $itemData['p_base_price'] ? json_decode( $itemData['p_base_price'], TRUE ) : [], $itemData['p_discounts'] ? json_decode( $itemData['p_discounts'], TRUE ) : [], $renewOptions, $itemData['p_stock'], $itemData['extra']['tax'] ? Tax::constructFromData( $itemData['extra']['tax'] ) : NULL, $itemData['p_initial_term'] ? new DateInterval("P{$itemData['p_initial_term']}") : NULL );
|
||||
|
||||
/* Display */
|
||||
return Theme::i()->getTemplate( 'global', 'nexus', 'front' )->searchResultProductSnippet( $indexData, $itemData, $itemData['extra']['image'] ?? NULL, $url, $priceInfo, $view == 'condensed' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Search Index Permissions
|
||||
*
|
||||
* @return string Comma-delimited values or '*'
|
||||
* @li Number indicates a group
|
||||
* @li Number prepended by "m" indicates a member
|
||||
* @li Number prepended by "s" indicates a social group
|
||||
*/
|
||||
public function searchIndexPermissions(): string
|
||||
{
|
||||
return $this->object->store ? $this->object->member_groups : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get URL from index data
|
||||
*
|
||||
* @param array $indexData Data from the search index
|
||||
* @param array $itemData Basic data about the item. Only includes columns returned by item::basicDataColumns()
|
||||
* @param string|NULL $action Action
|
||||
* @return Url
|
||||
*/
|
||||
public static function urlFromIndexData( array $indexData, array $itemData, string|null $action = NULL ): Url
|
||||
{
|
||||
return Url::internal( "app=nexus&module=store&controller=product&id={$indexData['index_item_id']}", 'front', 'store_product', Member::loggedIn()->language()->addToStack( 'nexus_package_' . $indexData['index_item_id'], FALSE, array( 'seotitle' => TRUE ) ) );
|
||||
}
|
||||
}
|
||||
@@ -11,36 +11,53 @@
|
||||
namespace IPS\nexus\extensions\core\Statistics;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Helpers\Chart;
|
||||
use IPS\Helpers\Chart\Database;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Gateway;
|
||||
use IPS\nexus\Invoice;
|
||||
use IPS\nexus\Money;
|
||||
use IPS\nexus\Transaction;
|
||||
use IPS\Request;
|
||||
use IPS\Theme;
|
||||
use OutOfRangeException;
|
||||
use function count;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Statistics Chart Extension
|
||||
*/
|
||||
class _Income extends \IPS\core\Statistics\Chart
|
||||
class Income extends \IPS\core\Statistics\Chart
|
||||
{
|
||||
/**
|
||||
* @brief Controller
|
||||
*/
|
||||
public $controller = 'nexus_reports_income_totals';
|
||||
public ?string $controller = 'nexus_reports_income_totals';
|
||||
|
||||
/**
|
||||
* @brief Identifier
|
||||
*/
|
||||
protected $_identifier = 'totals';
|
||||
protected string $_identifier = 'totals';
|
||||
|
||||
/**
|
||||
* Render Chart
|
||||
*
|
||||
* @param \IPS\Http\Url $url URL the chart is being shown on.
|
||||
* @return \IPS\Helpers\Chart
|
||||
* @param Url $url URL the chart is being shown on.
|
||||
* @return Chart
|
||||
*/
|
||||
public function getChart( \IPS\Http\Url $url ): \IPS\Helpers\Chart
|
||||
public function getChart( Url $url ): Chart
|
||||
{
|
||||
$chart = new \IPS\Helpers\Chart\Database(
|
||||
$chart = new Database(
|
||||
$url,
|
||||
'nexus_transactions',
|
||||
't_date',
|
||||
@@ -52,54 +69,54 @@ class _Income extends \IPS\core\Statistics\Chart
|
||||
'lineWidth' => 1,
|
||||
'areaOpacity' => 0.4
|
||||
),
|
||||
( \IPS\Request::i()->tab == 'members' ) ? 'PieChart' : 'AreaChart',
|
||||
( Request::i()->tab == 'members' ) ? 'PieChart' : 'AreaChart',
|
||||
'monthly',
|
||||
array( 'start' => 0, 'end' => 0 ),
|
||||
array(),
|
||||
$this->_identifier
|
||||
);
|
||||
$chart->setExtension( $this );
|
||||
$chart->where[] = array( '( t_status=? OR t_status=? ) AND t_method>0', \IPS\nexus\Transaction::STATUS_PAID, \IPS\nexus\Transaction::STATUS_PART_REFUNDED );
|
||||
$chart->where[] = array( '( t_status=? OR t_status=? ) AND t_method>0', Transaction::STATUS_PAID, Transaction::STATUS_PART_REFUNDED );
|
||||
|
||||
$chart->tableInclude = array( 't_id', 't_member', 't_invoice', 't_method', 't_amount', 't_date' );
|
||||
$chart->tableParsers = array(
|
||||
't_member' => function( $val ) {
|
||||
return \IPS\Theme::i()->getTemplate('global', 'nexus')->userLink( \IPS\Member::load( $val ) );
|
||||
return Theme::i()->getTemplate('global', 'nexus')->userLink( Member::load( $val ) );
|
||||
},
|
||||
't_method' => function( $val ) {
|
||||
if ( $val )
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\nexus\Gateway::load( $val )->_title;
|
||||
return Gateway::load( $val )->_title;
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('account_credit');
|
||||
return Member::loggedIn()->language()->addToStack('account_credit');
|
||||
}
|
||||
},
|
||||
't_amount' => function( $val, $row )
|
||||
{
|
||||
return (string) new \IPS\nexus\Money( $val, $row['t_currency'] );
|
||||
return (string) new Money( $val, $row['t_currency'] );
|
||||
},
|
||||
't_invoice' => function( $val )
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate('invoices', 'nexus')->link( \IPS\nexus\Invoice::load( $val ) );
|
||||
return Theme::i()->getTemplate('invoices', 'nexus')->link( Invoice::load( $val ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
return '';
|
||||
}
|
||||
},
|
||||
't_date' => function( $val ) {
|
||||
return \IPS\DateTime::ts( $val );
|
||||
return DateTime::ts( $val );
|
||||
}
|
||||
);
|
||||
|
||||
@@ -109,12 +126,13 @@ class _Income extends \IPS\core\Statistics\Chart
|
||||
/**
|
||||
* Set Extra
|
||||
*
|
||||
* @param \IPS\Helpers\Chart $chart Chart
|
||||
* @param Chart $chart Chart
|
||||
* @param string $what What we're setting.
|
||||
* @return void
|
||||
*/
|
||||
public function setExtra( \IPS\Helpers\Chart &$chart, string $what )
|
||||
public function setExtra( Chart $chart, string $what ) : void
|
||||
{
|
||||
$currencies = \IPS\nexus\Money::currencies();
|
||||
$currencies = Money::currencies();
|
||||
$this->controller = "nexus_reports_income_{$what}";
|
||||
$this->_identifier = $what;
|
||||
|
||||
@@ -131,7 +149,7 @@ class _Income extends \IPS\core\Statistics\Chart
|
||||
{
|
||||
$chart->groupBy = 't_member';
|
||||
|
||||
if( \count( $currencies ) === 1 )
|
||||
if( count( $currencies ) === 1 )
|
||||
{
|
||||
$chart->format = array_pop( $currencies );
|
||||
}
|
||||
@@ -141,9 +159,9 @@ class _Income extends \IPS\core\Statistics\Chart
|
||||
$chart->where[] = array( 't_currency=?', $chart->format );
|
||||
}
|
||||
|
||||
foreach ( \IPS\Db::i()->select( 't_member, SUM(t_amount)-SUM(t_partial_refund) as _amount', 'nexus_transactions', $chart->where, '_amount DESC', array( 0, 20 ), 't_member' ) as $member )
|
||||
foreach ( Db::i()->select( 't_member, SUM(t_amount)-SUM(t_partial_refund) as _amount', 'nexus_transactions', $chart->where, '_amount DESC', array( 0, 20 ), 't_member' ) as $member )
|
||||
{
|
||||
$chart->addSeries( \IPS\Member::load( $member['t_member'] )->name, 'number', 'SUM(t_amount)-SUM(t_partial_refund)', TRUE, $member['t_member'] );
|
||||
$chart->addSeries( Member::load( $member['t_member'] )->name, 'number', 'SUM(t_amount)-SUM(t_partial_refund)', TRUE, $member['t_member'] );
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -152,7 +170,7 @@ class _Income extends \IPS\core\Statistics\Chart
|
||||
$chart->groupBy = 't_method';
|
||||
$chart->format = $what;
|
||||
|
||||
foreach ( \IPS\nexus\Gateway::roots() as $gateway )
|
||||
foreach ( Gateway::roots() as $gateway )
|
||||
{
|
||||
$chart->addSeries( $gateway->_title, 'number', 'SUM(t_amount)-SUM(t_partial_refund)', TRUE, $gateway->id );
|
||||
}
|
||||
|
||||
@@ -11,36 +11,48 @@
|
||||
namespace IPS\nexus\extensions\core\Statistics;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use InvalidArgumentException;
|
||||
use IPS\GeoLocation;
|
||||
use IPS\Helpers\Chart;
|
||||
use IPS\Helpers\Chart\Database;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Invoice;
|
||||
use IPS\nexus\Money;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Statistics Chart Extension
|
||||
*/
|
||||
class _Market extends \IPS\core\Statistics\Chart
|
||||
class Market extends \IPS\core\Statistics\Chart
|
||||
{
|
||||
/**
|
||||
* @brief Controller
|
||||
*/
|
||||
public $controller = 'nexus_reports_markets_count';
|
||||
public ?string $controller = 'nexus_reports_markets_count';
|
||||
|
||||
/**
|
||||
* @brief Identifier
|
||||
*/
|
||||
protected $_identifier = 'count';
|
||||
protected string $_identifier = 'count';
|
||||
|
||||
/**
|
||||
* Render Chart
|
||||
*
|
||||
* @param \IPS\Http\Url $url URL the chart is being shown on.
|
||||
* @return \IPS\Helpers\Chart
|
||||
* @param Url $url URL the chart is being shown on.
|
||||
* @return Chart
|
||||
*/
|
||||
public function getChart( \IPS\Http\Url $url ): \IPS\Helpers\Chart
|
||||
public function getChart( Url $url ): Chart
|
||||
{
|
||||
$chart = new \IPS\Helpers\Chart\Database(
|
||||
$chart = new Database(
|
||||
$url,
|
||||
'nexus_invoices',
|
||||
'i_paid',
|
||||
@@ -60,12 +72,12 @@ class _Market extends \IPS\core\Statistics\Chart
|
||||
);
|
||||
$chart->setExtension( $this );
|
||||
$chart->availableTypes = array( 'GeoChart', 'AreaChart', 'LineChart', 'ColumnChart', 'BarChart', 'PieChart' );
|
||||
$chart->where[] = array( 'i_status=? AND i_billcountry IS NOT NULL', \IPS\nexus\Invoice::STATUS_PAID );
|
||||
$chart->where[] = array( 'i_status=? AND i_billcountry IS NOT NULL', Invoice::STATUS_PAID );
|
||||
$chart->groupBy = 'i_billcountry';
|
||||
|
||||
foreach ( \IPS\GeoLocation::$countries as $countryCode )
|
||||
foreach ( GeoLocation::$countries as $countryCode )
|
||||
{
|
||||
$chart->addSeries( [ 'value' => \IPS\Member::loggedIn()->language()->get( 'country-' . $countryCode ), 'key' => $countryCode ], 'number', $this->_identifier === 'count' ? 'COUNT(*)' : 'SUM(i_total)', TRUE, $countryCode );
|
||||
$chart->addSeries( [ 'value' => Member::loggedIn()->language()->get( 'country-' . $countryCode ), 'key' => $countryCode ], 'number', $this->_identifier === 'count' ? 'COUNT(*)' : 'SUM(i_total)', TRUE, $countryCode );
|
||||
}
|
||||
|
||||
if ( $chart->type === 'GeoChart' )
|
||||
@@ -80,14 +92,15 @@ class _Market extends \IPS\core\Statistics\Chart
|
||||
/**
|
||||
* Set Currency
|
||||
*
|
||||
* @param \IPS\Helpers\Chart $chart Chart
|
||||
* @param Chart $chart Chart
|
||||
* @param string $currency Currency
|
||||
* @return void
|
||||
*/
|
||||
public function setCurrency( \IPS\Helpers\Chart &$chart, string $currency )
|
||||
public function setCurrency( Chart $chart, string $currency ) : void
|
||||
{
|
||||
if ( !\in_array( $currency, \IPS\nexus\Money::currencies() ) )
|
||||
if ( !in_array( $currency, Money::currencies() ) )
|
||||
{
|
||||
throw new \InvalidArgumentException;
|
||||
throw new InvalidArgumentException;
|
||||
}
|
||||
|
||||
$this->_identifier = $currency;
|
||||
|
||||
@@ -11,31 +11,41 @@
|
||||
namespace IPS\nexus\extensions\core\Statistics;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Helpers\Chart;
|
||||
use IPS\Helpers\Chart\Database;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\Theme;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Statistics Chart Extension
|
||||
*/
|
||||
class _Sales extends \IPS\core\Statistics\Chart
|
||||
class Sales extends \IPS\core\Statistics\Chart
|
||||
{
|
||||
/**
|
||||
* @brief Controller
|
||||
*/
|
||||
public $controller = 'nexus_reports_purchases';
|
||||
public ?string $controller = 'nexus_reports_purchases';
|
||||
|
||||
/**
|
||||
* Render Chart
|
||||
*
|
||||
* @param \IPS\Http\Url $url URL the chart is being shown on.
|
||||
* @return \IPS\Helpers\Chart
|
||||
* @param Url $url URL the chart is being shown on.
|
||||
* @return Chart
|
||||
*/
|
||||
public function getChart( \IPS\Http\Url $url ): \IPS\Helpers\Chart
|
||||
public function getChart( Url $url ): Chart
|
||||
{
|
||||
$chart = new \IPS\Helpers\Chart\Database(
|
||||
$chart = new Database(
|
||||
$url,
|
||||
'nexus_purchases',
|
||||
'ps_start',
|
||||
@@ -54,20 +64,20 @@ class _Sales extends \IPS\core\Statistics\Chart
|
||||
$chart->tableInclude = array( 'ps_id', 'ps_member', 'ps_name', 'ps_start', 'ps_expire' );
|
||||
$chart->tableParsers = array(
|
||||
'ps_member' => function( $val ) {
|
||||
return \IPS\Theme::i()->getTemplate('global', 'nexus')->userLink( \IPS\Member::load( $val ) );
|
||||
return Theme::i()->getTemplate('global', 'nexus')->userLink( Member::load( $val ) );
|
||||
},
|
||||
'ps_start' => function( $val ) {
|
||||
return \IPS\DateTime::ts( $val );
|
||||
return DateTime::ts( $val );
|
||||
},
|
||||
'ps_expire' => function( $val ) {
|
||||
return $val ? \IPS\DateTime::ts( $val ) : '';
|
||||
return $val ? DateTime::ts( $val ) : '';
|
||||
}
|
||||
);
|
||||
|
||||
$packages = array();
|
||||
foreach ( \IPS\Db::i()->select( 'p_id', 'nexus_packages' ) as $packageId )
|
||||
foreach ( Db::i()->select( 'p_id', 'nexus_packages' ) as $packageId )
|
||||
{
|
||||
$packages[ $packageId ] = \IPS\Member::loggedIn()->language()->get( 'nexus_package_' . $packageId );
|
||||
$packages[ $packageId ] = Member::loggedIn()->language()->get( 'nexus_package_' . $packageId );
|
||||
}
|
||||
|
||||
asort( $packages );
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Statistics Chart 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 26 Jan 2023
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\extensions\core\Statistics;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Statistics Chart Extension
|
||||
*/
|
||||
class _Support extends \IPS\core\Statistics\Chart
|
||||
{
|
||||
/**
|
||||
* @brief Controller
|
||||
*/
|
||||
public $controller = 'nexus_support_volume';
|
||||
|
||||
/**
|
||||
* Render Chart
|
||||
*
|
||||
* @param \IPS\Http\Url $url URL the chart is being shown on.
|
||||
* @return \IPS\Helpers\Chart
|
||||
*/
|
||||
public function getChart( \IPS\Http\Url $url ): \IPS\Helpers\Chart
|
||||
{
|
||||
$chart = new \IPS\Helpers\Chart\Database( $url, 'nexus_support_requests', 'r_started', '',
|
||||
array(
|
||||
'vAxis' => array( 'title' => \IPS\Member::loggedIn()->language()->addToStack('support_requests_created') ),
|
||||
'backgroundColor' => '#ffffff',
|
||||
'colors' => array( '#10967e', '#ea7963', '#de6470', '#6b9dde', '#b09be4', '#eec766', '#9fc973', '#e291bf', '#55c1a6', '#5fb9da' ),
|
||||
'hAxis' => array( 'gridlines' => array( 'color' => '#f5f5f5' ) ),
|
||||
'lineWidth' => 1,
|
||||
'areaOpacity' => 0.4
|
||||
),
|
||||
'AreaChart'
|
||||
);
|
||||
$chart->setExtension( $this );
|
||||
$chart->groupBy = 'r_department';
|
||||
foreach( \IPS\nexus\Support\Department::roots() as $department )
|
||||
{
|
||||
$chart->addSeries( $department->_title, 'number', 'COUNT(*)', TRUE, $department->id );
|
||||
}
|
||||
|
||||
$chart->tableInclude = array( 'r_id', 'r_title', 'r_member', 'r_department', 'r_status', 'r_started', 'r_last_reply', 'r_replies' );
|
||||
$chart->tableParsers = array(
|
||||
'r_member' => function( $val ) {
|
||||
return \IPS\Theme::i()->getTemplate('global', 'nexus')->userLink( \IPS\Member::load( $val ) );
|
||||
},
|
||||
'r_department' => function( $val ) {
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'nexus_department_' . $val );
|
||||
},
|
||||
'r_status' => function( $val, $row )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'nexus_status_' . $val . '_admin' );
|
||||
},
|
||||
'r_started' => function( $val ) {
|
||||
return \IPS\DateTime::ts( $val );
|
||||
},
|
||||
'r_last_reply' => function( $val ) {
|
||||
return \IPS\DateTime::ts( $val );
|
||||
}
|
||||
);
|
||||
|
||||
return $chart;
|
||||
}
|
||||
}
|
||||
@@ -12,50 +12,30 @@
|
||||
namespace IPS\nexus\extensions\core\Uninstall;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Extensions\UninstallAbstract;
|
||||
use IPS\Settings;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstall callback
|
||||
*/
|
||||
class _DisablePOP
|
||||
class DisablePOP extends UninstallAbstract
|
||||
{
|
||||
/**
|
||||
* Code to execute before the application has been uninstalled
|
||||
*
|
||||
* @param string $application Application directory
|
||||
* @return array
|
||||
*/
|
||||
public function preUninstall( $application )
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Code to execute after the application has been uninstalled
|
||||
*
|
||||
* @param string $application Application directory
|
||||
* @return array
|
||||
*/
|
||||
public function postUninstall( $application )
|
||||
{
|
||||
/* Disable pop3 tasks */
|
||||
if ( \IPS\Settings::i()->pop3_server )
|
||||
{
|
||||
\IPS\Settings::i()->changeValues( array( 'pop3_server' => '' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Code to execute when other applications or plugins are uninstalled
|
||||
*
|
||||
* @param string $application Application directory
|
||||
* @param int $plugin Plugin ID
|
||||
* @return void
|
||||
*/
|
||||
public function onOtherUninstall( $application=NULL, $plugin=NULL )
|
||||
public function postUninstall( string $application ) : void
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
namespace IPS\nexus\extensions\core\UserMenu;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
|
||||
use IPS\Application\Module;
|
||||
use IPS\Helpers\Menu\Link;
|
||||
use IPS\Helpers\Menu\MenuItem;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\Output\UI\MenuExtension;
|
||||
use IPS\Settings;
|
||||
use IPS\Theme;
|
||||
use function count;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UserMenu extension: Store
|
||||
*/
|
||||
class Store extends MenuExtension
|
||||
{
|
||||
/**
|
||||
* Used to add additional links to the user account menu
|
||||
*
|
||||
* @param string $position ( can be content, settings, logout )
|
||||
* @return array<MenuItem>
|
||||
*/
|
||||
public function accountMenu( string $position = 'content' ): array
|
||||
{
|
||||
$return = [];
|
||||
if( $position == 'settings' )
|
||||
{
|
||||
if( Settings::i()->nexus_subs_enabled )
|
||||
{
|
||||
$return[] = new Link( Url::internal( "app=nexus&module=subscriptions&controller=subscriptions", "front", "nexus_subscriptions" ), 'nexus_manage_subscriptions', icon: 'fa-solid fa-arrows-rotate', identifier: 'subscriptions' );
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to add items to the mobile navigation Menu
|
||||
*
|
||||
* @param string $position ( can be content, settings, logout )
|
||||
* @return array<MenuItem>
|
||||
*/
|
||||
public function mobileMenu( string $position = 'content' ) : array
|
||||
{
|
||||
$return = [];
|
||||
|
||||
if( Settings::i()->nexus_subs_enabled and $position == 'content' )
|
||||
{
|
||||
$return[] = new Link( Url::internal( "app=nexus&module=subscriptions&controller=subscriptions", "front", "nexus_subscriptions" ), 'nexus_manage_subscriptions', "", icon: 'fa-solid fa-arrows-rotate', identifier: 'subscriptions' );
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to add additional content to userbar
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function userNav(): string
|
||||
{
|
||||
if( Member::loggedIn()->canAccessModule( Module::get( 'nexus', 'store' ) ) )
|
||||
{
|
||||
return Theme::i()->getTemplate( 'global', 'nexus' )->userNav();
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to add content to the mobile navigation header
|
||||
*
|
||||
* @param string $position (header/footer)
|
||||
* @param string $iconLocation
|
||||
* @return string
|
||||
*/
|
||||
public function mobileNav( string $position, string $iconLocation = 'footer' ) : string
|
||||
{
|
||||
if( Member::loggedIn()->canAccessModule( Module::get( 'nexus', 'store' ) ) )
|
||||
{
|
||||
if( $position == 'footer' and $iconLocation == 'footer' )
|
||||
{
|
||||
return Theme::i()->getTemplate( 'global', 'nexus' )->mobileFooterBar();
|
||||
}
|
||||
elseif( $position == 'header' and $iconLocation == 'header' )
|
||||
{
|
||||
return Theme::i()->getTemplate( 'global', 'nexus' )->mobileHeaderBar();
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -12,79 +12,87 @@
|
||||
namespace IPS\nexus\extensions\nexus\Item;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\Number;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Invoice;
|
||||
use IPS\nexus\Invoice\Item\Charge;
|
||||
use IPS\nexus\Money;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Account Credit Topup
|
||||
*/
|
||||
class _AccountCreditIncrease extends \IPS\nexus\Invoice\Item\Charge
|
||||
class AccountCreditIncrease extends Charge
|
||||
{
|
||||
/**
|
||||
* @brief Application
|
||||
*/
|
||||
public static $application = 'nexus';
|
||||
public static string $application = 'nexus';
|
||||
|
||||
/**
|
||||
* @brief Application
|
||||
*/
|
||||
public static $type = 'topup';
|
||||
public static string $type = 'topup';
|
||||
|
||||
/**
|
||||
* @brief Icon
|
||||
*/
|
||||
public static $icon = 'folder-open';
|
||||
public static string $icon = 'folder-open';
|
||||
|
||||
/**
|
||||
* @brief Title
|
||||
*/
|
||||
public static $title = 'account_credit_increase';
|
||||
public static string $title = 'account_credit_increase';
|
||||
|
||||
/**
|
||||
* @brief Can use coupons?
|
||||
*/
|
||||
public static $canUseCoupons = FALSE;
|
||||
public static bool $canUseCoupons = FALSE;
|
||||
|
||||
/**
|
||||
* @brief Can use account credit?
|
||||
*/
|
||||
public static $canUseAccountCredit = FALSE;
|
||||
public static bool $canUseAccountCredit = FALSE;
|
||||
|
||||
/**
|
||||
* Generate Invoice Form
|
||||
*
|
||||
* @param \IPS\Helpers\Form $form The form
|
||||
* @param \IPS\nexus\Invoice $invoice The invoice
|
||||
* @return void
|
||||
* @param Form $form The form
|
||||
* @param Invoice $invoice The invoice
|
||||
* @return void
|
||||
*/
|
||||
public static function form( \IPS\Helpers\Form $form, \IPS\nexus\Invoice $invoice )
|
||||
public static function form( Form $form, Invoice $invoice ): void
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'credit_amount', 0, TRUE, array( 'decimals' => TRUE ), NULL, NULL, $invoice->currency ) );
|
||||
$form->add( new Number( 'credit_amount', 0, TRUE, array( 'decimals' => TRUE ), NULL, NULL, $invoice->currency ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create From Form
|
||||
*
|
||||
* @param array $values Values from form
|
||||
* @param \IPS\nexus\Invoice $invoice The invoice
|
||||
* @return \IPS\nexus\extensions\nexus\Item\MiscellaneousCharge
|
||||
* @param Invoice $invoice The invoice
|
||||
* @return AccountCreditIncrease
|
||||
*/
|
||||
public static function createFromForm( array $values, \IPS\nexus\Invoice $invoice )
|
||||
public static function createFromForm( array $values, Invoice $invoice ): AccountCreditIncrease
|
||||
{
|
||||
$obj = new static( $invoice->member->language()->get('account_credit'), new \IPS\nexus\Money( $values['credit_amount'], $invoice->currency ) );
|
||||
return $obj;
|
||||
return new static( $invoice->member->language()->get('account_credit'), new Money( $values['credit_amount'], $invoice->currency ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* On Paid
|
||||
*
|
||||
* @param \IPS\nexus\Invoice $invoice The invoice
|
||||
* @return void
|
||||
* @param Invoice $invoice The invoice
|
||||
* @return void
|
||||
*/
|
||||
public function onPaid( \IPS\nexus\Invoice $invoice )
|
||||
public function onPaid( Invoice $invoice ): void
|
||||
{
|
||||
$credits = $invoice->member->cm_credits;
|
||||
|
||||
@@ -106,19 +114,19 @@ class _AccountCreditIncrease extends \IPS\nexus\Invoice\Item\Charge
|
||||
/**
|
||||
* On Unpaid description
|
||||
*
|
||||
* @param \IPS\nexus\Invoice $invoice The invoice
|
||||
* @param Invoice $invoice The invoice
|
||||
* @return array
|
||||
*/
|
||||
public function onUnpaidDescription( \IPS\nexus\Invoice $invoice )
|
||||
public function onUnpaidDescription( Invoice $invoice ): array
|
||||
{
|
||||
$return = parent::onUnpaidDescription( $invoice );
|
||||
|
||||
$message = \IPS\Member::loggedIn()->language()->addToStack('account_credit_remove', FALSE, array( 'sprintf' => array( $this->price, $invoice->member->cm_name ) ) );
|
||||
$message = Member::loggedIn()->language()->addToStack('account_credit_remove', FALSE, array( 'sprintf' => array( $this->price, $invoice->member->cm_name ) ) );
|
||||
|
||||
$credits = $invoice->member->cm_credits;
|
||||
if ( !$credits[ $this->price->currency ]->amount->subtract( $this->price->amount )->isPositive() )
|
||||
{
|
||||
$return[] = array( 'message' => $message, 'warning' => \IPS\Member::loggedIn()->language()->addToStack('account_credit_remove_neg') );
|
||||
$return[] = array( 'message' => $message, 'warning' => Member::loggedIn()->language()->addToStack('account_credit_remove_neg') );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -131,11 +139,11 @@ class _AccountCreditIncrease extends \IPS\nexus\Invoice\Item\Charge
|
||||
/**
|
||||
* On Unpaid
|
||||
*
|
||||
* @param \IPS\nexus\Invoice $invoice The invoice
|
||||
* @param Invoice $invoice The invoice
|
||||
* @param string $status Status
|
||||
* @return void
|
||||
* @return void
|
||||
*/
|
||||
public function onUnpaid( \IPS\nexus\Invoice $invoice, $status )
|
||||
public function onUnpaid( Invoice $invoice, string $status ): void
|
||||
{
|
||||
$credits = $invoice->member->cm_credits;
|
||||
|
||||
|
||||
@@ -12,69 +12,76 @@
|
||||
namespace IPS\nexus\extensions\nexus\Item;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\nexus\Coupon;
|
||||
use IPS\nexus\Invoice;
|
||||
use IPS\nexus\Invoice\Item\Charge;
|
||||
use OutOfRangeException;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Coupon Discount
|
||||
*/
|
||||
class _CouponDiscount extends \IPS\nexus\Invoice\Item\Charge
|
||||
class CouponDiscount extends Charge
|
||||
{
|
||||
/**
|
||||
* @brief Application
|
||||
*/
|
||||
public static $application = 'nexus';
|
||||
public static string $application = 'nexus';
|
||||
|
||||
/**
|
||||
* @brief Application
|
||||
*/
|
||||
public static $type = 'coupon';
|
||||
public static string $type = 'coupon';
|
||||
|
||||
/**
|
||||
* @brief Icon
|
||||
*/
|
||||
public static $icon = 'ticket';
|
||||
public static string $icon = 'ticket';
|
||||
|
||||
/**
|
||||
* @brief Title
|
||||
*/
|
||||
public static $title = 'coupon';
|
||||
public static string $title = 'coupon';
|
||||
|
||||
/**
|
||||
* On Paid
|
||||
*
|
||||
* @param \IPS\nexus\Invoice $invoice The invoice
|
||||
* @return void
|
||||
* @param Invoice $invoice The invoice
|
||||
* @return void
|
||||
*/
|
||||
public function onPaid( \IPS\nexus\Invoice $invoice )
|
||||
public function onPaid( Invoice $invoice ): void
|
||||
{
|
||||
try
|
||||
{
|
||||
$coupon = \IPS\nexus\Coupon::load( $this->id );
|
||||
$coupon = Coupon::load( $this->id );
|
||||
if ( $coupon->uses >= 1 )
|
||||
{
|
||||
$coupon->uses--;
|
||||
$coupon->save();
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
catch ( OutOfRangeException ) { }
|
||||
}
|
||||
|
||||
/**
|
||||
* On Unpaid
|
||||
*
|
||||
* @param \IPS\nexus\Invoice $invoice The invoice
|
||||
* @param Invoice $invoice The invoice
|
||||
* @param string $status Status
|
||||
* @return void
|
||||
* @return void
|
||||
*/
|
||||
public function onUnpaid( \IPS\nexus\Invoice $invoice, $status )
|
||||
public function onUnpaid( Invoice $invoice, string $status ): void
|
||||
{
|
||||
try
|
||||
{
|
||||
$coupon = \IPS\nexus\Coupon::load( $this->id );
|
||||
$coupon = Coupon::load( $this->id );
|
||||
if ( $coupon->uses != -1 )
|
||||
{
|
||||
$coupon->uses++;
|
||||
@@ -83,22 +90,22 @@ class _CouponDiscount extends \IPS\nexus\Invoice\Item\Charge
|
||||
|
||||
$this->onInvoiceCancel( $invoice );
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
catch ( OutOfRangeException ) { }
|
||||
}
|
||||
|
||||
/**
|
||||
* On Invoice Cancel (when unpaid)
|
||||
*
|
||||
* @param \IPS\nexus\Invoice $invoice The invoice
|
||||
* @return void
|
||||
* @param Invoice $invoice The invoice
|
||||
* @return void
|
||||
*/
|
||||
public function onInvoiceCancel( \IPS\nexus\Invoice $invoice )
|
||||
public function onInvoiceCancel( Invoice $invoice ): void
|
||||
{
|
||||
try
|
||||
{
|
||||
$coupon = \IPS\nexus\Coupon::load( $this->id );
|
||||
$coupon = Coupon::load( $this->id );
|
||||
$uses = $coupon->used_by ? json_decode( $coupon->used_by, TRUE ) : array();
|
||||
$member = isset( $this->extra['usedBy'] ) ? $this->extra['usedBy'] : $invoice->member->member_id;
|
||||
$member = $this->extra['usedBy'] ?? $invoice->member->member_id;
|
||||
if ( isset( $uses[ $member ] ) )
|
||||
{
|
||||
if ( $uses[ $member ] === 1 )
|
||||
@@ -113,6 +120,6 @@ class _CouponDiscount extends \IPS\nexus\Invoice\Item\Charge
|
||||
$coupon->save();
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
catch ( OutOfRangeException ) { }
|
||||
}
|
||||
}
|
||||
@@ -12,48 +12,100 @@
|
||||
namespace IPS\nexus\extensions\nexus\Item;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DateInterval;
|
||||
use DomainException;
|
||||
use IPS\File;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\Editor;
|
||||
use IPS\Helpers\Form\Interval;
|
||||
use IPS\Helpers\Form\Node;
|
||||
use IPS\Helpers\Form\Number;
|
||||
use IPS\Helpers\Form\Radio;
|
||||
use IPS\Helpers\Form\Select;
|
||||
use IPS\Helpers\Form\Text;
|
||||
use IPS\Helpers\Form\YesNo;
|
||||
use IPS\IPS;
|
||||
use IPS\Member;
|
||||
use IPS\Member\Group;
|
||||
use IPS\nexus\Invoice;
|
||||
use IPS\nexus\Money;
|
||||
use IPS\nexus\Package;
|
||||
use IPS\nexus\Package as PackageClass;
|
||||
use IPS\nexus\Purchase;
|
||||
use IPS\nexus\Purchase\LicenseKey;
|
||||
use IPS\nexus\Purchase\RenewalTerm;
|
||||
use IPS\nexus\Tax;
|
||||
use IPS\Request;
|
||||
use IPS\Settings;
|
||||
use OutOfRangeException;
|
||||
use StdClass;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Package
|
||||
*/
|
||||
class _CustomPackage extends \IPS\nexus\extensions\nexus\Item\Package
|
||||
class CustomPackage extends \IPS\nexus\extensions\nexus\Item\Package
|
||||
{
|
||||
/**
|
||||
* @brief Application
|
||||
*/
|
||||
public static $application = 'nexus';
|
||||
public static string $application = 'nexus';
|
||||
|
||||
/**
|
||||
* @brief Application
|
||||
*/
|
||||
public static $type = 'custom';
|
||||
public static string $type = 'custom';
|
||||
|
||||
/**
|
||||
* @brief Icon
|
||||
*/
|
||||
public static $icon = 'asterisk';
|
||||
public static string $icon = 'asterisk';
|
||||
|
||||
/**
|
||||
* @brief Title
|
||||
*/
|
||||
public static $title = 'custom';
|
||||
public static string $title = 'custom';
|
||||
|
||||
/**
|
||||
* Get Client Area Page HTML
|
||||
*
|
||||
* @param Purchase $purchase The purchase
|
||||
* @return array array( 'packageInfo' => '...', 'purchaseInfo' => '...' )
|
||||
*/
|
||||
public static function clientAreaPage( Purchase $purchase ): array
|
||||
{
|
||||
try
|
||||
{
|
||||
$package = PackageClass::load( $purchase->item_id );
|
||||
return array(
|
||||
'packageInfo' => $package->page,
|
||||
'purchaseInfo' => ''
|
||||
);
|
||||
}
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
return array( 'packageInfo' => '', 'purchaseInfo' => '' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate Invoice Form
|
||||
*
|
||||
* @param \IPS\Helpers\Form $form The form
|
||||
* @param \IPS\nexus\Invoice $invoice The invoice
|
||||
* @return void
|
||||
* @param Form $form The form
|
||||
* @param Invoice $invoice The invoice
|
||||
* @return void
|
||||
*/
|
||||
public static function form( \IPS\Helpers\Form $form, \IPS\nexus\Invoice $invoice )
|
||||
public static function form( Form $form, Invoice $invoice ): void
|
||||
{
|
||||
$groups = array();
|
||||
foreach ( \IPS\Member\Group::groups() as $group )
|
||||
foreach ( Group::groups() as $group )
|
||||
{
|
||||
$groups[ $group->g_id ] = $group->name;
|
||||
}
|
||||
@@ -62,11 +114,12 @@ class _CustomPackage extends \IPS\nexus\extensions\nexus\Item\Package
|
||||
$typeFields = array();
|
||||
$typeFieldToggles = array();
|
||||
$formId = 'form_new';
|
||||
foreach ( \IPS\nexus\Package::packageTypes() as $key => $class )
|
||||
foreach ( Package::packageTypes() as $key => $class )
|
||||
{
|
||||
$forceShow = TRUE;
|
||||
$types[ mb_strtolower( $key ) ] = 'p_type_' . $key;
|
||||
|
||||
|
||||
/* @var Package $class */
|
||||
foreach ( $class::acpFormFields( new $class, TRUE ) as $group => $fields )
|
||||
{
|
||||
foreach ( $fields as $field )
|
||||
@@ -78,21 +131,22 @@ class _CustomPackage extends \IPS\nexus\extensions\nexus\Item\Package
|
||||
if ( !$field->htmlId )
|
||||
{
|
||||
$field->htmlId = $field->name;
|
||||
$typeFieldToggles[ mb_strtolower( $key ) ][] = $field->htmlId;
|
||||
}
|
||||
}
|
||||
|
||||
$typeFieldToggles[ mb_strtolower( $key ) ][] = $field->htmlId;
|
||||
$typeFields[ $group ][] = $field;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $forceShow )
|
||||
{
|
||||
$typeFieldToggles[ mb_strtolower( $key ) ] = array_merge( isset( $typeFieldToggles[ mb_strtolower( $key ) ] ) ? $typeFieldToggles[ mb_strtolower( $key ) ] : array(), array( "{$formId}_tab_package_client_area", "{$formId}_header_package_associations", "{$formId}_header_package_associations_desc", 'p_associate', "{$formId}_header_package_renewals", 'p_renews', 'p_support_severity', 'p_lkey' ) );
|
||||
$typeFieldToggles[ mb_strtolower( $key ) ] = array_merge( $typeFieldToggles[mb_strtolower($key)] ?? array(), array( "{$formId}_tab_package_client_area", "{$formId}_header_package_associations", "{$formId}_header_package_associations_desc", 'p_associate', "{$formId}_header_package_renewals", 'p_renews', 'p_lkey' ) );
|
||||
}
|
||||
}
|
||||
|
||||
$form->addTab('package_settings');
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'p_type', 'product', TRUE, array( 'options' => $types, 'toggles' => $typeFieldToggles ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'p_name', NULL, TRUE ) );
|
||||
$form->add( new Radio( 'p_type', 'product', TRUE, array( 'options' => $types, 'toggles' => $typeFieldToggles ) ) );
|
||||
$form->add( new Text( 'p_name', NULL, TRUE ) );
|
||||
|
||||
foreach ( $typeFields['package_settings'] as $field )
|
||||
{
|
||||
@@ -100,37 +154,33 @@ class _CustomPackage extends \IPS\nexus\extensions\nexus\Item\Package
|
||||
}
|
||||
|
||||
$form->addTab( 'package_pricing' );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'p_base_price', 0, TRUE, array( 'decimals' => TRUE ), NULL, NULL, $invoice->currency ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'p_tax', 0, FALSE, array( 'class' => 'IPS\nexus\Tax', 'zeroVal' => 'do_not_tax' ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'p_renews', FALSE, FALSE, array( 'togglesOn' => array( 'p_renew_options', 'p_renew' ) ), NULL, NULL, NULL, 'p_renews' ) );
|
||||
$form->add( new Number( 'p_base_price', 0, TRUE, array( 'decimals' => TRUE ), NULL, NULL, $invoice->currency ) );
|
||||
$form->add( new Node( 'p_tax', 0, FALSE, array( 'class' => 'IPS\nexus\Tax', 'zeroVal' => 'do_not_tax' ) ) );
|
||||
$form->add( new YesNo( 'p_renews', FALSE, FALSE, array( 'togglesOn' => array( 'p_renew_options', 'p_renew' ) ), NULL, NULL, NULL, 'p_renews' ) );
|
||||
$form->add( new \IPS\nexus\Form\RenewalTerm( 'p_renew_options', NULL, FALSE, array( 'currency' => $invoice->currency ), NULL, NULL, NULL, 'p_renew_options' ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'p_renew', FALSE, FALSE, array( 'togglesOn' => array( 'p_renewal_days', 'p_renewal_days_advance' ) ), NULL, NULL, NULL, 'p_renew' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'p_renewal_days', -1, FALSE, array( 'unlimited' => -1, 'unlimitedLang' => 'any_time' ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('days_before_expiry'), 'p_renewal_days' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Interval( 'p_renewal_days_advance', -1, FALSE, array( 'valueAs' => \IPS\Helpers\Form\Interval::DAYS, 'unlimited' => -1 ), NULL, NULL, NULL, 'p_renewal_days_advance' ) );
|
||||
$form->add( new YesNo( 'p_renew', FALSE, FALSE, array( 'togglesOn' => array( 'p_renewal_days', 'p_renewal_days_advance' ) ), NULL, NULL, NULL, 'p_renew' ) );
|
||||
$form->add( new Number( 'p_renewal_days', -1, FALSE, array( 'unlimited' => -1, 'unlimitedLang' => 'any_time' ), NULL, NULL, Member::loggedIn()->language()->addToStack('days_before_expiry'), 'p_renewal_days' ) );
|
||||
$form->add( new Interval( 'p_renewal_days_advance', -1, FALSE, array( 'valueAs' => Interval::DAYS, 'unlimited' => -1 ), NULL, NULL, NULL, 'p_renewal_days_advance' ) );
|
||||
|
||||
$form->addTab( 'package_benefits' );
|
||||
unset( $groups[ \IPS\Settings::i()->guest_group ] );
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'p_primary_group', '*', FALSE, array( 'options' => $groups, 'unlimited' => '*', 'unlimitedLang' => 'do_not_change', 'unlimitedToggles' => array( 'p_return_primary' ), 'unlimitedToggleOn' => FALSE ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'p_return_primary', TRUE, FALSE, array(), NULL, NULL, NULL, 'p_return_primary' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'p_secondary_group', '*', FALSE, array( 'options' => $groups, 'multiple' => TRUE, 'unlimited' => '*', 'unlimitedLang' => 'do_not_change', 'unlimitedToggles' => array( 'p_return_secondary' ), 'unlimitedToggleOn' => FALSE ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'p_return_secondary', TRUE, FALSE, array(), NULL, NULL, NULL, 'p_return_secondary' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'p_support_severity', 0, FALSE, array( 'class' => 'IPS\nexus\Support\Severity', 'zeroVal' => 'none' ), NULL, NULL, NULL, 'p_support_severity' ) );
|
||||
|
||||
unset( $groups[ Settings::i()->guest_group ] );
|
||||
$form->add( new Select( 'p_primary_group', '*', FALSE, array( 'options' => $groups, 'unlimited' => '*', 'unlimitedLang' => 'do_not_change', 'unlimitedToggles' => array( 'p_return_primary' ), 'unlimitedToggleOn' => FALSE ) ) );
|
||||
$form->add( new YesNo( 'p_return_primary', TRUE, FALSE, array(), NULL, NULL, NULL, 'p_return_primary' ) );
|
||||
$form->add( new Select( 'p_secondary_group', '*', FALSE, array( 'options' => $groups, 'multiple' => TRUE, 'unlimited' => '*', 'unlimitedLang' => 'do_not_change', 'unlimitedToggles' => array( 'p_return_secondary' ), 'unlimitedToggleOn' => FALSE ) ) );
|
||||
$form->add( new YesNo( 'p_return_secondary', TRUE, FALSE, array(), NULL, NULL, NULL, 'p_return_secondary' ) );
|
||||
|
||||
foreach ( $typeFields['package_benefits'] as $field )
|
||||
{
|
||||
$form->add( $field );
|
||||
}
|
||||
|
||||
$form->addTab('package_client_area_display');
|
||||
$form->add( new \IPS\Helpers\Form\Editor( 'p_page', NULL, FALSE, array(
|
||||
$form->add( new Editor( 'p_page', NULL, FALSE, array(
|
||||
'app' => 'nexus',
|
||||
'key' => 'Admin',
|
||||
'autoSaveKey' => "nexus-new-pkg-pg",
|
||||
'attachIds' => NULL, 'minimize' => 'p_page_placeholder'
|
||||
), NULL, NULL, NULL, 'p_desc_editor' ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'p_support', FALSE, FALSE, array( 'togglesOn' => array( 'p_support_department' ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'p_support_department', 0, FALSE, array( 'class' => 'IPS\nexus\Support\Department', 'zeroVal' => 'none' ), NULL, NULL, NULL, 'p_support_department' ) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -138,20 +188,20 @@ class _CustomPackage extends \IPS\nexus\extensions\nexus\Item\Package
|
||||
* Generate Invoice Form: Second Step
|
||||
*
|
||||
* @param array $values Form values from previous step
|
||||
* @param \IPS\Helpers\Form $form The form
|
||||
* @param \IPS\nexus\Invoice $invoice The invoice
|
||||
* @return bool
|
||||
* @param Form $form The form
|
||||
* @param Invoice $invoice The invoice
|
||||
* @return bool
|
||||
*/
|
||||
public static function formSecondStep( array $values, \IPS\Helpers\Form $form, \IPS\nexus\Invoice $invoice )
|
||||
public static function formSecondStep( array $values, Form $form, Invoice $invoice ): bool
|
||||
{
|
||||
$types = \IPS\nexus\Package::packageTypes();
|
||||
$classname = $types[ mb_ucfirst( $values['p_type'] ) ];
|
||||
$types = Package::packageTypes();
|
||||
$classname = $types[ IPS::mb_ucfirst( $values['p_type'] ) ];
|
||||
|
||||
if ( method_exists( $classname, 'generateInvoiceForm' ) )
|
||||
{
|
||||
if ( isset( \IPS\Request::i()->customPackageId ) )
|
||||
if ( isset( Request::i()->customPackageId ) )
|
||||
{
|
||||
$package = \IPS\nexus\Package::load( \IPS\Request::i()->customPackageId );
|
||||
$package = Package::load( Request::i()->customPackageId );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -173,13 +223,13 @@ class _CustomPackage extends \IPS\nexus\extensions\nexus\Item\Package
|
||||
* Create the package
|
||||
*
|
||||
* @param array $values Values from form
|
||||
* @param \IPS\nexus\Invoice $invoice The invoice
|
||||
* @return \IPS\nexus\Package
|
||||
* @param Invoice $invoice The invoice
|
||||
* @return Package
|
||||
*/
|
||||
protected static function _createPackage( array $values, \IPS\nexus\Invoice $invoice )
|
||||
protected static function _createPackage( array $values, Invoice $invoice ) : Package
|
||||
{
|
||||
/* Init */
|
||||
$package = new \IPS\nexus\Package;
|
||||
$package = new Package;
|
||||
$package->custom = $invoice->member->member_id;
|
||||
|
||||
/* Figure out tax */
|
||||
@@ -192,7 +242,7 @@ class _CustomPackage extends \IPS\nexus\extensions\nexus\Item\Package
|
||||
$tax = $values['p_tax'];
|
||||
}
|
||||
}
|
||||
catch( \OutOfRangeException $e ){}
|
||||
catch( OutOfRangeException ){}
|
||||
|
||||
/* Set default values for stuff we didn't have */
|
||||
$values['p_member_groups'] = array();
|
||||
@@ -201,12 +251,12 @@ class _CustomPackage extends \IPS\nexus\extensions\nexus\Item\Package
|
||||
$values['p_loyalty_discounts'] = array();
|
||||
$values['p_bulk_discounts'] = array();
|
||||
$values['p_images'] = array();
|
||||
$values['p_group'] = new \StdClass;
|
||||
$values['p_group'] = new StdClass;
|
||||
$values['p_group']->id = 0;
|
||||
$renewTerm = $values['p_renews'] ?
|
||||
new \IPS\nexus\Purchase\RenewalTerm(
|
||||
new \IPS\nexus\Money( \IPS\Request::i()->p_renew_options['amount'], ( isset( \IPS\Request::i()->p_renew_options['currency'] ) ) ? \IPS\Request::i()->p_renew_options['currency'] : $invoice->currency ),
|
||||
new \DateInterval( 'P' . \IPS\Request::i()->p_renew_options['term'] . mb_strtoupper( \IPS\Request::i()->p_renew_options['unit'] ) ),
|
||||
new RenewalTerm(
|
||||
new Money( Request::i()->p_renew_options['amount'], ( isset( Request::i()->p_renew_options['currency'] ) ) ? Request::i()->p_renew_options['currency'] : $invoice->currency ),
|
||||
new DateInterval( 'P' . Request::i()->p_renew_options['term'] . mb_strtoupper( Request::i()->p_renew_options['unit'] ) ),
|
||||
$tax,
|
||||
FALSE
|
||||
) : NULL;
|
||||
@@ -216,7 +266,7 @@ class _CustomPackage extends \IPS\nexus\extensions\nexus\Item\Package
|
||||
$package->saveForm( $package->formatFormValues( $values ) );
|
||||
|
||||
/* Custom-specific */
|
||||
$package = \IPS\nexus\Package::load( $package->id );
|
||||
$package = Package::load( $package->id );
|
||||
$package->name = $values['p_name'];
|
||||
$package->base_price = json_encode( array( $invoice->currency => array( 'amount' => $values['p_base_price'], 'currency' => $invoice->currency ) ) );
|
||||
if ( $values['p_renews'] )
|
||||
@@ -236,6 +286,8 @@ class _CustomPackage extends \IPS\nexus\extensions\nexus\Item\Package
|
||||
$package->store = 0;
|
||||
$package->page = $values['p_page'];
|
||||
$package->save();
|
||||
|
||||
File::claimAttachments( 'nexus-new-pkg-pg', $package->id, null, 'custom-pg' );
|
||||
|
||||
/* Return */
|
||||
return $package;
|
||||
@@ -245,17 +297,23 @@ class _CustomPackage extends \IPS\nexus\extensions\nexus\Item\Package
|
||||
* Create From Form
|
||||
*
|
||||
* @param array $values Values from form
|
||||
* @param \IPS\nexus\Invoice $invoice The invoice
|
||||
* @return \IPS\nexus\extensions\nexus\Item\CustomPackage
|
||||
* @param Invoice $invoice The invoice
|
||||
* @return array|static
|
||||
*/
|
||||
public static function createFromForm( array $values, \IPS\nexus\Invoice $invoice )
|
||||
public static function createFromForm( array $values, Invoice $invoice ): array|static
|
||||
{
|
||||
/* Create the package */
|
||||
if ( isset( \IPS\Request::i()->customPackageId ) )
|
||||
$package = null;
|
||||
if ( isset( Request::i()->customPackageId ) )
|
||||
{
|
||||
$package = \IPS\nexus\Package::load( \IPS\Request::i()->customPackageId );
|
||||
try
|
||||
{
|
||||
$package = Package::load( Request::i()->customPackageId );
|
||||
}
|
||||
catch( OutOfRangeException ){}
|
||||
}
|
||||
else
|
||||
|
||||
if( $package === null )
|
||||
{
|
||||
$package = static::_createPackage( $values, $invoice );
|
||||
}
|
||||
@@ -267,10 +325,10 @@ class _CustomPackage extends \IPS\nexus\extensions\nexus\Item\Package
|
||||
{
|
||||
if( $package->tax )
|
||||
{
|
||||
$tax = \IPS\nexus\Tax::load( $package->tax );
|
||||
$tax = Tax::load( $package->tax );
|
||||
}
|
||||
}
|
||||
catch( \OutOfRangeException $e ){}
|
||||
catch( OutOfRangeException ){}
|
||||
|
||||
/* Work stuff out */
|
||||
$basePrice = json_decode( $package->base_price, TRUE );
|
||||
@@ -278,7 +336,7 @@ class _CustomPackage extends \IPS\nexus\extensions\nexus\Item\Package
|
||||
{
|
||||
$renewTerm = json_decode( $package->renew_options, TRUE );
|
||||
$renewTerm = array_pop( $renewTerm );
|
||||
$renewTerm = new \IPS\nexus\Purchase\RenewalTerm( new \IPS\nexus\Money( $renewTerm['cost']['amount'], $renewTerm['cost']['currency'] ), new \DateInterval( 'P' . $renewTerm['term'] . mb_strtoupper( $renewTerm['unit'] ) ), $tax, FALSE );
|
||||
$renewTerm = new RenewalTerm( new Money( $renewTerm['cost']['amount'], $renewTerm['cost']['currency'] ), new DateInterval( 'P' . $renewTerm['term'] . mb_strtoupper( $renewTerm['unit'] ) ), $tax, FALSE );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -286,23 +344,11 @@ class _CustomPackage extends \IPS\nexus\extensions\nexus\Item\Package
|
||||
}
|
||||
|
||||
/* Now create an item */
|
||||
$item = new static( $package->name, new \IPS\nexus\Money( $basePrice[ $invoice->currency ]['amount'], $invoice->currency ) );
|
||||
$item = new static( $package->name, new Money( $basePrice[ $invoice->currency ]['amount'], $invoice->currency ) );
|
||||
$item->renewalTerm = $renewTerm;
|
||||
$item->quantity = 1;
|
||||
$item->id = $package->id;
|
||||
$item->tax = $tax;
|
||||
if ( $package instanceof \IPS\nexus\Package\Product and $package->physical )
|
||||
{
|
||||
$item->physical = TRUE;
|
||||
$item->weight = new \IPS\nexus\Shipping\Weight( $package->weight );
|
||||
$item->length = new \IPS\nexus\Shipping\Length( $package->length );
|
||||
$item->width = new \IPS\nexus\Shipping\Length( $package->width );
|
||||
$item->height = new \IPS\nexus\Shipping\Length( $package->height );
|
||||
if ( $package->shipping !== '*' )
|
||||
{
|
||||
$item->shippingMethodIds = explode( ',', $package->shipping );
|
||||
}
|
||||
}
|
||||
$package->acpAddToInvoice( $item, $values, '', $invoice );
|
||||
|
||||
/* And return */
|
||||
@@ -312,21 +358,21 @@ class _CustomPackage extends \IPS\nexus\extensions\nexus\Item\Package
|
||||
/**
|
||||
* ACP Edit Form
|
||||
*
|
||||
* @param \IPS\nexus\Purchase $purchase The purchase
|
||||
* @param \IPS\Helpers\Form $form The form
|
||||
* @param \IPS\nexus\Purchase\RenewalTerm $renewals The renewal term
|
||||
* @return string
|
||||
* @param Purchase $purchase The purchase
|
||||
* @param Form $form The form
|
||||
* @param RenewalTerm|null $renewals The renewal term
|
||||
* @return void
|
||||
*/
|
||||
public static function acpEdit( \IPS\nexus\Purchase $purchase, \IPS\Helpers\Form $form, $renewals )
|
||||
public static function acpEdit( Purchase $purchase, Form $form, ?RenewalTerm $renewals ) : void
|
||||
{
|
||||
$form->addTab( 'basic_settings' );
|
||||
parent::acpEdit( $purchase, $form, $renewals );
|
||||
|
||||
$package = \IPS\nexus\Package::load( $purchase->item_id );
|
||||
$package = Package::load( $purchase->item_id );
|
||||
$typeFields = $package->acpFormFields( $package, TRUE, TRUE );
|
||||
|
||||
$groups = array();
|
||||
foreach ( \IPS\Member\Group::groups() as $group )
|
||||
foreach ( Group::groups() as $group )
|
||||
{
|
||||
$groups[ $group->g_id ] = $group->name;
|
||||
}
|
||||
@@ -339,18 +385,17 @@ class _CustomPackage extends \IPS\nexus\extensions\nexus\Item\Package
|
||||
}
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'p_renew', $package->renewal_days != 0, FALSE, array( 'togglesOn' => array( 'p_renewal_days', 'p_renewal_days_advance' ) ), NULL, NULL, NULL, 'p_renew' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'p_renewal_days', $package->renewal_days, FALSE, array( 'unlimited' => -1, 'unlimitedLang' => 'any_time' ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('days_before_expiry'), 'p_renewal_days' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Interval( 'p_renewal_days_advance', $package->renewal_days_advance, FALSE, array( 'valueAs' => \IPS\Helpers\Form\Interval::DAYS, 'unlimited' => -1 ), NULL, NULL, NULL, 'p_renewal_days_advance' ) );
|
||||
$form->add( new YesNo( 'p_renew', $package->renewal_days != 0, FALSE, array( 'togglesOn' => array( 'p_renewal_days', 'p_renewal_days_advance' ) ), NULL, NULL, NULL, 'p_renew' ) );
|
||||
$form->add( new Number( 'p_renewal_days', $package->renewal_days, FALSE, array( 'unlimited' => -1, 'unlimitedLang' => 'any_time' ), NULL, NULL, Member::loggedIn()->language()->addToStack('days_before_expiry'), 'p_renewal_days' ) );
|
||||
$form->add( new Interval( 'p_renewal_days_advance', $package->renewal_days_advance, FALSE, array( 'valueAs' => Interval::DAYS, 'unlimited' => -1 ), NULL, NULL, NULL, 'p_renewal_days_advance' ) );
|
||||
|
||||
$form->addTab( 'package_benefits' );
|
||||
unset( $groups[ \IPS\Settings::i()->guest_group ] );
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'p_primary_group', $package->primary_group ?: '*', FALSE, array( 'options' => $groups, 'unlimited' => '*', 'unlimitedLang' => 'do_not_change', 'unlimitedToggles' => array( 'p_return_primary' ), 'unlimitedToggleOn' => FALSE ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'p_return_primary', $package->return_primary, FALSE, array(), NULL, NULL, NULL, 'p_return_primary' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'p_secondary_group', $package->secondary_group ? explode( ',', $package->member_groups ) : '*', FALSE, array( 'options' => $groups, 'multiple' => TRUE, 'unlimited' => '*', 'unlimitedLang' => 'do_not_change', 'unlimitedToggles' => array( 'p_return_secondary' ), 'unlimitedToggleOn' => FALSE ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'p_return_secondary', $package->return_secondary, FALSE, array(), NULL, NULL, NULL, 'p_return_secondary' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'p_support_severity', 0, $package->support_severity ?: 0, array( 'class' => 'IPS\nexus\Support\Severity', 'zeroVal' => 'none' ), NULL, NULL, NULL, 'p_support_severity' ) );
|
||||
|
||||
unset( $groups[ Settings::i()->guest_group ] );
|
||||
$form->add( new Select( 'p_primary_group', $package->primary_group ?: '*', FALSE, array( 'options' => $groups, 'unlimited' => '*', 'unlimitedLang' => 'do_not_change', 'unlimitedToggles' => array( 'p_return_primary' ), 'unlimitedToggleOn' => FALSE ) ) );
|
||||
$form->add( new YesNo( 'p_return_primary', $package->return_primary, FALSE, array(), NULL, NULL, NULL, 'p_return_primary' ) );
|
||||
$form->add( new Select( 'p_secondary_group', $package->secondary_group ? explode( ',', $package->member_groups ) : '*', FALSE, array( 'options' => $groups, 'multiple' => TRUE, 'unlimited' => '*', 'unlimitedLang' => 'do_not_change', 'unlimitedToggles' => array( 'p_return_secondary' ), 'unlimitedToggleOn' => FALSE ) ) );
|
||||
$form->add( new YesNo( 'p_return_secondary', $package->return_secondary, FALSE, array(), NULL, NULL, NULL, 'p_return_secondary' ) );
|
||||
|
||||
if ( isset( $typeFields['package_benefits'] ) )
|
||||
{
|
||||
foreach ( $typeFields['package_benefits'] as $field )
|
||||
@@ -360,28 +405,27 @@ class _CustomPackage extends \IPS\nexus\extensions\nexus\Item\Package
|
||||
}
|
||||
|
||||
$form->addTab('package_client_area_display');
|
||||
$form->add( new \IPS\Helpers\Form\Editor( 'p_page', $package->page, FALSE, array(
|
||||
$form->add( new Editor( 'p_page', $package->page, FALSE, array(
|
||||
'app' => 'nexus',
|
||||
'key' => 'Admin',
|
||||
'autoSaveKey' => "nexus-new-pkg-pg",
|
||||
'attachIds' => NULL, 'minimize' => 'p_page_placeholder'
|
||||
'attachIds' => [ $package->id, null, 'custom-pg' ],
|
||||
'minimize' => 'p_page_placeholder'
|
||||
), NULL, NULL, NULL, 'p_desc_editor' ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'p_support', $package->support, FALSE, array( 'togglesOn' => array( 'p_support_department' ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'p_support_department', $package->support ?: 0, FALSE, array( 'class' => 'IPS\nexus\Support\Department', 'zeroVal' => 'none' ), NULL, NULL, NULL, 'p_support_department' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* ACP Edit Save
|
||||
*
|
||||
* @param \IPS\nexus\Purchase $purchase The purchase
|
||||
* @param Purchase $purchase The purchase
|
||||
* @param array $values Values from form
|
||||
* @return string
|
||||
* @return void
|
||||
*/
|
||||
public static function acpEditSave( \IPS\nexus\Purchase $purchase, array $values )
|
||||
public static function acpEditSave( Purchase $purchase, array $values ): void
|
||||
{
|
||||
parent::acpEditSave( $purchase, $values );
|
||||
|
||||
$package = \IPS\nexus\Package::load( $purchase->item_id );
|
||||
$package = Package::load( $purchase->item_id );
|
||||
|
||||
$resetLkey = FALSE;
|
||||
$updateLkey = FALSE;
|
||||
@@ -394,7 +438,6 @@ class _CustomPackage extends \IPS\nexus\extensions\nexus\Item\Package
|
||||
$package->return_primary = $values['p_return_primary'];
|
||||
$package->secondary_group = $values['p_secondary_group'] == '*' ? '*' : implode( ',', $values['p_secondary_group'] );
|
||||
$package->return_secondary = $values['p_return_secondary'];
|
||||
$package->support_severity = $values['p_support_severity'] ? $values['p_support_severity']->id : 0;
|
||||
|
||||
if ( $values['p_lkey'] != $package->lkey )
|
||||
{
|
||||
@@ -421,12 +464,13 @@ class _CustomPackage extends \IPS\nexus\extensions\nexus\Item\Package
|
||||
}
|
||||
|
||||
$package->page = $values['p_page'];
|
||||
$package->support = ( $values['p_support'] and $values['p_support_department'] ) ? $values['p_support_department']->id : 0;
|
||||
$package->save();
|
||||
|
||||
File::claimAttachments( 'nexus-new-pkg-pg', $package->id, null, 'custom-pg' );
|
||||
|
||||
if ( $resetLkey or $updateLkey or $deleteLkey )
|
||||
{
|
||||
$licenseTypes = \IPS\nexus\Purchase\LicenseKey::licenseKeyTypes();
|
||||
$licenseTypes = LicenseKey::licenseKeyTypes();
|
||||
|
||||
if ( $resetLkey or $deleteLkey )
|
||||
{
|
||||
@@ -434,11 +478,11 @@ class _CustomPackage extends \IPS\nexus\extensions\nexus\Item\Package
|
||||
{
|
||||
$purchase->licenseKey()->delete();
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
catch ( OutOfRangeException ) { }
|
||||
|
||||
if ( $resetLkey )
|
||||
{
|
||||
$class = $licenseTypes[ mb_ucfirst( $package->lkey ) ];
|
||||
$class = $licenseTypes[ IPS::mb_ucfirst( $package->lkey ) ];
|
||||
$licenseKey = new $class;
|
||||
}
|
||||
}
|
||||
@@ -448,14 +492,14 @@ class _CustomPackage extends \IPS\nexus\extensions\nexus\Item\Package
|
||||
{
|
||||
$licenseKey = $purchase->licenseKey();
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
$class = $licenseTypes[ mb_ucfirst( $package->lkey ) ];
|
||||
$class = $licenseTypes[ IPS::mb_ucfirst( $package->lkey ) ];
|
||||
$licenseKey = new $class;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $resetLkey or $updateLkey )
|
||||
if ( isset( $licenseKey ) and ( $resetLkey or $updateLkey ) )
|
||||
{
|
||||
$licenseKey->identifier = $package->lkey_identifier;
|
||||
$licenseKey->purchase = $purchase;
|
||||
@@ -464,15 +508,43 @@ class _CustomPackage extends \IPS\nexus\extensions\nexus\Item\Package
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional elements that will be used to create coupons
|
||||
* Also used on the Commission Rules
|
||||
*
|
||||
* @param array|string|null $current
|
||||
* @return array
|
||||
*/
|
||||
public static function customFormElements( array|string|null $current =null ) : array
|
||||
{
|
||||
/* Intentional override so that this doesn't show up in the coupon form */
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of values that will be stored with the coupon
|
||||
* Note: If you have any additional fields that have been added to the form
|
||||
* but are NOT saved to the database, you MUST unset them from the values array
|
||||
*
|
||||
* @param array $values
|
||||
* @param mixed|null $object
|
||||
* @return array|null
|
||||
*/
|
||||
public static function saveCustomForm( array &$values=array(), mixed $object = null ) : ?array
|
||||
{
|
||||
/* Intentional override so that this doesn't show up in the coupon form */
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show Purchase Record?
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public function showPurchaseRecord()
|
||||
public function showPurchaseRecord(): bool
|
||||
{
|
||||
return \IPS\nexus\Package::load( $this->id )->showPurchaseRecord();
|
||||
return Package::load( $this->id )->showPurchaseRecord();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -481,11 +553,11 @@ class _CustomPackage extends \IPS\nexus\extensions\nexus\Item\Package
|
||||
* 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
|
||||
* @param Member $member The new member
|
||||
* @return void
|
||||
* @throws DomainException
|
||||
*/
|
||||
public function memberCanPurchase( \IPS\Member $member )
|
||||
public function memberCanPurchase( Member $member ): void
|
||||
{
|
||||
// Custom packages do not have any purchase restrictions
|
||||
}
|
||||
|
||||
@@ -12,82 +12,120 @@
|
||||
namespace IPS\nexus\extensions\nexus\Item;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DomainException;
|
||||
use Exception;
|
||||
use IPS\Application;
|
||||
use IPS\Db;
|
||||
use IPS\Math\Number;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Donation\Goal;
|
||||
use IPS\nexus\Invoice;
|
||||
use IPS\nexus\Invoice\Item\Charge;
|
||||
use IPS\Notification;
|
||||
use IPS\Settings;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Donation
|
||||
*/
|
||||
class _Donation extends \IPS\nexus\Invoice\Item\Charge
|
||||
class Donation extends Charge
|
||||
{
|
||||
/**
|
||||
* @brief Application
|
||||
*/
|
||||
public static $application = 'nexus';
|
||||
public static string $application = 'nexus';
|
||||
|
||||
/**
|
||||
* @brief Application
|
||||
*/
|
||||
public static $type = 'donation';
|
||||
public static string $type = 'donation';
|
||||
|
||||
/**
|
||||
* @brief Icon
|
||||
*/
|
||||
public static $icon = 'money';
|
||||
public static string $icon = 'money-bill';
|
||||
|
||||
/**
|
||||
* @brief Title
|
||||
*/
|
||||
public static $title = 'donation';
|
||||
public static string $title = 'donation';
|
||||
|
||||
/**
|
||||
* @brief Can use coupons?
|
||||
*/
|
||||
public static $canUseCoupons = FALSE;
|
||||
public static bool $canUseCoupons = FALSE;
|
||||
|
||||
/**
|
||||
* @brief Can use account credit?
|
||||
*/
|
||||
public static $canUseAccountCredit = FALSE;
|
||||
public static bool $canUseAccountCredit = FALSE;
|
||||
|
||||
/**
|
||||
* On Paid
|
||||
*
|
||||
* @param \IPS\nexus\Invoice $invoice The invoice
|
||||
* @return void
|
||||
* @param Invoice $invoice The invoice
|
||||
* @return void
|
||||
*/
|
||||
public function onPaid( \IPS\nexus\Invoice $invoice )
|
||||
public function onPaid( Invoice $invoice ): void
|
||||
{
|
||||
try
|
||||
{
|
||||
$goal = \IPS\nexus\Donation\Goal::load( $this->id );
|
||||
$goalAmount = new \IPS\Math\Number( str_replace( \IPS\Member::loggedIn()->Language()->locale['decimal_point'], '.', (string) $goal->current ) );
|
||||
$goal = Goal::load( $this->id );
|
||||
$goalAmount = new Number( str_replace( Member::loggedIn()->Language()->locale['decimal_point'], '.', (string) $goal->current ) );
|
||||
$goalAmount = $goalAmount->add( $this->price->amount );
|
||||
$goal->current = (string) $goalAmount;
|
||||
|
||||
/* Have we reached the goal? */
|
||||
if( $goal->goal and !$goal->goal_reached and $goal->current >= $goal->goal )
|
||||
{
|
||||
$notification = new Notification( Application::load( 'core' ), 'donation_goal_reached', $goal, [ $goal ] );
|
||||
|
||||
foreach ( $goal->donors() as $member )
|
||||
{
|
||||
$notification->recipients->attach( $member );
|
||||
}
|
||||
$notification->send();
|
||||
|
||||
$goal->goal_reached = 1;
|
||||
}
|
||||
|
||||
$goal->save();
|
||||
|
||||
if( !$this->extra['anonymous'] )
|
||||
{
|
||||
$invoice->member->achievementAction( 'nexus', 'Donation', $goal );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
catch ( \Exception $e ) {}
|
||||
catch ( Exception ) {}
|
||||
|
||||
\IPS\Db::i()->insert( 'nexus_donate_logs', array(
|
||||
Db::i()->insert( 'nexus_donate_logs', array(
|
||||
'dl_goal' => $this->id,
|
||||
'dl_member' => $invoice->member->member_id,
|
||||
'dl_amount' => $this->price->amount,
|
||||
'dl_invoice'=> $invoice->id,
|
||||
'dl_date' => time()
|
||||
'dl_date' => time(),
|
||||
'dl_anon' => $this->extra['anonymous'],
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* On Unpaid
|
||||
*
|
||||
* @param \IPS\nexus\Invoice $invoice The invoice
|
||||
* @param Invoice $invoice The invoice
|
||||
* @param string $status Status
|
||||
* @return void
|
||||
* @return void
|
||||
*/
|
||||
public function onUnpaid( \IPS\nexus\Invoice $invoice, $status )
|
||||
public function onUnpaid( Invoice $invoice, string $status ): void
|
||||
{
|
||||
|
||||
}
|
||||
@@ -96,10 +134,10 @@ class _Donation extends \IPS\nexus\Invoice\Item\Charge
|
||||
* Requires Billing Address
|
||||
*
|
||||
* @return bool
|
||||
* @throws \DomainException
|
||||
* @throws DomainException
|
||||
*/
|
||||
public function requiresBillingAddress()
|
||||
public function requiresBillingAddress(): bool
|
||||
{
|
||||
return \in_array( 'donation', explode( ',', \IPS\Settings::i()->nexus_require_billing ) );
|
||||
return in_array( 'donation', explode( ',', Settings::i()->nexus_require_billing ) );
|
||||
}
|
||||
}
|
||||
@@ -12,77 +12,102 @@
|
||||
namespace IPS\nexus\extensions\nexus\Item;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DomainException;
|
||||
use InvalidArgumentException;
|
||||
use IPS\Email;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\Color;
|
||||
use IPS\Helpers\Form\Number;
|
||||
use IPS\Helpers\Form\Radio;
|
||||
use IPS\Helpers\Form\Text;
|
||||
use IPS\Helpers\Form\TextArea;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Gateway;
|
||||
use IPS\nexus\Invoice;
|
||||
use IPS\nexus\Money;
|
||||
use IPS\nexus\Purchase;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
use IPS\Settings;
|
||||
use IPS\Theme;
|
||||
use OutOfRangeException;
|
||||
use function chr;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
use function is_numeric;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gift Voucher
|
||||
*/
|
||||
class _GiftVoucher extends \IPS\nexus\Invoice\Item\Purchase
|
||||
class GiftVoucher extends Invoice\Item\Purchase
|
||||
{
|
||||
/**
|
||||
* @brief Application
|
||||
*/
|
||||
public static $application = 'nexus';
|
||||
public static string $application = 'nexus';
|
||||
|
||||
/**
|
||||
* @brief Application
|
||||
*/
|
||||
public static $type = 'giftvoucher';
|
||||
public static string $type = 'giftvoucher';
|
||||
|
||||
/**
|
||||
* @brief Icon
|
||||
*/
|
||||
public static $icon = 'gift';
|
||||
public static string $icon = 'gift';
|
||||
|
||||
/**
|
||||
* @brief Title
|
||||
*/
|
||||
public static $title = 'gift_voucher';
|
||||
public static string $title = 'gift_voucher';
|
||||
|
||||
/**
|
||||
* @brief Can use coupons?
|
||||
*/
|
||||
public static $canUseCoupons = FALSE;
|
||||
public static bool $canUseCoupons = FALSE;
|
||||
|
||||
/**
|
||||
* Get purchase from redeem code
|
||||
*
|
||||
* @param string $redemptionCode The redemption code
|
||||
* @return \IPS\nexus\Purchase
|
||||
* @throws \InvalidArgumentException
|
||||
* @return Purchase
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public static function getPurchase( $redemptionCode )
|
||||
public static function getPurchase( string $redemptionCode ) : Purchase
|
||||
{
|
||||
$exploded = explode( 'X', $redemptionCode );
|
||||
|
||||
if ( !isset( $exploded[0] ) or !\is_numeric( $exploded[0] ) )
|
||||
if ( !isset( $exploded[0] ) or !is_numeric( $exploded[0] ) )
|
||||
{
|
||||
throw new \InvalidArgumentException('BAD_FORMAT');
|
||||
throw new InvalidArgumentException('BAD_FORMAT');
|
||||
}
|
||||
try
|
||||
{
|
||||
$purchase = \IPS\nexus\Purchase::load( $exploded[0] );
|
||||
$purchase = Purchase::load( $exploded[0] );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
throw new \InvalidArgumentException('NO_PURCHASE');
|
||||
throw new InvalidArgumentException('NO_PURCHASE');
|
||||
}
|
||||
if ( $purchase->app != 'nexus' or $purchase->type != 'giftvoucher' )
|
||||
{
|
||||
throw new \InvalidArgumentException('BAD_PURCHASE');
|
||||
throw new InvalidArgumentException('BAD_PURCHASE');
|
||||
}
|
||||
if ( !$purchase->active or $purchase->cancelled )
|
||||
{
|
||||
throw new \InvalidArgumentException('CANCELED');
|
||||
throw new InvalidArgumentException('CANCELED');
|
||||
}
|
||||
$extra = $purchase->extra;
|
||||
if ( !isset( $extra['code'] ) or $redemptionCode !== "{$extra['code']}" )
|
||||
{
|
||||
throw new \InvalidArgumentException('BAD_CODE');
|
||||
throw new InvalidArgumentException('BAD_CODE');
|
||||
}
|
||||
|
||||
return $purchase;
|
||||
@@ -91,38 +116,39 @@ class _GiftVoucher extends \IPS\nexus\Invoice\Item\Purchase
|
||||
/**
|
||||
* Generate Invoice Form
|
||||
*
|
||||
* @param \IPS\Helpers\Form $form The form
|
||||
* @param \IPS\nexus\Invoice $invoice The invoice
|
||||
* @param Form $form The form
|
||||
* @param Invoice $invoice The invoice
|
||||
* @return void
|
||||
*/
|
||||
public static function form( \IPS\Helpers\Form $form, \IPS\nexus\Invoice $invoice )
|
||||
public static function form( Form $form, Invoice $invoice ) : void
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'gift_voucher_amount', 0, TRUE, array(), NULL, NULL, $invoice->currency ) );
|
||||
$form->add( new \IPS\Helpers\Form\Color( 'gift_voucher_color', '3b3b3b', FALSE ) );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'gift_voucher_method', 'print', TRUE, array( 'options' => array( 'email' => 'gift_voucher_email', 'print' => 'gift_voucher_print' ), 'toggles' => array( 'email' => array( 'gift_voucher_email' ) ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Email( 'gift_voucher_email', NULL, NULL, array(), function( $val )
|
||||
$form->add( new Number( 'gift_voucher_amount', 0, TRUE, array(), NULL, NULL, $invoice->currency ) );
|
||||
$form->add( new Color( 'gift_voucher_color', '3b3b3b', FALSE ) );
|
||||
$form->add( new Radio( 'gift_voucher_method', 'print', TRUE, array( 'options' => array( 'email' => 'gift_voucher_email', 'print' => 'gift_voucher_print' ), 'toggles' => array( 'email' => array( 'gift_voucher_email' ) ) ) ) );
|
||||
$form->add( new Form\Email( 'gift_voucher_email', NULL, NULL, array(), function($val )
|
||||
{
|
||||
if ( !$val and \IPS\Request::i()->gift_voucher_method === 'email' )
|
||||
if ( !$val and Request::i()->gift_voucher_method === 'email' )
|
||||
{
|
||||
throw new \DomainException('form_required');
|
||||
throw new DomainException('form_required');
|
||||
}
|
||||
}, NULL, NULL, 'gift_voucher_email' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'gift_voucher_recipient' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'gift_voucher_sender', $invoice->member->name ) );
|
||||
$form->add( new \IPS\Helpers\Form\TextArea( 'gift_voucher_message' ) );
|
||||
$form->add( new Text( 'gift_voucher_recipient' ) );
|
||||
$form->add( new Text( 'gift_voucher_sender', $invoice->member->name ) );
|
||||
$form->add( new TextArea( 'gift_voucher_message' ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create From Form
|
||||
*
|
||||
* @param array $values Values from form
|
||||
* @param \IPS\nexus\Invoice $invoice The invoice
|
||||
* @return \IPS\nexus\extensions\nexus\Item\MiscellaneousCharge
|
||||
* @param array $values Values from form
|
||||
* @param Invoice $invoice The invoice
|
||||
* @return GiftVoucher
|
||||
*/
|
||||
public static function createFromForm( array $values, \IPS\nexus\Invoice $invoice )
|
||||
public static function createFromForm( array $values, Invoice $invoice ): GiftVoucher
|
||||
{
|
||||
$item = new \IPS\nexus\extensions\nexus\Item\GiftVoucher( \IPS\Member::loggedIn()->language()->get('gift_voucher'), new \IPS\nexus\Money( $values['gift_voucher_amount'], $invoice->currency ) );
|
||||
$item->paymentMethodIds = array_keys( \IPS\nexus\Gateway::roots( NULL, NULL, array( 'm_active=1 AND m_gateway<>?', 'TwoCheckout' ) ) ); // It is against 2CO terms to use them for buying gift vouchers
|
||||
$item = new GiftVoucher( Member::loggedIn()->language()->get('gift_voucher'), new Money( $values['gift_voucher_amount'], $invoice->currency ) );
|
||||
$item->paymentMethodIds = array_keys( Gateway::roots( NULL, NULL, array( 'm_active=1' ) ) ); // It is against 2CO terms to use them for buying gift vouchers
|
||||
|
||||
$item->extra['method'] = $values['gift_voucher_method'];
|
||||
$item->extra['recipient_email'] = $values['gift_voucher_email'];
|
||||
$item->extra['recipient_name'] = $values['gift_voucher_recipient'];
|
||||
@@ -138,11 +164,11 @@ class _GiftVoucher extends \IPS\nexus\Invoice\Item\Purchase
|
||||
/**
|
||||
* On Purchase Generated
|
||||
*
|
||||
* @param \IPS\nexus\Purchase $purchase The purchase
|
||||
* @param \IPS\nexus\Invoice $invoice The invoice
|
||||
* @return void
|
||||
* @param Purchase $purchase The purchase
|
||||
* @param Invoice $invoice The invoice
|
||||
* @return void
|
||||
*/
|
||||
public static function onPurchaseGenerated( \IPS\nexus\Purchase $purchase, \IPS\nexus\Invoice $invoice )
|
||||
public static function onPurchaseGenerated( Purchase $purchase, Invoice $invoice ): void
|
||||
{
|
||||
/* Generate a redemption code */
|
||||
$code = "{$purchase->id}X{$purchase->member->member_id}X";
|
||||
@@ -152,8 +178,8 @@ class _GiftVoucher extends \IPS\nexus\Invoice\Item\Purchase
|
||||
{
|
||||
$chr = rand( 48, 90 );
|
||||
}
|
||||
while ( \in_array( $chr, array( 58, 59, 60, 61, 62, 63, 64, 88 ) ) );
|
||||
$code .= \chr( $chr );
|
||||
while ( in_array( $chr, array( 58, 59, 60, 61, 62, 63, 64, 88 ) ) );
|
||||
$code .= chr( $chr );
|
||||
}
|
||||
$extra = $purchase->extra;
|
||||
$extra['code'] = $code;
|
||||
@@ -163,49 +189,48 @@ class _GiftVoucher extends \IPS\nexus\Invoice\Item\Purchase
|
||||
/* Send the email */
|
||||
if ( $purchase->extra['method'] === 'email' )
|
||||
{
|
||||
\IPS\Email::buildFromTemplate( 'nexus', 'giftVoucher', array( $purchase->extra['recipient_name'], new \IPS\nexus\Money( $purchase->extra['amount'], $purchase->extra['currency'] ), $code, $purchase->extra['message'], $purchase->extra['sender'], $purchase->extra['color'] ), \IPS\Email::TYPE_TRANSACTIONAL )->send( $purchase->extra['recipient_email'] );
|
||||
Email::buildFromTemplate( 'nexus', 'giftVoucher', array( $purchase->extra['recipient_name'], new Money( $purchase->extra['amount'], $purchase->extra['currency'] ), $code, $purchase->extra['message'], $purchase->extra['sender'], $purchase->extra['color'] ), Email::TYPE_TRANSACTIONAL )->send( $purchase->extra['recipient_email'] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ACP Page HTML
|
||||
*
|
||||
* @param \IPS\nexus\Purchase $purchase The purchase
|
||||
* @return string
|
||||
* @param Purchase $purchase The purchase
|
||||
* @return string
|
||||
*/
|
||||
public static function acpPage( \IPS\nexus\Purchase $purchase )
|
||||
public static function acpPage( Purchase $purchase ): string
|
||||
{
|
||||
$extra = $purchase->extra;
|
||||
return \IPS\Theme::i()->getTemplate('purchases')->giftvoucher( $purchase, $extra );
|
||||
return (string) Theme::i()->getTemplate('purchases')->giftvoucher( $purchase, $extra );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Client Area Page HTML
|
||||
*
|
||||
* @param \IPS\nexus\Purchase $purchase The purchase
|
||||
* @return string
|
||||
* @param Purchase $purchase The purchase
|
||||
* @return array
|
||||
*/
|
||||
public static function clientAreaPage( \IPS\nexus\Purchase $purchase )
|
||||
public static function clientAreaPage( Purchase $purchase ): array
|
||||
{
|
||||
$extra = $purchase->extra;
|
||||
return array(
|
||||
'purchaseInfo' => \IPS\Theme::i()->getTemplate('purchases')->giftvoucher( $purchase, $extra )
|
||||
'purchaseInfo' => Theme::i()->getTemplate('purchases')->giftvoucher( $purchase, $extra )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Client Area Page HTML
|
||||
*
|
||||
* @param \IPS\nexus\Purchase $purchase The purchase
|
||||
* @return string
|
||||
* @param Purchase $purchase The purchase
|
||||
* @return void
|
||||
*/
|
||||
public static function clientAreaAction( \IPS\nexus\Purchase $purchase )
|
||||
public static function clientAreaAction( Purchase $purchase ): void
|
||||
{
|
||||
$extra = $purchase->extra;
|
||||
if ( $extra['method'] === 'print' )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'purchases' )->giftvoucherPrint( $extra ), 200, 'text/html' );
|
||||
return;
|
||||
Output::i()->sendOutput( Theme::i()->getTemplate( 'purchases' )->giftvoucherPrint( $extra ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,11 +238,11 @@ class _GiftVoucher extends \IPS\nexus\Invoice\Item\Purchase
|
||||
* Requires Billing Address
|
||||
*
|
||||
* @return bool
|
||||
* @throws \DomainException
|
||||
* @throws DomainException
|
||||
*/
|
||||
public function requiresBillingAddress()
|
||||
public function requiresBillingAddress(): bool
|
||||
{
|
||||
return \in_array( 'giftvoucher', explode( ',', \IPS\Settings::i()->nexus_require_billing ) );
|
||||
return in_array( 'giftvoucher', explode( ',', Settings::i()->nexus_require_billing ) );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,81 +12,80 @@
|
||||
namespace IPS\nexus\extensions\nexus\Item;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\Member;
|
||||
use IPS\Helpers\Form\Node;
|
||||
use IPS\Helpers\Form\Number;
|
||||
use IPS\Helpers\Form\Text;
|
||||
use IPS\Helpers\Form\YesNo;
|
||||
use IPS\nexus\Invoice;
|
||||
use IPS\nexus\Invoice\Item\Charge;
|
||||
use IPS\nexus\Money;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Miscellaneous Charge
|
||||
*/
|
||||
class _MiscellaneousCharge extends \IPS\nexus\Invoice\Item\Charge
|
||||
class MiscellaneousCharge extends Charge
|
||||
{
|
||||
/**
|
||||
* @brief Application
|
||||
*/
|
||||
public static $application = 'nexus';
|
||||
public static string $application = 'nexus';
|
||||
|
||||
/**
|
||||
* @brief Application
|
||||
*/
|
||||
public static $type = 'charge';
|
||||
public static string $type = 'charge';
|
||||
|
||||
/**
|
||||
* @brief Icon
|
||||
*/
|
||||
public static $icon = 'dollar';
|
||||
public static string $icon = 'dollar-sign';
|
||||
|
||||
/**
|
||||
* @brief Title
|
||||
*/
|
||||
public static $title = 'miscellaneous_charge';
|
||||
public static string $title = 'miscellaneous_charge';
|
||||
|
||||
/**
|
||||
* Generate Invoice Form
|
||||
*
|
||||
* @param \IPS\Helpers\Form $form The form
|
||||
* @param \IPS\nexus\Invoice $invoice The invoice
|
||||
* @param Form $form The form
|
||||
* @param Invoice $invoice The invoice
|
||||
* @return void
|
||||
*/
|
||||
public static function form( \IPS\Helpers\Form $form, \IPS\nexus\Invoice $invoice )
|
||||
public static function form( Form $form, Invoice $invoice ) : void
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'item_name', NULL, TRUE ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'item_net_price', 0, TRUE, array( 'decimals' => TRUE, 'min' => NULL ), NULL, NULL, $invoice->currency ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'item_tax_rate', 0, FALSE, array( 'class' => 'IPS\nexus\Tax', 'zeroVal' => 'item_tax_rate_none' ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'item_paymethods', 0, FALSE, array( 'class' => 'IPS\nexus\Gateway', 'multiple' => TRUE, 'zeroVal' => 'all' ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'item_physical', FALSE, FALSE, array( 'togglesOn' => array( 'item_weight', 'item_shipmethods' ) ) ) );
|
||||
$form->add( new \IPS\nexus\Form\Weight( 'item_weight', NULL, FALSE, array(), NULL, NULL, NULL, 'item_weight' ) );
|
||||
|
||||
$availableShippingMethods = array();
|
||||
foreach ( \IPS\nexus\Shipping\FlatRate::roots() as $rate )
|
||||
{
|
||||
$availableShippingMethods[ $rate->_id ] = $rate->_title;
|
||||
}
|
||||
if ( \IPS\Settings::i()->easypost_api_key and \IPS\Settings::i()->easypost_show_rates )
|
||||
{
|
||||
$availableShippingMethods['easypost'] = 'enhancements__nexus_EasyPost';
|
||||
}
|
||||
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'item_shipmethods', '*', FALSE, array( 'options' => $availableShippingMethods, 'multiple' => TRUE, 'unlimited' => '*', 'impliedUnlimited' => TRUE ), NULL, NULL, NULL, 'item_shipmethods' ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'item_pay_other', FALSE, FALSE, array( 'togglesOn' => array( 'item_pay_to', 'item_commission', 'item_fee' ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Member( 'item_pay_to', FALSE, FALSE, array(), NULL, NULL, NULL, 'item_pay_to' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'item_commission', FALSE, FALSE, array( 'min' => 0, 'max' => 100 ), NULL, NULL, '%', 'item_commission' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'item_fee', FALSE, FALSE, array(), NULL, NULL, $invoice->currency, 'item_fee' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'invoice_quantity', 1, FALSE, array( 'min' => 1 ) ) );
|
||||
$form->add( new Text( 'item_name', NULL, TRUE ) );
|
||||
$form->add( new Number( 'item_net_price', 0, TRUE, array( 'decimals' => TRUE, 'min' => NULL ), NULL, NULL, $invoice->currency ) );
|
||||
$form->add( new Node( 'item_tax_rate', 0, FALSE, array( 'class' => 'IPS\nexus\Tax', 'zeroVal' => 'item_tax_rate_none' ) ) );
|
||||
$form->add( new Node( 'item_paymethods', 0, FALSE, array( 'class' => 'IPS\nexus\Gateway', 'multiple' => TRUE, 'zeroVal' => 'all' ) ) );
|
||||
|
||||
$form->add( new YesNo( 'item_pay_other', FALSE, FALSE, array( 'togglesOn' => array( 'item_pay_to', 'item_commission', 'item_fee' ) ) ) );
|
||||
$form->add( new Member( 'item_pay_to', FALSE, FALSE, array(), NULL, NULL, NULL, 'item_pay_to' ) );
|
||||
$form->add( new Number( 'item_commission', FALSE, FALSE, array( 'min' => 0, 'max' => 100 ), NULL, NULL, '%', 'item_commission' ) );
|
||||
$form->add( new Number( 'item_fee', FALSE, FALSE, array(), NULL, NULL, $invoice->currency, 'item_fee' ) );
|
||||
$form->add( new Number( 'invoice_quantity', 1, FALSE, array( 'min' => 1 ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create From Form
|
||||
*
|
||||
* @param array $values Values from form
|
||||
* @param \IPS\nexus\Invoice $invoice The invoice
|
||||
* @return \IPS\nexus\extensions\nexus\Item\MiscellaneousCharge
|
||||
* @param Invoice $invoice The invoice
|
||||
* @return MiscellaneousCharge
|
||||
*/
|
||||
public static function createFromForm( array $values, \IPS\nexus\Invoice $invoice )
|
||||
public static function createFromForm( array $values, Invoice $invoice ): MiscellaneousCharge
|
||||
{
|
||||
$obj = new static( $values['item_name'], new \IPS\nexus\Money( $values['item_net_price'], $invoice->currency ) );
|
||||
$obj = new static( $values['item_name'], new Money( $values['item_net_price'], $invoice->currency ) );
|
||||
$obj->quantity = $values['invoice_quantity'];
|
||||
if ( $values['item_tax_rate'] )
|
||||
{
|
||||
@@ -96,20 +95,11 @@ class _MiscellaneousCharge extends \IPS\nexus\Invoice\Item\Charge
|
||||
{
|
||||
$obj->paymentMethodIds = array_keys( $values['item_paymethods'] );
|
||||
}
|
||||
if ( $values['item_physical'] )
|
||||
{
|
||||
$obj->physical = TRUE;
|
||||
$obj->weight = $values['item_weight'];
|
||||
if ( $values['item_shipmethods'] !== '*' )
|
||||
{
|
||||
$obj->shippingMethodIds = array_keys( $values['item_shipmethods'] );
|
||||
}
|
||||
}
|
||||
if ( $values['item_pay_other'] )
|
||||
{
|
||||
$obj->payTo = $values['item_pay_to'];
|
||||
$obj->commission = $values['item_commission'];
|
||||
$obj->fee = new \IPS\nexus\Money( $values['item_fee'], $invoice->currency );
|
||||
$obj->fee = new Money( $values['item_fee'], $invoice->currency );
|
||||
}
|
||||
return $obj;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,45 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Invoice Item Class for Shipping Charges
|
||||
* @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 20 Mar 2014
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\extensions\nexus\Item;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoice Item Class for Shipping Charges
|
||||
*/
|
||||
class _ShippingCharge extends \IPS\nexus\Invoice\Item\Charge
|
||||
{
|
||||
/**
|
||||
* @brief Application
|
||||
*/
|
||||
public static $application = 'nexus';
|
||||
|
||||
/**
|
||||
* @brief Application
|
||||
*/
|
||||
public static $type = 'shipping';
|
||||
|
||||
/**
|
||||
* @brief Icon
|
||||
*/
|
||||
public static $icon = 'truck';
|
||||
|
||||
/**
|
||||
* @brief Title
|
||||
*/
|
||||
public static $title = 'checkout_shipping';
|
||||
}
|
||||
Loaded 100 of 6736 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user