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
@@ -12,35 +12,40 @@
|
||||
namespace IPS\nexus\modules\admin\customers;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Node\Controller;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* fields
|
||||
*/
|
||||
class _fields extends \IPS\Node\Controller
|
||||
class fields extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
protected $nodeClass = 'IPS\nexus\Customer\CustomField';
|
||||
protected string $nodeClass = 'IPS\nexus\Customer\CustomField';
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'customer_fields_manage' );
|
||||
Dispatcher::i()->checkAcpPermission( 'customer_fields_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
}
|
||||
@@ -12,43 +12,78 @@
|
||||
namespace IPS\nexus\modules\admin\customers;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DateInterval;
|
||||
use DomainException;
|
||||
use Exception;
|
||||
use IPS\Db;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\Number;
|
||||
use IPS\Helpers\Form\Radio;
|
||||
use IPS\Helpers\Form\YesNo;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Invoice;
|
||||
use IPS\nexus\Invoice\Item\Renewal;
|
||||
use IPS\nexus\Money;
|
||||
use IPS\nexus\Package\CustomField;
|
||||
use IPS\nexus\Purchase;
|
||||
use IPS\nexus\Purchase\RenewalTerm;
|
||||
use IPS\nexus\Tax;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
use IPS\Session;
|
||||
use IPS\Theme;
|
||||
use LogicException;
|
||||
use OutOfRangeException;
|
||||
use function defined;
|
||||
use const IPS\Helpers\Table\SEARCH_DATE_RANGE;
|
||||
use const IPS\Helpers\Table\SEARCH_NUMERIC;
|
||||
use const IPS\Helpers\Table\SEARCH_SELECT;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Purchases
|
||||
*/
|
||||
class _purchases extends \IPS\Dispatcher\Controller
|
||||
class purchases extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* @var Purchase|null
|
||||
*/
|
||||
protected ?Purchase $purchase = null;
|
||||
|
||||
/**
|
||||
* View
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'purchases_view' );
|
||||
Dispatcher::i()->checkAcpPermission( 'purchases_view' );
|
||||
|
||||
try
|
||||
{
|
||||
$this->purchase = \IPS\nexus\Purchase::load( \IPS\Request::i()->id );
|
||||
$this->purchase = Purchase::load( Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X195/2', 404, '' );
|
||||
Output::i()->error( 'node_error', '2X195/2', 404, '' );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = $this->purchase->name . " (#{$this->purchase->id})";
|
||||
Output::i()->title = $this->purchase->name . " (#{$this->purchase->id})";
|
||||
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'purchases.css', 'nexus', 'admin' ) );
|
||||
Output::i()->cssFiles = array_merge( Output::i()->cssFiles, Theme::i()->css( 'purchases.css', 'nexus', 'admin' ) );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -57,7 +92,7 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
$this->view();
|
||||
}
|
||||
@@ -67,20 +102,20 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function view()
|
||||
protected function view() : void
|
||||
{
|
||||
/* Popup view */
|
||||
if ( \IPS\Request::i()->isAjax() and isset( \IPS\Request::i()->hovercard ) )
|
||||
if ( Request::i()->isAjax() and isset( Request::i()->hovercard ) )
|
||||
{
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'purchases' )->hovercard( $this->purchase );
|
||||
Output::i()->output = Theme::i()->getTemplate( 'purchases' )->hovercard( $this->purchase );
|
||||
return;
|
||||
}
|
||||
|
||||
/* Create children tree */
|
||||
$children = \IPS\nexus\Purchase::tree( $this->purchase->acpUrl(), array(), "p{$this->purchase->id}", $this->purchase, FALSE );
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
$children = Purchase::tree( $this->purchase->acpUrl(), array(), "p{$this->purchase->id}", $this->purchase, FALSE );
|
||||
if ( Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->output = $children;
|
||||
Output::i()->output = $children;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -90,12 +125,12 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
try
|
||||
{
|
||||
if ( $displayValue = trim( \IPS\nexus\Package\CustomField::load( $k )->displayValue( $v, TRUE ) ) )
|
||||
if ( $displayValue = trim( CustomField::load( $k )->displayValue( $v, TRUE ) ) )
|
||||
{
|
||||
$customFields[ $k ] = $displayValue;
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
catch ( OutOfRangeException ) { }
|
||||
}
|
||||
|
||||
/* Get customer */
|
||||
@@ -103,15 +138,15 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$customer = $this->purchase->member;
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
$customer = NULL;
|
||||
}
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->sidebar['actions'] = $this->purchase->buttons();
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'purchases' )->view( $this->purchase, $customer, $children, $customFields );
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'admin_members.js', 'core' ) );
|
||||
Output::i()->sidebar['actions'] = $this->purchase->buttons();
|
||||
Output::i()->output = Theme::i()->getTemplate( 'purchases' )->view( $this->purchase, $customer, $children, $customFields );
|
||||
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js( 'admin_members.js', 'core' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,28 +155,28 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
* @note This is lazy loaded after the purchase page is generated
|
||||
* @return void
|
||||
*/
|
||||
protected function showInvoices()
|
||||
protected function showInvoices() : void
|
||||
{
|
||||
/* Create associated invoices table */
|
||||
try
|
||||
{
|
||||
$originalInvoice = $this->purchase->original_invoice;
|
||||
$invoices = \IPS\nexus\Invoice::table( array( array( 'i_id=? OR ' . \IPS\Db::i()->findInSet( 'i_renewal_ids', array( $this->purchase->id ) ), $originalInvoice->id ) ), $this->purchase->acpUrl()->setQueryString( 'do', 'showInvoices' ), "p.{$this->purchase->id}" );
|
||||
$invoices = Invoice::table( array( array( 'i_id=? OR ' . Db::i()->findInSet( 'i_renewal_ids', array( $this->purchase->id ) ), $originalInvoice->id ) ), $this->purchase->acpUrl()->setQueryString( 'do', 'showInvoices' ), "p.{$this->purchase->id}" );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
$invoices = \IPS\nexus\Invoice::table( array( array( \IPS\Db::i()->findInSet( 'i_renewal_ids', array( $this->purchase->id ) ) ) ), $this->purchase->acpUrl()->setQueryString( 'do', 'showInvoices' ), "p.{$this->purchase->id}" );
|
||||
$invoices = Invoice::table( array( array( Db::i()->findInSet( 'i_renewal_ids', array( $this->purchase->id ) ) ) ), $this->purchase->acpUrl()->setQueryString( 'do', 'showInvoices' ), "p.{$this->purchase->id}" );
|
||||
}
|
||||
$invoices->filters = array(
|
||||
'paid' => array( 'i_status=?', \IPS\nexus\Invoice::STATUS_PAID )
|
||||
'paid' => array( 'i_status=?', Invoice::STATUS_PAID )
|
||||
);
|
||||
$invoices->advancedSearch = array(
|
||||
'i_status' => array( \IPS\Helpers\Table\SEARCH_SELECT, array( 'options' => \IPS\nexus\Invoice::statuses(), 'multiple' => TRUE ) ),
|
||||
'i_total' => \IPS\Helpers\Table\SEARCH_NUMERIC,
|
||||
'i_date' => \IPS\Helpers\Table\SEARCH_DATE_RANGE,
|
||||
'i_status' => array( SEARCH_SELECT, array( 'options' => Invoice::statuses(), 'multiple' => TRUE ) ),
|
||||
'i_total' => SEARCH_NUMERIC,
|
||||
'i_date' => SEARCH_DATE_RANGE,
|
||||
);
|
||||
|
||||
\IPS\Output::i()->output = (string) $invoices;
|
||||
Output::i()->output = (string) $invoices;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -149,14 +184,14 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function edit()
|
||||
protected function edit() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'purchases_edit' );
|
||||
Dispatcher::i()->checkAcpPermission( 'purchases_edit' );
|
||||
|
||||
/* Work stuff out */
|
||||
$renewals = $this->purchase->renewals ?: NULL;
|
||||
$groupedChildren = array();
|
||||
if ( $renewals and \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_parent=? AND ps_grouped_renewals<>? AND ps_cancelled=0', $this->purchase->id, '' ) )->first() )
|
||||
if ( $renewals and Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_parent=? AND ps_grouped_renewals<>? AND ps_cancelled=0', $this->purchase->id, '' ) )->first() )
|
||||
{
|
||||
$renewals = $this->purchase->renewals;
|
||||
foreach ( $this->purchase->children() as $child )
|
||||
@@ -173,23 +208,23 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
if( $this->purchase->tax )
|
||||
{
|
||||
$tax = \IPS\nexus\Tax::load( $this->purchase->tax );
|
||||
$tax = Tax::load( $this->purchase->tax );
|
||||
}
|
||||
}
|
||||
catch( \OutOfRangeException $e ){}
|
||||
catch( OutOfRangeException ){}
|
||||
|
||||
try
|
||||
{
|
||||
$childGroupedRenewalTerm = new \IPS\nexus\Purchase\RenewalTerm( new \IPS\nexus\Money( $childGroupedRenewals['price'], $this->purchase->renewals->cost->currency ), new \DateInterval( 'P' . $childGroupedRenewals['term'] . mb_strtoupper( $childGroupedRenewals['unit'] ) ), $tax );
|
||||
$renewals = new \IPS\nexus\Purchase\RenewalTerm( $renewals->subtract( $childGroupedRenewalTerm ), $renewals->interval );
|
||||
$childGroupedRenewalTerm = new RenewalTerm( new Money( $childGroupedRenewals['price'], $this->purchase->renewals->cost->currency ), new DateInterval( 'P' . $childGroupedRenewals['term'] . mb_strtoupper( $childGroupedRenewals['unit'] ) ), $tax );
|
||||
$renewals = new RenewalTerm( $renewals->subtract( $childGroupedRenewalTerm ), $renewals->interval );
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
catch ( Exception ) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Build form */
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form = new Form;
|
||||
$this->purchase->acpEdit( $form, $renewals );
|
||||
|
||||
/* Handle submissions */
|
||||
@@ -218,7 +253,7 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->output = $form;
|
||||
Output::i()->output = $form;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -226,21 +261,21 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function transfer()
|
||||
protected function transfer() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'purchases_transfer' );
|
||||
Dispatcher::i()->checkAcpPermission( 'purchases_transfer' );
|
||||
if ( $this->purchase->grouped_renewals )
|
||||
{
|
||||
\IPS\Output::i()->error( 'not_with_grouped', '2X195/6', 403, '' );
|
||||
Output::i()->error( 'not_with_grouped', '2X195/6', 403, '' );
|
||||
}
|
||||
if ( $this->purchase->billing_agreement and !$this->purchase->billing_agreement->canceled )
|
||||
{
|
||||
\IPS\Output::i()->error( 'not_with_billing_agreement', '2X195/G', 403, '' );
|
||||
Output::i()->error( 'not_with_billing_agreement', '2X195/G', 403, '' );
|
||||
}
|
||||
|
||||
/* Build form */
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\Member( 'ps_member', NULL, TRUE ) );
|
||||
$form = new Form;
|
||||
$form->add( new Form\Member( 'ps_member', NULL, TRUE ) );
|
||||
|
||||
/* Handle submissions */
|
||||
if ( $values = $form->values() )
|
||||
@@ -251,9 +286,9 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$this->purchase->transfer( $values['ps_member'] );
|
||||
}
|
||||
catch ( \DomainException $e )
|
||||
catch ( DomainException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( $e->getMessage(), '2X195/8', 403 );
|
||||
Output::i()->error( $e->getMessage(), '2X195/8', 403 );
|
||||
}
|
||||
|
||||
/* Log */
|
||||
@@ -265,7 +300,7 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->output = $form;
|
||||
Output::i()->output = $form;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -273,39 +308,39 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function renew()
|
||||
public function renew() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'invoices_add', 'nexus', 'payments' );
|
||||
Dispatcher::i()->checkAcpPermission( 'invoices_add', 'nexus', 'payments' );
|
||||
|
||||
if ( $this->purchase->grouped_renewals )
|
||||
{
|
||||
\IPS\Output::i()->error( 'not_with_grouped', '2X195/7', 403, '' );
|
||||
Output::i()->error( 'not_with_grouped', '2X195/7', 403, '' );
|
||||
}
|
||||
if ( $this->purchase->billing_agreement and !$this->purchase->billing_agreement->canceled )
|
||||
{
|
||||
\IPS\Output::i()->error( 'not_with_billing_agreement', '2X195/D', 403, '' );
|
||||
Output::i()->error( 'not_with_billing_agreement', '2X195/D', 403, '' );
|
||||
}
|
||||
|
||||
/* If this purchase has renewal term, we cannot generate a renewal invoice */
|
||||
if ( !$this->purchase->renewals )
|
||||
{
|
||||
\IPS\Output::i()->error( 'purchase_no_renew', '2X195/3', 403, '' );
|
||||
Output::i()->error( 'purchase_no_renew', '2X195/3', 403, '' );
|
||||
}
|
||||
|
||||
/* Build form */
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form = new Form;
|
||||
$cycles = $this->purchase->canRenewUntil( NULL, TRUE, TRUE );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'renew_cycles', 1, TRUE, array( 'min' => 1, 'max' => ( $cycles === TRUE ? NULL : $cycles ) ) ) );
|
||||
$form->add( new Number( 'renew_cycles', 1, TRUE, array( 'min' => 1, 'max' => ( $cycles === TRUE ? NULL : $cycles ) ) ) );
|
||||
|
||||
/* Handle submissions */
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
/* Generate Invoice */
|
||||
$invoice = new \IPS\nexus\Invoice;
|
||||
$invoice = new Invoice;
|
||||
$invoice->currency = $this->purchase->renewal_currency;
|
||||
$invoice->member = $this->purchase->member;
|
||||
$invoice->billaddress = $this->purchase->member->primaryBillingAddress();
|
||||
$invoice->addItem( \IPS\nexus\Invoice\Item\Renewal::create( $this->purchase, $values['renew_cycles'] ) );
|
||||
$invoice->addItem( Renewal::create( $this->purchase, $values['renew_cycles'] ) );
|
||||
$invoice->save();
|
||||
$invoice->sendNotification();
|
||||
|
||||
@@ -314,26 +349,26 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
$this->purchase->save();
|
||||
|
||||
/* Take us to that invoice */
|
||||
\IPS\Output::i()->redirect( $invoice->acpUrl() );
|
||||
Output::i()->redirect( $invoice->acpUrl() );
|
||||
}
|
||||
|
||||
/* If this purchase already has an unpaid renewal invoice, display a warning */
|
||||
if ( $this->purchase->invoice_pending )
|
||||
{
|
||||
/* Which will be a proper warning if that invoice is still pending */
|
||||
if ( $this->purchase->invoice_pending->status === \IPS\nexus\Invoice::STATUS_PENDING )
|
||||
if ( $this->purchase->invoice_pending->status === Invoice::STATUS_PENDING )
|
||||
{
|
||||
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'global', 'core' )->message( \IPS\Member::loggedIn()->language()->addToStack('warn_renew_invoice_pending', FALSE, array( 'sprintf' => array( $this->purchase->invoice_pending->acpUrl() ) ) ), 'warning', NULL, FALSE, TRUE );
|
||||
Output::i()->output .= Theme::i()->getTemplate( 'global', 'core' )->message( Member::loggedIn()->language()->addToStack('warn_renew_invoice_pending', FALSE, array( 'sprintf' => array( $this->purchase->invoice_pending->acpUrl() ) ) ), 'warning', NULL, FALSE, TRUE );
|
||||
}
|
||||
/* Or just informational if it is canceled or expired */
|
||||
elseif ( $this->purchase->invoice_pending->status !== \IPS\nexus\Invoice::STATUS_PAID )
|
||||
elseif ( $this->purchase->invoice_pending->status !== Invoice::STATUS_PAID )
|
||||
{
|
||||
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'global', 'core' )->message( \IPS\Member::loggedIn()->language()->addToStack('info_renew_invoice_pending', FALSE, array( 'sprintf' => array( $this->purchase->invoice_pending->acpUrl() ) ) ), 'information', NULL, FALSE, TRUE );
|
||||
Output::i()->output .= Theme::i()->getTemplate( 'global', 'core' )->message( Member::loggedIn()->language()->addToStack('info_renew_invoice_pending', FALSE, array( 'sprintf' => array( $this->purchase->invoice_pending->acpUrl() ) ) ), 'information', NULL, FALSE, TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->output .= $form;
|
||||
Output::i()->output .= $form;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -341,15 +376,15 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function cancel()
|
||||
protected function cancel() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'purchases_cancel' );
|
||||
Dispatcher::i()->checkAcpPermission( 'purchases_cancel' );
|
||||
|
||||
$parent = $this->purchase->parent();
|
||||
|
||||
if ( ( $this->purchase->billing_agreement and !$this->purchase->billing_agreement->canceled ) or ( $this->purchase->grouped_renewals and $parent->billing_agreement and !$parent->billing_agreement->canceled ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'not_with_billing_agreement', '2X195/H', 403, '' );
|
||||
Output::i()->error( 'not_with_billing_agreement', '2X195/H', 403, '' );
|
||||
}
|
||||
|
||||
/* What options are available for cancelling? */
|
||||
@@ -361,15 +396,15 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
$options['cancel'] = 'cancel_type_cancel';
|
||||
|
||||
/* Build form */
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'cancel_type', 'no_renew', FALSE, array(
|
||||
$form = new Form;
|
||||
$form->add( new Radio( 'cancel_type', 'no_renew', FALSE, array(
|
||||
'options' => $options,
|
||||
'toggles' => array( 'cancel' => array( 'form_cancel_type_warning' ) )
|
||||
) ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'ps_can_reactivate', FALSE ) );
|
||||
$form->add( new YesNo( 'ps_can_reactivate', FALSE ) );
|
||||
if ( $onCancelWarning = $this->purchase->onCancelWarning() )
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words['cancel_type_warning'] = $onCancelWarning;
|
||||
Member::loggedIn()->language()->words['cancel_type_warning'] = $onCancelWarning;
|
||||
}
|
||||
|
||||
/* Handle submissions */
|
||||
@@ -409,7 +444,7 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
/* Display form */
|
||||
\IPS\Output::i()->output = $form;
|
||||
Output::i()->output = $form;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -417,22 +452,22 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function reactivate()
|
||||
protected function reactivate() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'purchases_cancel' );
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Dispatcher::i()->checkAcpPermission( 'purchases_cancel' );
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
$error = NULL;
|
||||
if ( !$this->purchase->canAcpReactivate( $error ) )
|
||||
{
|
||||
\IPS\Output::i()->error( $error ?? 'can_not_reactivate', '2X195/K', 403, '' );
|
||||
Output::i()->error( $error ?? 'can_not_reactivate', '2X195/K', 403, '' );
|
||||
}
|
||||
|
||||
$parent = $this->purchase->parent();
|
||||
|
||||
if ( ( $this->purchase->billing_agreement and !$this->purchase->billing_agreement->canceled ) or ( $this->purchase->grouped_renewals and $parent->billing_agreement and !$parent->billing_agreement->canceled ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'not_with_billing_agreement', '2X195/I', 403, '' );
|
||||
Output::i()->error( 'not_with_billing_agreement', '2X195/I', 403, '' );
|
||||
}
|
||||
|
||||
/* If grouped, ungroup */
|
||||
@@ -464,16 +499,16 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function delete()
|
||||
protected function delete() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'purchases_delete' );
|
||||
\IPS\Request::i()->confirmedDelete();
|
||||
Dispatcher::i()->checkAcpPermission( 'purchases_delete' );
|
||||
Request::i()->confirmedDelete();
|
||||
|
||||
$parent = $this->purchase->parent();
|
||||
|
||||
if ( ( $this->purchase->billing_agreement and !$this->purchase->billing_agreement->canceled ) or ( $this->purchase->grouped_renewals and $parent->billing_agreement and !$parent->billing_agreement->canceled ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'not_with_billing_agreement', '2X195/J', 403, '' );
|
||||
Output::i()->error( 'not_with_billing_agreement', '2X195/J', 403, '' );
|
||||
}
|
||||
|
||||
if ( $this->purchase->grouped_renewals )
|
||||
@@ -487,11 +522,11 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
|
||||
if ( $parent )
|
||||
{
|
||||
\IPS\Output::i()->redirect( $parent->acpUrl() );
|
||||
Output::i()->redirect( $parent->acpUrl() );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->redirect( $this->purchase->member->acpUrl() );
|
||||
Output::i()->redirect( $this->purchase->member->acpUrl() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -500,15 +535,15 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function extra()
|
||||
protected function extra() : void
|
||||
{
|
||||
if ( $output = $this->purchase->acpAction() )
|
||||
{
|
||||
\IPS\Output::i()->output = $output;
|
||||
Output::i()->output = $output;
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->redirect( $this->purchase->acpUrl() );
|
||||
Output::i()->redirect( $this->purchase->acpUrl() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -517,14 +552,14 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function group()
|
||||
protected function group() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'purchases_edit' );
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Dispatcher::i()->checkAcpPermission( 'purchases_edit' );
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
if ( $this->purchase->billing_agreement and !$this->purchase->billing_agreement->canceled )
|
||||
{
|
||||
\IPS\Output::i()->error( 'not_with_billing_agreement', '2X195/E', 403, '' );
|
||||
Output::i()->error( 'not_with_billing_agreement', '2X195/E', 403, '' );
|
||||
}
|
||||
|
||||
try
|
||||
@@ -532,9 +567,9 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
$this->purchase->groupWithParent();
|
||||
$this->purchase->member->log( 'purchase', array( 'type' => 'group', 'id' => $this->purchase->id, 'name' => $this->purchase->name ) );
|
||||
}
|
||||
catch ( \LogicException $e )
|
||||
catch ( LogicException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'grouperr_' . $e->getMessage(), '1X195/4', 403, '' );
|
||||
Output::i()->error( 'grouperr_' . $e->getMessage(), '1X195/4', 403, '' );
|
||||
}
|
||||
$this->_redirect();
|
||||
}
|
||||
@@ -544,14 +579,14 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function ungroup()
|
||||
protected function ungroup() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'purchases_edit' );
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Dispatcher::i()->checkAcpPermission( 'purchases_edit' );
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
if ( $this->purchase->billing_agreement and !$this->purchase->billing_agreement->canceled )
|
||||
{
|
||||
\IPS\Output::i()->error( 'not_with_billing_agreement', '2X195/F', 403, '' );
|
||||
Output::i()->error( 'not_with_billing_agreement', '2X195/F', 403, '' );
|
||||
}
|
||||
|
||||
try
|
||||
@@ -559,9 +594,9 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
$this->purchase->ungroupFromParent();
|
||||
$this->purchase->member->log( 'purchase', array( 'type' => 'ungroup', 'id' => $this->purchase->id, 'name' => $this->purchase->name ) );
|
||||
}
|
||||
catch ( \LogicException $e )
|
||||
catch ( LogicException )
|
||||
{
|
||||
\IPS\Output::i()->error( '', '1X195/5', 403, '' );
|
||||
Output::i()->error( '', '1X195/5', 403, '' );
|
||||
}
|
||||
$this->_redirect();
|
||||
}
|
||||
@@ -571,37 +606,33 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function _redirect()
|
||||
protected function _redirect() : void
|
||||
{
|
||||
if ( isset( \IPS\Request::i()->r ) )
|
||||
if ( isset( Request::i()->r ) )
|
||||
{
|
||||
switch ( mb_substr( \IPS\Request::i()->r, 0, 1 ) )
|
||||
switch ( mb_substr( Request::i()->r, 0, 1 ) )
|
||||
{
|
||||
case 'p':
|
||||
try
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\nexus\Purchase::load( $this->purchase->parent )->acpUrl() );
|
||||
Output::i()->redirect( Purchase::load( $this->purchase->parent )->acpUrl() );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
\IPS\Output::i()->redirect( $this->purchase->member->acpUrl() );
|
||||
Output::i()->redirect( $this->purchase->member->acpUrl() );
|
||||
}
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
\IPS\Output::i()->redirect( $this->purchase->acpUrl() );
|
||||
Output::i()->redirect( $this->purchase->acpUrl() );
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
\IPS\Output::i()->redirect( $this->purchase->member->acpUrl() );
|
||||
break;
|
||||
|
||||
case 's':
|
||||
\IPS\Output::i()->redirect( \IPS\nexus\Support\Request::load( mb_substr( \IPS\Request::i()->r, 2 ) )->acpUrl() );
|
||||
Output::i()->redirect( $this->purchase->member->acpUrl() );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( $this->purchase->acpUrl() );
|
||||
Output::i()->redirect( $this->purchase->acpUrl() );
|
||||
}
|
||||
}
|
||||
@@ -12,30 +12,48 @@
|
||||
namespace IPS\nexus\modules\admin\customers;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\GeoLocation;
|
||||
use IPS\Helpers\Table\Db;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Customer\CustomField;
|
||||
use IPS\Output;
|
||||
use IPS\Theme;
|
||||
use function defined;
|
||||
use const IPS\Helpers\Table\SEARCH_BOOL;
|
||||
use const IPS\Helpers\Table\SEARCH_CONTAINS_TEXT;
|
||||
use const IPS\Helpers\Table\SEARCH_DATE_RANGE;
|
||||
use const IPS\Helpers\Table\SEARCH_MEMBER;
|
||||
use const IPS\Helpers\Table\SEARCH_NUMERIC;
|
||||
use const IPS\Helpers\Table\SEARCH_SELECT;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Customer Search
|
||||
*/
|
||||
class _search extends \IPS\Dispatcher\Controller
|
||||
class search extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'customers_view' );
|
||||
Dispatcher::i()->checkAcpPermission( 'customers_view' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -44,9 +62,9 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
$table = new \IPS\Helpers\Table\Db( 'core_members', \IPS\Http\Url::internal('app=nexus&module=customers&controller=search') );
|
||||
$table = new Db( 'core_members', Url::internal('app=nexus&module=customers&controller=search') );
|
||||
$table->langPrefix = 'customerTable_';
|
||||
$table->joins = array(
|
||||
array(
|
||||
@@ -64,11 +82,11 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
$table->parsers = array(
|
||||
'photo' => function( $val, $row )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate('customers')->rowPhoto( \IPS\Member::constructFromData( $row ) );
|
||||
return Theme::i()->getTemplate('customers')->rowPhoto( Member::constructFromData( $row ) );
|
||||
},
|
||||
'address' => function( $val )
|
||||
{
|
||||
return \IPS\GeoLocation::buildFromJson( $val );
|
||||
return $val ? GeoLocation::buildFromJson( $val ) : NULL;
|
||||
}
|
||||
);
|
||||
$table->noSort = array( 'photo', 'address' );
|
||||
@@ -76,44 +94,44 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
$table->rowClasses = array( 'address' => array( 'ipsTable_wrap' ) );
|
||||
|
||||
$table->advancedSearch = array(
|
||||
'cm_first_name' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT,
|
||||
'cm_last_name' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT,
|
||||
'email' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT,
|
||||
'name' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT
|
||||
'cm_first_name' => SEARCH_CONTAINS_TEXT,
|
||||
'cm_last_name' => SEARCH_CONTAINS_TEXT,
|
||||
'email' => SEARCH_CONTAINS_TEXT,
|
||||
'name' => SEARCH_CONTAINS_TEXT
|
||||
);
|
||||
foreach ( \IPS\nexus\Customer\CustomField::roots() as $field )
|
||||
foreach ( CustomField::roots() as $field )
|
||||
{
|
||||
switch ( $field->type )
|
||||
{
|
||||
case 'Checkbox':
|
||||
case 'YesNo':
|
||||
$table->advancedSearch[ $field->column ] = \IPS\Helpers\Table\SEARCH_BOOL;
|
||||
$table->advancedSearch[ $field->column ] = SEARCH_BOOL;
|
||||
break;
|
||||
|
||||
case 'CheckboxSet':
|
||||
case 'Select':
|
||||
case 'Radio':
|
||||
$table->advancedSearch[ $field->column ] = array( \IPS\Helpers\Table\SEARCH_SELECT, array( 'options' => json_decode( $field->extra ), 'multiple' => $field->multiple ) );
|
||||
$table->advancedSearch[ $field->column ] = array( SEARCH_SELECT, array( 'options' => json_decode( $field->extra ), 'multiple' => $field->multiple ) );
|
||||
break;
|
||||
|
||||
case 'Date':
|
||||
$table->advancedSearch[ $field->column ] = \IPS\Helpers\Table\SEARCH_DATE_RANGE;
|
||||
$table->advancedSearch[ $field->column ] = SEARCH_DATE_RANGE;
|
||||
break;
|
||||
|
||||
case 'Member':
|
||||
$table->advancedSearch[ $field->column ] = array( \IPS\Helpers\Table\SEARCH_MEMBER, array( 'multiple' => $field->multiple ) );
|
||||
$table->advancedSearch[ $field->column ] = array( SEARCH_MEMBER, array( 'multiple' => $field->multiple ) );
|
||||
break;
|
||||
|
||||
case 'Number':
|
||||
$table->advancedSearch[ $field->column ] = \IPS\Helpers\Table\SEARCH_NUMERIC;
|
||||
$table->advancedSearch[ $field->column ] = SEARCH_NUMERIC;
|
||||
break;
|
||||
|
||||
default:
|
||||
$table->advancedSearch[ $field->column ] = \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT;
|
||||
$table->advancedSearch[ $field->column ] = SEARCH_CONTAINS_TEXT;
|
||||
break;
|
||||
}
|
||||
|
||||
\IPS\Member::loggedIn()->language()->words[ 'customerTable_field_' . $field->id ] = $field->_title;
|
||||
Member::loggedIn()->language()->words[ 'customerTable_field_' . $field->id ] = $field->_title;
|
||||
|
||||
$table->parsers[ $field->column ] = array( $field, 'displayValue' );
|
||||
}
|
||||
@@ -124,12 +142,12 @@ class _search extends \IPS\Dispatcher\Controller
|
||||
'view' => array(
|
||||
'icon' => 'search',
|
||||
'title' => 'view',
|
||||
'link' => \IPS\Http\Url::internal("app=core&module=members&controller=members&do=view&tab=nexus_Main&id={$row['member_id']}"),
|
||||
'link' => Url::internal("app=core&module=members&controller=members&do=view&tab=nexus_Main&id={$row['member_id']}"),
|
||||
),
|
||||
);
|
||||
};
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__nexus_customers');
|
||||
\IPS\Output::i()->output = (string) $table;
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('menu__nexus_customers');
|
||||
Output::i()->output = (string) $table;
|
||||
}
|
||||
}
|
||||
@@ -12,59 +12,92 @@
|
||||
namespace IPS\nexus\modules\admin\customers;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DomainException;
|
||||
use Exception;
|
||||
use IPS\Db;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\File;
|
||||
use IPS\GeoLocation;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\Editor;
|
||||
use IPS\Helpers\Form\Node;
|
||||
use IPS\Helpers\Form\Text;
|
||||
use IPS\Helpers\Form\YesNo;
|
||||
use IPS\Helpers\MultipleRedirect;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Math\Number;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Customer;
|
||||
use IPS\nexus\Customer\Address;
|
||||
use IPS\nexus\Customer\AlternativeContact;
|
||||
use IPS\nexus\Customer\CreditCard;
|
||||
use IPS\nexus\Customer\CustomField;
|
||||
use IPS\nexus\Gateway;
|
||||
use IPS\nexus\Invoice;
|
||||
use IPS\nexus\Money;
|
||||
use IPS\nexus\Tax;
|
||||
use IPS\nexus\Transaction;
|
||||
use IPS\Output;
|
||||
use IPS\Patterns\ActiveRecordIterator;
|
||||
use IPS\Request;
|
||||
use IPS\Session;
|
||||
use IPS\Theme;
|
||||
use OutOfRangeException;
|
||||
use UnderflowException;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* View
|
||||
*/
|
||||
class _view extends \IPS\Dispatcher\Controller
|
||||
class view extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* @brief Member
|
||||
*/
|
||||
protected $member;
|
||||
protected Customer $member;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'customers_view' );
|
||||
Dispatcher::i()->checkAcpPermission( 'customers_view' );
|
||||
|
||||
try
|
||||
{
|
||||
$this->member = \IPS\nexus\Customer::load( \IPS\Request::i()->id );
|
||||
$this->member = Customer::load( Request::i()->id );
|
||||
if ( !$this->member->member_id )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
throw new OutOfRangeException;
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X233/1', 404, '' );
|
||||
Output::i()->error( 'node_error', '2X233/1', 404, '' );
|
||||
}
|
||||
|
||||
\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' ) );
|
||||
\IPS\Output::i()->title = "{$this->member->cm_name}";
|
||||
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' ) );
|
||||
Output::i()->title = "{$this->member->cm_name}";
|
||||
|
||||
parent::execute();
|
||||
}
|
||||
@@ -75,9 +108,9 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
* @return void
|
||||
* @deprecated
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
\IPS\Output::i()->redirect( $this->member->acpUrl() );
|
||||
Output::i()->redirect( $this->member->acpUrl() );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,37 +118,37 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function addresses()
|
||||
protected function addresses() : void
|
||||
{
|
||||
$addresses = new \IPS\Helpers\Table\Db( 'nexus_customer_addresses', \IPS\Http\Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( 'view', 'addresses' ), array( '`member`=?', $this->member->member_id ) );
|
||||
$addresses->sortBy = 'primary_billing, primary_shipping, added';
|
||||
$addresses->include = array( 'address', 'primary_billing', 'primary_shipping' );
|
||||
$addresses = new \IPS\Helpers\Table\Db( 'nexus_customer_addresses', Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( 'view', 'addresses' ), array( '`member`=?', $this->member->member_id ) );
|
||||
$addresses->sortBy = 'primary_billing, added';
|
||||
$addresses->include = array( 'address', 'primary_billing' );
|
||||
$addresses->parsers = array( 'address' => function( $val )
|
||||
{
|
||||
$address = \IPS\GeoLocation::buildFromJson( $val );
|
||||
return $address->toString( '<br>' ) . ( ( isset( $address->business ) and $address->business and isset( $address->vat ) and $address->vat ) ? ( '<br>' . \IPS\Member::loggedIn()->language()->addToStack('cm_checkout_vat_number') . ': ' .\IPS\Theme::i()->getTemplate( 'global', 'nexus' )->vatNumber( $address->vat ) ) : '' );
|
||||
$address = GeoLocation::buildFromJson( $val );
|
||||
return $address->toString( '<br>' ) . ( ( isset( $address->business ) and $address->business and isset( $address->vat ) and $address->vat ) ? ( '<br>' . Member::loggedIn()->language()->addToStack('cm_checkout_vat_number') . ': ' . Theme::i()->getTemplate( 'global', 'nexus' )->vatNumber( $address->vat ) ) : '' );
|
||||
} );
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customers_edit_details' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customers_edit_details' ) )
|
||||
{
|
||||
$addresses->rootButtons = array(
|
||||
'add' => array(
|
||||
'link' => \IPS\Http\Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( 'do', 'addressForm' ),
|
||||
'link' => Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( 'do', 'addressForm' ),
|
||||
'title' => 'add',
|
||||
'icon' => 'plus',
|
||||
'data' => array( 'ipsDialog' => true, 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('add_address') )
|
||||
'data' => array( 'ipsDialog' => true, 'ipsDialog-title' => Member::loggedIn()->language()->addToStack('add_address') )
|
||||
)
|
||||
);
|
||||
$addresses->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' => 'addressForm', 'address_id' => $row['id'] ) ),
|
||||
'link' => Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( array( 'do' => 'addressForm', 'address_id' => $row['id'] ) ),
|
||||
'title' => 'edit',
|
||||
'icon' => 'pencil',
|
||||
'data' => array( 'ipsDialog' => true, 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('edit_address') )
|
||||
'data' => array( 'ipsDialog' => true, 'ipsDialog-title' => Member::loggedIn()->language()->addToStack('edit_address') )
|
||||
),
|
||||
'delete' => array(
|
||||
'link' => \IPS\Http\Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( array( 'do' => 'deleteAddress', 'address_id' => $row['id'] ) ),
|
||||
'link' => Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( array( 'do' => 'deleteAddress', 'address_id' => $row['id'] ) ),
|
||||
'title' => 'delete',
|
||||
'icon' => 'times-circle',
|
||||
'data' => array( 'delete' => '' )
|
||||
@@ -124,9 +157,9 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
};
|
||||
}
|
||||
|
||||
$addresses->tableTemplate = array( \IPS\Theme::i()->getTemplate('customers'), 'addressTable' );
|
||||
$addresses->rowsTemplate = array( \IPS\Theme::i()->getTemplate('customers'), 'addressTableRows' );
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('customers')->customerPopup( $addresses );
|
||||
$addresses->tableTemplate = array( Theme::i()->getTemplate('customers'), 'addressTable' );
|
||||
$addresses->rowsTemplate = array( Theme::i()->getTemplate('customers'), 'addressTableRows' );
|
||||
Output::i()->output = Theme::i()->getTemplate('customers')->customerPopup( $addresses );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -134,17 +167,18 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function edit()
|
||||
public function edit() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'customers_edit_details' );
|
||||
Dispatcher::i()->checkAcpPermission( 'customers_edit_details' );
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form = new Form;
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'cm_first_name', $this->member->cm_first_name, FALSE ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'cm_last_name', $this->member->cm_last_name, FALSE ) );
|
||||
$form->add( new Text( 'cm_first_name', $this->member->cm_first_name, FALSE ) );
|
||||
$form->add( new Text( 'cm_last_name', $this->member->cm_last_name, FALSE ) );
|
||||
|
||||
foreach ( \IPS\nexus\Customer\CustomField::roots() as $field )
|
||||
foreach ( CustomField::roots() as $field )
|
||||
{
|
||||
/* @var CustomField $field */
|
||||
$column = $field->column;
|
||||
if ( $field->type === 'Editor' )
|
||||
{
|
||||
@@ -153,7 +187,7 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
$form->add( $field->buildHelper( $this->member->$column ) );
|
||||
}
|
||||
|
||||
if ( $values = $form->values( TRUE ) )
|
||||
if ( $values = $form->values(TRUE) )
|
||||
{
|
||||
$changes = array();
|
||||
foreach ( array( 'cm_first_name', 'cm_last_name' ) as $k )
|
||||
@@ -169,8 +203,9 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
$this->member->$k = $values[ $k ];
|
||||
}
|
||||
}
|
||||
foreach ( \IPS\nexus\Customer\CustomField::roots() as $field )
|
||||
foreach ( CustomField::roots() as $field )
|
||||
{
|
||||
/* @var CustomField $field */
|
||||
$column = $field->column;
|
||||
if ( $this->member->$column != $values["nexus_ccfield_{$field->id}"] )
|
||||
{
|
||||
@@ -188,10 +223,10 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
$this->member->log( 'info', $changes );
|
||||
}
|
||||
$this->member->save();
|
||||
\IPS\Output::i()->redirect( $this->member->acpUrl() );
|
||||
Output::i()->redirect( $this->member->acpUrl() );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = $form;
|
||||
Output::i()->output = $form;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -199,15 +234,15 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function credits()
|
||||
public function credits() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'customers_edit_credit' );
|
||||
Dispatcher::i()->checkAcpPermission( 'customers_edit_credit' );
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->class = 'ipsForm_vertical';
|
||||
foreach ( \IPS\nexus\Money::currencies() as $currency )
|
||||
$form = new Form;
|
||||
$form->class = 'ipsForm--vertical ipsForm--edit-credits';
|
||||
foreach ( Money::currencies() as $currency )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Number( $currency, isset( $this->member->cm_credits[ $currency ] ) ? $this->member->cm_credits[ $currency ]->amount : 0, FALSE, array( 'min' => 0, 'decimals' => \IPS\nexus\Money::numberOfDecimalsForCurrency( $currency ) ), NULL, NULL, $currency ) );
|
||||
$form->add( new Form\Number( $currency, isset( $this->member->cm_credits[ $currency ] ) ? $this->member->cm_credits[ $currency ]->amount : 0, FALSE, array( 'min' => 0, 'decimals' => Money::numberOfDecimalsForCurrency( $currency ) ), NULL, NULL, $currency ) );
|
||||
}
|
||||
|
||||
if ( $values = $form->values() )
|
||||
@@ -215,19 +250,19 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
$credits = $this->member->cm_credits;
|
||||
foreach ( $values as $currency => $amount )
|
||||
{
|
||||
$amount = new \IPS\Math\Number( number_format( $amount, \IPS\nexus\Money::numberOfDecimalsForCurrency( $currency ), '.', '' ) );
|
||||
$amount = new Number( number_format( $amount, Money::numberOfDecimalsForCurrency( $currency ), '.', '' ) );
|
||||
if ( ( isset( $this->member->cm_credits[ $currency ] ) and $this->member->cm_credits[ $currency ]->amount->compare( $amount ) !== 0 ) or $amount )
|
||||
{
|
||||
$this->member->log( 'comission', array( 'type' => 'manual', 'old' => isset( $this->member->cm_credits[ $currency ] ) ? $this->member->cm_credits[ $currency ]->amountAsString() : 0, 'new' => (string) $amount, 'currency' => $currency ) );
|
||||
}
|
||||
$credits[ $currency ] = new \IPS\nexus\Money( $amount, $currency );
|
||||
$credits[ $currency ] = new Money( $amount, $currency );
|
||||
}
|
||||
$this->member->cm_credits = $credits;
|
||||
$this->member->save();
|
||||
\IPS\Output::i()->redirect( $this->member->acpUrl() );
|
||||
Output::i()->redirect( $this->member->acpUrl() );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = (string) $form;
|
||||
Output::i()->output = (string) $form;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -235,31 +270,31 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function noteForm()
|
||||
public function noteForm() : void
|
||||
{
|
||||
$noteId = NULL;
|
||||
$note = NULL;
|
||||
if ( \IPS\Request::i()->note_id )
|
||||
if ( Request::i()->note_id )
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'customer_notes_edit' );
|
||||
$noteId = \intval( \IPS\Request::i()->note_id );
|
||||
Dispatcher::i()->checkAcpPermission( 'customer_notes_edit' );
|
||||
$noteId = intval( Request::i()->note_id );
|
||||
try
|
||||
{
|
||||
$note = \IPS\Db::i()->select( 'note_text', 'nexus_notes', array( 'note_id=?', \IPS\Request::i()->note_id ) )->first();
|
||||
$note = Db::i()->select( 'note_text', 'nexus_notes', array( 'note_id=?', Request::i()->note_id ) )->first();
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
catch ( UnderflowException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X233/3', 404, '' );
|
||||
Output::i()->error( 'node_error', '2X233/3', 404, '' );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'customer_notes_add' );
|
||||
Dispatcher::i()->checkAcpPermission( 'customer_notes_add' );
|
||||
}
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->class = 'ipsForm_vertical';
|
||||
$form->add( new \IPS\Helpers\Form\Editor( 'customer_note', $note, TRUE, array(
|
||||
$form = new Form;
|
||||
$form->class = 'ipsForm--vertical ipsForm--customer-notes';
|
||||
$form->add( new Editor( 'customer_note', $note, TRUE, array(
|
||||
'app' => 'nexus',
|
||||
'key' => 'Customer',
|
||||
'autoSaveKey' => $noteId ? "nexus-note-{$this->member->member_id}-{$noteId}" : "nexus-note-{$this->member->member_id}-new",
|
||||
@@ -267,39 +302,31 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
) ) );
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
if ( \IPS\Request::i()->note_id )
|
||||
if ( Request::i()->note_id )
|
||||
{
|
||||
\IPS\Db::i()->update( 'nexus_notes', array(
|
||||
Db::i()->update( 'nexus_notes', array(
|
||||
'note_text' => $values['customer_note']
|
||||
), array( 'note_id=?', \IPS\Request::i()->note_id ) );
|
||||
), array( 'note_id=?', Request::i()->note_id ) );
|
||||
|
||||
$this->member->log( 'note', 'edited' );
|
||||
}
|
||||
else
|
||||
{
|
||||
$noteId = \IPS\Db::i()->insert( 'nexus_notes', array(
|
||||
$noteId = Db::i()->insert( 'nexus_notes', array(
|
||||
'note_member' => $this->member->member_id,
|
||||
'note_text' => $values['customer_note'],
|
||||
'note_author' => \IPS\Member::loggedIn()->member_id,
|
||||
'note_author' => Member::loggedIn()->member_id,
|
||||
'note_date' => time(),
|
||||
) );
|
||||
|
||||
\IPS\File::claimAttachments( "nexus-note-{$this->member->member_id}-new", $this->member->member_id, $noteId, 'note' );
|
||||
File::claimAttachments( "nexus-note-{$this->member->member_id}-new", $this->member->member_id, $noteId, 'note' );
|
||||
|
||||
$this->member->log( 'note', 'added' );
|
||||
}
|
||||
|
||||
if ( isset( \IPS\Request::i()->support ) and \IPS\Request::i()->support )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\nexus\Support\Request::load( \IPS\Request::i()->support )->acpUrl() );
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) {}
|
||||
}
|
||||
\IPS\Output::i()->redirect( $this->member->acpUrl() );
|
||||
|
||||
Output::i()->redirect( $this->member->acpUrl() );
|
||||
}
|
||||
\IPS\Output::i()->output = $form;
|
||||
Output::i()->output = $form;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -307,25 +334,17 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function deleteNote()
|
||||
public function deleteNote() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'customer_notes_delete' );
|
||||
Dispatcher::i()->checkAcpPermission( 'customer_notes_delete' );
|
||||
|
||||
/* Make sure the user confirmed the deletion */
|
||||
\IPS\Request::i()->confirmedDelete();
|
||||
Request::i()->confirmedDelete();
|
||||
|
||||
\IPS\Db::i()->delete( 'nexus_notes', array( 'note_id=?', \IPS\Request::i()->note_id ) );
|
||||
Db::i()->delete( 'nexus_notes', array( 'note_id=?', Request::i()->note_id ) );
|
||||
$this->member->log( 'note', 'deleted' );
|
||||
|
||||
if ( isset( \IPS\Request::i()->support ) and \IPS\Request::i()->support )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\nexus\Support\Request::load( \IPS\Request::i()->support )->acpUrl() );
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) {}
|
||||
}
|
||||
\IPS\Output::i()->redirect( $this->member->acpUrl() );
|
||||
Output::i()->redirect( $this->member->acpUrl() );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -333,35 +352,34 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addressForm()
|
||||
public function addressForm() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'customers_edit_details' );
|
||||
Dispatcher::i()->checkAcpPermission( 'customers_edit_details' );
|
||||
|
||||
if ( \IPS\Request::i()->address_id )
|
||||
if ( Request::i()->address_id )
|
||||
{
|
||||
try
|
||||
{
|
||||
$address = \IPS\nexus\Customer\Address::load( \IPS\Request::i()->address_id );
|
||||
$address = Address::load( Request::i()->address_id );
|
||||
if ( $address->member !== $this->member )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
throw new OutOfRangeException;
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X233/2', 404, '' );
|
||||
Output::i()->error( 'node_error', '2X233/2', 404, '' );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$address = new \IPS\nexus\Customer\Address;
|
||||
$address = new Address;
|
||||
$address->member = $this->member;
|
||||
$address->primary_billing = ( \IPS\Db::i()->select( 'COUNT(*)', 'nexus_customer_addresses', array( '`member`=? AND primary_billing=1', $this->member->member_id ) )->first() == 0 );
|
||||
$address->primary_shipping = ( \IPS\Db::i()->select( 'COUNT(*)', 'nexus_customer_addresses', array( '`member`=? AND primary_shipping=1', $this->member->member_id ) )->first() == 0 );
|
||||
$address->primary_billing = ( Db::i()->select( 'COUNT(*)', 'nexus_customer_addresses', array( '`member`=? AND primary_billing=1', $this->member->member_id ) )->first() == 0 );
|
||||
}
|
||||
|
||||
$needTaxStatus = NULL;
|
||||
foreach ( \IPS\nexus\Tax::roots() as $tax )
|
||||
foreach ( Tax::roots() as $tax )
|
||||
{
|
||||
if ( $tax->type === 'eu' )
|
||||
{
|
||||
@@ -376,10 +394,9 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
$addressHelperClass = $needTaxStatus ? 'IPS\nexus\Form\BusinessAddress' : 'IPS\Helpers\Form\Address';
|
||||
$addressHelperOptions = ( $needTaxStatus === 'eu' ) ? array( 'vat' => TRUE ) : array();
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form = new Form;
|
||||
$form->add( new $addressHelperClass( 'address', $address->address, TRUE, $addressHelperOptions ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'primary_billing', $address->primary_billing ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'primary_shipping', $address->primary_shipping ) );
|
||||
$form->add( new YesNo( 'primary_billing', $address->primary_billing ) );
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
if ( $address->id )
|
||||
@@ -390,14 +407,9 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
if ( $values['primary_billing'] and !$address->primary_billing )
|
||||
{
|
||||
\IPS\Db::i()->update( 'nexus_customer_addresses', array( 'primary_billing' => 0 ), array( '`member`=?', $this->member->member_id ) );
|
||||
Db::i()->update( 'nexus_customer_addresses', array( 'primary_billing' => 0 ), array( '`member`=?', $this->member->member_id ) );
|
||||
$this->member->log( 'address', array( 'type' => 'primary_billing', 'details' => json_encode( $values['address'] ) ) );
|
||||
}
|
||||
if ( $values['primary_shipping'] and !$address->primary_shipping )
|
||||
{
|
||||
\IPS\Db::i()->update( 'nexus_customer_addresses', array( 'primary_shipping' => 0 ), array( '`member`=?', $this->member->member_id ) );
|
||||
$this->member->log( 'address', array( 'type' => 'primary_shipping', 'details' => json_encode( $values['address'] ) ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -406,12 +418,11 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
|
||||
$address->address = $values['address'];
|
||||
$address->primary_billing = $values['primary_billing'];
|
||||
$address->primary_shipping = $values['primary_shipping'];
|
||||
$address->save();
|
||||
|
||||
\IPS\Output::i()->redirect( $this->member->acpUrl() );
|
||||
Output::i()->redirect( $this->member->acpUrl() );
|
||||
}
|
||||
\IPS\Output::i()->output = $form;
|
||||
Output::i()->output = $form;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -419,21 +430,21 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function deleteAddress()
|
||||
public function deleteAddress() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'customers_edit_details' );
|
||||
Dispatcher::i()->checkAcpPermission( 'customers_edit_details' );
|
||||
|
||||
/* Make sure the user confirmed the deletion */
|
||||
\IPS\Request::i()->confirmedDelete();
|
||||
Request::i()->confirmedDelete();
|
||||
|
||||
try
|
||||
{
|
||||
$address = \IPS\nexus\Customer\Address::load( \IPS\Request::i()->address_id );
|
||||
$address = Address::load( Request::i()->address_id );
|
||||
$this->member->log( 'address', array( 'type' => 'delete', 'details' => json_encode( $address->address ) ) );
|
||||
$address->delete();
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
\IPS\Output::i()->redirect( $this->member->acpUrl() );
|
||||
catch ( OutOfRangeException ) { }
|
||||
Output::i()->redirect( $this->member->acpUrl() );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -442,18 +453,18 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
* @csrfChecked Uses Form helper in Gateway classes 7 Oct 2019
|
||||
* @return void
|
||||
*/
|
||||
public function addCard()
|
||||
public function addCard() : void
|
||||
{
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'global_gateways.js', 'nexus', 'global' ) );
|
||||
$form = \IPS\nexus\Customer\CreditCard::create( $this->member, TRUE );
|
||||
if ( $form instanceof \IPS\nexus\Customer\CreditCard )
|
||||
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js( 'global_gateways.js', 'nexus', 'global' ) );
|
||||
$form = CreditCard::create( $this->member, TRUE );
|
||||
if ( $form instanceof CreditCard )
|
||||
{
|
||||
$this->member->log( 'card', array( 'type' => 'add', 'number' => $form->card->lastFour ) );
|
||||
\IPS\Output::i()->redirect( $this->member->acpUrl() );
|
||||
Output::i()->redirect( $this->member->acpUrl() );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->output = $form;
|
||||
Output::i()->output = $form;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -462,19 +473,19 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function deleteCard()
|
||||
public function deleteCard() : void
|
||||
{
|
||||
/* Make sure the user confirmed the deletion */
|
||||
\IPS\Request::i()->confirmedDelete();
|
||||
Request::i()->confirmedDelete();
|
||||
|
||||
try
|
||||
{
|
||||
$card = \IPS\nexus\Customer\CreditCard::load( \IPS\Request::i()->card_id );
|
||||
$card = CreditCard::load( Request::i()->card_id );
|
||||
$this->member->log( 'card', array( 'type' => 'delete', 'number' => $card->card->lastFour ) );
|
||||
$card->delete();
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
\IPS\Output::i()->redirect( $this->member->acpUrl() );
|
||||
catch ( OutOfRangeException ) { }
|
||||
Output::i()->redirect( $this->member->acpUrl() );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -482,54 +493,52 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function alternativeContactForm()
|
||||
public function alternativeContactForm() : void
|
||||
{
|
||||
$existing = NULL;
|
||||
if ( isset( \IPS\Request::i()->alt_id ) )
|
||||
if ( isset( Request::i()->alt_id ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$existing = \IPS\nexus\Customer\AlternativeContact::constructFromData( \IPS\Db::i()->select( '*', 'nexus_alternate_contacts', array( 'main_id=? AND alt_id=?', $this->member->member_id, \IPS\Request::i()->alt_id ) )->first() );
|
||||
$existing = AlternativeContact::constructFromData( Db::i()->select( '*', 'nexus_alternate_contacts', array( 'main_id=? AND alt_id=?', $this->member->member_id, Request::i()->alt_id ) )->first() );
|
||||
}
|
||||
catch ( \UnderflowException $e ) {}
|
||||
catch ( UnderflowException ) {}
|
||||
}
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form = new Form;
|
||||
if ( !$existing )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Member( 'altcontact_member_admin', NULL, TRUE, array(), function( $val )
|
||||
$form->add( new Form\Member( 'altcontact_member_admin', NULL, TRUE, array(), function( $val )
|
||||
{
|
||||
if( $this->member->member_id === $val->member_id )
|
||||
{
|
||||
throw new \DomainException('altcontact_member_admin_self');
|
||||
throw new DomainException('altcontact_member_admin_self');
|
||||
}
|
||||
} ) );
|
||||
}
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'altcontact_purchases_admin', $existing ? iterator_to_array( $existing->purchases ) : NULL, FALSE, array( 'class' => 'IPS\nexus\Purchase', 'forceOwner' => $this->member, 'multiple' => TRUE ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'altcontact_support_admin', $existing ? $existing->support : FALSE ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'altcontact_billing_admin', $existing ? $existing->billing : FALSE ) );
|
||||
$form->add( new Node( 'altcontact_purchases_admin', $existing ? iterator_to_array( $existing->purchases ) : NULL, FALSE, array( 'class' => 'IPS\nexus\Purchase', 'forceOwner' => $this->member, 'multiple' => TRUE ) ) );
|
||||
$form->add( new YesNo( 'altcontact_billing_admin', $existing ? $existing->billing : FALSE ) );
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
if ( $existing )
|
||||
{
|
||||
$altContact = $existing;
|
||||
$this->member->log( 'alternative', array( 'type' => 'edit', 'alt_id' => $altContact->alt_id->member_id, 'alt_name' => $altContact->alt_id->name, 'purchases' => json_encode( $values['altcontact_purchases_admin'] ? $values['altcontact_purchases_admin'] : array() ), 'billing' => $values['altcontact_billing_admin'], 'support' => $values['altcontact_support_admin'] ) );
|
||||
$this->member->log( 'alternative', array( 'type' => 'edit', 'alt_id' => $altContact->alt_id->member_id, 'alt_name' => $altContact->alt_id->name, 'purchases' => json_encode( $values['altcontact_purchases_admin'] ?: array() ), 'billing' => $values['altcontact_billing_admin'] ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$altContact = new \IPS\nexus\Customer\AlternativeContact;
|
||||
$altContact = new AlternativeContact;
|
||||
$altContact->main_id = $this->member;
|
||||
$altContact->alt_id = $values['altcontact_member_admin'];
|
||||
$this->member->log( 'alternative', array( 'type' => 'add', 'alt_id' => $values['altcontact_member_admin']->member_id, 'alt_name' => $values['altcontact_member_admin']->name, 'purchases' => json_encode( $values['altcontact_purchases_admin'] ? $values['altcontact_purchases_admin'] : array() ), 'billing' => $values['altcontact_billing_admin'], 'support' => $values['altcontact_support_admin'] ) );
|
||||
$this->member->log( 'alternative', array( 'type' => 'add', 'alt_id' => $values['altcontact_member_admin']->member_id, 'alt_name' => $values['altcontact_member_admin']->name, 'purchases' => json_encode( $values['altcontact_purchases_admin'] ?: array() ), 'billing' => $values['altcontact_billing_admin'] ) );
|
||||
}
|
||||
$altContact->purchases = $values['altcontact_purchases_admin'] ? $values['altcontact_purchases_admin'] : array();
|
||||
$altContact->purchases = $values['altcontact_purchases_admin'] ?: array();
|
||||
$altContact->billing = $values['altcontact_billing_admin'];
|
||||
$altContact->support = $values['altcontact_support_admin'];
|
||||
$altContact->save();
|
||||
|
||||
\IPS\Output::i()->redirect( $this->member->acpUrl() );
|
||||
Output::i()->redirect( $this->member->acpUrl() );
|
||||
}
|
||||
\IPS\Output::i()->output = $form;
|
||||
Output::i()->output = $form;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -537,19 +546,19 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function deleteAlternativeContact()
|
||||
public function deleteAlternativeContact() : void
|
||||
{
|
||||
/* Make sure the user confirmed the deletion */
|
||||
\IPS\Request::i()->confirmedDelete();
|
||||
Request::i()->confirmedDelete();
|
||||
|
||||
try
|
||||
{
|
||||
$contact = \IPS\nexus\Customer\AlternativeContact::constructFromData( \IPS\Db::i()->select( '*', 'nexus_alternate_contacts', array( 'main_id=? AND alt_id=?', $this->member->member_id, \IPS\Request::i()->alt_id ) )->first() );
|
||||
$contact = AlternativeContact::constructFromData( Db::i()->select( '*', 'nexus_alternate_contacts', array( 'main_id=? AND alt_id=?', $this->member->member_id, Request::i()->alt_id ) )->first() );
|
||||
$this->member->log( 'alternative', array( 'type' => 'delete', 'alt_id' => $contact->alt_id->member_id, 'alt_name' => $contact->alt_id->name ) );
|
||||
$contact->delete();
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
\IPS\Output::i()->redirect( $this->member->acpUrl() );
|
||||
catch ( OutOfRangeException ) { }
|
||||
Output::i()->redirect( $this->member->acpUrl() );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -557,37 +566,36 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function void()
|
||||
public function void() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'customers_void' );
|
||||
Dispatcher::i()->checkAcpPermission( 'customers_void' );
|
||||
|
||||
if ( isset( \IPS\Request::i()->process ) )
|
||||
if ( isset( Request::i()->process ) )
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Session::i()->csrfCheck();
|
||||
$values = array(
|
||||
'void_refund_transactions' => \IPS\Request::i()->trans,
|
||||
'void_cancel_billing_agreements' => \IPS\Request::i()->ba,
|
||||
'void_cancel_purchases' => \IPS\Request::i()->purch,
|
||||
'void_refund_transactions' => Request::i()->trans,
|
||||
'void_cancel_billing_agreements' => Request::i()->ba,
|
||||
'void_cancel_purchases' => Request::i()->purch,
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$form = new \IPS\Helpers\Form( 'void_account', 'void_account' );
|
||||
$form = new Form( 'void_account', 'void_account' );
|
||||
$form->ajaxOutput = TRUE;
|
||||
$form->addMessage( 'void_account_warning' );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'void_refund_transactions', TRUE ) );
|
||||
if ( \IPS\nexus\Gateway::billingAgreementGateways() )
|
||||
$form->add( new YesNo( 'void_refund_transactions', TRUE ) );
|
||||
if ( Gateway::billingAgreementGateways() )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'void_cancel_billing_agreements', TRUE ) );
|
||||
$form->add( new YesNo( 'void_cancel_billing_agreements', TRUE ) );
|
||||
}
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'void_cancel_purchases', TRUE ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'void_cancel_invoices', TRUE ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'void_resolve_support', \IPS\Settings::i()->nexus_autoresolve_status, FALSE, array( 'class' => 'IPS\nexus\Support\Status', 'zeroVal' => 'do_not_change' ) ) );
|
||||
if ( $this->member->member_id != \IPS\Member::loggedIn()->member_id )
|
||||
$form->add( new YesNo( 'void_cancel_purchases', TRUE ) );
|
||||
$form->add( new YesNo( 'void_cancel_invoices', TRUE ) );
|
||||
if ( $this->member->member_id != Member::loggedIn()->member_id )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'void_ban_account', TRUE ) );
|
||||
$form->add( new YesNo( 'void_ban_account', TRUE ) );
|
||||
}
|
||||
$form->add( new \IPS\Helpers\Form\Editor( 'void_add_note', NULL, FALSE, array(
|
||||
$form->add( new Editor( 'void_add_note', NULL, FALSE, array(
|
||||
'app' => 'nexus',
|
||||
'key' => 'Customer',
|
||||
'autoSaveKey' => "nexus-note-{$this->member->member_id}-new",
|
||||
@@ -598,32 +606,28 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
if ( $values['void_cancel_invoices'] )
|
||||
{
|
||||
\IPS\Db::i()->update( 'nexus_invoices', array( 'i_status' => \IPS\nexus\Invoice::STATUS_CANCELED ), array( 'i_member=? AND i_status<>?', $this->member->member_id, \IPS\nexus\Invoice::STATUS_PAID ) );
|
||||
Db::i()->update( 'nexus_invoices', array( 'i_status' => Invoice::STATUS_CANCELED ), array( 'i_member=? AND i_status<>?', $this->member->member_id, Invoice::STATUS_PAID ) );
|
||||
}
|
||||
if ( $values['void_resolve_support'] )
|
||||
{
|
||||
\IPS\Db::i()->update( 'nexus_support_requests', array( 'r_status' => $values['void_resolve_support']->_id ), array( 'r_member=?', $this->member->member_id ) );
|
||||
}
|
||||
if ( $this->member->member_id != \IPS\Member::loggedIn()->member_id and $values['void_ban_account'] )
|
||||
if ( $this->member->member_id != Member::loggedIn()->member_id and $values['void_ban_account'] )
|
||||
{
|
||||
$this->member->temp_ban = -1;
|
||||
$this->member->save();
|
||||
}
|
||||
if ( $values['void_add_note'] )
|
||||
{
|
||||
$noteId = \IPS\Db::i()->insert( 'nexus_notes', array(
|
||||
$noteId = Db::i()->insert( 'nexus_notes', array(
|
||||
'note_member' => $this->member->member_id,
|
||||
'note_text' => $values['void_add_note'],
|
||||
'note_author' => \IPS\Member::loggedIn()->member_id,
|
||||
'note_author' => Member::loggedIn()->member_id,
|
||||
'note_date' => time(),
|
||||
) );
|
||||
|
||||
\IPS\File::claimAttachments( "nexus-note-{$this->member->member_id}-new", $this->member->id, $noteId, 'note' );
|
||||
File::claimAttachments( "nexus-note-{$this->member->member_id}-new", $this->member->id, $noteId, 'note' );
|
||||
}
|
||||
|
||||
if ( !$values['void_refund_transactions'] and !$values['void_cancel_purchases'] and !$values['void_cancel_billing_agreements'] )
|
||||
{
|
||||
\IPS\Output::i()->redirect( $this->member->acpUrl() );
|
||||
Output::i()->redirect( $this->member->acpUrl() );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -632,35 +636,36 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$member = $this->member;
|
||||
|
||||
\IPS\Output::i()->output = new \IPS\Helpers\MultipleRedirect( \IPS\Http\Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( array(
|
||||
Output::i()->output = new MultipleRedirect( Url::internal("app=nexus&module=customers&controller=view&id={$this->member->member_id}")->setQueryString( array(
|
||||
'do' => 'void',
|
||||
'process' => 1,
|
||||
'trans' => $values['void_refund_transactions'],
|
||||
'ba' => isset( $values['void_cancel_billing_agreements'] ) ? $values['void_cancel_billing_agreements'] : FALSE ,
|
||||
'ba' => $values['void_cancel_billing_agreements'] ?? FALSE,
|
||||
'purch' => $values['void_cancel_purchases'],
|
||||
) )->csrf(), function( $data ) use ( $member )
|
||||
{
|
||||
if ( !\is_array( $data ) )
|
||||
if ( !is_array( $data ) )
|
||||
{
|
||||
$data = array( 'trans' => 0, 'ba' => 0, 'purch' => 0, 'fail' => array() );
|
||||
}
|
||||
|
||||
$done = 0;
|
||||
|
||||
if ( \IPS\Request::i()->trans )
|
||||
if ( Request::i()->trans )
|
||||
{
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_transactions', array( 't_member=?', $member->member_id ), 't_id', array( $data['trans'], 10 ) ), 'IPS\nexus\Transaction' ) as $transaction )
|
||||
foreach ( new ActiveRecordIterator( Db::i()->select( '*', 'nexus_transactions', array( 't_member=?', $member->member_id ), 't_id', array( $data['trans'], 10 ) ), 'IPS\nexus\Transaction' ) as $transaction )
|
||||
{
|
||||
if ( \in_array( $transaction->status, array( $transaction::STATUS_PENDING, $transaction::STATUS_WAITING, $transaction::STATUS_GATEWAY_PENDING ) ) )
|
||||
/* @var Transaction $transaction */
|
||||
if ( in_array( $transaction->status, array( $transaction::STATUS_PENDING, $transaction::STATUS_WAITING, $transaction::STATUS_GATEWAY_PENDING ) ) )
|
||||
{
|
||||
$transaction->status = $transaction::STATUS_REVIEW;
|
||||
$transaction->save();
|
||||
}
|
||||
elseif ( \in_array( $transaction->status, array( $transaction::STATUS_PAID, $transaction::STATUS_HELD, $transaction::STATUS_REVIEW, $transaction::STATUS_PART_REFUNDED ) ) )
|
||||
elseif ( in_array( $transaction->status, array( $transaction::STATUS_PAID, $transaction::STATUS_HELD, $transaction::STATUS_REVIEW, $transaction::STATUS_PART_REFUNDED ) ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
if ( $transaction->auth and \in_array( $transaction->status, array( $transaction::STATUS_HELD, $transaction::STATUS_REVIEW ) ) )
|
||||
if ( $transaction->auth and in_array( $transaction->status, array( $transaction::STATUS_HELD, $transaction::STATUS_REVIEW ) ) )
|
||||
{
|
||||
$transaction->void();
|
||||
}
|
||||
@@ -669,9 +674,9 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
$transaction->refund();
|
||||
}
|
||||
|
||||
$transaction->invoice->markUnpaid( \IPS\nexus\Invoice::STATUS_CANCELED, \IPS\Member::loggedIn() );
|
||||
$transaction->invoice->markUnpaid( Invoice::STATUS_CANCELED, Member::loggedIn() );
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
catch ( Exception )
|
||||
{
|
||||
$data['fail'][] = $transaction->id;
|
||||
}
|
||||
@@ -681,33 +686,34 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
$done++;
|
||||
if ( $done >= 10 )
|
||||
{
|
||||
return array( $data, \IPS\Member::loggedIn()->language()->addToStack('processing') );
|
||||
return array( $data, Member::loggedIn()->language()->addToStack('processing') );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( \IPS\Request::i()->ba )
|
||||
if ( Request::i()->ba )
|
||||
{
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_billing_agreements', array( 'ba_member=?', $member->member_id ), 'ba_id', array( $data['ba'], 10 ) ), 'IPS\nexus\Customer\BillingAgreement' ) as $billingAgreement )
|
||||
foreach ( new ActiveRecordIterator( Db::i()->select( '*', 'nexus_billing_agreements', array( 'ba_member=?', $member->member_id ), 'ba_id', array( $data['ba'], 10 ) ), 'IPS\nexus\Customer\BillingAgreement' ) as $billingAgreement )
|
||||
{
|
||||
/* @var Customer\BillingAgreement $billingAgreement */
|
||||
try
|
||||
{
|
||||
$billingAgreement->cancel();
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
catch ( Exception ) { }
|
||||
|
||||
$data['ba']++;
|
||||
$done++;
|
||||
if ( $done >= 10 )
|
||||
{
|
||||
return array( $data, \IPS\Member::loggedIn()->language()->addToStack('processing') );
|
||||
return array( $data, Member::loggedIn()->language()->addToStack('processing') );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( \IPS\Request::i()->purch )
|
||||
if ( Request::i()->purch )
|
||||
{
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_purchases', array( 'ps_member=?', $member->member_id ), 'ps_id', array( $data['purch'], 10 ) ), 'IPS\nexus\Purchase' ) as $purchase )
|
||||
foreach ( new ActiveRecordIterator( Db::i()->select( '*', 'nexus_purchases', array( 'ps_member=?', $member->member_id ), 'ps_id', array( $data['purch'], 10 ) ), 'IPS\nexus\Purchase' ) as $purchase )
|
||||
{
|
||||
$purchase->cancelled = TRUE;
|
||||
$purchase->can_reactivate = FALSE;
|
||||
@@ -717,7 +723,7 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
$done++;
|
||||
if ( $done >= 10 )
|
||||
{
|
||||
return array( $data, \IPS\Member::loggedIn()->language()->addToStack('processing') );
|
||||
return array( $data, Member::loggedIn()->language()->addToStack('processing') );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -726,20 +732,19 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
return NULL;
|
||||
}, function() use ( $member )
|
||||
{
|
||||
if ( \count( $_SESSION['voidAccountFails'] ) )
|
||||
if ( count( $_SESSION['voidAccountFails'] ) )
|
||||
{
|
||||
\IPS\Output::i()->redirect( $member->acpUrl()->setQueryString( 'do', 'voidFails' ) );
|
||||
Output::i()->redirect( $member->acpUrl()->setQueryString( 'do', 'voidFails' ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->redirect( $member->acpUrl() );
|
||||
Output::i()->redirect( $member->acpUrl() );
|
||||
}
|
||||
} );
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->output = $form;
|
||||
Output::i()->output = $form;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -748,8 +753,8 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function voidFails()
|
||||
public function voidFails() : void
|
||||
{
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'customers' )->voidFails( $_SESSION['voidAccountFails'] );
|
||||
Output::i()->output = Theme::i()->getTemplate( 'customers' )->voidFails( $_SESSION['voidAccountFails'] );
|
||||
}
|
||||
}
|
||||
@@ -12,30 +12,47 @@
|
||||
namespace IPS\nexus\modules\admin\payments;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DomainException;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Customer\BillingAgreement;
|
||||
use IPS\nexus\Gateway\PayPal\Exception;
|
||||
use IPS\nexus\Purchase;
|
||||
use IPS\nexus\Transaction;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
use IPS\Session;
|
||||
use IPS\Theme;
|
||||
use OutOfRangeException;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Billing Agreements
|
||||
*/
|
||||
class _billingagreements extends \IPS\Dispatcher\Controller
|
||||
class billingagreements extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'billingagreements_view' );
|
||||
Dispatcher::i()->checkAcpPermission( 'billingagreements_view' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -44,12 +61,12 @@ class _billingagreements extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function manage()
|
||||
public function manage() : void
|
||||
{
|
||||
/* Load */
|
||||
try
|
||||
{
|
||||
$billingAgreement = \IPS\nexus\Customer\BillingAgreement::load( \IPS\Request::i()->id );
|
||||
$billingAgreement = BillingAgreement::load( Request::i()->id );
|
||||
|
||||
if ( !$billingAgreement->canceled and $billingAgreement->status() == $billingAgreement::STATUS_CANCELED )
|
||||
{
|
||||
@@ -58,13 +75,13 @@ class _billingagreements extends \IPS\Dispatcher\Controller
|
||||
$billingAgreement->save();
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X320/1', 404, '' );
|
||||
Output::i()->error( 'node_error', '2X320/1', 404, '' );
|
||||
}
|
||||
catch ( \IPS\nexus\Gateway\PayPal\Exception $e )
|
||||
catch ( Exception $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'billing_agreement_error_public', '4X320/9', 500, 'billing_agreement_error', array(), $e->getName() );
|
||||
Output::i()->error( 'billing_agreement_error_public', '4X320/9', 500, 'billing_agreement_error', array(), $e->getName() );
|
||||
}
|
||||
|
||||
/* Show */
|
||||
@@ -72,20 +89,20 @@ class _billingagreements extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
/* Purchases */
|
||||
$purchases = NULL;
|
||||
if( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'purchases_view' ) and ( !isset( \IPS\Request::i()->table ) ) )
|
||||
if( Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'purchases_view' ) and ( !isset( Request::i()->table ) ) )
|
||||
{
|
||||
$purchases = \IPS\nexus\Purchase::tree( $billingAgreement->acpUrl(), array( array( 'ps_billing_agreement=?', $billingAgreement->id ) ), 'ba' );
|
||||
$purchases = Purchase::tree( $billingAgreement->acpUrl(), array( array( 'ps_billing_agreement=?', $billingAgreement->id ) ), 'ba' );
|
||||
}
|
||||
|
||||
/* Transactions */
|
||||
$transactions = NULL;
|
||||
if( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'transactions_manage' ) and ( !isset( \IPS\Request::i()->table ) ) )
|
||||
if( Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'transactions_manage' ) and ( !isset( Request::i()->table ) ) )
|
||||
{
|
||||
$transactions = \IPS\nexus\Transaction::table( array( array( 't_billing_agreement=? AND t_status<>?', $billingAgreement->id, \IPS\nexus\Transaction::STATUS_PENDING ) ), $billingAgreement->acpUrl(), 'ba' );
|
||||
$transactions = Transaction::table( array( array( 't_billing_agreement=? AND t_status<>?', $billingAgreement->id, Transaction::STATUS_PENDING ) ), $billingAgreement->acpUrl(), 'ba' );
|
||||
$transactions->limit = 50;
|
||||
foreach ( $transactions->include as $k => $v )
|
||||
{
|
||||
if ( \in_array( $v, array( 't_method', 't_member' ) ) )
|
||||
if ( in_array( $v, array( 't_method', 't_member' ) ) )
|
||||
{
|
||||
unset( $transactions->include[ $k ] );
|
||||
}
|
||||
@@ -93,27 +110,27 @@ class _billingagreements extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
/* Action Buttons */
|
||||
if( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'billingagreements_manage' ) )
|
||||
if( Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'billingagreements_manage' ) )
|
||||
{
|
||||
if ( $billingAgreement->status() == $billingAgreement::STATUS_ACTIVE )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['actions']['refresh'] = array(
|
||||
Output::i()->sidebar['actions']['refresh'] = array(
|
||||
'icon' => 'refresh',
|
||||
'title' => 'billing_agreement_check',
|
||||
'link' => $billingAgreement->acpUrl()->setQueryString( array( 'do' => 'act', 'act' => 'refresh' ) )->csrf(),
|
||||
'data' => array( 'confirm' => '' )
|
||||
);
|
||||
|
||||
\IPS\Output::i()->sidebar['actions']['suspend'] = array(
|
||||
Output::i()->sidebar['actions']['suspend'] = array(
|
||||
'icon' => 'times',
|
||||
'title' => 'billing_agreement_suspend',
|
||||
'link' => $billingAgreement->acpUrl()->setQueryString( array( 'do' => 'act', 'act' => 'suspend' ) )->csrf(),
|
||||
'data' => array( 'confirm' => '', 'confirmSubMessage' => \IPS\Member::loggedIn()->language()->addToStack('billing_agreement_suspend_confirm') )
|
||||
'data' => array( 'confirm' => '', 'confirmSubMessage' => Member::loggedIn()->language()->addToStack('billing_agreement_suspend_confirm') )
|
||||
);
|
||||
}
|
||||
elseif ( $billingAgreement->status() == $billingAgreement::STATUS_SUSPENDED )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['actions']['reactivate'] = array(
|
||||
Output::i()->sidebar['actions']['reactivate'] = array(
|
||||
'icon' => 'check',
|
||||
'title' => 'billing_agreement_reactivate',
|
||||
'link' => $billingAgreement->acpUrl()->setQueryString( array( 'do' => 'act', 'act' => 'reactivate' ) )->csrf(),
|
||||
@@ -122,7 +139,7 @@ class _billingagreements extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
if ( $billingAgreement->status() != $billingAgreement::STATUS_CANCELED )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['actions']['cancel'] = array(
|
||||
Output::i()->sidebar['actions']['cancel'] = array(
|
||||
'icon' => 'times-circle',
|
||||
'title' => 'billing_agreement_cancel',
|
||||
'link' => $billingAgreement->acpUrl()->setQueryString( array( 'do' => 'act', 'act' => 'cancel' ) )->csrf(),
|
||||
@@ -131,16 +148,16 @@ class _billingagreements extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'billing_agreement_id', FALSE, array( 'sprintf' => array( $billingAgreement->gw_id ) ) );
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'billingagreements' )->view( $billingAgreement, $purchases, $transactions );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack( 'billing_agreement_id', FALSE, array( 'sprintf' => array( $billingAgreement->gw_id ) ) );
|
||||
Output::i()->output = Theme::i()->getTemplate( 'billingagreements' )->view( $billingAgreement, $purchases, $transactions );
|
||||
}
|
||||
catch ( \IPS\nexus\Gateway\PayPal\Exception $e )
|
||||
catch ( Exception $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'billing_agreement_error', '1X320/2', 500, '', array(), $e->getName() );
|
||||
Output::i()->error( 'billing_agreement_error', '1X320/2', 500, '', array(), $e->getName() );
|
||||
}
|
||||
catch ( \DomainException $e )
|
||||
catch ( DomainException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'billing_agreement_error', '1X320/3', 500 );
|
||||
Output::i()->error( 'billing_agreement_error', '1X320/3' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,18 +166,18 @@ class _billingagreements extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function reconcile()
|
||||
public function reconcile() : void
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
/* Load */
|
||||
try
|
||||
{
|
||||
$billingAgreement = \IPS\nexus\Customer\BillingAgreement::load( \IPS\Request::i()->id );
|
||||
$billingAgreement = BillingAgreement::load( Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X320/5', 404, '' );
|
||||
Output::i()->error( 'node_error', '2X320/5', 404, '' );
|
||||
}
|
||||
|
||||
/* Reconcile */
|
||||
@@ -169,15 +186,15 @@ class _billingagreements extends \IPS\Dispatcher\Controller
|
||||
$billingAgreement->next_cycle = $billingAgreement->nextPaymentDate();
|
||||
$billingAgreement->save();
|
||||
|
||||
\IPS\Output::i()->redirect( $billingAgreement->acpUrl() );
|
||||
Output::i()->redirect( $billingAgreement->acpUrl() );
|
||||
}
|
||||
catch ( \IPS\nexus\Gateway\PayPal\Exception $e )
|
||||
catch ( Exception $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'billing_agreement_error', '1X320/6', 500, '', array(), $e->getName() );
|
||||
Output::i()->error( 'billing_agreement_error', '1X320/6', 500, '', array(), $e->getName() );
|
||||
}
|
||||
catch ( \DomainException $e )
|
||||
catch ( DomainException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'billing_agreement_error', '1X320/7', 500 );
|
||||
Output::i()->error( 'billing_agreement_error', '1X320/7' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,25 +203,25 @@ class _billingagreements extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function act()
|
||||
public function act() : void
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
/* Check act */
|
||||
$act = \IPS\Request::i()->act;
|
||||
if ( !\in_array( $act, array( 'suspend', 'reactivate', 'cancel', 'refresh' ) ) )
|
||||
$act = Request::i()->act;
|
||||
if ( !in_array( $act, array( 'suspend', 'reactivate', 'cancel', 'refresh' ) ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '3X320/8', 403, '' );
|
||||
Output::i()->error( 'node_error', '3X320/8', 403, '' );
|
||||
}
|
||||
|
||||
/* Load */
|
||||
try
|
||||
{
|
||||
$billingAgreement = \IPS\nexus\Customer\BillingAgreement::load( \IPS\Request::i()->id );
|
||||
$billingAgreement = BillingAgreement::load( Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X320/8', 404, '' );
|
||||
Output::i()->error( 'node_error', '2X320/8', 404, '' );
|
||||
}
|
||||
|
||||
/* Perform Action */
|
||||
@@ -212,15 +229,15 @@ class _billingagreements extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$billingAgreement->$act();
|
||||
|
||||
\IPS\Output::i()->redirect( $billingAgreement->acpUrl() );
|
||||
Output::i()->redirect( $billingAgreement->acpUrl() );
|
||||
}
|
||||
catch ( \IPS\nexus\Gateway\PayPal\Exception $e )
|
||||
catch ( Exception $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'billing_agreement_error', '1X320/9', 500, '', array(), $e->getName() );
|
||||
Output::i()->error( 'billing_agreement_error', '1X320/9', 500, '', array(), $e->getName() );
|
||||
}
|
||||
catch ( \DomainException $e )
|
||||
catch ( DomainException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'billing_agreement_error', '1X320/A', 500 );
|
||||
Output::i()->error( 'billing_agreement_error', '1X320/A' );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,30 +12,47 @@
|
||||
namespace IPS\nexus\modules\admin\payments;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Db;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\CheckboxSet;
|
||||
use IPS\Helpers\Form\Radio;
|
||||
use IPS\Helpers\Form\YesNo;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Form\Money;
|
||||
use IPS\Output;
|
||||
use IPS\Session;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checkout Settings
|
||||
*/
|
||||
class _checkoutsettings extends \IPS\Dispatcher\Controller
|
||||
class checkoutsettings extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'checkout_settings' );
|
||||
Dispatcher::i()->checkAcpPermission( 'checkout_settings' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -44,32 +61,32 @@ class _checkoutsettings extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function manage()
|
||||
public function manage() : void
|
||||
{
|
||||
$requireBillingOptions = array();
|
||||
$requireBillingOptions['product'] = 'nexus_require_billing_package';
|
||||
if ( ( $giftVouchers = json_decode( \IPS\Settings::i()->nexus_gift_vouchers, TRUE ) and \count( $giftVouchers ) ) or \IPS\Settings::i()->nexus_gift_vouchers_free )
|
||||
if ( ( $giftVouchers = json_decode( Settings::i()->nexus_gift_vouchers, TRUE ) and count( $giftVouchers ) ) or Settings::i()->nexus_gift_vouchers_free )
|
||||
{
|
||||
$requireBillingOptions['giftvoucher'] = 'nexus_require_billing_gift';
|
||||
}
|
||||
if ( \IPS\Db::i()->select( 'COUNT(*)', 'nexus_donate_goals' )->first() )
|
||||
if ( Db::i()->select( 'COUNT(*)', 'nexus_donate_goals' )->first() )
|
||||
{
|
||||
$requireBillingOptions['donation'] = 'nexus_require_billing_donation';
|
||||
}
|
||||
|
||||
if ( \IPS\Settings::i()->nexus_subs_enabled and \IPS\Db::i()->select( 'COUNT(*)', 'nexus_member_subscription_packages' )->first() )
|
||||
if ( Settings::i()->nexus_subs_enabled and Db::i()->select( 'COUNT(*)', 'nexus_member_subscription_packages' )->first() )
|
||||
{
|
||||
$requireBillingOptions['subscriptions'] = 'nexus_require_billing_subscriptions';
|
||||
}
|
||||
|
||||
$requireBillingOptions['other'] = 'nexus_require_billing_other';
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form = new Form;
|
||||
$form->addHeader( 'checkout_settings' );
|
||||
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'nexus_require_billing', explode( ',', \IPS\Settings::i()->nexus_require_billing ), FALSE, array( 'options' => $requireBillingOptions ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_split_payments_on', \IPS\Settings::i()->nexus_split_payments != -1, FALSE, array( 'togglesOn' => array( 'nexus_split_payments' ) ) ) );
|
||||
$form->add( new \IPS\nexus\Form\Money( 'nexus_split_payments', \IPS\Settings::i()->nexus_split_payments ?: '*', FALSE, array( 'unlimitedLang' => 'no_restriction' ), NULL, NULL, NULL, 'nexus_split_payments' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'nexus_tac', \IPS\Settings::i()->nexus_tac, FALSE, array(
|
||||
$form->add( new CheckboxSet( 'nexus_require_billing', explode( ',', Settings::i()->nexus_require_billing ), FALSE, array( 'options' => $requireBillingOptions ) ) );
|
||||
$form->add( new YesNo( 'nexus_split_payments_on', Settings::i()->nexus_split_payments != -1, FALSE, array( 'togglesOn' => array( 'nexus_split_payments' ) ) ) );
|
||||
$form->add( new Money( 'nexus_split_payments', Settings::i()->nexus_split_payments ?: '*', FALSE, array( 'unlimitedLang' => 'no_restriction' ), NULL, NULL, NULL, 'nexus_split_payments' ) );
|
||||
$form->add( new Radio( 'nexus_tac', Settings::i()->nexus_tac, FALSE, array(
|
||||
'options' => array(
|
||||
'none' => 'nexus_tac_none',
|
||||
'button' => 'nexus_tac_button',
|
||||
@@ -80,26 +97,26 @@ class _checkoutsettings extends \IPS\Dispatcher\Controller
|
||||
'checkbox' => array( 'nexus_tac_link' )
|
||||
)
|
||||
) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Url( 'nexus_tac_link', \IPS\Settings::i()->nexus_tac_link, FALSE, array(), NULL, NULL, NULL, 'nexus_tac_link' ) );
|
||||
$form->add( new Form\Url( 'nexus_tac_link', Settings::i()->nexus_tac_link, FALSE, array(), NULL, NULL, NULL, 'nexus_tac_link' ) );
|
||||
$form->addHeader( 'nexus_checkreg' );
|
||||
$form->addMessage( 'nexus_checkreg_desc' );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_checkreg_usernames', \IPS\Settings::i()->nexus_checkreg_usernames ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_checkreg_captcha', \IPS\Settings::i()->nexus_checkreg_captcha ) );
|
||||
if ( \IPS\Settings::i()->reg_auth_type != 'none' )
|
||||
$form->add( new YesNo( 'nexus_checkreg_usernames', Settings::i()->nexus_checkreg_usernames ) );
|
||||
$form->add( new YesNo( 'nexus_checkreg_captcha', Settings::i()->nexus_checkreg_captcha ) );
|
||||
if ( Settings::i()->reg_auth_type != 'none' )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_checkreg_validate', \IPS\Settings::i()->nexus_checkreg_validate ) );
|
||||
$form->add( new YesNo( 'nexus_checkreg_validate', Settings::i()->nexus_checkreg_validate ) );
|
||||
}
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
$values['nexus_split_payments'] = $values['nexus_split_payments_on'] ? ( $values['nexus_split_payments'] == '*' ? 0 : json_encode( $values['nexus_split_payments'] ) ) : -1;
|
||||
unset( $values['nexus_split_payments_on'] );
|
||||
$values['nexus_require_billing'] = \count( $values['nexus_require_billing'] ) ? implode( ',', $values['nexus_require_billing'] ) : 'none';
|
||||
$values['nexus_require_billing'] = count( $values['nexus_require_billing'] ) ? implode( ',', $values['nexus_require_billing'] ) : 'none';
|
||||
$form->saveAsSettings( $values );
|
||||
|
||||
\IPS\Session::i()->log( 'acplogs__checkout_settings' );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=nexus&module=payments&controller=paymentsettings&tab=checkoutsettings' ) );
|
||||
Session::i()->log( 'acplogs__checkout_settings' );
|
||||
Output::i()->redirect( Url::internal( 'app=nexus&module=payments&controller=paymentsettings&tab=checkoutsettings' ) );
|
||||
}
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('checkout_settings');
|
||||
\IPS\Output::i()->output = $form;
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('checkout_settings');
|
||||
Output::i()->output = $form;
|
||||
}
|
||||
}
|
||||
@@ -13,34 +13,48 @@ namespace IPS\nexus\modules\admin\payments;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
|
||||
use IPS\Db;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\Helpers\Form\Checkbox;
|
||||
use IPS\Helpers\Form\Matrix;
|
||||
use IPS\Helpers\Form\Select;
|
||||
use IPS\Helpers\Form\Text;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Lang;
|
||||
use IPS\Member;
|
||||
use IPS\Output;
|
||||
use IPS\Session;
|
||||
use IPS\Settings;
|
||||
use IPS\Theme;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Currencies
|
||||
*/
|
||||
class _currencies extends \IPS\Dispatcher\Controller
|
||||
class currencies extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'currencies_manage' );
|
||||
Dispatcher::i()->checkAcpPermission( 'currencies_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -49,23 +63,23 @@ class _currencies extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function manage()
|
||||
public function manage() : void
|
||||
{
|
||||
$languages = \IPS\Lang::languages();
|
||||
$languages = Lang::languages();
|
||||
|
||||
$matrix = new \IPS\Helpers\Form\Matrix;
|
||||
$matrix = new Matrix;
|
||||
$matrix->squashFields = FALSE; // This has issues with select fields
|
||||
$matrix->langPrefix = 'currency_';
|
||||
$matrix->columns = array(
|
||||
'code' => function( $key, $value, $data )
|
||||
{
|
||||
return new \IPS\Helpers\Form\Text( $key, $value, FALSE, array( 'minLength' => 3, 'maxLength' => 3, 'placeholder' => 'USD' ) );
|
||||
return new Text( $key, $value, FALSE, array( 'minLength' => 3, 'maxLength' => 3, 'placeholder' => 'USD' ) );
|
||||
},
|
||||
'default' => function( $key, $value, $data ) use ( $languages )
|
||||
{
|
||||
if ( \count( $languages ) === 1 )
|
||||
if ( count( $languages ) === 1 )
|
||||
{
|
||||
return new \IPS\Helpers\Form\Checkbox( $key, $value );
|
||||
return new Checkbox( $key, $value );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -75,13 +89,13 @@ class _currencies extends \IPS\Dispatcher\Controller
|
||||
$options[ $v->id ] = $v->_title;
|
||||
}
|
||||
|
||||
return new \IPS\Helpers\Form\Select( $key, $value, FALSE, array( 'options' => $options, 'multiple' => TRUE ) );
|
||||
return new Select( $key, $value, FALSE, array( 'options' => $options, 'multiple' => TRUE ) );
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$warnings = '';
|
||||
if ( $currencies = json_decode( \IPS\Settings::i()->nexus_currency, TRUE ) )
|
||||
if ( $currencies = json_decode( Settings::i()->nexus_currency, TRUE ) )
|
||||
{
|
||||
foreach ( $currencies as $code => $defaults )
|
||||
{
|
||||
@@ -92,124 +106,63 @@ class _currencies extends \IPS\Dispatcher\Controller
|
||||
|
||||
if ( !in_array( $code, array( 'AED', 'AFN', 'ALL', 'AMD', 'ANG', 'AOA', 'ARS', 'AUD', 'AWG', 'AZN', 'BAM', 'BBD', 'BDT', 'BGN', 'BHD', 'BIF', 'BMD', 'BND', 'BOB', 'BRL', 'BSD', 'BTN', 'BWP', 'BYN', 'BYR', 'BZD', 'CAD', 'CDF', 'CHF', 'CLF', 'CLP', 'CNY', 'COP', 'CRC', 'CUC', 'CUP', 'CVE', 'CZK', 'DJF', 'DKK', 'DOP', 'DZD', 'EGP', 'ERN', 'ETB', 'EUR', 'FJD', 'FKP', 'GBP', 'GEL', 'GGP', 'GHS', 'GIP', 'GMD', 'GNF', 'GTQ', 'GYD', 'HKD', 'HNL', 'HRK', 'HTG', 'HUF', 'IDR', 'ILS', 'IMP', 'INR', 'IQD', 'IRR', 'ISK', 'JEP', 'JMD', 'JOD', 'JPY', 'KES', 'KGS', 'KHR', 'KMF', 'KPW', 'KRW', 'KWD', 'KYD', 'KZT', 'LAK', 'LBP', 'LKR', 'LRD', 'LSL', 'LYD', 'MAD', 'MDL', 'MGA', 'MKD', 'MMK', 'MNT', 'MOP', 'MRO', 'MUR', 'MVR', 'MWK', 'MXN', 'MYR', 'MZN', 'NAD', 'NGN', 'NIO', 'NOK', 'NPR', 'NZD', 'OMR', 'PAB', 'PEN', 'PGK', 'PHP', 'PKR', 'PLN', 'PYG', 'QAR', 'RON', 'RSD', 'RUB', 'RWF', 'SAR', 'SBD', 'SCR', 'SDG', 'SEK', 'SGD', 'SHP', 'SLL', 'SOS', 'SPL*', 'SRD', 'STD', 'SVC', 'SYP', 'SZL', 'THB', 'TJS', 'TMT', 'TND', 'TOP', 'TRY', 'TTD', 'TVD', 'TWD', 'TZS', 'UAH', 'UGX', 'USD', 'UYU', 'UZS', 'VEF', 'VND', 'VUV', 'WST', 'XAF', 'XCD', 'XDR', 'XOF', 'XPF', 'YER', 'ZAR', 'ZMW', 'ZWD' ) ) )
|
||||
{
|
||||
$warnings .= \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->message( \IPS\Member::loggedIn()->language()->addToStack( 'currency_code_invalid', FALSE, array( 'sprintf' => array( $code ) ) ), 'warning' );
|
||||
$warnings .= Theme::i()->getTemplate( 'global', 'core', 'global' )->message( Member::loggedIn()->language()->addToStack( 'currency_code_invalid', FALSE, array( 'sprintf' => array( $code ) ) ), 'warning' );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$matrix->rows[] = array(
|
||||
'code' => \IPS\Settings::i()->nexus_currency,
|
||||
'default' => \count( $languages ) === 1 ? TRUE : array_keys( $languages )
|
||||
'code' => Settings::i()->nexus_currency,
|
||||
'default' => count( $languages ) === 1 ? TRUE : array_keys( $languages )
|
||||
);
|
||||
}
|
||||
|
||||
$currencies = json_decode( \IPS\Settings::i()->nexus_currency, true );
|
||||
if( empty( $currencies ) )
|
||||
{
|
||||
$currencies = \IPS\Settings::i()->nexus_currency;
|
||||
}
|
||||
$errors = $this->_checkCurrencies( $currencies );
|
||||
|
||||
|
||||
if ( $values = $matrix->values() )
|
||||
{
|
||||
$save = array();
|
||||
|
||||
$definition = \IPS\Db::i()->getTableDefinition( 'nexus_package_base_prices' );
|
||||
/* @var array $definition */
|
||||
$definition = Db::i()->getTableDefinition( 'nexus_package_base_prices' );
|
||||
|
||||
foreach ( $values as $data )
|
||||
{
|
||||
if ( $data['code'] )
|
||||
{
|
||||
$save[ $data['code'] ] = ( \count( $languages ) === 1 ) ? ( $data['default'] ? array_keys( $languages ) : array() ) : $data['default'];
|
||||
$save[ $data['code'] ] = ( count( $languages ) === 1 ) ? ( $data['default'] ? array_keys( $languages ) : array() ) : $data['default'];
|
||||
|
||||
/* Add the column if it doesn't exist */
|
||||
if ( !isset( $definition['columns'][ $data['code'] ] ) )
|
||||
{
|
||||
\IPS\Db::i()->addColumn( 'nexus_package_base_prices', array(
|
||||
Db::i()->addColumn( 'nexus_package_base_prices', array(
|
||||
'name' => $data['code'],
|
||||
'type' => 'FLOAT'
|
||||
) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Settings::i()->changeValues( array( 'nexus_currency' => json_encode( $save ) ) );
|
||||
|
||||
/* Sanity check the final result */
|
||||
$errors = $this->_checkCurrencies( $save );
|
||||
if( !$errors )
|
||||
foreach ( $definition['columns'] AS $key => $value )
|
||||
{
|
||||
\IPS\Settings::i()->changeValues( array( 'nexus_currency' => json_encode( $save ) ) );
|
||||
|
||||
foreach ( $definition['columns'] AS $key => $value )
|
||||
if ( $key === 'id' )
|
||||
{
|
||||
if ( $key === 'id' )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !isset( $save[$key] ) )
|
||||
{
|
||||
\IPS\Db::i()->dropColumn( 'nexus_package_base_prices', $key );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
\IPS\Session::i()->log( 'acplogs__currencies' );
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=nexus&module=payments&controller=paymentsettings&tab=currencies' ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Clear the elements from the matrix so that they are forced to rebuild.
|
||||
Otherwise, it hides the last row in the table */
|
||||
$matrix->elements = null;
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = $errors . $matrix . $warnings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanity check on currency settings
|
||||
*
|
||||
* @param array|string $values
|
||||
* @return string
|
||||
*/
|
||||
protected function _checkCurrencies( array|string $values ) : string
|
||||
{
|
||||
$errors = '';
|
||||
|
||||
/* If we have a string here, then we're good to go, we only have one currency */
|
||||
if( \is_string( $values ) )
|
||||
{
|
||||
return $errors;
|
||||
}
|
||||
|
||||
$languages = Lang::languages();
|
||||
|
||||
foreach( array_keys( $languages ) as $langId )
|
||||
{
|
||||
$langUsed = 0;
|
||||
foreach( $values as $code => $defaults )
|
||||
{
|
||||
if( in_array( $langId, $defaults ) )
|
||||
|
||||
if ( !isset( $save[$key] ) )
|
||||
{
|
||||
$langUsed++;
|
||||
Db::i()->dropColumn( 'nexus_package_base_prices', $key );
|
||||
}
|
||||
}
|
||||
|
||||
/* If the language doesn't have a default, throw an error */
|
||||
if( !$langUsed )
|
||||
{
|
||||
$errors .= \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->message( \IPS\Member::loggedIn()->language()->addToStack( 'currency_code_lang_missing', FALSE, array( 'sprintf' => array( $languages[ $langId ]->_title ) ) ), 'error' );
|
||||
}
|
||||
|
||||
/* A language can't have more than one default */
|
||||
if( $langUsed > 1 )
|
||||
{
|
||||
$errors .= \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->message( \IPS\Member::loggedIn()->language()->addToStack( 'currency_code_multiple_default', false, array( 'sprintf' => array( $languages[ $langId ]->_title ) ) ), 'error' );
|
||||
}
|
||||
|
||||
Session::i()->log( 'acplogs__currencies' );
|
||||
|
||||
Output::i()->redirect( Url::internal( 'app=nexus&module=payments&controller=paymentsettings&tab=currencies' ) );
|
||||
}
|
||||
|
||||
return $errors;
|
||||
|
||||
Output::i()->output = $matrix . $warnings;
|
||||
}
|
||||
}
|
||||
@@ -12,35 +12,40 @@
|
||||
namespace IPS\nexus\modules\admin\payments;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Node\Controller;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* donations
|
||||
*/
|
||||
class _donationgoals extends \IPS\Node\Controller
|
||||
class donationgoals extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
protected $nodeClass = 'IPS\nexus\Donation\Goal';
|
||||
protected string $nodeClass = 'IPS\nexus\Donation\Goal';
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'donationgoals_manage' );
|
||||
Dispatcher::i()->checkAcpPermission( 'donationgoals_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
}
|
||||
@@ -12,30 +12,53 @@
|
||||
namespace IPS\nexus\modules\admin\payments;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use Exception;
|
||||
use IPS\Application;
|
||||
use IPS\DateTime;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\Helpers\Table\Db;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Donation\Goal;
|
||||
use IPS\nexus\Invoice;
|
||||
use IPS\nexus\Money;
|
||||
use IPS\Output;
|
||||
use IPS\Theme;
|
||||
use IPS\Widget;
|
||||
use OutOfRangeException;
|
||||
use function count;
|
||||
use function defined;
|
||||
use const IPS\Helpers\Table\SEARCH_DATE_RANGE;
|
||||
use const IPS\Helpers\Table\SEARCH_MEMBER;
|
||||
use const IPS\Helpers\Table\SEARCH_NODE;
|
||||
use const IPS\Helpers\Table\SEARCH_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;
|
||||
}
|
||||
|
||||
/**
|
||||
* donations
|
||||
*/
|
||||
class _donations extends \IPS\Dispatcher\Controller
|
||||
class donations extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'donations_manage' );
|
||||
Dispatcher::i()->checkAcpPermission( 'donations_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -44,18 +67,18 @@ class _donations extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
if( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'donationgoals_manage' ) )
|
||||
if( Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'donationgoals_manage' ) )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['actions'][] = array(
|
||||
Output::i()->sidebar['actions'][] = array(
|
||||
'icon' => 'cog',
|
||||
'title' => 'donation_goals',
|
||||
'link' => \IPS\Http\Url::internal( "app=nexus&module=payments&controller=donationgoals" )
|
||||
'link' => Url::internal( "app=nexus&module=payments&controller=donationgoals" )
|
||||
);
|
||||
}
|
||||
|
||||
$table = new \IPS\Helpers\Table\Db( 'nexus_donate_logs', \IPS\Http\Url::internal('app=nexus&module=payments&controller=donations') );
|
||||
$table = new Db( 'nexus_donate_logs', Url::internal('app=nexus&module=payments&controller=donations') );
|
||||
|
||||
$table->include = array( 'dl_goal', 'dl_amount', 'dl_member', 'dl_invoice', 'dl_date' );
|
||||
$table->parsers = array(
|
||||
@@ -63,24 +86,24 @@ class _donations extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\nexus\Donation\Goal::load( $val )->_title;
|
||||
return Goal::load( $val )->_title;
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
catch ( Exception )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
},
|
||||
'dl_member' => function ( $val )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate('global')->userLink( \IPS\Member::load( $val ) );
|
||||
return Theme::i()->getTemplate('global')->userLink( Member::load( $val ) );
|
||||
},
|
||||
'dl_amount' => function( $val, $row )
|
||||
{
|
||||
try
|
||||
{
|
||||
return (string) new \IPS\nexus\Money( $val, \IPS\nexus\Donation\Goal::load( $row['dl_goal'] )->currency );
|
||||
return (string) new Money( $val, Goal::load( $row['dl_goal'] )->currency );
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
catch ( Exception )
|
||||
{
|
||||
return $val;
|
||||
}
|
||||
@@ -89,32 +112,38 @@ class _donations extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate('invoices')->link( \IPS\nexus\Invoice::load( $val ), TRUE );
|
||||
return Theme::i()->getTemplate('invoices')->link( Invoice::load( $val ), TRUE );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
return '';
|
||||
}
|
||||
},
|
||||
'dl_date' => function( $val )
|
||||
{
|
||||
return \IPS\DateTime::ts( $val );
|
||||
return DateTime::ts( $val );
|
||||
}
|
||||
);
|
||||
|
||||
foreach ( \IPS\nexus\Donation\Goal::roots() as $goal )
|
||||
foreach ( Goal::roots() as $goal )
|
||||
{
|
||||
$table->filters[ "nexus_donategoal_{$goal->_id}" ] = "dl_goal={$goal->_id}";
|
||||
}
|
||||
$table->advancedSearch = array(
|
||||
'dl_goal' => array( \IPS\Helpers\Table\SEARCH_NODE, array( 'class' => '\IPS\nexus\Donation\Goal' ) ),
|
||||
'dl_member' => \IPS\Helpers\Table\SEARCH_MEMBER,
|
||||
'dl_amount' => \IPS\Helpers\Table\SEARCH_NUMERIC,
|
||||
'dl_date' => \IPS\Helpers\Table\SEARCH_DATE_RANGE,
|
||||
'dl_goal' => array( SEARCH_NODE, array( 'class' => '\IPS\nexus\Donation\Goal' ) ),
|
||||
'dl_member' => SEARCH_MEMBER,
|
||||
'dl_amount' => SEARCH_NUMERIC,
|
||||
'dl_date' => SEARCH_DATE_RANGE,
|
||||
);
|
||||
|
||||
\IPS\Output::i()->output = (string) $table;
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__nexus_payments_donations');
|
||||
|
||||
$message = '';
|
||||
if ( ! count( Widget::usedWhere( Application::load('nexus'), 'donations' ) ) )
|
||||
{
|
||||
/* Nudge the admin to add the sidebar block */
|
||||
$message = Theme::i()->getTemplate('forms', 'core' )->blurb( 'commerce_donation_goals_widget_not_in_use' );
|
||||
}
|
||||
|
||||
Output::i()->output = $message . $table;
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('menu__nexus_payments_donations');
|
||||
}
|
||||
}
|
||||
@@ -12,30 +12,42 @@
|
||||
namespace IPS\nexus\modules\admin\payments;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\CheckboxSet;
|
||||
use IPS\Helpers\Form\Stack;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Output;
|
||||
use IPS\Session;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification Copy Settings
|
||||
*/
|
||||
class _emails extends \IPS\Dispatcher\Controller
|
||||
class emails extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'email_copies_settings' );
|
||||
Dispatcher::i()->checkAcpPermission( 'email_copies_settings' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -44,10 +56,10 @@ class _emails extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function manage()
|
||||
public function manage() : void
|
||||
{
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'nexus_notify_copy_types', explode( ',', \IPS\Settings::i()->nexus_notify_copy_types ), FALSE, array( 'options' => array(
|
||||
$form = new Form;
|
||||
$form->add( new CheckboxSet( 'nexus_notify_copy_types', explode( ',', Settings::i()->nexus_notify_copy_types ), FALSE, array( 'options' => array(
|
||||
'invoice_warn' => 'nexus_notify_copy_invoice_warn',
|
||||
'new_invoice' => 'nexus_notify_copy_new_invoice',
|
||||
'payment_received' => 'nexus_notify_copy_payment_received',
|
||||
@@ -57,16 +69,16 @@ class _emails extends \IPS\Dispatcher\Controller
|
||||
'payment_refunded' => 'nexus_notify_copy_payment_refunded',
|
||||
'commission_earned' => 'nexus_notify_copy_commission_earned',
|
||||
) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Stack( 'nexus_notify_copy_email', explode( ',', \IPS\Settings::i()->nexus_notify_copy_email ) ) );
|
||||
$form->add( new Stack( 'nexus_notify_copy_email', explode( ',', Settings::i()->nexus_notify_copy_email ) ) );
|
||||
|
||||
if ( $form->values() )
|
||||
{
|
||||
$form->saveAsSettings();
|
||||
|
||||
\IPS\Session::i()->log( 'acplogs__email_copies_setting' );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=nexus&module=payments&controller=paymentsettings&tab=emails' ), 'saved' );
|
||||
Session::i()->log( 'acplogs__email_copies_setting' );
|
||||
Output::i()->redirect( Url::internal( 'app=nexus&module=payments&controller=paymentsettings&tab=emails' ), 'saved' );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = $form;
|
||||
Output::i()->output = $form;
|
||||
}
|
||||
}
|
||||
@@ -12,45 +12,52 @@
|
||||
namespace IPS\nexus\modules\admin\payments;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Node\Controller;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Anti-Fraud Rules
|
||||
*/
|
||||
class _fraud extends \IPS\Node\Controller
|
||||
class fraud extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
protected $nodeClass = 'IPS\nexus\Fraud\Rule';
|
||||
protected string $nodeClass = 'IPS\nexus\Fraud\Rule';
|
||||
|
||||
/**
|
||||
* Description can contain HTML?
|
||||
*/
|
||||
public $_descriptionHtml = TRUE;
|
||||
public bool $_descriptionHtml = TRUE;
|
||||
|
||||
/**
|
||||
* Show the "add" button in the page root rather than the table root
|
||||
*/
|
||||
protected $_addButtonInRoot = FALSE;
|
||||
protected bool $_addButtonInRoot = FALSE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'fraud_manage' );
|
||||
Dispatcher::i()->checkAcpPermission( 'fraud_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -59,9 +66,9 @@ class _fraud extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function manage()
|
||||
public function manage() : void
|
||||
{
|
||||
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'forms', 'core' )->blurb( 'fraud_rule_blurb', TRUE, TRUE );
|
||||
Output::i()->output .= Theme::i()->getTemplate( 'forms', 'core' )->blurb( 'fraud_rule_blurb', TRUE, TRUE );
|
||||
|
||||
parent::manage();
|
||||
}
|
||||
|
||||
@@ -12,35 +12,52 @@
|
||||
namespace IPS\nexus\modules\admin\payments;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use InvalidArgumentException;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\Radio;
|
||||
use IPS\Helpers\Wizard;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Lang;
|
||||
use IPS\nexus\Gateway;
|
||||
use IPS\Node\Controller;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
use IPS\Session;
|
||||
use IPS\Task;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Payment Gateways
|
||||
*/
|
||||
class _gateways extends \IPS\Node\Controller
|
||||
class gateways extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
protected $nodeClass = 'IPS\nexus\Gateway';
|
||||
protected string $nodeClass = 'IPS\nexus\Gateway';
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'gateways_manage' );
|
||||
Dispatcher::i()->checkAcpPermission( 'gateways_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -49,7 +66,7 @@ class _gateways extends \IPS\Node\Controller
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function _getRootButtons()
|
||||
public function _getRootButtons(): array
|
||||
{
|
||||
$buttons = parent::_getRootButtons();
|
||||
|
||||
@@ -66,39 +83,34 @@ class _gateways extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function form()
|
||||
protected function form() : void
|
||||
{
|
||||
if ( \IPS\Request::i()->id )
|
||||
if ( Request::i()->id )
|
||||
{
|
||||
return parent::form();
|
||||
parent::form();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( \IPS\IN_DEV )
|
||||
{
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'plupload/moxie.js', 'core', 'interface' ) );
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'plupload/plupload.dev.js', 'core', 'interface' ) );
|
||||
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js( 'plupload/moxie.js', 'core', 'interface' ) );
|
||||
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js( 'plupload/plupload.dev.js', 'core', 'interface' ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'plupload/plupload.full.min.js', 'core', 'interface' ) );
|
||||
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js( 'plupload/plupload.full.min.js', 'core', 'interface' ) );
|
||||
}
|
||||
\IPS\Output::i()->output = (string) new \IPS\Helpers\Wizard( array(
|
||||
Output::i()->output = (string) new Wizard( array(
|
||||
'gateways_gateway' => function( $data )
|
||||
{
|
||||
$options = array();
|
||||
foreach ( \IPS\nexus\Gateway::gateways() as $key => $class )
|
||||
foreach ( Gateway::gateways() as $key => $class )
|
||||
{
|
||||
/* Deprecate Authorize.net, Braintree and 2Checkout don't allow them to be used for new gateways */
|
||||
if( \in_array( $key, array( 'AuthorizeNet', 'TwoCheckout', 'Braintree' ) ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$options[ $key ] = 'gateway__' . $key;
|
||||
}
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'gateways_gateway', TRUE, NULL, array( 'options' => $options ) ) );
|
||||
$form = new Form;
|
||||
$form->add( new Radio( 'gateways_gateway', TRUE, NULL, array( 'options' => $options ) ) );
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
return array( 'gateway' => $values['gateways_gateway'] );
|
||||
@@ -107,8 +119,8 @@ class _gateways extends \IPS\Node\Controller
|
||||
},
|
||||
'gateways_details' => function( $data )
|
||||
{
|
||||
$form = new \IPS\Helpers\Form('gw');
|
||||
$class = \IPS\nexus\Gateway::gateways()[ $data['gateway'] ];
|
||||
$form = new Form('gw');
|
||||
$class = Gateway::gateways()[ $data['gateway'] ];
|
||||
$obj = new $class;
|
||||
$obj->gateway = $data['gateway'];
|
||||
$obj->active = TRUE;
|
||||
@@ -128,7 +140,7 @@ class _gateways extends \IPS\Node\Controller
|
||||
{
|
||||
$settings = $obj->testSettings( $settings );
|
||||
}
|
||||
catch ( \InvalidArgumentException $e )
|
||||
catch ( InvalidArgumentException $e )
|
||||
{
|
||||
$form->error = $e->getMessage();
|
||||
return $form;
|
||||
@@ -144,14 +156,14 @@ class _gateways extends \IPS\Node\Controller
|
||||
}
|
||||
|
||||
$obj->save();
|
||||
\IPS\Lang::saveCustom( 'nexus', "nexus_paymethod_{$obj->id}", $name );
|
||||
\IPS\Session::i()->log( 'acplogs__nexus_added_gateway', array( "nexus_paymethod_{$obj->id}" => TRUE ) );
|
||||
Lang::saveCustom( 'nexus', "nexus_paymethod_{$obj->id}", $name );
|
||||
Session::i()->log( 'acplogs__nexus_added_gateway', array( "nexus_paymethod_{$obj->id}" => TRUE ) );
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=payments&controller=paymentsettings&tab=gateways') );
|
||||
Output::i()->redirect( Url::internal('app=nexus&module=payments&controller=paymentsettings&tab=gateways') );
|
||||
}
|
||||
return $form;
|
||||
}
|
||||
), \IPS\Http\Url::internal('app=nexus&module=payments&controller=paymentsettings&tab=gateways&do=form') );
|
||||
), Url::internal('app=nexus&module=payments&controller=paymentsettings&tab=gateways&do=form') );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,42 +172,43 @@ class _gateways extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function delete()
|
||||
protected function delete() : void
|
||||
{
|
||||
/* Get node */
|
||||
/* @var Gateway $nodeClass */
|
||||
$nodeClass = $this->nodeClass;
|
||||
if ( \IPS\Request::i()->subnode )
|
||||
if ( Request::i()->subnode )
|
||||
{
|
||||
$nodeClass = $nodeClass::$subnodeClass;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$node = $nodeClass::load( \IPS\Request::i()->id );
|
||||
$node = $nodeClass::load( Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X411/1', 404, '' );
|
||||
Output::i()->error( 'node_error', '2X411/1', 404, '' );
|
||||
}
|
||||
|
||||
/* Permission check */
|
||||
if( !$node->canDelete() )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_noperm_delete', '2X411/2', 403, '' );
|
||||
Output::i()->error( 'node_noperm_delete', '2X411/2', 403, '' );
|
||||
}
|
||||
|
||||
if( $node->hasActiveBillingAgreements() )
|
||||
{
|
||||
/* Make sure the user confirmed the deletion */
|
||||
\IPS\Request::i()->confirmedDelete();
|
||||
Request::i()->confirmedDelete();
|
||||
|
||||
\IPS\Task::queue( 'nexus', 'DeletePaymentMethod', array( 'id' => $node->id ), 3, array( 'id' ) );
|
||||
\IPS\Session::i()->log( 'acplog__node_deleted_c', array( $this->title => TRUE, $node->titleForLog() => FALSE ) );
|
||||
\IPS\Output::i()->redirect( $this->url->setQueryString( array( 'root' => ( $node->parent() ? $node->parent()->_id : '' ) ) ), 'deleted' );
|
||||
Task::queue( 'nexus', 'DeletePaymentMethod', array( 'id' => $node->id ), 3, array( 'id' ) );
|
||||
Session::i()->log( 'acplog__node_deleted_c', array( $node->_title => TRUE, $node->titleForLog() => FALSE ) );
|
||||
Output::i()->redirect( $this->url->setQueryString( array( 'root' => ( $node->parent() ? $node->parent()->_id : '' ) ) ), 'deleted' );
|
||||
}
|
||||
else
|
||||
{
|
||||
return parent::delete();
|
||||
parent::delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,30 +12,36 @@
|
||||
namespace IPS\nexus\modules\admin\payments;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Dispatcher\Controller;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoice Timeline
|
||||
*/
|
||||
class _invoiceTimeline extends \IPS\Dispatcher\Controller
|
||||
class invoiceTimeline extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Manage
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'invoiceTimeline.css', 'nexus', 'admin' ) );
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('invoices')->invoiceTimeline();
|
||||
Output::i()->cssFiles = array_merge( Output::i()->cssFiles, Theme::i()->css( 'invoiceTimeline.css', 'nexus', 'admin' ) );
|
||||
Output::i()->output = Theme::i()->getTemplate('invoices')->invoiceTimeline();
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -12,21 +12,30 @@
|
||||
namespace IPS\nexus\modules\admin\payments;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Payment Settings
|
||||
*/
|
||||
class _paymentsettings extends \IPS\Dispatcher\Controller
|
||||
class paymentsettings extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Call
|
||||
@@ -36,38 +45,34 @@ class _paymentsettings extends \IPS\Dispatcher\Controller
|
||||
public function __call( $method, $args )
|
||||
{
|
||||
$tabs = array();
|
||||
if( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'currencies_manage' ) )
|
||||
if( Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'currencies_manage' ) )
|
||||
{
|
||||
$tabs['currencies'] = 'currencies';
|
||||
}
|
||||
if( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'gateways_manage' ) )
|
||||
if( Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'gateways_manage' ) )
|
||||
{
|
||||
$tabs['gateways'] = 'payment_methods';
|
||||
}
|
||||
if( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'tax_manage' ) )
|
||||
if( Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'tax_manage' ) )
|
||||
{
|
||||
$tabs['tax'] = 'tax_rates';
|
||||
}
|
||||
if( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'checkout_settings' ) )
|
||||
if( Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'checkout_settings' ) )
|
||||
{
|
||||
$tabs['checkoutsettings'] = 'checkout_settings';
|
||||
}
|
||||
if( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'fraud_manage' ) )
|
||||
if( Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'fraud_manage' ) )
|
||||
{
|
||||
$tabs['fraud'] = 'anti_fraud_rules';
|
||||
}
|
||||
if( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'transaction_review_settings' ) )
|
||||
{
|
||||
$tabs['review'] = 'transaction_review';
|
||||
}
|
||||
if( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'email_copies_settings' ) )
|
||||
if( Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'email_copies_settings' ) )
|
||||
{
|
||||
$tabs['emails'] = 'notification_copies';
|
||||
}
|
||||
|
||||
if ( isset( \IPS\Request::i()->tab ) and isset( $tabs[ \IPS\Request::i()->tab ] ) )
|
||||
if ( isset( Request::i()->tab ) and isset( $tabs[ Request::i()->tab ] ) )
|
||||
{
|
||||
$activeTab = \IPS\Request::i()->tab;
|
||||
$activeTab = Request::i()->tab;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -77,15 +82,15 @@ class _paymentsettings extends \IPS\Dispatcher\Controller
|
||||
|
||||
$classname = 'IPS\nexus\modules\admin\payments\\' . $activeTab;
|
||||
$class = new $classname;
|
||||
$class->url = \IPS\Http\Url::internal("app=nexus&module=payments&controller=paymentsettings&tab={$activeTab}");
|
||||
$class->url = Url::internal("app=nexus&module=payments&controller=paymentsettings&tab={$activeTab}");
|
||||
$class->execute();
|
||||
|
||||
if ( $method !== 'manage' or \IPS\Request::i()->isAjax() )
|
||||
if ( $method !== 'manage' or Request::i()->isAjax() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('payment_settings');
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->tabs( $tabs, $activeTab, \IPS\Output::i()->output, \IPS\Http\Url::internal( "app=nexus&module=payments&controller=paymentsettings" ) );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('payment_settings');
|
||||
Output::i()->output = Theme::i()->getTemplate( 'global', 'core' )->tabs( $tabs, $activeTab, Output::i()->output, Url::internal( "app=nexus&module=payments&controller=paymentsettings" ) );
|
||||
}
|
||||
}
|
||||
@@ -12,30 +12,58 @@
|
||||
namespace IPS\nexus\modules\admin\payments;
|
||||
|
||||
/* 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\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\CheckboxSet;
|
||||
use IPS\Helpers\Form\Custom;
|
||||
use IPS\Helpers\Form\YesNo;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\Member\Group;
|
||||
use IPS\nexus\Form\Money;
|
||||
use IPS\nexus\Gateway;
|
||||
use IPS\nexus\Payout;
|
||||
use IPS\Output;
|
||||
use IPS\Patterns\ActiveRecordIterator;
|
||||
use IPS\Request;
|
||||
use IPS\Session;
|
||||
use IPS\Settings;
|
||||
use IPS\Task;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Payouts
|
||||
*/
|
||||
class _payouts extends \IPS\Dispatcher\Controller
|
||||
class payouts extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'payouts_manage' );
|
||||
Dispatcher::i()->checkAcpPermission( 'payouts_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -44,48 +72,48 @@ class _payouts extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
/* Redirect to settings if we haven't set it up */
|
||||
if ( !\IPS\Settings::i()->nexus_payout )
|
||||
if ( !Settings::i()->nexus_payout )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=nexus&module=payments&controller=payouts&do=settings' ) );
|
||||
Output::i()->redirect( Url::internal( 'app=nexus&module=payments&controller=payouts&do=settings' ) );
|
||||
}
|
||||
|
||||
/* Build table */
|
||||
$table = \IPS\nexus\Payout::table( array(), \IPS\Http\Url::internal('app=nexus&module=payments&controller=payouts') );
|
||||
$table = Payout::table( array(), Url::internal('app=nexus&module=payments&controller=payouts') );
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__nexus_payments_payouts');
|
||||
if( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'payouts_settings' ) )
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('menu__nexus_payments_payouts');
|
||||
if( Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'payouts_settings' ) )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['actions'] = array(
|
||||
Output::i()->sidebar['actions'] = array(
|
||||
'settings' => array(
|
||||
'icon' => 'cog',
|
||||
'title' => 'account_credit_settings',
|
||||
'link' => \IPS\Http\Url::internal( 'app=nexus&module=payments&controller=payouts&do=settings' )
|
||||
'link' => Url::internal( 'app=nexus&module=payments&controller=payouts&do=settings' )
|
||||
),
|
||||
);
|
||||
|
||||
foreach ( \IPS\Db::i()->select( 'po_gateway', 'nexus_payouts', array( 'po_status=?', \IPS\nexus\Payout::STATUS_PENDING ), NULL, NULL, 'po_gateway' ) as $gateway )
|
||||
foreach ( Db::i()->select( 'po_gateway', 'nexus_payouts', array( 'po_status=?', Payout::STATUS_PENDING ), NULL, NULL, 'po_gateway' ) as $gateway )
|
||||
{
|
||||
$classname = \IPS\nexus\Gateway::payoutGateways()[ $gateway ];
|
||||
$classname = Gateway::payoutGateways()[ $gateway ];
|
||||
if ( class_exists( $classname ) and method_exists( $classname, 'massProcess' ) )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['actions'][] = [
|
||||
Output::i()->sidebar['actions'][] = [
|
||||
'icon' => 'check',
|
||||
'title' => \IPS\Member::loggedIn()->language()->addToStack( 'account_credit_mass_payout', TRUE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( 'payout__admin_' . $gateway ) ) ) ),
|
||||
'link' => \IPS\Http\Url::internal( 'app=nexus&module=payments&controller=payouts&do=massprocess&gateway=' . $gateway )->csrf(),
|
||||
'title' => Member::loggedIn()->language()->addToStack( 'account_credit_mass_payout', TRUE, array( 'sprintf' => array( Member::loggedIn()->language()->addToStack( 'payout__admin_' . $gateway ) ) ) ),
|
||||
'link' => Url::internal( 'app=nexus&module=payments&controller=payouts&do=massprocess&gateway=' . $gateway )->csrf(),
|
||||
'data' => [
|
||||
'confirm' => '',
|
||||
'confirmMessage' => \IPS\Member::loggedIn()->language()->addToStack( 'nexus_payout_confirm_title' ),
|
||||
'confirmSubMessage' => \IPS\Member::loggedIn()->language()->addToStack( 'nexus_payout_confirm_text' )
|
||||
'confirmMessage' => Member::loggedIn()->language()->addToStack( 'nexus_payout_confirm_title' ),
|
||||
'confirmSubMessage' => Member::loggedIn()->language()->addToStack( 'nexus_payout_confirm_text' )
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
\IPS\Output::i()->output = (string) $table;
|
||||
Output::i()->output = (string) $table;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,20 +121,20 @@ class _payouts extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function view()
|
||||
protected function view() : void
|
||||
{
|
||||
try
|
||||
{
|
||||
$payout = \IPS\nexus\Payout::load( \IPS\Request::i()->id );
|
||||
$payout = Payout::load( Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X200/2', 404, '' );
|
||||
Output::i()->error( 'node_error', '2X200/2', 404, '' );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->sidebar['actions'] = $payout->buttons( 'v' );
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'payout_number', FALSE, array( 'sprintf' => array( $payout->id ) ) );
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('payouts')->view( $payout );
|
||||
Output::i()->sidebar['actions'] = $payout->buttons( 'v' );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack( 'payout_number', FALSE, array( 'sprintf' => array( $payout->id ) ) );
|
||||
Output::i()->output = Theme::i()->getTemplate('payouts')->view( $payout );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -114,48 +142,48 @@ class _payouts extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function process()
|
||||
protected function process() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'payouts_process' );
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Dispatcher::i()->checkAcpPermission( 'payouts_process' );
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
try
|
||||
{
|
||||
$payout = \IPS\nexus\Payout::load( \IPS\Request::i()->id );
|
||||
$payout = Payout::load( Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X200/3', 404, '' );
|
||||
Output::i()->error( 'node_error', '2X200/3', 404, '' );
|
||||
}
|
||||
|
||||
if ( $payout->status !== $payout::STATUS_PENDING )
|
||||
{
|
||||
\IPS\Output::i()->error( 'err_payout_not_pending', '1X200/4', 403, '' );
|
||||
Output::i()->error( 'err_payout_not_pending', '1X200/4', 403, '' );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$payout->process();
|
||||
$payout->status = $payout->process();
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
catch ( Exception $e )
|
||||
{
|
||||
\IPS\Output::i()->error( $e->getMessage(), '1X200/1', 500, '' );
|
||||
Output::i()->error( $e->getMessage(), '1X200/1', 500, '' );
|
||||
}
|
||||
|
||||
$payout->processed_by = \IPS\Member::loggedIn();
|
||||
$payout->processed_by = Member::loggedIn();
|
||||
$payout->save();
|
||||
\IPS\Session::i()->log( 'acplogs__payout_processed', array( $payout->id => FALSE ) );
|
||||
Session::i()->log( 'acplogs__payout_processed', array( $payout->id => FALSE ) );
|
||||
$payout->member->log( 'payout', array( 'type' => 'processed', 'amount' => $payout->amount->amount, 'currency' => $payout->amount->currency, 'payout_id' => $payout->id ) );
|
||||
|
||||
/* If the payout was actually completed, notify the user */
|
||||
if( $payout->status == \IPS\nexus\Payout::STATUS_COMPLETE )
|
||||
if( $payout->status == Payout::STATUS_COMPLETE )
|
||||
{
|
||||
$payout->markCompleted();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Use task if the payout is pending */
|
||||
$task = \IPS\Task::load( 'payoutPending', 'key', [ 'app=?', 'nexus' ] );
|
||||
$task = Task::load( 'payoutPending', 'key', [ 'app=?', 'nexus' ] );
|
||||
$task->enabled = TRUE;
|
||||
$task->save();
|
||||
}
|
||||
@@ -168,38 +196,39 @@ class _payouts extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function massprocess()
|
||||
protected function massprocess() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'payouts_process' );
|
||||
\IPS\Request::i()->confirmedDelete( 'nexus_payout_confirm_title', 'nexus_payout_confirm_text', 'nexus_payout_proceed' );
|
||||
Dispatcher::i()->checkAcpPermission( 'payouts_process' );
|
||||
Request::i()->confirmedDelete( 'nexus_payout_confirm_title', 'nexus_payout_confirm_text', 'nexus_payout_proceed' );
|
||||
|
||||
$classname = \IPS\nexus\Gateway::payoutGateways()[ \IPS\Request::i()->gateway ];
|
||||
$classname = Gateway::payoutGateways()[ Request::i()->gateway ];
|
||||
if ( !class_exists( $classname ) or !method_exists( $classname, 'massProcess' ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'generic_error', '2X200/8', 403, '' );
|
||||
Output::i()->error( 'generic_error', '2X200/8', 403, '' );
|
||||
}
|
||||
|
||||
$payouts = new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_payouts', array( 'po_status=? AND po_gateway=?', \IPS\nexus\Payout::STATUS_PENDING, \IPS\Request::i()->gateway ) ), $classname );
|
||||
$payouts = new ActiveRecordIterator( Db::i()->select( '*', 'nexus_payouts', array( 'po_status=? AND po_gateway=?', Payout::STATUS_PENDING, Request::i()->gateway ) ), $classname );
|
||||
|
||||
try
|
||||
{
|
||||
$classname::massProcess( $payouts );
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
catch ( Exception $e )
|
||||
{
|
||||
\IPS\Output::i()->error( $e->getMessage(), '1X200/9', 403, '' );
|
||||
Output::i()->error( $e->getMessage(), '1X200/9', 403, '' );
|
||||
}
|
||||
|
||||
$pending = 0;
|
||||
foreach ( $payouts as $payout )
|
||||
{
|
||||
$payout->processed_by = \IPS\Member::loggedIn();
|
||||
/* @var Payout $payout */
|
||||
$payout->processed_by = Member::loggedIn();
|
||||
$payout->save();
|
||||
\IPS\Session::i()->log( 'acplogs__payout_processed', array( $payout->id => FALSE ) );
|
||||
Session::i()->log( 'acplogs__payout_processed', array( $payout->id => FALSE ) );
|
||||
$payout->member->log( 'payout', array( 'type' => 'processed', 'amount' => $payout->amount->amount, 'currency' => $payout->amount->currency, 'payout_id' => $payout->id ) );
|
||||
|
||||
/* Only do this if the payout is actually complete! */
|
||||
if( $payout->status == \IPS\nexus\Payout::STATUS_COMPLETE )
|
||||
if( $payout->status == Payout::STATUS_COMPLETE )
|
||||
{
|
||||
$payout->markCompleted();
|
||||
continue;
|
||||
@@ -211,12 +240,12 @@ class _payouts extends \IPS\Dispatcher\Controller
|
||||
/* Use task if there are incomplete payouts */
|
||||
if( $pending )
|
||||
{
|
||||
$task = \IPS\Task::load( 'payoutPending', 'key', [ 'app=?', 'nexus' ] );
|
||||
$task = Task::load( 'payoutPending', 'key', [ 'app=?', 'nexus' ] );
|
||||
$task->enabled = TRUE;
|
||||
$task->save();
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=payments&controller=payouts') );
|
||||
Output::i()->redirect( Url::internal('app=nexus&module=payments&controller=payouts') );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -224,33 +253,33 @@ class _payouts extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function cancel()
|
||||
protected function cancel() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'payouts_cancel' );
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Dispatcher::i()->checkAcpPermission( 'payouts_cancel' );
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
try
|
||||
{
|
||||
$payout = \IPS\nexus\Payout::load( \IPS\Request::i()->id );
|
||||
$payout = Payout::load( Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X200/6', 404, '' );
|
||||
Output::i()->error( 'node_error', '2X200/6', 404, '' );
|
||||
}
|
||||
|
||||
if ( $payout->status !== $payout::STATUS_PENDING )
|
||||
{
|
||||
\IPS\Output::i()->error( 'err_payout_not_pending', '1X200/5', 403, '' );
|
||||
Output::i()->error( 'err_payout_not_pending', '1X200/5', 403, '' );
|
||||
}
|
||||
|
||||
$payout->status = $payout::STATUS_CANCELED;
|
||||
$payout->completed = new \IPS\DateTime;
|
||||
$payout->processed_by = \IPS\Member::loggedIn();
|
||||
$payout->completed = new DateTime;
|
||||
$payout->processed_by = Member::loggedIn();
|
||||
$payout->save();
|
||||
\IPS\Session::i()->log( 'acplogs__payout_cancelled', array( $payout->id => FALSE ) );
|
||||
Session::i()->log( 'acplogs__payout_cancelled', array( $payout->id => FALSE ) );
|
||||
$payout->member->log( 'payout', array( 'type' => 'cancel', 'amount' => $payout->amount->amount, 'currency' => $payout->amount->currency, 'payout_id' => $payout->id ) );
|
||||
|
||||
if ( \IPS\Request::i()->prompt )
|
||||
if ( Request::i()->prompt )
|
||||
{
|
||||
$credits = $payout->member->cm_credits;
|
||||
$credits[ $payout->amount->currency ]->amount = $credits[ $payout->amount->currency ]->amount->add( $payout->amount->amount );
|
||||
@@ -266,27 +295,27 @@ class _payouts extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function delete()
|
||||
protected function delete() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'payouts_delete' );
|
||||
Dispatcher::i()->checkAcpPermission( 'payouts_delete' );
|
||||
|
||||
/* Make sure the user confirmed the deletion */
|
||||
\IPS\Request::i()->confirmedDelete();
|
||||
Request::i()->confirmedDelete();
|
||||
|
||||
try
|
||||
{
|
||||
$payout = \IPS\nexus\Payout::load( \IPS\Request::i()->id );
|
||||
$payout = Payout::load( Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X200/7', 404, '' );
|
||||
Output::i()->error( 'node_error', '2X200/7', 404, '' );
|
||||
}
|
||||
|
||||
$payout->delete();
|
||||
\IPS\Session::i()->log( 'acplogs__payout_deleted', array( $payout->id => FALSE ) );
|
||||
Session::i()->log( 'acplogs__payout_deleted', array( $payout->id => FALSE ) );
|
||||
$payout->member->log( 'payout', array( 'type' => 'dismissed', 'amount' => $payout->amount->amount, 'currency' => $payout->amount->currency, 'payout_id' => $payout->id ) );
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=payments&controller=payouts') );
|
||||
Output::i()->redirect( Url::internal('app=nexus&module=payments&controller=payouts') );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -294,18 +323,19 @@ class _payouts extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function settings()
|
||||
protected function settings() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'payouts_settings' );
|
||||
Dispatcher::i()->checkAcpPermission( 'payouts_settings' );
|
||||
|
||||
$options = array();
|
||||
$toggles = array();
|
||||
$fields = array();
|
||||
foreach ( \IPS\nexus\Gateway::payoutGateways() as $key => $class )
|
||||
foreach ( Gateway::payoutGateways() as $key => $class )
|
||||
{
|
||||
$options[ $key ] = 'payout__admin_' . $key;
|
||||
$toggles[ $key ] = array( 'form_header_payout_settings' );
|
||||
|
||||
|
||||
/* @var Payout $class */
|
||||
foreach ( $class::settings() as $field )
|
||||
{
|
||||
if ( !$field->htmlId )
|
||||
@@ -319,41 +349,41 @@ class _payouts extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
$groups = array();
|
||||
foreach ( \IPS\Member\Group::groups( TRUE, FALSE ) as $group )
|
||||
foreach ( Group::groups( TRUE, FALSE ) as $group )
|
||||
{
|
||||
$groups[ $group->g_id ] = $group->name;
|
||||
}
|
||||
|
||||
$settings = \IPS\Settings::i()->nexus_payout ? json_decode( \IPS\Settings::i()->nexus_payout, TRUE ) : array();
|
||||
$settings = \is_array( $settings ) ? array_keys( $settings ) : array();
|
||||
$settings = Settings::i()->nexus_payout ? json_decode( Settings::i()->nexus_payout, TRUE ) : array();
|
||||
$settings = is_array( $settings ) ? array_keys( $settings ) : array();
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->addMessage('payout_description');
|
||||
$form = new Form;
|
||||
$form->addMessage('payout_description', 'ipsMessage--transparent');
|
||||
$form->addHeader('commission_settings');
|
||||
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'nexus_no_commission', explode( ',', \IPS\Settings::i()->nexus_no_commission ), FALSE, array( 'multiple' => TRUE, 'options' => $groups ) ) );
|
||||
$form->add( new CheckboxSet( 'nexus_no_commission', explode( ',', Settings::i()->nexus_no_commission ), FALSE, array( 'multiple' => TRUE, 'options' => $groups ) ) );
|
||||
$form->addHeader('withdrawal_methods');
|
||||
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'nexus_payout', $settings, FALSE, array( 'options' => $options, 'toggles' => $toggles ) ) );
|
||||
$form->add( new CheckboxSet( 'nexus_payout', $settings, FALSE, array( 'options' => $options, 'toggles' => $toggles ) ) );
|
||||
foreach ( $fields as $field )
|
||||
{
|
||||
$form->add( $field );
|
||||
}
|
||||
$form->addHeader('payout_settings');
|
||||
$form->add( new \IPS\nexus\Form\Money( 'nexus_payout_min', ( \IPS\Settings::i()->nexus_payout_min AND \IPS\Settings::i()->nexus_payout_min != '*' ) ? json_decode( \IPS\Settings::i()->nexus_payout_min, TRUE ) : '*', FALSE, array( 'unlimitedLang' => 'no_restriction' ), NULL, NULL, NULL, 'nexus_payout_min' ) );
|
||||
$form->add( new Money( 'nexus_payout_min', ( Settings::i()->nexus_payout_min AND Settings::i()->nexus_payout_min != '*' ) ? json_decode( Settings::i()->nexus_payout_min, TRUE ) : '*', FALSE, array( 'unlimitedLang' => 'no_restriction' ), NULL, NULL, NULL, 'nexus_payout_min' ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Custom( 'nexus_payout_maximum', NULL, FALSE, array( 'getHtml' => function( $element ) {
|
||||
$amount = new \IPS\nexus\Form\Money( 'nexus_payout_maximum[2]', ( \IPS\Settings::i()->nexus_payout_max AND \IPS\Settings::i()->nexus_payout_max != '*' ) ? json_decode( \IPS\Settings::i()->nexus_payout_max, TRUE ) : '*', FALSE, array( 'unlimitedLang' => 'no_restriction', 'unlimitedTogglesOff' => array( 'payout_max_limited' ) ), NULL, NULL, NULL, 'nexus_payout_max' );
|
||||
$period = \IPS\Settings::i()->nexus_payout_max_period ? json_decode( \IPS\Settings::i()->nexus_payout_max_period, TRUE ) : array( 1, 'day' );
|
||||
$form->add( new Custom( 'nexus_payout_maximum', NULL, FALSE, array( 'getHtml' => function( $element ) {
|
||||
$amount = new Money( 'nexus_payout_maximum[2]', ( Settings::i()->nexus_payout_max AND Settings::i()->nexus_payout_max != '*' ) ? json_decode( Settings::i()->nexus_payout_max, TRUE ) : '*', FALSE, array( 'unlimitedLang' => 'no_restriction', 'unlimitedTogglesOff' => array( 'payout_max_limited' ) ), NULL, NULL, NULL, 'nexus_payout_max' );
|
||||
$period = Settings::i()->nexus_payout_max_period ? json_decode( Settings::i()->nexus_payout_max_period, TRUE ) : array( 1, 'day' );
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'payouts' )->maximumLimits( $amount->html(), (int) $period[0], $period[1] );
|
||||
return Theme::i()->getTemplate( 'payouts' )->maximumLimits( $amount->html(), (int) $period[0], $period[1] );
|
||||
} ), NULL, NULL, NULL, 'nexus_payout_maximum' ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_payout_approve', \IPS\Settings::i()->nexus_payout_approve, FALSE, array(), NULL, NULL, NULL, 'nexus_payout_approve' ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_payout_unlimited_times', \IPS\Settings::i()->nexus_payout_unlimited_times, TRUE ) );
|
||||
$form->add( new YesNo( 'nexus_payout_approve', Settings::i()->nexus_payout_approve, FALSE, array(), NULL, NULL, NULL, 'nexus_payout_approve' ) );
|
||||
$form->add( new YesNo( 'nexus_payout_unlimited_times', Settings::i()->nexus_payout_unlimited_times, TRUE ) );
|
||||
|
||||
$form->addHeader('topup_settings');
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'allow_topups', \IPS\Settings::i()->nexus_min_topup, FALSE, array( 'togglesOn' => array( 'nexus_min_topup', 'nexus_max_credit' ) ) ) );
|
||||
$form->add( new \IPS\nexus\Form\Money( 'nexus_min_topup', \IPS\Settings::i()->nexus_min_topup ?: '*', FALSE, array( 'unlimitedLang' => 'no_restriction' ), NULL, NULL, NULL, 'nexus_min_topup' ) );
|
||||
$form->add( new \IPS\nexus\Form\Money( 'nexus_max_credit', \IPS\Settings::i()->nexus_max_credit ?: '*', FALSE, array( 'unlimitedLang' => 'no_restriction' ), NULL, NULL, NULL, 'nexus_max_credit' ) );
|
||||
$form->add( new YesNo( 'allow_topups', Settings::i()->nexus_min_topup, FALSE, array( 'togglesOn' => array( 'nexus_min_topup', 'nexus_max_credit' ) ) ) );
|
||||
$form->add( new Money( 'nexus_min_topup', Settings::i()->nexus_min_topup ?: '*', FALSE, array( 'unlimitedLang' => 'no_restriction' ), NULL, NULL, NULL, 'nexus_min_topup' ) );
|
||||
$form->add( new Money( 'nexus_max_credit', Settings::i()->nexus_max_credit ?: '*', FALSE, array( 'unlimitedLang' => 'no_restriction' ), NULL, NULL, NULL, 'nexus_max_credit' ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
@@ -378,8 +408,8 @@ class _payouts extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
$values['nexus_payout'] = json_encode( $payoutSettings );
|
||||
$values['nexus_payout_min'] = \is_array( $values['nexus_payout_min'] ) ? json_encode( $values['nexus_payout_min'] ) : '*';
|
||||
$values['nexus_payout_max'] = ( \is_array( $values['nexus_payout_maximum'][2] ) AND ( !isset( $values['nexus_payout_maximum'][2]['__unlimited'] ) OR !$values['nexus_payout_maximum'][2]['__unlimited'] ) ) ? json_encode( $values['nexus_payout_maximum'][2] ) : '*';
|
||||
$values['nexus_payout_min'] = is_array( $values['nexus_payout_min'] ) ? json_encode( $values['nexus_payout_min'] ) : '*';
|
||||
$values['nexus_payout_max'] = ( is_array( $values['nexus_payout_maximum'][2] ) AND ( !isset( $values['nexus_payout_maximum'][2]['__unlimited'] ) OR !$values['nexus_payout_maximum'][2]['__unlimited'] ) ) ? json_encode( $values['nexus_payout_maximum'][2] ) : '*';
|
||||
$values['nexus_payout_max_period'] = ( $values['nexus_payout_max'] == '*' ) ? NULL : json_encode( array( $values['nexus_payout_maximum'][0], $values['nexus_payout_maximum'][1] ) );
|
||||
|
||||
if ( $values['allow_topups'] )
|
||||
@@ -397,51 +427,51 @@ class _payouts extends \IPS\Dispatcher\Controller
|
||||
$values['nexus_no_commission'] = implode( ',', $values['nexus_no_commission'] );
|
||||
|
||||
$form->saveAsSettings( $values );
|
||||
\IPS\Session::i()->log( 'acplogs__payout_settings' );
|
||||
Session::i()->log( 'acplogs__payout_settings' );
|
||||
|
||||
/* Remove any ACP notifications related to Payout Settings */
|
||||
foreach( \IPS\nexus\Gateway::payoutGateways() as $key => $class )
|
||||
foreach( Gateway::payoutGateways() as $key => $class )
|
||||
{
|
||||
\IPS\core\AdminNotification::remove( 'nexus', 'ConfigurationError', "po{$key}" );
|
||||
AdminNotification::remove( 'nexus', 'ConfigurationError', "po{$key}" );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=payments&controller=payouts'), 'saved' );
|
||||
Output::i()->redirect( Url::internal('app=nexus&module=payments&controller=payouts'), 'saved' );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('account_credit_settings');
|
||||
\IPS\Output::i()->output = $form;
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('account_credit_settings');
|
||||
Output::i()->output = $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect
|
||||
*
|
||||
* @param \IPS\nexus\Payout $payout The payout
|
||||
* @param Payout $payout The payout
|
||||
* @return void
|
||||
*/
|
||||
protected function _redirect( \IPS\nexus\Payout $payout )
|
||||
protected function _redirect( Payout $payout ) : void
|
||||
{
|
||||
if ( isset( \IPS\Request::i()->r ) )
|
||||
if ( isset( Request::i()->r ) )
|
||||
{
|
||||
switch ( mb_substr( \IPS\Request::i()->r, 0, 1 ) )
|
||||
switch ( mb_substr( Request::i()->r, 0, 1 ) )
|
||||
{
|
||||
case 'v':
|
||||
\IPS\Output::i()->redirect( $payout->acpUrl() );
|
||||
Output::i()->redirect( $payout->acpUrl() );
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
\IPS\Output::i()->redirect( $payout->member->acpUrl() );
|
||||
Output::i()->redirect( $payout->member->acpUrl() );
|
||||
break;
|
||||
|
||||
case 't':
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=payments&controller=payouts')->setQueryString( 'filter', \IPS\Request::i()->filter ) );
|
||||
Output::i()->redirect( Url::internal('app=nexus&module=payments&controller=payouts')->setQueryString( 'filter', Request::i()->filter ) );
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=core&module=overview&controller=notifications') );
|
||||
Output::i()->redirect( Url::internal('app=core&module=overview&controller=notifications') );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( $payout->acpUrl() );
|
||||
Output::i()->redirect( $payout->acpUrl() );
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Transaction Review
|
||||
* @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 26 Mar 2014
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\modules\admin\payments;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transaction Review
|
||||
*/
|
||||
class _review extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'transaction_review_settings' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function manage()
|
||||
{
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_revw_sa_on', \IPS\Settings::i()->nexus_revw_sa != -1, FALSE, array( 'togglesOn' => array( 'nexus_revw_sa' ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'nexus_revw_sa', \IPS\Settings::i()->nexus_revw_sa ?: 0, FALSE, array( 'class' => 'IPS\nexus\Support\StockAction', 'zeroVal' => 'do_not_suggest_stock_action' ), NULL, NULL, NULL, 'nexus_revw_sa' ) );
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
if ( !$values['nexus_revw_sa_on'] )
|
||||
{
|
||||
$values['nexus_revw_sa'] = -1;
|
||||
}
|
||||
elseif ( $values['nexus_revw_sa'] )
|
||||
{
|
||||
$values['nexus_revw_sa'] = $values['nexus_revw_sa']->id;
|
||||
}
|
||||
unset( $values['nexus_revw_sa_on'] );
|
||||
|
||||
$form->saveAsSettings( $values );
|
||||
|
||||
\IPS\Session::i()->log( 'acplogs__transaction_review_settings' );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=nexus&module=payments&controller=paymentsettings&tab=review' ), 'saved' );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = $form;
|
||||
}
|
||||
}
|
||||
@@ -1,642 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Shipments
|
||||
* @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\modules\admin\payments;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shipments
|
||||
*/
|
||||
class _shipping extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'shiporders_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
{
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'payments', 'shipmethods_manage' ) )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['actions']['settings'] = array(
|
||||
'title' => 'shipping_rates',
|
||||
'icon' => 'cog',
|
||||
'link' => \IPS\Http\Url::internal('app=nexus&module=payments&controller=shippingrates'),
|
||||
);
|
||||
}
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('shipping');
|
||||
\IPS\Output::i()->output = (string) \IPS\nexus\Shipping\Order::table( \IPS\Http\Url::internal( 'app=nexus&module=payments&controller=shipping' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* View
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function view()
|
||||
{
|
||||
/* Load */
|
||||
try
|
||||
{
|
||||
$shipment = \IPS\nexus\Shipping\Order::load( \IPS\Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X193/1', 404, '' );
|
||||
}
|
||||
|
||||
$easyPost = NULL;
|
||||
if ( \IPS\Settings::i()->easypost_api_key )
|
||||
{
|
||||
$extra = json_decode( $shipment->extra, TRUE );
|
||||
if ( isset( $extra['shipment'] ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$easyPost = \IPS\Http\Url::external( 'https://api.easypost.com/v2/shipments/' . $extra['shipment'] )->request()->login( \IPS\Settings::i()->easypost_api_key, '' )->get()->decodeJson();
|
||||
}
|
||||
catch ( \IPS\Http\Request\Exception $e ) { }
|
||||
}
|
||||
}
|
||||
|
||||
/* Add Buttons */
|
||||
\IPS\Output::i()->sidebar['actions'] = $shipment->buttons( 'v' );
|
||||
|
||||
/* Output */
|
||||
\IPS\Output::i()->title = $shipment->method ? \IPS\Member::loggedIn()->language()->addToStack( 'shipment_number_with_method', FALSE, array( 'sprintf' => array( $shipment->id, $shipment->method->_title ) ) ) : \IPS\Member::loggedIn()->language()->addToStack( 'shipment_number', FALSE, array( 'sprintf' => array( $shipment->id ) ) );
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'shiporders' )->view( $shipment, $easyPost );
|
||||
}
|
||||
|
||||
/**
|
||||
* Ship
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function ship()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'shiporders_edit' );
|
||||
|
||||
/* Load */
|
||||
try
|
||||
{
|
||||
$shipment = \IPS\nexus\Shipping\Order::load( \IPS\Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X193/2', 404, '' );
|
||||
}
|
||||
|
||||
/* Build Form */
|
||||
$form = new \IPS\Helpers\Form( 'form', 'shipment_ship' );
|
||||
if ( \IPS\Settings::i()->easypost_api_key )
|
||||
{
|
||||
/* Calculate stuff */
|
||||
$weightInOz = 0;
|
||||
$lengthInInches = 0;
|
||||
$widthInInches = 0;
|
||||
$heightInInches = 0;
|
||||
foreach ( $shipment->items as $item )
|
||||
{
|
||||
$weight = new \IPS\nexus\Shipping\Weight( $item['weight']['kilograms'] );
|
||||
$weightInOz += ( $weight->float('oz') * $item['quantity'] );
|
||||
|
||||
foreach ( array( 'length', 'width', 'height' ) as $k )
|
||||
{
|
||||
$dim = new \IPS\nexus\Shipping\Length( $item[ $k ]['metres'] );
|
||||
$v = "{$k}InInches";
|
||||
$$v += ( $dim->float('in') * $item['quantity'] );
|
||||
}
|
||||
}
|
||||
|
||||
/* Method */
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'shipment_ship_method', 'easypost', TRUE, array(
|
||||
'options' => array( 'easypost' => 'shipment_ship_easypost', 'manual' => 'shipment_ship_manual' ),
|
||||
'toggles' => array(
|
||||
'easypost' => array( 'form_header_easypost_package_header', 'easypost_package', 'easypost_package_weight', 'form_header_easypost_customs_header', 'easypost_customs_details' ),
|
||||
'manual' => array( 'o_tracknumber', 'tracking_url' )
|
||||
)
|
||||
) ) );
|
||||
|
||||
/* Parcel */
|
||||
$form->addHeader( 'easypost_package_header' );
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'easypost_package', 'custom', NULL, array(
|
||||
'options' => array(
|
||||
'custom' => 'easypost_package_custom',
|
||||
'easypost_package_usps' => array(
|
||||
'Card' => 'easypost_package_usps_Card',
|
||||
'Letter' => 'easypost_package_usps_Letter',
|
||||
'Flat' => 'easypost_package_usps_Flat',
|
||||
'Parcel' => 'easypost_package_usps_Parcel',
|
||||
'LargeParcel' => 'easypost_package_usps_LargeParcel',
|
||||
'IrregularParcel' => 'easypost_package_usps_IrregularParcel',
|
||||
'FlatRateEnvelope' => 'easypost_package_usps_FlatRateEnvelope',
|
||||
'FlatRateLegalEnvelope' => 'easypost_package_usps_FlatRateLegalEnvelope',
|
||||
'FlatRatePaddedEnvelope' => 'easypost_package_usps_FlatRatePaddedEnvelope',
|
||||
'FlatRateGiftCardEnvelope' => 'easypost_package_usps_FlatRateGiftCardEnvelope',
|
||||
'FlatRateWindowEnvelope' => 'easypost_package_usps_FlatRateWindowEnvelope',
|
||||
'FlatRateCardboardEnvelope' => 'easypost_package_usps_FlatRateCardboardEnvelope',
|
||||
'SmallFlatRateEnvelope' => 'easypost_package_usps_SmallFlatRateEnvelope',
|
||||
'SmallFlatRateBox' => 'easypost_package_usps_SmallFlatRateBox',
|
||||
'MediumFlatRateBox' => 'easypost_package_usps_MediumFlatRateBox',
|
||||
'LargeFlatRateBox' => 'easypost_package_usps_LargeFlatRateBox',
|
||||
'RegionalRateBoxA' => 'easypost_package_usps_RegionalRateBoxA',
|
||||
'RegionalRateBoxB' => 'easypost_package_usps_RegionalRateBoxB',
|
||||
'RegionalRateBoxC' => 'easypost_package_usps_RegionalRateBoxC',
|
||||
'LargeFlatRateBoardGameBox' => 'easypost_package_usps_LargeFlatRateBoardGameBox',
|
||||
),
|
||||
'easypost_package_ups' => array(
|
||||
'UPSLetter' => 'easypost_package_ups_UPSLetter',
|
||||
'UPSExpressBox' => 'easypost_package_ups_UPSExpressBox',
|
||||
'UPS25kgBox' => 'easypost_package_ups_UPS25kgBox',
|
||||
'UPS10kgBox' => 'easypost_package_ups_UPS10kgBox',
|
||||
'Tube' => 'easypost_package_ups_Tube',
|
||||
'Pak' => 'easypost_package_ups_Pak',
|
||||
'Pallet' => 'easypost_package_ups_Pallet',
|
||||
'SmallExpressBox' => 'easypost_package_ups_SmallExpressBox',
|
||||
'MediumExpressBox' => 'easypost_package_ups_MediumExpressBox',
|
||||
'LargeExpressBox' => 'easypost_package_ups_LargeExpressBox',
|
||||
),
|
||||
'easypost_package_fedex' => array(
|
||||
'FedExEnvelope' => 'easypost_package_fedex_FedExEnvelope',
|
||||
'FedExBox' => 'easypost_package_fedex_FedExBox',
|
||||
'FedExPak' => 'easypost_package_fedex_FedExPak',
|
||||
'FedExTube' => 'easypost_package_fedex_FedExTube',
|
||||
'FedEx10kgBox' => 'easypost_package_fedex_FedEx10kgBox',
|
||||
'FedEx25kgBox' => 'easypost_package_fedex_FedEx25kgBox',
|
||||
),
|
||||
),
|
||||
'toggles' => array(
|
||||
'custom' => array( 'easypost_package_length', 'easypost_package_width', 'easypost_package_height' )
|
||||
)
|
||||
), NULL, NULL, NULL, 'easypost_package' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'easypost_package_length', $lengthInInches, NULL, array(), function( $val )
|
||||
{
|
||||
if ( !$val and \IPS\Request::i()->shipment_ship_method == 'easypost' and \IPS\Request::i()->easypost_package == 'custom' )
|
||||
{
|
||||
throw new \DomainException('form_required');
|
||||
}
|
||||
}, NULL, \IPS\Member::loggedIn()->language()->addToStack('inches'), 'easypost_package_length' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'easypost_package_width', $widthInInches, NULL, array(), function( $val )
|
||||
{
|
||||
if ( !$val and \IPS\Request::i()->shipment_ship_method == 'easypost' and \IPS\Request::i()->easypost_package == 'custom' )
|
||||
{
|
||||
throw new \DomainException('form_required');
|
||||
}
|
||||
}, NULL, \IPS\Member::loggedIn()->language()->addToStack('inches'), 'easypost_package_width' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'easypost_package_height', $heightInInches, NULL, array(), function( $val )
|
||||
{
|
||||
if ( !$val and \IPS\Request::i()->shipment_ship_method == 'easypost' and \IPS\Request::i()->easypost_package == 'custom' )
|
||||
{
|
||||
throw new \DomainException('form_required');
|
||||
}
|
||||
}, NULL, \IPS\Member::loggedIn()->language()->addToStack('inches'), 'easypost_package_height' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'easypost_package_weight', $weightInOz, NULL, array( 'decimals' => 1 ), function( $val )
|
||||
{
|
||||
if ( !$val and \IPS\Request::i()->shipment_ship_method == 'easypost' )
|
||||
{
|
||||
throw new \DomainException('form_required');
|
||||
}
|
||||
}, NULL, 'oz', 'easypost_package_weight' ) );
|
||||
|
||||
$matrix = NULL;
|
||||
$fromCountry = \IPS\GeoLocation::buildFromJson( \IPS\Settings::i()->easypost_address ?: \IPS\Settings::i()->site_address )->country;
|
||||
if ( $fromCountry != $shipment->data['address']['country'] )
|
||||
{
|
||||
$originCountries = array();
|
||||
foreach ( \IPS\GeoLocation::$countries as $code )
|
||||
{
|
||||
$originCountries[ $code ] = 'country-' . $code;
|
||||
}
|
||||
|
||||
$matrix = new \IPS\Helpers\Form\Matrix;
|
||||
$matrix->columns = array(
|
||||
'epc_description' => function( $key, $value, $data )
|
||||
{
|
||||
return new \IPS\Helpers\Form\Text( $key, $value, TRUE );
|
||||
},
|
||||
'epc_quantity' => function( $key, $value, $data )
|
||||
{
|
||||
return new \IPS\Helpers\Form\Number( $key, $value ?: 1, TRUE );
|
||||
},
|
||||
'epc_value' => function( $key, $value, $data )
|
||||
{
|
||||
return new \IPS\Helpers\Form\Number( $key, $value ?: 0, TRUE, array( 'decimals' => TRUE ) );
|
||||
},
|
||||
'epc_weight' => function( $key, $value, $data )
|
||||
{
|
||||
return new \IPS\Helpers\Form\Text( $key, $value ?: 0, TRUE, array( 'decimals' => 1 ) );
|
||||
},
|
||||
'epc_origin' => function( $key, $value, $data ) use ( $originCountries, $fromCountry )
|
||||
{
|
||||
return new \IPS\Helpers\Form\Select( $key, $value ?: $fromCountry, FALSE, array( 'options' => $originCountries ) );
|
||||
},
|
||||
'epc_hs_tarrif' => function( $key, $value, $data )
|
||||
{
|
||||
return new \IPS\Helpers\Form\Text( $key, $value, FALSE, array( 'maxLength' => 6, 'placeholder' => \IPS\Member::loggedIn()->language()->addToStack('optional') ) );
|
||||
},
|
||||
);
|
||||
foreach ( $shipment->items as $item )
|
||||
{
|
||||
$weight = new \IPS\nexus\Shipping\Weight( $item['weight']['kilograms'] );
|
||||
$matrix->rows[] = array(
|
||||
'epc_description' => $item['name'],
|
||||
'epc_quantity' => $item['quantity'],
|
||||
'epc_value' => $item['price']['currency'] === 'USD' ? $item['price']['amount'] : 0,
|
||||
'epc_weight' => round( $weight->float('oz'), 1 )
|
||||
);
|
||||
}
|
||||
|
||||
$form->addHeader( 'easypost_customs_header' );
|
||||
$form->addMatrix( 'easypost_customs_details', $matrix );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'o_tracknumber', NULL, FALSE, array( 'maxLength' => 255 ), NULL, NULL, NULL, 'o_tracknumber' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Url( 'tracking_url', NULL, FALSE, array( 'maxLength' => 255 ), NULL, NULL, NULL, 'tracking_url' ) );
|
||||
|
||||
/* Handle Submissions */
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
/* EasyPost */
|
||||
if ( isset( $values['shipment_ship_method'] ) AND $values['shipment_ship_method'] === 'easypost' )
|
||||
{
|
||||
try
|
||||
{
|
||||
/* Parcel Data */
|
||||
if ( $values['easypost_package'] === 'custom' )
|
||||
{
|
||||
$parcelData = array(
|
||||
'length' => $values['easypost_package_length'],
|
||||
'width' => $values['easypost_package_width'],
|
||||
'height' => $values['easypost_package_height'],
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$parcelData = array( 'predefined_package' => $values['easypost_package'] );
|
||||
}
|
||||
$parcelData['weight'] = $values['easypost_package_weight'];
|
||||
|
||||
/* Customs Info */
|
||||
$customsInfo = NULL;
|
||||
if ( isset( $values['easypost_customs_details'] ) )
|
||||
{
|
||||
$customItems = array();
|
||||
$totalValue = 0;
|
||||
foreach ( $values['easypost_customs_details'] as $customItem )
|
||||
{
|
||||
if ( $customItem['epc_description'] )
|
||||
{
|
||||
$totalValue += $customItem['epc_value'];
|
||||
$customItems[] = array(
|
||||
'description' => $customItem['epc_description'],
|
||||
'quantity' => $customItem['epc_quantity'],
|
||||
'value' => $customItem['epc_value'],
|
||||
'weight' => $customItem['epc_weight'],
|
||||
'hs_tariff_number' => $customItem['epc_hs_tarrif'],
|
||||
'origin_country' => $customItem['epc_origin'],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$customsInfo = array(
|
||||
'eel_pfc' => ( $totalValue < 2500 ) ? 'NOEEI 30.37(a)' : '',
|
||||
'contents_type' => 'merchandise',
|
||||
'customs_items' => $customItems
|
||||
);
|
||||
}
|
||||
|
||||
/* Send API call */
|
||||
$toAddress = $shipment->data['address'];
|
||||
$fromAddress = \IPS\GeoLocation::buildFromJson( \IPS\Settings::i()->easypost_address ?: \IPS\Settings::i()->site_address );
|
||||
$easyPost = \IPS\Http\Url::external( 'https://api.easypost.com/v2/shipments' )->request()->login( \IPS\Settings::i()->easypost_api_key, '' )->post( array( 'shipment' => array(
|
||||
'to_address' => array(
|
||||
'street1' => array_shift( $toAddress['addressLines'] ),
|
||||
'street2' => \count( $toAddress['addressLines'] ) ? implode( ', ', $toAddress['addressLines'] ) : NULL,
|
||||
'city' => $toAddress['city'],
|
||||
'state' => $toAddress['region'],
|
||||
'zip' => $toAddress['postalCode'],
|
||||
'country' => $toAddress['country'],
|
||||
'name' => $shipment->data['cm_first_name'] . ' ' . $shipment->data['cm_last_name'],
|
||||
'phone' => $shipment->data['cm_phone'],
|
||||
'email' => $shipment->invoice->member->email
|
||||
),
|
||||
'from_address' => array(
|
||||
'street1' => array_shift( $fromAddress->addressLines ),
|
||||
'street2' => \count( $fromAddress->addressLines ) ? implode( ', ', $fromAddress->addressLines ) : NULL,
|
||||
'city' => $fromAddress->city,
|
||||
'state' => $fromAddress->region,
|
||||
'zip' => $fromAddress->postalCode,
|
||||
'country' => $fromAddress->country,
|
||||
'company' => \IPS\Settings::i()->board_name,
|
||||
'phone' => \IPS\Settings::i()->easypost_phone,
|
||||
'email' => \IPS\Settings::i()->email_in
|
||||
),
|
||||
'parcel' => $parcelData,
|
||||
'customs_info' => $customsInfo
|
||||
) ) )->decodeJson();
|
||||
|
||||
if ( !\count( $easyPost['rates'] ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'err_no_easypost', '1X193/6', 403, '' );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=nexus&module=payments&controller=shipping&do=easypost&id={$easyPost['id']}&shipment={$shipment->id}" ) );
|
||||
}
|
||||
catch ( \IPS\Http\Request\Exception $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'err_err_easypost', '3X193/7', 500, '', array(), $e->getMessage() );
|
||||
}
|
||||
}
|
||||
/* Manual */
|
||||
else
|
||||
{
|
||||
$shipment->status = \IPS\nexus\Shipping\Order::STATUS_SHIPPED;
|
||||
$shipment->shipped_date = new \IPS\DateTime;
|
||||
if ( $values['o_tracknumber'] )
|
||||
{
|
||||
$shipment->tracknumber = $values['o_tracknumber'];
|
||||
}
|
||||
if ( $values['tracking_url'] )
|
||||
{
|
||||
$shipment->service = $values['tracking_url'];
|
||||
}
|
||||
$shipment->save();
|
||||
$shipment->sendNotification();
|
||||
}
|
||||
|
||||
$shipment->invoice->member->log( 'shipping', array( 'id' => $shipment->id ) );
|
||||
$this->_redirect( $shipment );
|
||||
}
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'shipment_number', FALSE, array( 'sprintf' => array( $shipment->id ) ) );
|
||||
\IPS\Output::i()->output = $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* EasyPost
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function easypost()
|
||||
{
|
||||
/* Get Data */
|
||||
try
|
||||
{
|
||||
$easyPost = \IPS\Http\Url::external( 'https://api.easypost.com/v2/shipments/' . \IPS\Request::i()->id )->request()->login( \IPS\Settings::i()->easypost_api_key, '' )->get()->decodeJson();
|
||||
$shipment = \IPS\nexus\Shipping\Order::load( \IPS\Request::i()->shipment );
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'err_err_easypost', '3X193/8', 500, '', array(), $e->getMessage() );
|
||||
}
|
||||
|
||||
/* Gigure out our options */
|
||||
$selected = NULL;
|
||||
$options = array();
|
||||
$descriptions = array();
|
||||
foreach ( $easyPost['rates'] as $rate )
|
||||
{
|
||||
if ( $rate['service'] === $shipment->api_service )
|
||||
{
|
||||
$selected = $rate['id'];
|
||||
}
|
||||
|
||||
$service = '';
|
||||
for ( $i=0; $i<\strlen( $rate['service'] ); $i++ )
|
||||
{
|
||||
if ( \strtoupper( $rate['service'][ $i ] ) === $rate['service'][ $i ] )
|
||||
{
|
||||
$service .= " {$rate['service'][ $i ]}";
|
||||
}
|
||||
else
|
||||
{
|
||||
$service .= $rate['service'][ $i ];
|
||||
}
|
||||
}
|
||||
|
||||
$options[ $rate['id'] ] = $rate['carrier'] . $service . ' - ' . new \IPS\nexus\Money( $rate['rate'], $rate['currency'] );
|
||||
if ( $rate['est_delivery_days'] )
|
||||
{
|
||||
$descriptions[ $rate['id'] ] = \IPS\Member::loggedIn()->language()->addToStack( 'easypost_rates_desc', FALSE, array( 'sprintf' => array( $rate['est_delivery_days'] ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
/* Build form */
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'easypost_rate', $selected, TRUE, array( 'options' => $options, 'descriptions' => $descriptions ) ) );
|
||||
|
||||
/* Handle submissions */
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
try
|
||||
{
|
||||
$response = \IPS\Http\Url::external( 'https://api.easypost.com/v2/shipments/' . \IPS\Request::i()->id . '/buy' )->request()->login( \IPS\Settings::i()->easypost_api_key, '' )->post( array(
|
||||
'rate' => array(
|
||||
'id' => $values['easypost_rate']
|
||||
)
|
||||
) )->decodeJson();
|
||||
|
||||
if ( isset( $response['error'] ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'err_err_easypost', '3X193/9', 500, '', array(), $response['error']['message'] );
|
||||
}
|
||||
|
||||
$shipment->label = $response['postage_label']['label_url'];
|
||||
$shipment->tracknumber = $response['tracking_code'];
|
||||
$shipment->extra = json_encode( array( 'shipment' => $response['selected_rate']['shipment_id'], 'rate' => $response['selected_rate']['id'] ) );
|
||||
$shipment->status = \IPS\nexus\Shipping\Order::STATUS_SHIPPED;
|
||||
$shipment->shipped_date = new \IPS\DateTime;
|
||||
$shipment->save();
|
||||
$shipment->sendNotification();
|
||||
|
||||
\IPS\Output::i()->redirect( $shipment->acpUrl() );
|
||||
}
|
||||
catch ( \IPS\Http\Request\Exception $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'err_err_easypost', '3X193/A', 500, '', array(), $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
/* How much did the customer pay for shipping? */
|
||||
$invoiceSummary = $shipment->invoice->summary();
|
||||
$otherShipments = \count( $shipment->invoice->shipments() ) - 1;
|
||||
$message = $otherShipments ? \IPS\Member::loggedIn()->language()->addToStack( 'shipment_cost_others', FALSE, array( 'sprintf' => array( $invoiceSummary['shippingTotal'], $shipment->invoice->id, $otherShipments ) ) ) : \IPS\Member::loggedIn()->language()->addToStack( 'shipment_cost_noothers', FALSE, array( 'sprintf' => array( $invoiceSummary['shippingTotal'] ) ) );
|
||||
\IPS\Member::loggedIn()->language()->words['easypost_rate_desc'] = $message;
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'shipment_number', FALSE, array( 'sprintf' => array( $shipment->id ) ) );
|
||||
\IPS\Output::i()->output = $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function cancel()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'shiporders_edit' );
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
/* Load */
|
||||
try
|
||||
{
|
||||
$shipment = \IPS\nexus\Shipping\Order::load( \IPS\Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X193/4', 404, '' );
|
||||
}
|
||||
|
||||
/* Cancel */
|
||||
$shipment->status = $shipment::STATUS_CANCELED;
|
||||
$shipment->save();
|
||||
|
||||
/* Log */
|
||||
$shipment->invoice->member->log( 'shipping', array( 'id' => $shipment->id, 'type' => 'canc' ) );
|
||||
|
||||
/* Redirect */
|
||||
$this->_redirect( $shipment );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'shiporders_delete' );
|
||||
|
||||
/* Make sure the user confirmed the deletion */
|
||||
\IPS\Request::i()->confirmedDelete();
|
||||
|
||||
/* Load */
|
||||
try
|
||||
{
|
||||
$shipment = \IPS\nexus\Shipping\Order::load( \IPS\Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X193/5', 404, '' );
|
||||
}
|
||||
|
||||
/* Delete */
|
||||
$shipment->delete();
|
||||
|
||||
/* Log */
|
||||
try
|
||||
{
|
||||
$shipment->invoice->member->log( 'shipping', array( 'id' => $shipment->id, 'deleted' => TRUE ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) {}
|
||||
|
||||
/* Redirect */
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=payments&controller=shipping') );
|
||||
}
|
||||
|
||||
/**
|
||||
* Print
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function printout()
|
||||
{
|
||||
/* Load */
|
||||
try
|
||||
{
|
||||
$shipment = \IPS\nexus\Shipping\Order::load( \IPS\Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X193/3', 404, '' );
|
||||
}
|
||||
$data = $shipment->data;
|
||||
|
||||
if ( \IPS\Request::i()->print === 'apilabel' )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( $shipment->label, 200, 'application/pdf' );
|
||||
}
|
||||
|
||||
if ( \IPS\Request::i()->print === 'label' )
|
||||
{
|
||||
$output = \IPS\Theme::i()->getTemplate('shiporders', 'nexus', 'global')->packingLabel( $shipment );
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'shipping.css', 'nexus' ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$output = \IPS\Theme::i()->getTemplate('shiporders', 'nexus', 'global')->packingSheet( $shipment );
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'shipping.css', 'nexus' ) );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core', 'front' )->blankTemplate( $output ), 200, 'text/html' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect
|
||||
*
|
||||
* @param \IPS\nexus\Shipping\Order $shipment The shipment
|
||||
* @return void
|
||||
*/
|
||||
protected function _redirect( \IPS\nexus\Shipping\Order $shipment )
|
||||
{
|
||||
if ( isset( \IPS\Request::i()->r ) )
|
||||
{
|
||||
switch ( \IPS\Request::i()->r )
|
||||
{
|
||||
case 'v':
|
||||
\IPS\Output::i()->redirect( $shipment->acpUrl() );
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
\IPS\Output::i()->redirect( $shipment->invoice->acpUrl() );
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
\IPS\Output::i()->redirect( $shipment->member->acpUrl() );
|
||||
break;
|
||||
|
||||
case 't':
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=payments&controller=shipping') );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( $transaction->acpUrl() );
|
||||
}
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Shipping Rates
|
||||
* @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 13 Feb 2014
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\modules\admin\payments;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shipping
|
||||
*/
|
||||
class _shippingrates extends \IPS\Node\Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
protected $nodeClass = 'IPS\nexus\Shipping\FlatRate';
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'shipmethods_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Warning about unconsecutive rules
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function warning()
|
||||
{
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->decision( 'ship_rates_' . \IPS\Request::i()->type, array(
|
||||
'ship_rates_go_back' => \IPS\Http\Url::internal( 'app=nexus&module=payments&controller=shippingrates&do=form&id=' . \IPS\Request::i()->id ),
|
||||
'ship_rates_save_anyway' => $this->url,
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect after save
|
||||
*
|
||||
* @param \IPS\Node\Model|NULL $old A clone of the node as it was before or NULL if this is a creation
|
||||
* @param \IPS\Node\Model $new The node now
|
||||
* @param string $lastUsedTab The tab last used in the form
|
||||
* @return void
|
||||
*/
|
||||
protected function _afterSave( ?\IPS\Node\Model $old, \IPS\Node\Model $new, $lastUsedTab = FALSE )
|
||||
{
|
||||
$haveNoLowerLimit = FALSE;
|
||||
$haveNoUpperLimit = FALSE;
|
||||
$lastUpper = NULL;
|
||||
$consecutive = TRUE;
|
||||
|
||||
foreach ( json_decode( $new->rates, TRUE ) as $rate )
|
||||
{
|
||||
if ( !$haveNoLowerLimit )
|
||||
{
|
||||
if ( $rate['min'] === '*' )
|
||||
{
|
||||
$haveNoLowerLimit = TRUE;
|
||||
}
|
||||
elseif ( \is_array( $rate['min'] ) )
|
||||
{
|
||||
$allAreZero = TRUE;
|
||||
foreach ( $rate['min'] as $val )
|
||||
{
|
||||
if ( (int) $val !== 0 )
|
||||
{
|
||||
$allAreZero = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $allAreZero )
|
||||
{
|
||||
$haveNoLowerLimit = TRUE;
|
||||
}
|
||||
}
|
||||
elseif ( (int) $rate['min'] === 0 )
|
||||
{
|
||||
$haveNoLowerLimit = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !$haveNoUpperLimit and $rate['max'] === '*' )
|
||||
{
|
||||
$haveNoUpperLimit = TRUE;
|
||||
}
|
||||
|
||||
if ( $lastUpper !== NULL )
|
||||
{
|
||||
if ( \is_array( $lastUpper ) )
|
||||
{
|
||||
foreach ( $lastUpper as $k => $v )
|
||||
{
|
||||
if ( \strval( $rate['min'][ $k ] - $v ) >= 0.02 ) # @note: We use strval() here to prevent PHP from applying a precision to the float, inadvertently causing this to return TRUE
|
||||
{
|
||||
$consecutive = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif ( \strval( $rate['min'] - $lastUpper ) >= 0.02 ) # @note: We use strval() here to prevent PHP from applying a precision to the float, inadvertently causing this to return TRUE
|
||||
{
|
||||
$consecutive = FALSE;
|
||||
}
|
||||
}
|
||||
$lastUpper = $rate['max'];
|
||||
}
|
||||
|
||||
if( !$haveNoLowerLimit )
|
||||
{
|
||||
\IPS\Output::i()->redirect( $this->url->setQueryString( array( 'do' => 'warning', 'type' => 'missing_lower', 'id' => $new->_id ) ) );
|
||||
}
|
||||
elseif( !$haveNoUpperLimit )
|
||||
{
|
||||
\IPS\Output::i()->redirect( $this->url->setQueryString( array( 'do' => 'warning', 'type' => 'missing_upper', 'id' => $new->_id ) ) );
|
||||
}
|
||||
elseif ( !$consecutive )
|
||||
{
|
||||
\IPS\Output::i()->redirect( $this->url->setQueryString( array( 'do' => 'warning', 'type' => 'unconsecutive', 'id' => $new->_id ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
parent::_afterSave( $old, $new, $lastUsedTab );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,35 +12,40 @@
|
||||
namespace IPS\nexus\modules\admin\payments;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Node\Controller;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* tax
|
||||
*/
|
||||
class _tax extends \IPS\Node\Controller
|
||||
class tax extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
protected $nodeClass = 'IPS\nexus\Tax';
|
||||
protected string $nodeClass = 'IPS\nexus\Tax';
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'tax_manage' );
|
||||
Dispatcher::i()->checkAcpPermission( 'tax_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
}
|
||||
@@ -12,31 +12,62 @@
|
||||
namespace IPS\nexus\modules\admin\payments;
|
||||
|
||||
/* 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\Dispatcher;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\Number;
|
||||
use IPS\Helpers\Form\Radio;
|
||||
use IPS\Helpers\Form\YesNo;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Invoice;
|
||||
use IPS\nexus\Money;
|
||||
use IPS\nexus\Transaction;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
use IPS\Session;
|
||||
use IPS\Theme;
|
||||
use LogicException;
|
||||
use OutOfRangeException;
|
||||
use RuntimeException;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
use const IPS\Helpers\Table\SEARCH_CONTAINS_TEXT;
|
||||
use const IPS\Helpers\Table\SEARCH_DATE_RANGE;
|
||||
use const IPS\Helpers\Table\SEARCH_MEMBER;
|
||||
use const IPS\Helpers\Table\SEARCH_NODE;
|
||||
use const IPS\Helpers\Table\SEARCH_NUMERIC;
|
||||
use const IPS\Helpers\Table\SEARCH_SELECT;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transactions
|
||||
*/
|
||||
class _transactions extends \IPS\Dispatcher\Controller
|
||||
class transactions extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'transactions_manage' );
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'transaction.css', 'nexus', 'admin' ) );
|
||||
Dispatcher::i()->checkAcpPermission( 'transactions_manage' );
|
||||
Output::i()->cssFiles = array_merge( Output::i()->cssFiles, Theme::i()->css( 'transaction.css', 'nexus', 'admin' ) );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -45,30 +76,30 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
/* Create Table */
|
||||
$table = \IPS\nexus\Transaction::table( array( array( 't_status<>?', \IPS\nexus\Transaction::STATUS_PENDING ) ), \IPS\Http\Url::internal( 'app=nexus&module=payments&controller=transactions' ), 't' );
|
||||
$table = Transaction::table( array( array( 't_status<>?', Transaction::STATUS_PENDING ) ), Url::internal( 'app=nexus&module=payments&controller=transactions' ), 't' );
|
||||
$table->filters = array(
|
||||
'trans_attention_required' => 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 ) ) ),
|
||||
'trans_attention_required' => array( Db::i()->in( 't_status', array( Transaction::STATUS_HELD, Transaction::STATUS_WAITING, Transaction::STATUS_REVIEW, Transaction::STATUS_DISPUTED ) ) ),
|
||||
);
|
||||
$table->advancedSearch = array(
|
||||
't_id' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT,
|
||||
't_status' => array( \IPS\Helpers\Table\SEARCH_SELECT, array( 'options' => \IPS\nexus\Transaction::statuses(), 'multiple' => TRUE ) ),
|
||||
't_member' => \IPS\Helpers\Table\SEARCH_MEMBER,
|
||||
't_amount' => \IPS\Helpers\Table\SEARCH_NUMERIC,
|
||||
't_method' => array( \IPS\Helpers\Table\SEARCH_NODE, array( 'class' => '\IPS\nexus\Gateway' ) ),
|
||||
't_date' => \IPS\Helpers\Table\SEARCH_DATE_RANGE,
|
||||
't_id' => SEARCH_CONTAINS_TEXT,
|
||||
't_status' => array( SEARCH_SELECT, array( 'options' => Transaction::statuses(), 'multiple' => TRUE ) ),
|
||||
't_member' => SEARCH_MEMBER,
|
||||
't_amount' => SEARCH_NUMERIC,
|
||||
't_method' => array( SEARCH_NODE, array( 'class' => '\IPS\nexus\Gateway' ) ),
|
||||
't_date' => SEARCH_DATE_RANGE,
|
||||
);
|
||||
$table->quickSearch = 't_id';
|
||||
|
||||
/* Display */
|
||||
if ( isset( \IPS\Request::i()->attn ) and \IPS\Db::i()->select( 'COUNT(*)', 'nexus_transactions', array( '( t_status=? OR t_status=? OR t_status=? )', \IPS\nexus\Transaction::STATUS_HELD, \IPS\nexus\Transaction::STATUS_REVIEW, \IPS\nexus\Transaction::STATUS_DISPUTED ) ) )
|
||||
if ( isset( Request::i()->attn ) and Db::i()->select( 'COUNT(*)', 'nexus_transactions', array( '( t_status=? OR t_status=? OR t_status=? )', Transaction::STATUS_HELD, Transaction::STATUS_REVIEW, Transaction::STATUS_DISPUTED ) ) )
|
||||
{
|
||||
$table->filter = 'trans_attention_required';
|
||||
}
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__nexus_payments_transactions');
|
||||
\IPS\Output::i()->output = (string) $table;
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('menu__nexus_payments_transactions');
|
||||
Output::i()->output = (string) $table;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,21 +107,21 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function view()
|
||||
public function view() : void
|
||||
{
|
||||
/* Load Transaction */
|
||||
try
|
||||
{
|
||||
$transaction = \IPS\nexus\Transaction::load( \IPS\Request::i()->id );
|
||||
$transaction = Transaction::load( Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X186/8', 404, '' );
|
||||
Output::i()->error( 'node_error', '2X186/8', 404, '' );
|
||||
}
|
||||
|
||||
/* Output */
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'transaction_number', FALSE, array( 'sprintf' => array( $transaction->id ) ) );
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'transactions' )->view( $transaction );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack( 'transaction_number', FALSE, array( 'sprintf' => array( $transaction->id ) ) );
|
||||
Output::i()->output = Theme::i()->getTemplate( 'transactions' )->view( $transaction );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,26 +129,27 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function approve()
|
||||
public function approve() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'transactions_edit' );
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
Dispatcher::i()->checkAcpPermission( 'transactions_edit' );
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
/* Load Transaction */
|
||||
try
|
||||
{
|
||||
$transaction = \IPS\nexus\Transaction::load( \IPS\Request::i()->id );
|
||||
$transaction = Transaction::load( Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X186/9', 404, '' );
|
||||
Output::i()->error( 'node_error', '2X186/9', 404, '' );
|
||||
}
|
||||
|
||||
$method = $transaction->method;
|
||||
|
||||
/* Can we approve it? */
|
||||
if ( !$method or !\in_array( $transaction->status, array( \IPS\nexus\Transaction::STATUS_WAITING, \IPS\nexus\Transaction::STATUS_HELD, \IPS\nexus\Transaction::STATUS_REVIEW, \IPS\nexus\Transaction::STATUS_GATEWAY_PENDING, \IPS\nexus\Transaction::STATUS_DISPUTED ) ) )
|
||||
if ( !$method or !in_array( $transaction->status, array( Transaction::STATUS_WAITING, Transaction::STATUS_HELD, Transaction::STATUS_REVIEW, Transaction::STATUS_GATEWAY_PENDING, Transaction::STATUS_DISPUTED ) ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'transaction_status_err', '2X186/A', 403, '' );
|
||||
Output::i()->error( 'transaction_status_err', '2X186/A', 403, '' );
|
||||
}
|
||||
|
||||
/* Log it */
|
||||
@@ -125,7 +157,7 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$transaction->member->log( 'transaction', array(
|
||||
'type' => 'status',
|
||||
'status' => \IPS\nexus\Transaction::STATUS_PAID,
|
||||
'status' => Transaction::STATUS_PAID,
|
||||
'id' => $transaction->id
|
||||
) );
|
||||
}
|
||||
@@ -133,28 +165,29 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
/* Do it */
|
||||
try
|
||||
{
|
||||
if ( $transaction->status !== \IPS\nexus\Transaction::STATUS_DISPUTED )
|
||||
if ( $transaction->status !== Transaction::STATUS_DISPUTED )
|
||||
{
|
||||
$transaction->capture();
|
||||
}
|
||||
$transaction->approve( \IPS\Member::loggedIn() );
|
||||
|
||||
$transaction->approve( Member::loggedIn() );
|
||||
}
|
||||
catch ( \LogicException $e )
|
||||
catch ( LogicException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( $e->getMessage(), '3X186/2', 500, '' );
|
||||
Output::i()->error( $e->getMessage(), '3X186/2', 500, '' );
|
||||
}
|
||||
catch ( \RuntimeException $e )
|
||||
catch ( RuntimeException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'transaction_capture_err', '3X186/3', 500, '' );
|
||||
Output::i()->error( 'transaction_capture_err', '3X186/3', 500, '' );
|
||||
}
|
||||
|
||||
/* Send Email */
|
||||
$transaction->sendNotification();
|
||||
|
||||
/* Redirect */
|
||||
if ( \IPS\Request::i()->isAjax() and \IPS\Request::i()->queueStatus )
|
||||
if ( Request::i()->isAjax() and Request::i()->queueStatus )
|
||||
{
|
||||
\IPS\Output::i()->json( array( 'message' => \IPS\Member::loggedIn()->language()->addToStack('tstatus_okay_set'), 'queue' => \IPS\nexus\extensions\core\AdminNotifications\Transaction::queueHtml( \IPS\Request::i()->queueStatus ) ) );
|
||||
Output::i()->json( array( 'message' => Member::loggedIn()->language()->addToStack('tstatus_okay_set'), 'queue' => \IPS\nexus\extensions\core\AdminNotifications\Transaction::queueHtml( Request::i()->queueStatus ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -167,33 +200,32 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function review()
|
||||
public function review() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'transactions_edit' );
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Dispatcher::i()->checkAcpPermission( 'transactions_edit' );
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
/* Load Transaction */
|
||||
try
|
||||
{
|
||||
$transaction = \IPS\nexus\Transaction::load( \IPS\Request::i()->id );
|
||||
$transaction = Transaction::load( Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X186/C', 404, '' );
|
||||
Output::i()->error( 'node_error', '2X186/C', 404, '' );
|
||||
}
|
||||
$method = $transaction->method;
|
||||
|
||||
|
||||
/* Can we flag it? */
|
||||
if ( !\in_array( $transaction->status, array( \IPS\nexus\Transaction::STATUS_WAITING, \IPS\nexus\Transaction::STATUS_HELD ) ) )
|
||||
if ( !in_array( $transaction->status, array( Transaction::STATUS_WAITING, Transaction::STATUS_HELD ) ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'transaction_status_err', '2X186/B', 403, '' );
|
||||
Output::i()->error( 'transaction_status_err', '2X186/B', 403, '' );
|
||||
}
|
||||
|
||||
/* Set it */
|
||||
$extra = $transaction->extra;
|
||||
$extra['history'][] = array( 's' => \IPS\nexus\Transaction::STATUS_REVIEW, 'on' => time(), 'by' => \IPS\Member::loggedIn()->member_id );
|
||||
$extra['history'][] = array( 's' => Transaction::STATUS_REVIEW, 'on' => time(), 'by' => Member::loggedIn()->member_id );
|
||||
$transaction->extra = $extra;
|
||||
$transaction->status = \IPS\nexus\Transaction::STATUS_REVIEW;
|
||||
$transaction->status = Transaction::STATUS_REVIEW;
|
||||
$transaction->save();
|
||||
|
||||
/* Log it */
|
||||
@@ -201,59 +233,18 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$transaction->member->log( 'transaction', array(
|
||||
'type' => 'status',
|
||||
'status' => \IPS\nexus\Transaction::STATUS_REVIEW,
|
||||
'status' => Transaction::STATUS_REVIEW,
|
||||
'id' => $transaction->id
|
||||
) );
|
||||
}
|
||||
|
||||
/* Notification */
|
||||
\IPS\core\AdminNotification::send( 'nexus', 'Transaction', \IPS\nexus\Transaction::STATUS_REVIEW, TRUE, $transaction );
|
||||
|
||||
/* Create a support request? */
|
||||
if ( \IPS\Settings::i()->nexus_revw_sa != -1 )
|
||||
{
|
||||
$extraData = array();
|
||||
if ( $transaction->member->member_id )
|
||||
{
|
||||
$extraData['member'] = $transaction->member->member_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
$extraData['email'] = $transaction->invoice->guest_data['member']['email'];
|
||||
}
|
||||
|
||||
$createUrl = \IPS\Http\Url::internal('app=nexus&module=support&controller=requests&do=create');
|
||||
$key = md5( $createUrl );
|
||||
|
||||
if ( \IPS\Settings::i()->nexus_revw_sa )
|
||||
{
|
||||
$extraData['stock_action'] = \IPS\Settings::i()->nexus_revw_sa;
|
||||
$_SESSION["wizard-{$key}-data"] = $extraData;
|
||||
$_SESSION["wizard-{$key}-step"] = 'request_details';
|
||||
}
|
||||
else
|
||||
{
|
||||
$_SESSION["wizard-{$key}-data"] = $extraData;
|
||||
if ( \count( \IPS\nexus\Support\StockAction::roots() ) )
|
||||
{
|
||||
$_SESSION["wizard-{$key}-step"] = 'stock_action';
|
||||
}
|
||||
else
|
||||
{
|
||||
$_SESSION["wizard-{$key}-step"] = 'request_details';
|
||||
}
|
||||
}
|
||||
|
||||
$_SESSION["wizard-{$key}-data"]['transaction'] = $transaction->id;
|
||||
$_SESSION["wizard-{$key}-data"]['ref'] = isset( \IPS\Request::i()->r ) ? \IPS\Request::i()->r : 'v';
|
||||
|
||||
\IPS\Output::i()->redirect( $createUrl );
|
||||
}
|
||||
AdminNotification::send( 'nexus', 'Transaction', Transaction::STATUS_REVIEW, TRUE, $transaction );
|
||||
|
||||
/* Redirect */
|
||||
if ( \IPS\Request::i()->isAjax() and \IPS\Request::i()->queueStatus )
|
||||
if ( Request::i()->isAjax() and Request::i()->queueStatus )
|
||||
{
|
||||
\IPS\Output::i()->json( array( 'message' => \IPS\Member::loggedIn()->language()->addToStack('tstatus_revw_set'), 'queue' => \IPS\nexus\extensions\core\AdminNotifications\Transaction::queueHtml( \IPS\Request::i()->queueStatus ) ) );
|
||||
Output::i()->json( array( 'message' => Member::loggedIn()->language()->addToStack('tstatus_revw_set'), 'queue' => \IPS\nexus\extensions\core\AdminNotifications\Transaction::queueHtml( Request::i()->queueStatus ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -266,38 +257,37 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function void()
|
||||
public function void() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'transactions_edit' );
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Dispatcher::i()->checkAcpPermission( 'transactions_edit' );
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
/* Load Transaction */
|
||||
try
|
||||
{
|
||||
$transaction = \IPS\nexus\Transaction::load( \IPS\Request::i()->id );
|
||||
$transaction = Transaction::load( Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X186/4', 404, '' );
|
||||
Output::i()->error( 'node_error', '2X186/4', 404, '' );
|
||||
}
|
||||
$method = $transaction->method;
|
||||
|
||||
|
||||
/* Can we void it? */
|
||||
if ( !\in_array( $transaction->status, array( \IPS\nexus\Transaction::STATUS_WAITING, \IPS\nexus\Transaction::STATUS_GATEWAY_PENDING ) ) and ( !$transaction->auth or !\in_array( $transaction->status, array( \IPS\nexus\Transaction::STATUS_HELD, \IPS\nexus\Transaction::STATUS_REVIEW ) ) ) )
|
||||
if ( !in_array( $transaction->status, array( Transaction::STATUS_WAITING, Transaction::STATUS_GATEWAY_PENDING ) ) and ( !$transaction->auth or !in_array( $transaction->status, array( Transaction::STATUS_HELD, Transaction::STATUS_REVIEW ) ) ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'transaction_status_err', '2X186/5', 403, '' );
|
||||
Output::i()->error( 'transaction_status_err', '2X186/5', 403, '' );
|
||||
}
|
||||
|
||||
/* Void it */
|
||||
try
|
||||
{
|
||||
$transaction->void( $transaction );
|
||||
$transaction->void();
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
catch ( Exception $e )
|
||||
{
|
||||
if ( !isset( \IPS\Request::i()->override ) )
|
||||
if ( !isset( Request::i()->override ) )
|
||||
{
|
||||
\IPS\Output::i()->error( \IPS\Member::loggedIn()->language()->addToStack( 'transaction_void_err', FALSE, array( 'sprintf' => array( $transaction->acpUrl()->setQueryString( array( 'do' => 'void', 'override' => 1 ) ) ) ) ), '3X186/6', 500, '', array(), $e->getMessage() );
|
||||
Output::i()->error( Member::loggedIn()->language()->addToStack( 'transaction_void_err', FALSE, array( 'sprintf' => array( $transaction->acpUrl()->setQueryString( array( 'do' => 'void', 'override' => 1 ) ) ) ) ), '3X186/6', 500, '', array(), $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,9 +295,9 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
$transaction->sendNotification();
|
||||
|
||||
/* Redirect */
|
||||
if ( \IPS\Request::i()->isAjax() and \IPS\Request::i()->queueStatus )
|
||||
if ( Request::i()->isAjax() and Request::i()->queueStatus )
|
||||
{
|
||||
\IPS\Output::i()->json( array( 'message' => \IPS\Member::loggedIn()->language()->addToStack('tstatus_fail_set'), 'queue' => \IPS\nexus\extensions\core\AdminNotifications\Transaction::queueHtml( \IPS\Request::i()->queueStatus ) ) );
|
||||
Output::i()->json( array( 'message' => Member::loggedIn()->language()->addToStack('tstatus_fail_set'), 'queue' => \IPS\nexus\extensions\core\AdminNotifications\Transaction::queueHtml( Request::i()->queueStatus ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -320,25 +310,25 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function refund()
|
||||
public function refund() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'transactions_refund' );
|
||||
Dispatcher::i()->checkAcpPermission( 'transactions_refund' );
|
||||
|
||||
/* Load Transaction */
|
||||
try
|
||||
{
|
||||
$transaction = \IPS\nexus\Transaction::load( \IPS\Request::i()->id );
|
||||
$transaction = Transaction::load( Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X186/D', 404, '' );
|
||||
Output::i()->error( 'node_error', '2X186/D', 404, '' );
|
||||
}
|
||||
$method = $transaction->method;
|
||||
|
||||
/* Can we refund it? */
|
||||
if ( !\in_array( $transaction->status, array( \IPS\nexus\Transaction::STATUS_PAID, \IPS\nexus\Transaction::STATUS_HELD, \IPS\nexus\Transaction::STATUS_REVIEW, \IPS\nexus\Transaction::STATUS_PART_REFUNDED, \IPS\nexus\Transaction::STATUS_DISPUTED ) ) )
|
||||
if ( !in_array( $transaction->status, array( Transaction::STATUS_PAID, Transaction::STATUS_HELD, Transaction::STATUS_REVIEW, Transaction::STATUS_PART_REFUNDED, Transaction::STATUS_DISPUTED ) ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'transaction_status_err', '2X186/E', 403, '' );
|
||||
Output::i()->error( 'transaction_status_err', '2X186/E', 403, '' );
|
||||
}
|
||||
|
||||
/* What are the refund methods? */
|
||||
@@ -366,22 +356,22 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
$refundMethods['none'] = 'refund_method_none';
|
||||
|
||||
/* Build form */
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'refund_method', ( $method and $method::SUPPORTS_REFUNDS ) ? 'gateway' : 'credit', TRUE, array( 'options' => $refundMethods, 'toggles' => $refundMethodToggles ) ) );
|
||||
$form = new Form;
|
||||
$form->add( new Radio( 'refund_method', ( $method and $method::SUPPORTS_REFUNDS ) ? 'gateway' : 'credit', TRUE, array( 'options' => $refundMethods, 'toggles' => $refundMethodToggles ) ) );
|
||||
if ( $refundReasons )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'refund_reason', NULL, FALSE, array( 'options' => $refundReasons ), NULL, NULL, NULL, 'refund_reason' ) );
|
||||
$form->add( new Radio( 'refund_reason', NULL, FALSE, array( 'options' => $refundReasons ), NULL, NULL, NULL, 'refund_reason' ) );
|
||||
}
|
||||
if ( $method and $method::SUPPORTS_REFUNDS and $method::SUPPORTS_PARTIAL_REFUNDS )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'refund_amount', 0, TRUE, array(
|
||||
$form->add( new Number( 'refund_amount', 0, TRUE, array(
|
||||
'unlimited' => 0,
|
||||
'unlimitedLang' => (
|
||||
$transaction->partial_refund->amount->isGreaterThanZero()
|
||||
? \IPS\Member::loggedIn()->language()->addToStack( 'refund_full_remaining', FALSE, array( 'sprintf' => array(
|
||||
new \IPS\nexus\Money( $transaction->amount->amount->subtract( $transaction->partial_refund->amount ), $transaction->currency ) )
|
||||
? Member::loggedIn()->language()->addToStack( 'refund_full_remaining', FALSE, array( 'sprintf' => array(
|
||||
new Money( $transaction->amount->amount->subtract( $transaction->partial_refund->amount ), $transaction->currency ) )
|
||||
) )
|
||||
: \IPS\Member::loggedIn()->language()->addToStack( 'refund_full', FALSE, array( 'sprintf' => array( $transaction->amount ) ) )
|
||||
: Member::loggedIn()->language()->addToStack( 'refund_full', FALSE, array( 'sprintf' => array( $transaction->amount ) ) )
|
||||
),
|
||||
'max' => (string) $transaction->amount->amount->subtract( $transaction->partial_refund->amount ),
|
||||
'decimals' => TRUE
|
||||
@@ -389,19 +379,19 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
|
||||
if ( $transaction->credit->amount->isGreaterThanZero() )
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words['refund_amount_desc'] = sprintf( \IPS\Member::loggedIn()->language()->get('refund_amount_descwarn'), $transaction->credit );
|
||||
Member::loggedIn()->language()->words['refund_amount_desc'] = sprintf( Member::loggedIn()->language()->get('refund_amount_descwarn'), $transaction->credit );
|
||||
}
|
||||
}
|
||||
if ( $transaction->credit->amount->compare( $transaction->amount->amount ) === -1 )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'refund_credit_amount', 0, TRUE, array(
|
||||
$form->add( new Number( 'refund_credit_amount', 0, TRUE, array(
|
||||
'unlimited' => 0,
|
||||
'unlimitedLang' => (
|
||||
$transaction->credit->amount->isGreaterThanZero()
|
||||
? \IPS\Member::loggedIn()->language()->addToStack( 'refund_full_remaining', FALSE, array( 'sprintf' => array(
|
||||
new \IPS\nexus\Money( $transaction->amount->amount->subtract( $transaction->credit->amount ), $transaction->currency ) )
|
||||
? Member::loggedIn()->language()->addToStack( 'refund_full_remaining', FALSE, array( 'sprintf' => array(
|
||||
new Money( $transaction->amount->amount->subtract( $transaction->credit->amount ), $transaction->currency ) )
|
||||
) )
|
||||
: \IPS\Member::loggedIn()->language()->addToStack( 'refund_full', FALSE, array( 'sprintf' => array( $transaction->amount ) ) )
|
||||
: Member::loggedIn()->language()->addToStack( 'refund_full', FALSE, array( 'sprintf' => array( $transaction->amount ) ) )
|
||||
),
|
||||
'max' => (string) $transaction->amount->amount->subtract( $transaction->credit->amount ),
|
||||
'decimals' => TRUE
|
||||
@@ -409,43 +399,43 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
|
||||
if ( $transaction->partial_refund->amount->isGreaterThanZero() )
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words['refund_credit_amount_desc'] = sprintf( \IPS\Member::loggedIn()->language()->get('refund_credit_amount_descwarn'), $transaction->partial_refund );
|
||||
Member::loggedIn()->language()->words['refund_credit_amount_desc'] = sprintf( Member::loggedIn()->language()->get('refund_credit_amount_descwarn'), $transaction->partial_refund );
|
||||
}
|
||||
}
|
||||
if ( $transaction->credit->amount->isGreaterThanZero() )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'refund_reverse_credit', TRUE, TRUE, array( 'togglesOn' => array( 'form_refund_reverse_credit_warning' ) ), NULL, NULL, NULL, 'refund_reverse_credit' ) );
|
||||
\IPS\Member::loggedIn()->language()->words['refund_reverse_credit'] = sprintf( \IPS\Member::loggedIn()->language()->get( 'refund_reverse_credit' ), $transaction->credit );
|
||||
$form->add( new YesNo( 'refund_reverse_credit', TRUE, TRUE, array( 'togglesOn' => array( 'form_refund_reverse_credit_warning' ) ), NULL, NULL, NULL, 'refund_reverse_credit' ) );
|
||||
Member::loggedIn()->language()->words['refund_reverse_credit'] = sprintf( Member::loggedIn()->language()->get( 'refund_reverse_credit' ), $transaction->credit );
|
||||
|
||||
$credits = $transaction->member->cm_credits;
|
||||
if ( $credits[ $transaction->amount->currency ]->amount->compare( $transaction->credit->amount ) === -1 )
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words['refund_reverse_credit_warning'] = \IPS\Member::loggedIn()->language()->addToStack( 'account_credit_remove_neg' );
|
||||
Member::loggedIn()->language()->words['refund_reverse_credit_warning'] = Member::loggedIn()->language()->addToStack( 'account_credit_remove_neg' );
|
||||
}
|
||||
}
|
||||
if ( $transaction->invoice !== NULL and $transaction->invoice->status === \IPS\nexus\Invoice::STATUS_PAID )
|
||||
if ( $transaction->invoice !== NULL and $transaction->invoice->status === Invoice::STATUS_PAID )
|
||||
{
|
||||
$field = new \IPS\Helpers\Form\Radio( 'refund_invoice_status', \IPS\nexus\Invoice::STATUS_PENDING, TRUE, array(
|
||||
$field = new Radio( 'refund_invoice_status', Invoice::STATUS_PENDING, TRUE, array(
|
||||
'options' => array(
|
||||
\IPS\nexus\Invoice::STATUS_PAID => 'refund_invoice_paid',
|
||||
\IPS\nexus\Invoice::STATUS_PENDING => 'refund_invoice_pending',
|
||||
\IPS\nexus\Invoice::STATUS_CANCELED => 'refund_invoice_canceled',
|
||||
Invoice::STATUS_PAID => 'refund_invoice_paid',
|
||||
Invoice::STATUS_PENDING => 'refund_invoice_pending',
|
||||
Invoice::STATUS_CANCELED => 'refund_invoice_canceled',
|
||||
),
|
||||
'toggles' => array(
|
||||
\IPS\nexus\Invoice::STATUS_PENDING => array( 'form_refund_invoice_status_warning' ),
|
||||
\IPS\nexus\Invoice::STATUS_CANCELED => array( 'form_refund_invoice_status_warning' )
|
||||
Invoice::STATUS_PENDING => array( 'form_refund_invoice_status_warning' ),
|
||||
Invoice::STATUS_CANCELED => array( 'form_refund_invoice_status_warning' )
|
||||
)
|
||||
) );
|
||||
$field->warningBox = \IPS\Theme::i()->getTemplate('invoices')->unpaidConsequences( $transaction->invoice );
|
||||
$field->warningBox = Theme::i()->getTemplate('invoices')->unpaidConsequences( $transaction->invoice );
|
||||
$form->add( $field );
|
||||
}
|
||||
if ( $billingAgreement = $transaction->billing_agreement )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'refund_cancel_billing_agreement', TRUE, NULL, array( 'togglesOff' => array( 'form_refund_cancel_billing_agreement_warning' ) ) ) );
|
||||
$form->add( new YesNo( 'refund_cancel_billing_agreement', TRUE, NULL, array( 'togglesOff' => array( 'form_refund_cancel_billing_agreement_warning' ) ) ) );
|
||||
|
||||
if ( \IPS\Db::i()->select( 'COUNT(*)', 'nexus_transactions', array( 't_billing_agreement=? AND t_id<?', $billingAgreement->id, $transaction->id ) )->first() )
|
||||
if ( Db::i()->select( 'COUNT(*)', 'nexus_transactions', array( 't_billing_agreement=? AND t_id<?', $billingAgreement->id, $transaction->id ) )->first() )
|
||||
{
|
||||
unset( \IPS\Member::loggedIn()->language()->words['refund_cancel_billing_agreement_warning'] );
|
||||
unset( Member::loggedIn()->language()->words['refund_cancel_billing_agreement_warning'] );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -461,9 +451,9 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$transaction->billing_agreement->cancel();
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
catch ( Exception $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'billing_agreement_cancel_error', '3X186/G', 500, '', array(), $e->getMessage() );
|
||||
Output::i()->error( 'billing_agreement_cancel_error', '3X186/G', 500, '', array(), $e->getMessage() );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -487,21 +477,21 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
$amount = $values['refund_credit_amount'];
|
||||
}
|
||||
|
||||
$transaction->refund( $values['refund_method'], $amount, isset( $values['refund_reason'] ) ? $values['refund_reason'] : NULL );
|
||||
$transaction->refund( $values['refund_method'], $amount, $values['refund_reason'] ?? NULL);
|
||||
}
|
||||
catch ( \LogicException $e )
|
||||
catch ( LogicException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( $e->getMessage(), '1X186/1', 500, '' );
|
||||
Output::i()->error( $e->getMessage(), '1X186/1', 500, '' );
|
||||
}
|
||||
catch ( \RuntimeException $e )
|
||||
catch ( RuntimeException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'refund_failed', '3X186/7', 500, '' );
|
||||
Output::i()->error( 'refund_failed', '3X186/7', 500, '' );
|
||||
}
|
||||
|
||||
/* Handle invoice */
|
||||
if( $transaction->invoice !== NULL )
|
||||
{
|
||||
if ( isset( $values['refund_invoice_status'] ) and $values['refund_invoice_status'] !== \IPS\nexus\Invoice::STATUS_PAID )
|
||||
if ( isset( $values['refund_invoice_status'] ) and $values['refund_invoice_status'] !== Invoice::STATUS_PAID )
|
||||
{
|
||||
$transaction->invoice->markUnpaid( $values['refund_invoice_status'] );
|
||||
|
||||
@@ -524,8 +514,8 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
$this->_redirect( $transaction );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'transaction_refund_title', FALSE, array( 'sprintf' => array( $transaction->amount ) ) );
|
||||
\IPS\Output::i()->output = $form;
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack( 'transaction_refund_title', FALSE, array( 'sprintf' => array( $transaction->amount ) ) );
|
||||
Output::i()->output = $form;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -533,21 +523,21 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
public function delete() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'transactions_delete' );
|
||||
Dispatcher::i()->checkAcpPermission( 'transactions_delete' );
|
||||
|
||||
/* Make sure the user confirmed the deletion */
|
||||
\IPS\Request::i()->confirmedDelete();
|
||||
Request::i()->confirmedDelete();
|
||||
|
||||
/* Load Transaction */
|
||||
try
|
||||
{
|
||||
$transaction = \IPS\nexus\Transaction::load( \IPS\Request::i()->id );
|
||||
$transaction = Transaction::load( Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X186/F', 404, '' );
|
||||
Output::i()->error( 'node_error', '2X186/F', 404, '' );
|
||||
}
|
||||
|
||||
/* Delete */
|
||||
@@ -565,50 +555,50 @@ class _transactions extends \IPS\Dispatcher\Controller
|
||||
) );
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
// If the member no longer exists, we just won't log it
|
||||
}
|
||||
|
||||
/* Redirect */
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=payments&controller=transactions')->getSafeUrlFromFilters());
|
||||
Output::i()->redirect( Url::internal('app=nexus&module=payments&controller=transactions')->getSafeUrlFromFilters());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Redirect
|
||||
*
|
||||
* @param \IPS\nexus\Transaction $transaction The transaction
|
||||
* @param Transaction $transaction The transaction
|
||||
* @return void
|
||||
*/
|
||||
protected function _redirect( \IPS\nexus\Transaction $transaction )
|
||||
protected function _redirect( Transaction $transaction ) : void
|
||||
{
|
||||
if ( isset( \IPS\Request::i()->r ) )
|
||||
if ( isset( Request::i()->r ) )
|
||||
{
|
||||
switch ( \IPS\Request::i()->r )
|
||||
switch ( Request::i()->r )
|
||||
{
|
||||
case 'v':
|
||||
\IPS\Output::i()->redirect( $transaction->acpUrl()->getSafeUrlFromFilters() );
|
||||
Output::i()->redirect( $transaction->acpUrl()->getSafeUrlFromFilters() );
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
\IPS\Output::i()->redirect( $transaction->invoice->acpUrl()->getSafeUrlFromFilters() );
|
||||
Output::i()->redirect( $transaction->invoice->acpUrl()->getSafeUrlFromFilters() );
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
\IPS\Output::i()->redirect( $transaction->member->acpUrl()->getSafeUrlFromFilters());
|
||||
Output::i()->redirect( $transaction->member->acpUrl()->getSafeUrlFromFilters());
|
||||
break;
|
||||
|
||||
case 't':
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=payments&controller=transactions')->getSafeUrlFromFilters() );
|
||||
Output::i()->redirect( Url::internal('app=nexus&module=payments&controller=transactions')->getSafeUrlFromFilters() );
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=core&module=overview&controller=notifications')->getSafeUrlFromFilters());
|
||||
Output::i()->redirect( Url::internal('app=core&module=overview&controller=notifications')->getSafeUrlFromFilters());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( $transaction->acpUrl()->getSafeUrlFromFilters());
|
||||
Output::i()->redirect( $transaction->acpUrl()->getSafeUrlFromFilters());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief donations
|
||||
* @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 16 Mar 2023
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\modules\admin\reports;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\Helpers\Chart\Database;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\Output;
|
||||
use IPS\Theme;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ($_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0') . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* donations
|
||||
*/
|
||||
class donations extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* @brief Allow MySQL RW separation for efficiency
|
||||
*/
|
||||
public static bool $allowRWSeparation = TRUE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute() : void
|
||||
{
|
||||
Dispatcher::i()->checkAcpPermission( 'donations_stats_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* View Chart
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage() : void
|
||||
{
|
||||
$chart = new Database(
|
||||
Url::internal('app=nexus&module=reports&controller=donations'),
|
||||
'nexus_donate_logs',
|
||||
'dl_date',
|
||||
'',
|
||||
array(
|
||||
'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
|
||||
)
|
||||
);
|
||||
|
||||
$chart->groupBy = 'dl_goal';
|
||||
$chart->tableInclude = array( 'dl_id', 'dl_member', 'dl_amount', 'dl_date' );
|
||||
$chart->tableParsers = array(
|
||||
'dl_member' => function( $val ) {
|
||||
return Theme::i()->getTemplate('global', 'nexus')->userLink( Member::load( $val ) );
|
||||
},
|
||||
'dl_date' => function( $val ) {
|
||||
return DateTime::ts( $val );
|
||||
}
|
||||
);
|
||||
|
||||
$goals = array();
|
||||
foreach ( Db::i()->select( 'd_id', 'nexus_donate_goals' ) as $goalId )
|
||||
{
|
||||
$goals[ $goalId ] = Member::loggedIn()->language()->get( 'nexus_donategoal_' . $goalId );
|
||||
}
|
||||
|
||||
asort( $goals );
|
||||
foreach ( $goals as $id => $name )
|
||||
{
|
||||
$chart->addSeries( $name, 'number', 'sum(dl_amount)', TRUE, $id );
|
||||
}
|
||||
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('menu__nexus_reports_donations');
|
||||
Output::i()->output = (string) $chart;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
|
||||
|
||||
/**
|
||||
* @brief Income Report
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
@@ -12,35 +14,49 @@
|
||||
namespace IPS\nexus\modules\admin\reports;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\core\Statistics\Chart;
|
||||
use IPS\Helpers\Chart\Dynamic;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Money;
|
||||
use IPS\Output;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Income Report
|
||||
*/
|
||||
class _income extends \IPS\Dispatcher\Controller
|
||||
class income extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* @brief Allow MySQL RW separation for efficiency
|
||||
*/
|
||||
public static $allowRWSeparation = TRUE;
|
||||
public static bool $allowRWSeparation = TRUE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'income_manage' );
|
||||
Dispatcher::i()->checkAcpPermission( 'income_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -49,13 +65,13 @@ class _income extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
$currencies = \IPS\nexus\Money::currencies();
|
||||
$currencies = Money::currencies();
|
||||
|
||||
$tabs = array( 'totals' => 'nexus_report_income_totals' );
|
||||
|
||||
if( \count( $currencies ) == 1 )
|
||||
if( count( $currencies ) == 1 )
|
||||
{
|
||||
$tabs['members'] = 'nexus_report_income_members';
|
||||
}
|
||||
@@ -63,30 +79,31 @@ class _income extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
foreach ( $currencies as $currency )
|
||||
{
|
||||
$tabs[ 'members_' . $currency ] = \IPS\Member::loggedIn()->language()->addToStack( 'nexus_report_income_by_member', FALSE, array( 'sprintf' => array( $currency ) ) );
|
||||
$tabs[ 'members_' . $currency ] = Member::loggedIn()->language()->addToStack( 'nexus_report_income_by_member', FALSE, array( 'sprintf' => array( $currency ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $currencies as $currency )
|
||||
{
|
||||
$tabs[ $currency ] = \IPS\Member::loggedIn()->language()->addToStack( 'nexus_report_income_by_method', FALSE, array( 'sprintf' => array( $currency ) ) );
|
||||
$tabs[ $currency ] = Member::loggedIn()->language()->addToStack( 'nexus_report_income_by_method', FALSE, array( 'sprintf' => array( $currency ) ) );
|
||||
}
|
||||
|
||||
\IPS\Request::i()->tab ??= 'totals';
|
||||
$activeTab = ( array_key_exists( \IPS\Request::i()->tab, $tabs ) ) ? \IPS\Request::i()->tab : 'totals';
|
||||
|
||||
$extension = \IPS\core\Statistics\Chart::loadFromExtension( 'nexus', 'Income' );
|
||||
$chart = $extension->getChart( \IPS\Http\Url::internal( 'app=nexus&module=reports&controller=income&tab=' . $activeTab ) );
|
||||
Request::i()->tab ??= 'totals';
|
||||
$activeTab = ( array_key_exists( Request::i()->tab, $tabs ) ) ? Request::i()->tab : 'totals';
|
||||
|
||||
$extension = Chart::loadFromExtension( 'nexus', 'Income' );
|
||||
$chart = $extension->getChart( Url::internal( 'app=nexus&module=reports&controller=income&tab=' . $activeTab ) );
|
||||
$extension->setExtra( $chart, $activeTab );
|
||||
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
|
||||
/* @var Dynamic $chart */
|
||||
if ( Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->output = (string) $chart;
|
||||
Output::i()->output = (string) $chart;
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__nexus_reports_income');
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->tabs( $tabs, $activeTab, (string) $chart, \IPS\Http\Url::internal( "app=nexus&module=reports&controller=income" ) );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('menu__nexus_reports_income');
|
||||
Output::i()->output = Theme::i()->getTemplate( 'global', 'core' )->tabs( $tabs, $activeTab, (string) $chart, Url::internal( "app=nexus&module=reports&controller=income" ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,35 +12,49 @@
|
||||
namespace IPS\nexus\modules\admin\reports;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use InvalidArgumentException;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\core\Statistics\Chart;
|
||||
use IPS\Helpers\Chart\Dynamic;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Money;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Markets Report
|
||||
*/
|
||||
class _markets extends \IPS\Dispatcher\Controller
|
||||
class markets extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* @brief Allow MySQL RW separation for efficiency
|
||||
*/
|
||||
public static $allowRWSeparation = TRUE;
|
||||
public static bool $allowRWSeparation = TRUE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'markets_manage' );
|
||||
Dispatcher::i()->checkAcpPermission( 'markets_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -49,37 +63,37 @@ class _markets extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
$tabs['count'] = 'nexus_report_count';
|
||||
foreach ( \IPS\nexus\Money::currencies() as $currency )
|
||||
foreach ( Money::currencies() as $currency )
|
||||
{
|
||||
$tabs[ $currency ] = \IPS\Member::loggedIn()->language()->addToStack( 'nexus_report_income', FALSE, array( 'sprintf' => array( $currency ) ) );
|
||||
$tabs[ $currency ] = Member::loggedIn()->language()->addToStack( 'nexus_report_income', FALSE, array( 'sprintf' => array( $currency ) ) );
|
||||
}
|
||||
|
||||
\IPS\Request::i()->tab ??= 'count';
|
||||
$activeTab = ( array_key_exists( \IPS\Request::i()->tab, $tabs ) ) ? \IPS\Request::i()->tab : 'count';
|
||||
$extension = \IPS\core\Statistics\Chart::loadFromExtension( 'nexus', 'Market' );
|
||||
$chart = $extension->getChart( \IPS\Http\Url::internal( "app=nexus&module=reports&controller=markets&tab={$activeTab}" ) );
|
||||
|
||||
|
||||
Request::i()->tab ??= 'count';
|
||||
$activeTab = ( array_key_exists( Request::i()->tab, $tabs ) ) ? Request::i()->tab : 'count';
|
||||
$extension = Chart::loadFromExtension( 'nexus', 'Market' );
|
||||
$chart = $extension->getChart( Url::internal( "app=nexus&module=reports&controller=markets&tab={$activeTab}" ) );
|
||||
|
||||
if ( $activeTab !== 'count' )
|
||||
{
|
||||
try
|
||||
{
|
||||
$extension->setCurrency( $chart, $activeTab );
|
||||
}
|
||||
catch( \InvalidArgumentException ) {}
|
||||
catch( InvalidArgumentException ) {}
|
||||
}
|
||||
|
||||
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
|
||||
/* @var Dynamic $chart */
|
||||
if ( Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->output = (string) $chart;
|
||||
Output::i()->output = (string) $chart;
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__nexus_reports_markets');
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->tabs( $tabs, $activeTab, (string) $chart, \IPS\Http\Url::internal( "app=nexus&module=reports&controller=markets" ) );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('menu__nexus_reports_markets');
|
||||
Output::i()->output = Theme::i()->getTemplate( 'global', 'core' )->tabs( $tabs, $activeTab, (string) $chart, Url::internal( "app=nexus&module=reports&controller=markets" ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,35 +12,44 @@
|
||||
namespace IPS\nexus\modules\admin\reports;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\core\Statistics\Chart;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\Output;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Purchases Reports
|
||||
*/
|
||||
class _purchases extends \IPS\Dispatcher\Controller
|
||||
class purchases extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* @brief Allow MySQL RW separation for efficiency
|
||||
*/
|
||||
public static $allowRWSeparation = TRUE;
|
||||
public static bool $allowRWSeparation = TRUE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'purchases_manage' );
|
||||
Dispatcher::i()->checkAcpPermission( 'purchases_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -49,10 +58,9 @@ class _purchases extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
$chart = \IPS\core\Statistics\Chart::loadFromExtension( 'nexus', 'Sales' )->getChart( \IPS\Http\Url::internal( 'app=nexus&module=reports&controller=purchases' ) );
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__nexus_reports_purchases');
|
||||
\IPS\Output::i()->output = (string) $chart;
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('menu__nexus_reports_purchases');
|
||||
Output::i()->output = (string) Chart::loadFromExtension( 'nexus', 'Sales' )->getChart( Url::internal( 'app=nexus&module=reports&controller=purchases' ) );
|
||||
}
|
||||
}
|
||||
@@ -12,35 +12,49 @@
|
||||
namespace IPS\nexus\modules\admin\store;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Helpers\Table\Custom;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Coupon;
|
||||
use IPS\Node\Controller;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* coupons
|
||||
*/
|
||||
class _coupons extends \IPS\Node\Controller
|
||||
class coupons extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
protected $nodeClass = 'IPS\nexus\Coupon';
|
||||
protected string $nodeClass = 'IPS\nexus\Coupon';
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'coupons_manage' );
|
||||
Dispatcher::i()->checkAcpPermission( 'coupons_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -49,19 +63,19 @@ class _coupons extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function viewUses()
|
||||
public function viewUses() : void
|
||||
{
|
||||
try
|
||||
{
|
||||
$coupon = \IPS\nexus\Coupon::load( \IPS\Request::i()->id );
|
||||
$coupon = Coupon::load( Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X234/1', 404, '' );
|
||||
Output::i()->error( 'node_error', '2X234/1', 404, '' );
|
||||
}
|
||||
|
||||
$data = array();
|
||||
$usedBy = json_decode( $coupon->used_by, TRUE );
|
||||
$usedBy = $coupon->used_by ? json_decode( $coupon->used_by, TRUE ) : null;
|
||||
if ( $usedBy )
|
||||
{
|
||||
foreach ( $usedBy as $member => $uses )
|
||||
@@ -71,17 +85,17 @@ class _coupons extends \IPS\Node\Controller
|
||||
}
|
||||
|
||||
|
||||
$table = new \IPS\Helpers\Table\Custom( $data, \IPS\Http\Url::internal("app=nexus&module=store&controller=coupons&do=viewUses&id={$coupon->id}") );
|
||||
$table = new Custom( $data, Url::internal("app=nexus&module=store&controller=coupons&do=viewUses&id={$coupon->id}") );
|
||||
$table->parsers = array(
|
||||
'coupon_customer' => function ( $val )
|
||||
{
|
||||
return \is_numeric( $val ) ? \IPS\Theme::i()->getTemplate('global')->userLink( \IPS\Member::load( $val ) ) : $val;
|
||||
return is_numeric( $val ) ? Theme::i()->getTemplate('global')->userLink( Member::load( $val ) ) : $val;
|
||||
}
|
||||
);
|
||||
$table->sortBy = 'coupon_uses';
|
||||
$table->noSort = array( 'coupon_customer' );
|
||||
|
||||
\IPS\Output::i()->title = $coupon->code;
|
||||
\IPS\Output::i()->output = (string) $table;
|
||||
Output::i()->title = $coupon->code;
|
||||
Output::i()->output = (string) $table;
|
||||
}
|
||||
}
|
||||
@@ -12,35 +12,47 @@
|
||||
namespace IPS\nexus\modules\admin\store;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Db;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Node\Controller;
|
||||
use IPS\Node\Model;
|
||||
use IPS\Output;
|
||||
use IPS\Patterns\ActiveRecordIterator;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* fields
|
||||
*/
|
||||
class _fields extends \IPS\Node\Controller
|
||||
class fields extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
protected $nodeClass = 'IPS\nexus\Package\CustomField';
|
||||
protected string $nodeClass = 'IPS\nexus\Package\CustomField';
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'package_fields_manage' );
|
||||
Dispatcher::i()->checkAcpPermission( 'package_fields_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -49,10 +61,10 @@ class _fields extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'forms', 'core' )->blurb( 'custom_package_fields_blurb' );
|
||||
return parent::manage();
|
||||
Output::i()->output = Theme::i()->getTemplate( 'forms', 'core' )->blurb( 'custom_package_fields_blurb' );
|
||||
parent::manage();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,11 +72,11 @@ class _fields extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function warning()
|
||||
protected function warning() : void
|
||||
{
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'store' )->productOptionsChanged(
|
||||
new \IPS\Patterns\ActiveRecordIterator(
|
||||
\IPS\Db::i()->select( '*', 'nexus_packages', \IPS\Db::i()->in( 'p_id', explode( ',', \IPS\Request::i()->ids ) ) ),
|
||||
Output::i()->output = Theme::i()->getTemplate( 'store' )->productOptionsChanged(
|
||||
new ActiveRecordIterator(
|
||||
Db::i()->select( '*', 'nexus_packages', Db::i()->in( 'p_id', explode( ',', Request::i()->ids ) ) ),
|
||||
'IPS\nexus\Package'
|
||||
)
|
||||
);
|
||||
@@ -72,19 +84,19 @@ class _fields extends \IPS\Node\Controller
|
||||
/**
|
||||
* Redirect after save
|
||||
*
|
||||
* @param \IPS\Node\Model $old A clone of the node as it was before or NULL if this is a creation
|
||||
* @param \IPS\Node\Model $new The node now
|
||||
* @param Model|null $old A clone of the node as it was before or NULL if this is a creation
|
||||
* @param Model $new The node now
|
||||
* @param string $lastUsedTab The tab last used in the form
|
||||
* @return void
|
||||
*/
|
||||
protected function _afterSave( ?\IPS\Node\Model $old, \IPS\Node\Model $new, $lastUsedTab = FALSE )
|
||||
protected function _afterSave( ?Model $old, Model $new, mixed $lastUsedTab = FALSE ): void
|
||||
{
|
||||
if ( $old AND $old->extra != $new->extra )
|
||||
{
|
||||
$products = \IPS\Db::i()->select( 'DISTINCT(opt_package)', 'nexus_product_options', "opt_values LIKE '%\"{$new->_id}\":%'" );
|
||||
if ( \count( $products ) )
|
||||
$products = Db::i()->select( 'DISTINCT(opt_package)', 'nexus_product_options', "opt_values LIKE '%\"{$new->_id}\":%'" );
|
||||
if ( count( $products ) )
|
||||
{
|
||||
\IPS\Output::i()->redirect( $this->url->setQueryString( array( 'do' => 'warning', 'ids' => implode( ',', iterator_to_array( $products ) ) ) ) );
|
||||
Output::i()->redirect( $this->url->setQueryString( array( 'do' => 'warning', 'ids' => implode( ',', iterator_to_array( $products ) ) ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,35 +12,42 @@
|
||||
namespace IPS\nexus\modules\admin\store;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Node\Controller;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* filters
|
||||
*/
|
||||
class _filters extends \IPS\Node\Controller
|
||||
class filters extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
protected $nodeClass = 'IPS\nexus\Package\Filter';
|
||||
protected string $nodeClass = 'IPS\nexus\Package\Filter';
|
||||
|
||||
/**
|
||||
* Manage
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'forms', 'core' )->blurb( 'product_filters_blurb' );
|
||||
Output::i()->output .= Theme::i()->getTemplate( 'forms', 'core' )->blurb( 'product_filters_blurb' );
|
||||
parent::manage();
|
||||
}
|
||||
|
||||
@@ -49,9 +56,9 @@ class _filters extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'filters_manage' );
|
||||
Dispatcher::i()->checkAcpPermission( 'filters_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
}
|
||||
@@ -12,37 +12,79 @@
|
||||
namespace IPS\nexus\modules\admin\store;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DateInterval;
|
||||
use Exception;
|
||||
use IPS\Data\Store;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Email;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\Matrix;
|
||||
use IPS\Helpers\Form\Node;
|
||||
use IPS\Helpers\Form\Radio;
|
||||
use IPS\Helpers\Form\Select;
|
||||
use IPS\Helpers\Form\YesNo;
|
||||
use IPS\Helpers\MultipleRedirect;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Customer;
|
||||
use IPS\nexus\Money;
|
||||
use IPS\nexus\Package;
|
||||
use IPS\nexus\Purchase;
|
||||
use IPS\nexus\Purchase\LicenseKey\Standard;
|
||||
use IPS\nexus\Purchase\RenewalTerm;
|
||||
use IPS\Node\Controller;
|
||||
use IPS\Node\Model;
|
||||
use IPS\Output;
|
||||
use IPS\Patterns\ActiveRecordIterator;
|
||||
use IPS\Request;
|
||||
use IPS\Session;
|
||||
use IPS\Task;
|
||||
use IPS\Theme;
|
||||
use OutOfRangeException;
|
||||
use UnderflowException;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function get_class;
|
||||
use function in_array;
|
||||
use function is_array;
|
||||
use function is_object;
|
||||
use const IPS\Helpers\Table\SEARCH_DATE_RANGE;
|
||||
use const IPS\Helpers\Table\SEARCH_MEMBER;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Packages
|
||||
*/
|
||||
class _packages extends \IPS\Node\Controller
|
||||
class packages extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
protected $nodeClass = 'IPS\nexus\Package\Group';
|
||||
protected string $nodeClass = 'IPS\nexus\Package\Group';
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'packages_manage' );
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'admin_store.js', 'nexus', 'admin' ) );
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__nexus_store_packages');
|
||||
Dispatcher::i()->checkAcpPermission( 'packages_manage' );
|
||||
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js( 'admin_store.js', 'nexus', 'admin' ) );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('menu__nexus_store_packages');
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -51,7 +93,7 @@ class _packages extends \IPS\Node\Controller
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function _getRootButtons()
|
||||
public function _getRootButtons(): array
|
||||
{
|
||||
$buttons = parent::_getRootButtons();
|
||||
|
||||
@@ -69,31 +111,33 @@ class _packages extends \IPS\Node\Controller
|
||||
* @param object $node Node returned from $nodeClass::load()
|
||||
* @return NULL|string
|
||||
*/
|
||||
public function _getRowHtml( $node )
|
||||
public function _getRowHtml( object $node ): ?string
|
||||
{
|
||||
if ( $node instanceof \IPS\nexus\Package and \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'purchases_view' ) )
|
||||
if ( $node instanceof Package and Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'purchases_view' ) )
|
||||
{
|
||||
$active = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=? AND ps_active=1', 'nexus', 'package', $node->_id ) )->first();
|
||||
$expired = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=? AND ps_active=0 AND ps_cancelled=0', 'nexus', 'package', $node->_id ) )->first();
|
||||
$canceled = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=? AND ps_active=0 AND ps_cancelled=1', 'nexus', 'package', $node->_id ) )->first();
|
||||
$active = Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=? AND ps_active=1', 'nexus', 'package', $node->_id ) )->first();
|
||||
$expired = Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=? AND ps_active=0 AND ps_cancelled=0', 'nexus', 'package', $node->_id ) )->first();
|
||||
$canceled = Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=? AND ps_active=0 AND ps_cancelled=1', 'nexus', 'package', $node->_id ) )->first();
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'store', 'nexus' )->productRowHtml( $node, $active, $expired, $canceled );
|
||||
return Theme::i()->getTemplate( 'store', 'nexus' )->productRowHtml( $node, $active, $expired, $canceled );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect after save
|
||||
*
|
||||
* @param \IPS\Node\Model $old A clone of the node as it was before or NULL if this is a creation
|
||||
* @param \IPS\Node\Model $new The node now
|
||||
* @param Model|null $old A clone of the node as it was before or NULL if this is a creation
|
||||
* @param Model $new The node now
|
||||
* @param string $lastUsedTab The tab last used in the form
|
||||
* @return void
|
||||
*/
|
||||
protected function _afterSave( ?\IPS\Node\Model $old, \IPS\Node\Model $new, $lastUsedTab = FALSE )
|
||||
protected function _afterSave( ?Model $old, Model $new, mixed $lastUsedTab = FALSE ): void
|
||||
{
|
||||
if ( !( $new instanceof \IPS\nexus\Package ) )
|
||||
if ( !( $new instanceof Package ) )
|
||||
{
|
||||
return parent::_afterSave( $old, $new, $lastUsedTab );
|
||||
parent::_afterSave( $old, $new, $lastUsedTab );
|
||||
}
|
||||
|
||||
$changes = array();
|
||||
@@ -109,28 +153,28 @@ class _packages extends \IPS\Node\Controller
|
||||
}
|
||||
|
||||
/* Clear cache */
|
||||
unset( \IPS\Data\Store::i()->nexusPackagesWithReviews );
|
||||
unset( Store::i()->nexusPackagesWithReviews );
|
||||
|
||||
/* If something has changed, see if anyone has purchased */
|
||||
$purchases = 0;
|
||||
|
||||
if( \count( $changes ) )
|
||||
if( count( $changes ) )
|
||||
{
|
||||
$purchases = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=?', 'nexus', 'package', $new->id ) )->first();
|
||||
$purchases = Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=?', 'nexus', 'package', $new->id ) )->first();
|
||||
}
|
||||
|
||||
/* Only show this screen if the package has been purchased. Otherwise even just copying a package and saving asks if you want to update
|
||||
existing purchases unnecessarily */
|
||||
if ( !empty( $changes ) AND $purchases )
|
||||
{
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->decision( 'product_change_blurb', array(
|
||||
'product_change_blurb_existing' => \IPS\Http\Url::internal( "app=nexus&module=store&controller=packages&do=updateExisting&id={$new->_id}" )->setQueryString( 'changes', json_encode( $changes ) )->csrf(),
|
||||
{
|
||||
Output::i()->output = Theme::i()->getTemplate( 'global', 'core', 'global' )->decision( 'product_change_blurb', array(
|
||||
'product_change_blurb_existing' => Url::internal( "app=nexus&module=store&controller=packages&do=updateExisting&id={$new->_id}" )->setQueryString( 'changes', json_encode( $changes ) )->csrf(),
|
||||
'product_change_blurb_new' => $this->url->setQueryString( array( 'root' => ( $new->parent() ? $new->parent()->_id : '' ) ) ),
|
||||
) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return parent::_afterSave( $old, $new, $lastUsedTab );
|
||||
parent::_afterSave( $old, $new, $lastUsedTab );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,32 +183,40 @@ class _packages extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
public function delete() : void
|
||||
{
|
||||
/* If &subnode=1 is not in the URL, we are deleting a group and not a package, so we don't need to check the package */
|
||||
if( !\IPS\Request::i()->subnode )
|
||||
if( !Request::i()->subnode )
|
||||
{
|
||||
return parent::delete();
|
||||
parent::delete();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Load package */
|
||||
try
|
||||
{
|
||||
$package = \IPS\nexus\Package::load( \IPS\Request::i()->id );
|
||||
$package = Package::load( Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
return parent::delete();
|
||||
parent::delete();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Are there any purchases of this product? */
|
||||
$active = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=? AND ps_active=1', 'nexus', 'package', $package->_id ) )->first();
|
||||
$expiredRenewable = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=? AND ps_active=0 AND ps_cancelled=0 AND ps_renewals>0', 'nexus', 'package', $package->_id ) )->first();
|
||||
$expredNonRenewable = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=? AND ps_active=0 AND ps_cancelled=0 AND ps_renewals=0', 'nexus', 'package', $package->_id ) )->first();
|
||||
$canceledCanBeReactivated = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=? AND ps_active=0 AND ps_cancelled=1 AND ps_can_reactivate=1', 'nexus', 'package', $package->_id ) )->first();
|
||||
$canceledCannotBeReactivated = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=? AND ps_active=0 AND ps_cancelled=1 AND ps_can_reactivate=0', 'nexus', 'package', $package->_id ) )->first();
|
||||
$active = Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=? AND ps_active=1', 'nexus', 'package', $package->_id ) )->first();
|
||||
$expiredRenewable = Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=? AND ps_active=0 AND ps_cancelled=0 AND ps_renewals>0', 'nexus', 'package', $package->_id ) )->first();
|
||||
$expredNonRenewable = Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=? AND ps_active=0 AND ps_cancelled=0 AND ps_renewals=0', 'nexus', 'package', $package->_id ) )->first();
|
||||
$canceledCanBeReactivated = Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=? AND ps_active=0 AND ps_cancelled=1 AND ps_can_reactivate=1', 'nexus', 'package', $package->_id ) )->first();
|
||||
$canceledCannotBeReactivated = Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=? AND ps_active=0 AND ps_cancelled=1 AND ps_can_reactivate=0', 'nexus', 'package', $package->_id ) )->first();
|
||||
if ( $active or $expiredRenewable or $canceledCanBeReactivated )
|
||||
{
|
||||
{
|
||||
/* If this is an ajax request, then we need to redirect so we can show the confirmation screen */
|
||||
if( Request::i()->isAjax() OR ( isset( Request::i()->wasConfirmed ) AND Request::i()->wasConfirmed ) )
|
||||
{
|
||||
Output::i()->redirect( $this->url->setQueryString( array( 'do' => 'delete', 'subnode' => 1, 'id' => $package->id ) ) );
|
||||
}
|
||||
|
||||
$upgradeTo = FALSE;
|
||||
$prices = json_decode( $package->base_price, TRUE );
|
||||
if ( $package->renew_options )
|
||||
@@ -188,6 +240,12 @@ class _packages extends \IPS\Node\Controller
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We cannot upgrade to legacy packages */
|
||||
if( $_package->locked )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$_prices = json_decode( $_package->base_price, TRUE );
|
||||
if ( $_package->renew_options )
|
||||
@@ -216,13 +274,13 @@ class _packages extends \IPS\Node\Controller
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = $package->_title;
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'store' )->productDeleteWarning( $package, $active, $expiredRenewable, $expredNonRenewable, $canceledCanBeReactivated, $canceledCannotBeReactivated, $upgradeTo );
|
||||
Output::i()->title = $package->_title;
|
||||
Output::i()->output = Theme::i()->getTemplate( 'store' )->productDeleteWarning( $package, $active, $expiredRenewable, $expredNonRenewable, $canceledCanBeReactivated, $canceledCannotBeReactivated, $upgradeTo );
|
||||
return;
|
||||
}
|
||||
|
||||
/* If not, just handle the delete as normal */
|
||||
return parent::delete();
|
||||
parent::delete();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -230,18 +288,18 @@ class _packages extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function hide()
|
||||
public function hide() : void
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
/* Load package */
|
||||
try
|
||||
{
|
||||
$package = \IPS\nexus\Package::load( \IPS\Request::i()->id );
|
||||
$package = Package::load( Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X249/3', 404, '' );
|
||||
Output::i()->error( 'node_error', '2X249/3', 404, '' );
|
||||
}
|
||||
|
||||
/* Do it */
|
||||
@@ -249,10 +307,10 @@ class _packages extends \IPS\Node\Controller
|
||||
$package->reg = FALSE;
|
||||
$package->save();
|
||||
|
||||
\IPS\Session::i()->log( 'acplogs__nexus_package_hidden', array( 'nexus_package_' . $package->id => TRUE ) );
|
||||
Session::i()->log( 'acplogs__nexus_package_hidden', array( 'nexus_package_' . $package->id => TRUE ) );
|
||||
|
||||
/* Redirect */
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=nexus&module=store&controller=packages" )->setQueryString( array( 'root' => ( $package->parent() ? $package->parent()->_id : '' ) ) ) );
|
||||
Output::i()->redirect( Url::internal( "app=nexus&module=store&controller=packages" )->setQueryString( array( 'root' => ( $package->parent() ? $package->parent()->_id : '' ) ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -260,33 +318,33 @@ class _packages extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function updateExisting()
|
||||
public function updateExisting() : void
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
try
|
||||
{
|
||||
$package = \IPS\nexus\Package::load( \IPS\Request::i()->id );
|
||||
$package = Package::load( Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X249/1', 404, '' );
|
||||
Output::i()->error( 'node_error', '2X249/1', 404, '' );
|
||||
}
|
||||
|
||||
$changes = json_decode( \IPS\Request::i()->changes, TRUE );
|
||||
$changes = json_decode( Request::i()->changes, TRUE );
|
||||
|
||||
if ( !isset( \IPS\Request::i()->processing ) )
|
||||
if ( !isset( Request::i()->processing ) )
|
||||
{
|
||||
if ( isset( $changes['renew_options'] ) )
|
||||
{
|
||||
\IPS\Output::i()->bypassCsrfKeyCheck = TRUE;
|
||||
$matrix = new \IPS\Helpers\Form\Matrix( 'matrix', 'continue' );
|
||||
Output::i()->bypassCsrfKeyCheck = TRUE;
|
||||
$matrix = new Matrix( 'matrix', 'continue' );
|
||||
$matrix->manageable = FALSE;
|
||||
|
||||
$newOptions = array( '-' => \IPS\Member::loggedIn()->language()->addToStack('do_not_change') );
|
||||
$newOptions = array( '-' => Member::loggedIn()->language()->addToStack('do_not_change') );
|
||||
$existingRenewOptions = json_decode( $package->renew_options, TRUE );
|
||||
|
||||
if( !\is_array( $existingRenewOptions ) )
|
||||
if( !is_array( $existingRenewOptions ) )
|
||||
{
|
||||
$existingRenewOptions = array();
|
||||
}
|
||||
@@ -296,27 +354,27 @@ class _packages extends \IPS\Node\Controller
|
||||
$costs = array();
|
||||
foreach ( $newOption['cost'] as $data )
|
||||
{
|
||||
$costs[] = new \IPS\nexus\Money( $data['amount'], $data['currency'] );
|
||||
$costs[] = new Money( $data['amount'], $data['currency'] );
|
||||
}
|
||||
|
||||
switch ( $newOption['unit'] )
|
||||
{
|
||||
case 'd':
|
||||
$term = \IPS\Member::loggedIn()->language()->addToStack('renew_days', FALSE, array( 'pluralize' => array( $newOption['term'] ) ) );
|
||||
$term = Member::loggedIn()->language()->addToStack('renew_days', FALSE, array( 'pluralize' => array( $newOption['term'] ) ) );
|
||||
break;
|
||||
case 'm':
|
||||
$term = \IPS\Member::loggedIn()->language()->addToStack('renew_months', FALSE, array( 'pluralize' => array( $newOption['term'] ) ) );
|
||||
$term = Member::loggedIn()->language()->addToStack('renew_months', FALSE, array( 'pluralize' => array( $newOption['term'] ) ) );
|
||||
break;
|
||||
case 'y':
|
||||
$term = \IPS\Member::loggedIn()->language()->addToStack('renew_years', FALSE, array( 'pluralize' => array( $newOption['term'] ) ) );
|
||||
$term = Member::loggedIn()->language()->addToStack('renew_years', FALSE, array( 'pluralize' => array( $newOption['term'] ) ) );
|
||||
break;
|
||||
}
|
||||
|
||||
$newOptions[ "o{$k}" ] = \IPS\Member::loggedIn()->language()->addToStack( 'renew_option', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->formatList( $costs, \IPS\Member::loggedIn()->language()->get('or_list_format') ), $term ) ) );
|
||||
$newOptions[ "o{$k}" ] = Member::loggedIn()->language()->addToStack( 'renew_option', FALSE, array( 'sprintf' => array( Member::loggedIn()->language()->formatList( $costs, Member::loggedIn()->language()->get('or_list_format') ), $term ) ) );
|
||||
}
|
||||
$newOptions['z'] = \IPS\Member::loggedIn()->language()->addToStack('remove_renewal_no_expire_leave');
|
||||
$newOptions['y'] = \IPS\Member::loggedIn()->language()->addToStack('remove_renewal_no_expire_reactivate');
|
||||
$newOptions['x'] = \IPS\Member::loggedIn()->language()->addToStack('remove_renewal_expire');
|
||||
$newOptions['z'] = Member::loggedIn()->language()->addToStack('remove_renewal_no_expire_leave');
|
||||
$newOptions['y'] = Member::loggedIn()->language()->addToStack('remove_renewal_no_expire_reactivate');
|
||||
$newOptions['x'] = Member::loggedIn()->language()->addToStack('remove_renewal_expire');
|
||||
$matrix->columns = array(
|
||||
'customers_currently_paying' => function( $key, $value, $data )
|
||||
{
|
||||
@@ -324,7 +382,7 @@ class _packages extends \IPS\Node\Controller
|
||||
},
|
||||
'now_pay' => function( $key, $value, $data ) use ( $newOptions )
|
||||
{
|
||||
return new \IPS\Helpers\Form\Select( $key, $data[1], TRUE, array( 'options' => $newOptions, 'noDefault' => TRUE ) );
|
||||
return new Select( $key, $data[1], TRUE, array( 'options' => $newOptions, 'noDefault' => TRUE ) );
|
||||
},
|
||||
);
|
||||
|
||||
@@ -335,23 +393,23 @@ class _packages extends \IPS\Node\Controller
|
||||
$costs = array();
|
||||
foreach ( $oldOption['cost'] as $data )
|
||||
{
|
||||
$costs[] = new \IPS\nexus\Money( $data['amount'], $data['currency'] );
|
||||
$costs[] = new Money( $data['amount'], $data['currency'] );
|
||||
}
|
||||
|
||||
switch ( $oldOption['unit'] )
|
||||
{
|
||||
case 'd':
|
||||
$term = \IPS\Member::loggedIn()->language()->addToStack('renew_days', FALSE, array( 'pluralize' => array( $oldOption['term'] ) ) );
|
||||
$term = Member::loggedIn()->language()->addToStack('renew_days', FALSE, array( 'pluralize' => array( $oldOption['term'] ) ) );
|
||||
break;
|
||||
case 'm':
|
||||
$term = \IPS\Member::loggedIn()->language()->addToStack('renew_months', FALSE, array( 'pluralize' => array( $oldOption['term'] ) ) );
|
||||
$term = Member::loggedIn()->language()->addToStack('renew_months', FALSE, array( 'pluralize' => array( $oldOption['term'] ) ) );
|
||||
break;
|
||||
case 'y':
|
||||
$term = \IPS\Member::loggedIn()->language()->addToStack('renew_years', FALSE, array( 'pluralize' => array( $oldOption['term'] ) ) );
|
||||
$term = Member::loggedIn()->language()->addToStack('renew_years', FALSE, array( 'pluralize' => array( $oldOption['term'] ) ) );
|
||||
break;
|
||||
}
|
||||
|
||||
$matrix->rows[ $k ] = array( \IPS\Member::loggedIn()->language()->addToStack( 'renew_option', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->formatList( $costs, \IPS\Member::loggedIn()->language()->get('or_list_format') ), $term ) ) ), "o{$k}" );
|
||||
$matrix->rows[ $k ] = array( Member::loggedIn()->language()->addToStack( 'renew_option', FALSE, array( 'sprintf' => array( Member::loggedIn()->language()->formatList( $costs, Member::loggedIn()->language()->get('or_list_format') ), $term ) ) ), "o{$k}" );
|
||||
}
|
||||
}
|
||||
$matrix->rows['x'] = array( 'any_other_amount', '-' );
|
||||
@@ -372,13 +430,13 @@ class _packages extends \IPS\Node\Controller
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->output .= $matrix;
|
||||
Output::i()->output .= $matrix;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ( isset( $changes['tax'] ) or isset( $changes['renew_options'] ) ) and !isset( \IPS\Request::i()->ba ) )
|
||||
if ( ( isset( $changes['tax'] ) or isset( $changes['renew_options'] ) ) and !isset( Request::i()->ba ) )
|
||||
{
|
||||
$needBaPrompt = FALSE;
|
||||
$canChangeOptions = FALSE;
|
||||
@@ -386,7 +444,7 @@ class _packages extends \IPS\Node\Controller
|
||||
{
|
||||
foreach ( $changes['renew_options'] as $ro )
|
||||
{
|
||||
if ( !\in_array( $ro['new'], array( '-', 'x', 'y', 'z' ) ) )
|
||||
if ( !in_array( $ro['new'], array( '-', 'x', 'y', 'z' ) ) )
|
||||
{
|
||||
$canChangeOptions = TRUE;
|
||||
$needBaPrompt = TRUE;
|
||||
@@ -399,17 +457,17 @@ class _packages extends \IPS\Node\Controller
|
||||
$needBaPrompt = TRUE;
|
||||
}
|
||||
|
||||
if ( $needBaPrompt and $withBillingAgreement = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=? AND ps_billing_agreement>0 AND ba_canceled=0', 'nexus', 'package', $package->id ) )->join( 'nexus_billing_agreements', 'ba_id=ps_billing_agreement' )->first() )
|
||||
if ( $needBaPrompt and $withBillingAgreement = Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=? AND ps_billing_agreement>0 AND ba_canceled=0', 'nexus', 'package', $package->id ) )->join( 'nexus_billing_agreements', 'ba_id=ps_billing_agreement' )->first() )
|
||||
{
|
||||
$options = array(
|
||||
'change_renew_ba_skip' => \IPS\Http\Url::internal( "app=nexus&module=store&controller=packages&do=updateExisting" )->setQueryString( array(
|
||||
'id' => \IPS\Request::i()->id,
|
||||
'change_renew_ba_skip' => Url::internal( "app=nexus&module=store&controller=packages&do=updateExisting" )->setQueryString( array(
|
||||
'id' => Request::i()->id,
|
||||
'changes' => json_encode( $changes ),
|
||||
'processing'=> 1,
|
||||
'ba' => 0
|
||||
) )->csrf(),
|
||||
'change_renew_ba_cancel' => \IPS\Http\Url::internal( "app=nexus&module=store&controller=packages&do=updateExisting" )->setQueryString( array(
|
||||
'id' => \IPS\Request::i()->id,
|
||||
'change_renew_ba_cancel' => Url::internal( "app=nexus&module=store&controller=packages&do=updateExisting" )->setQueryString( array(
|
||||
'id' => Request::i()->id,
|
||||
'changes' => json_encode( $changes ),
|
||||
'processing'=> 1,
|
||||
'ba' => 1
|
||||
@@ -417,44 +475,44 @@ class _packages extends \IPS\Node\Controller
|
||||
);
|
||||
if ( $canChangeOptions )
|
||||
{
|
||||
$options['change_renew_ba_go_back'] = \IPS\Http\Url::internal( "app=nexus&module=store&controller=packages&do=updateExisting" )->setQueryString( array(
|
||||
'id' => \IPS\Request::i()->id,
|
||||
'changes' => \IPS\Request::i()->changes,
|
||||
$options['change_renew_ba_go_back'] = Url::internal( "app=nexus&module=store&controller=packages&do=updateExisting" )->setQueryString( array(
|
||||
'id' => Request::i()->id,
|
||||
'changes' => Request::i()->changes,
|
||||
) )->csrf();
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->decision( 'change_renew_ba_blurb', $options );
|
||||
|
||||
Output::i()->output = Theme::i()->getTemplate( 'global', 'core', 'global' )->decision( 'change_renew_ba_blurb', $options );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = new \IPS\Helpers\MultipleRedirect(
|
||||
\IPS\Http\Url::internal( "app=nexus&module=store&controller=packages&do=updateExisting&id=1&changes=secondary_group" )->setQueryString( array(
|
||||
'id' => \IPS\Request::i()->id,
|
||||
Output::i()->output = new MultipleRedirect(
|
||||
Url::internal( "app=nexus&module=store&controller=packages&do=updateExisting&id=1&changes=secondary_group" )->setQueryString( array(
|
||||
'id' => Request::i()->id,
|
||||
'changes' => json_encode( $changes ),
|
||||
'processing'=> 1,
|
||||
'ba' => isset( \IPS\Request::i()->ba ) ? \IPS\Request::i()->ba : 0
|
||||
'ba' => isset( Request::i()->ba ) ? Request::i()->ba : 0
|
||||
) )->csrf(),
|
||||
function( $data ) use ( $package, $changes )
|
||||
{
|
||||
if( !\is_array( $data ) )
|
||||
if( !is_array( $data ) )
|
||||
{
|
||||
$data['offset'] = 0;
|
||||
$data['lastId'] = 0;
|
||||
}
|
||||
|
||||
$select = \IPS\Db::i()->select( '*', 'nexus_purchases', array( "ps_id>? and ps_app=? and ps_type=? and ps_item_id=?", $data['lastId'], 'nexus', 'package', $package->id ), 'ps_id', 1 );
|
||||
$select = Db::i()->select( '*', 'nexus_purchases', array( "ps_id>? and ps_app=? and ps_type=? and ps_item_id=?", $data['lastId'], 'nexus', 'package', $package->id ), 'ps_id', 1 );
|
||||
|
||||
try
|
||||
{
|
||||
$purchase = \IPS\nexus\Purchase::constructFromData( $select->first() );
|
||||
$total = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( "ps_app=? and ps_type=? and ps_item_id=?", 'nexus', 'package', $package->id ) )->first();
|
||||
$purchase = Purchase::constructFromData( $select->first() );
|
||||
$total = Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( "ps_app=? and ps_type=? and ps_item_id=?", 'nexus', 'package', $package->id ) )->first();
|
||||
|
||||
$package->updatePurchase( $purchase, $changes, \IPS\Request::i()->ba );
|
||||
$package->updatePurchase( $purchase, $changes, Request::i()->ba );
|
||||
|
||||
return array( [ 'offset' => ++$data['offset'], 'lastId' => $purchase->id ], \IPS\Member::loggedIn()->language()->get('processing'), 100 / $total * $data['offset'] );
|
||||
return array( [ 'offset' => ++$data['offset'], 'lastId' => $purchase->id ], Member::loggedIn()->language()->get('processing'), 100 / $total * $data['offset'] );
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
catch ( UnderflowException )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -462,7 +520,7 @@ class _packages extends \IPS\Node\Controller
|
||||
},
|
||||
function() use ( $package )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=nexus&module=store&controller=packages" )->setQueryString( array( 'root' => ( $package->parent() ? $package->parent()->_id : '' ) ) ) );
|
||||
Output::i()->redirect( Url::internal( "app=nexus&module=store&controller=packages" )->setQueryString( array( 'root' => ( $package->parent() ? $package->parent()->_id : '' ) ) ) );
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -470,23 +528,22 @@ class _packages extends \IPS\Node\Controller
|
||||
/**
|
||||
* Build Product Options Table
|
||||
*
|
||||
* @return array
|
||||
* @return void
|
||||
*/
|
||||
public function productoptions()
|
||||
public function productoptions() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'packages_edit' );
|
||||
Dispatcher::i()->checkAcpPermission( 'packages_edit' );
|
||||
|
||||
if ( !\IPS\Request::i()->fields or !\IPS\Request::i()->package )
|
||||
if ( !Request::i()->fields or !Request::i()->package )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput('');
|
||||
return;
|
||||
Output::i()->sendOutput('');
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$package = \IPS\nexus\Package::load( \IPS\Request::i()->package );
|
||||
$package = Package::load( Request::i()->package );
|
||||
|
||||
$fields = iterator_to_array( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_package_fields', \IPS\Db::i()->in( 'cf_id', explode( ',', \IPS\Request::i()->fields ) ) ), 'IPS\nexus\Package\CustomField' ) );
|
||||
$fields = iterator_to_array( new ActiveRecordIterator( Db::i()->select( '*', 'nexus_package_fields', Db::i()->in( 'cf_id', explode( ',', Request::i()->fields ) ) ), 'IPS\nexus\Package\CustomField' ) );
|
||||
$allTheOptions = array();
|
||||
foreach ( $fields as $field )
|
||||
{
|
||||
@@ -511,13 +568,13 @@ class _packages extends \IPS\Node\Controller
|
||||
$rows[ json_encode( $options ) ] = $options;
|
||||
}
|
||||
|
||||
$existingValues = iterator_to_array( \IPS\Db::i()->select( '*', 'nexus_product_options', array( 'opt_package=?', $package->id ) )->setKeyField( 'opt_values' ) );
|
||||
$existingValues = iterator_to_array( Db::i()->select( '*', 'nexus_product_options', array( 'opt_package=?', $package->id ) )->setKeyField( 'opt_values' ) );
|
||||
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate('store')->productOptionsTable( $fields, $rows, $existingValues, \IPS\Request::i()->renews ) );
|
||||
Output::i()->sendOutput( Theme::i()->getTemplate('store')->productOptionsTable( $fields, $rows, $existingValues, Request::i()->renews ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( $e->getMessage(), 500 );
|
||||
Output::i()->sendOutput( $e->getMessage(), 500 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -527,8 +584,9 @@ class _packages extends \IPS\Node\Controller
|
||||
* @param array $_ Array
|
||||
* @return array
|
||||
*/
|
||||
protected function arraycartesian($_) {
|
||||
if(\count($_) == 0)
|
||||
protected function arraycartesian( array $_) : array
|
||||
{
|
||||
if(count($_) == 0)
|
||||
return array(array());
|
||||
foreach($_ as $k=>$a) {
|
||||
unset($_[$k]);
|
||||
@@ -547,30 +605,30 @@ class _packages extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function viewPurchases()
|
||||
protected function viewPurchases() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'purchases_view', 'nexus', 'customers' );
|
||||
Dispatcher::i()->checkAcpPermission( 'purchases_view', 'nexus', 'customers' );
|
||||
|
||||
try
|
||||
{
|
||||
$package = \IPS\nexus\Package::load( \IPS\Request::i()->id );
|
||||
$package = Package::load( Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X249/2', 404, '' );
|
||||
Output::i()->error( 'node_error', '2X249/2', 404, '' );
|
||||
}
|
||||
|
||||
$table = new \IPS\Helpers\Table\Db( 'nexus_purchases', \IPS\Http\Url::internal( "app=nexus&module=store&controller=packages&do=viewPurchases&id={$package->id}" ), array( array( 'ps_app=? AND ps_type=? AND ps_item_id=?', 'nexus', 'package', $package->id ) ) );
|
||||
$table = new \IPS\Helpers\Table\Db( 'nexus_purchases', Url::internal( "app=nexus&module=store&controller=packages&do=viewPurchases&id={$package->id}" ), array( array( 'ps_app=? AND ps_type=? AND ps_item_id=?', 'nexus', 'package', $package->id ) ) );
|
||||
$table->include = array( 'ps_id', 'ps_member', 'purchase_status', 'ps_start', 'ps_expire', 'ps_renewals' );
|
||||
$table->quickSearch = 'ps_id';
|
||||
$table->advancedSearch = array(
|
||||
'ps_member' => \IPS\Helpers\Table\SEARCH_MEMBER,
|
||||
'ps_start' => \IPS\Helpers\Table\SEARCH_DATE_RANGE,
|
||||
'ps_expire' => \IPS\Helpers\Table\SEARCH_DATE_RANGE,
|
||||
'ps_member' => SEARCH_MEMBER,
|
||||
'ps_start' => SEARCH_DATE_RANGE,
|
||||
'ps_expire' => SEARCH_DATE_RANGE,
|
||||
);
|
||||
$table->noSort = array( 'purchase_status' );
|
||||
|
||||
if ( $package->renew_options or \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=? AND ps_active=0 AND ps_cancelled=0', 'nexus', 'package', $package->_id ) )->first() )
|
||||
if ( $package->renew_options or Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=? AND ps_active=0 AND ps_cancelled=0', 'nexus', 'package', $package->_id ) )->first() )
|
||||
{
|
||||
$table->filters = array( 'purchase_tab_active' => 'ps_active=1', 'purchase_tab_expired' => 'ps_active=0 AND ps_cancelled=0', 'purchase_tab_canceled' => 'ps_active=0 AND ps_cancelled=1' );
|
||||
}
|
||||
@@ -583,45 +641,45 @@ class _packages extends \IPS\Node\Controller
|
||||
'ps_member' => function( $val ) {
|
||||
try
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate('global', 'nexus')->userLink( \IPS\Member::load( $val ) );
|
||||
return Theme::i()->getTemplate('global', 'nexus')->userLink( Member::load( $val ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('deleted_member');
|
||||
return Member::loggedIn()->language()->addToStack('deleted_member');
|
||||
}
|
||||
},
|
||||
'purchase_status' => function( $val, $row ) {
|
||||
$purchase = \IPS\nexus\Purchase::constructFromData( $row );
|
||||
$purchase = Purchase::constructFromData( $row );
|
||||
if ( $purchase->cancelled )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('purchase_canceled');
|
||||
return Member::loggedIn()->language()->addToStack('purchase_canceled');
|
||||
}
|
||||
elseif ( !$purchase->active )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('purchase_expired');
|
||||
return Member::loggedIn()->language()->addToStack('purchase_expired');
|
||||
}
|
||||
elseif ( $purchase->grace_period and ( $purchase->expire and $purchase->expire->getTimestamp() < time() ) )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('purchase_in_grace_period');
|
||||
return Member::loggedIn()->language()->addToStack('purchase_in_grace_period');
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('purchase_active');
|
||||
return Member::loggedIn()->language()->addToStack('purchase_active');
|
||||
}
|
||||
},
|
||||
'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 ) : '--';
|
||||
},
|
||||
'ps_renewals' => function( $val, $row ) {
|
||||
$purchase = \IPS\nexus\Purchase::constructFromData( $row );
|
||||
return $purchase->grouped_renewals ? \IPS\Member::loggedIn()->language()->addToStack('purchase_grouped') : ( (string) ( $purchase->renewals ?: '--' ) );
|
||||
$purchase = Purchase::constructFromData( $row );
|
||||
return $purchase->grouped_renewals ? Member::loggedIn()->language()->addToStack('purchase_grouped') : ( (string) ( $purchase->renewals ?: '--' ) );
|
||||
}
|
||||
);
|
||||
$table->rowButtons = function( $row ) {
|
||||
$purchase = \IPS\nexus\Purchase::constructFromData( $row );
|
||||
$purchase = Purchase::constructFromData( $row );
|
||||
return array_merge( array(
|
||||
'view' => array(
|
||||
'link' => $purchase->acpUrl()->setQueryString( 'popup', true ),
|
||||
@@ -631,13 +689,13 @@ class _packages extends \IPS\Node\Controller
|
||||
), $purchase->buttons() );
|
||||
};
|
||||
|
||||
\IPS\Output::i()->title = $package->_title;
|
||||
\IPS\Output::i()->output = $table;
|
||||
\IPS\Output::i()->sidebar['actions'] = array(
|
||||
Output::i()->title = $package->_title;
|
||||
Output::i()->output = $table;
|
||||
Output::i()->sidebar['actions'] = array(
|
||||
'cancel_purchases' => array(
|
||||
'icon' => 'arrow-right',
|
||||
'title' => 'mass_change_all_purchases',
|
||||
'link' => \IPS\Http\Url::internal( "app=nexus&module=store&controller=packages" )->setQueryString( array( 'do' => 'massManagePurchases', 'id' => $package->_id ) ),
|
||||
'link' => Url::internal( "app=nexus&module=store&controller=packages" )->setQueryString( array( 'do' => 'massManagePurchases', 'id' => $package->_id ) ),
|
||||
'data' => array(
|
||||
'ipsDialog' => TRUE,
|
||||
'ipsDialog-title' => $package->_title
|
||||
@@ -651,31 +709,31 @@ class _packages extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function massManagePurchases()
|
||||
protected function massManagePurchases() : void
|
||||
{
|
||||
try
|
||||
{
|
||||
$package = \IPS\nexus\Package::load( \IPS\Request::i()->id );
|
||||
$package = Package::load( Request::i()->id );
|
||||
if ( $package->deleteOrMoveQueued() )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
throw new OutOfRangeException;
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X249/4', 404, '' );
|
||||
Output::i()->error( 'node_error', '2X249/4', 404, '' );
|
||||
}
|
||||
|
||||
$form = new \IPS\Helpers\Form( 'form', 'go' );
|
||||
$form = new Form( 'form', 'go' );
|
||||
$form->addMessage('mass_change_purchases_explain');
|
||||
|
||||
$options = array();
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'purchases_edit' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'purchases_edit' ) )
|
||||
{
|
||||
$options['change'] = 'mass_change_purchases_change';
|
||||
$options['expire'] = 'mass_change_purchases_expire';
|
||||
}
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'purchases_cancel' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'purchases_cancel' ) )
|
||||
{
|
||||
$options['cancel'] = 'mass_change_purchases_cancel';
|
||||
}
|
||||
@@ -698,31 +756,31 @@ class _packages extends \IPS\Node\Controller
|
||||
$renewFieldsDescriptions = array();
|
||||
foreach ( $renewOptions as $k => $option )
|
||||
{
|
||||
$renewTermObject = new \IPS\nexus\Purchase\RenewalTerm( new \IPS\nexus\Money( 0, '' ), new \DateInterval( 'P' . $option['term'] . mb_strtoupper( $option['unit'] ) ) );
|
||||
$renewTermObject = new RenewalTerm( new Money( 0, '' ), new DateInterval( 'P' . $option['term'] . mb_strtoupper( $option['unit'] ) ) );
|
||||
|
||||
$costs = array();
|
||||
foreach ( $option['cost'] as $cost )
|
||||
{
|
||||
$costs[] = new \IPS\nexus\Money( $cost['amount'], $cost['currency'] );
|
||||
$costs[] = new Money( $cost['amount'], $cost['currency'] );
|
||||
}
|
||||
|
||||
$renewalOptions[ $k ] = sprintf( \IPS\Member::loggedIn()->language()->get( 'renew_option'), implode( ' / ', $costs ), $renewTermObject->getTermUnit() );
|
||||
$renewalOptions[ $k ] = sprintf( Member::loggedIn()->language()->get( 'renew_option'), implode( ' / ', $costs ), $renewTermObject->getTermUnit() );
|
||||
}
|
||||
|
||||
if ( $renewalOptions )
|
||||
{
|
||||
$desciptions[ $siblingPackage->id ] = \IPS\Member::loggedIn()->language()->formatList( $renewalOptions, \IPS\Member::loggedIn()->language()->get('or_list_format') );
|
||||
$renewFields[] = new \IPS\Helpers\Form\Radio( 'renew_option_' . $siblingPackage->id, NULL, NULL, array( 'options' => $renewalOptions, 'descriptions' => $renewFieldsDescriptions, 'parse' => 'normal' ), NULL, NULL, NULL, 'renew_option_' . $siblingPackage->id );
|
||||
\IPS\Member::loggedIn()->language()->words['renew_option_' . $siblingPackage->id] = \IPS\Member::loggedIn()->language()->addToStack( 'renewal_term', FALSE );
|
||||
$desciptions[ $siblingPackage->id ] = Member::loggedIn()->language()->formatList( $renewalOptions, Member::loggedIn()->language()->get('or_list_format') );
|
||||
$renewFields[] = new Radio( 'renew_option_' . $siblingPackage->id, NULL, NULL, array( 'options' => $renewalOptions, 'descriptions' => $renewFieldsDescriptions, 'parse' => 'normal' ), NULL, NULL, NULL, 'renew_option_' . $siblingPackage->id );
|
||||
Member::loggedIn()->language()->words['renew_option_' . $siblingPackage->id] = Member::loggedIn()->language()->addToStack( 'renewal_term', FALSE );
|
||||
$toggles[ $siblingPackage->id ] = array( 'renew_option_' . $siblingPackage->id );
|
||||
}
|
||||
else
|
||||
{
|
||||
$desciptions[ $siblingPackage->id ] = \IPS\Member::loggedIn()->language()->addToStack('mass_change_purchases_no_renewals');
|
||||
$desciptions[ $siblingPackage->id ] = Member::loggedIn()->language()->addToStack('mass_change_purchases_no_renewals');
|
||||
}
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'cancel_type', NULL, TRUE, array(
|
||||
$form->add( new Radio( 'cancel_type', NULL, TRUE, array(
|
||||
'options' => $options,
|
||||
'toggles' => array(
|
||||
'change' => array( 'mass_change_purchases_to', 'mass_change_purchases_override' ),
|
||||
@@ -733,17 +791,17 @@ class _packages extends \IPS\Node\Controller
|
||||
) ) );
|
||||
if ( !$upgradeDowngradeOptions )
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words['mass_change_purchases_change_desc'] = \IPS\Member::loggedIn()->language()->addToStack('cancel_type_change_no_siblings');
|
||||
Member::loggedIn()->language()->words['mass_change_purchases_change_desc'] = Member::loggedIn()->language()->addToStack('cancel_type_change_no_siblings');
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'mass_change_purchases_to', NULL, NULL, array( 'options' => $upgradeDowngradeOptions, 'descriptions' => $desciptions, 'toggles' => $toggles, 'parse' => 'normal' ), NULL, NULL, NULL, 'mass_change_purchases_to' ) );
|
||||
$form->add( new Radio( 'mass_change_purchases_to', NULL, NULL, array( 'options' => $upgradeDowngradeOptions, 'descriptions' => $desciptions, 'toggles' => $toggles, 'parse' => 'normal' ), NULL, NULL, NULL, 'mass_change_purchases_to' ) );
|
||||
foreach ( $renewFields as $field )
|
||||
{
|
||||
$form->add( $field );
|
||||
}
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'mass_change_purchases_override', TRUE, NULL, array(), NULL, NULL, NULL, 'mass_change_purchases_override' ) );
|
||||
$form->add( new YesNo( 'mass_change_purchases_override', TRUE, NULL, array(), NULL, NULL, NULL, 'mass_change_purchases_override' ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'ps_can_reactivate', NULL, FALSE, array(), NULL, NULL, NULL, 'ps_can_reactivate' ) );
|
||||
$form->add( new YesNo( 'ps_can_reactivate', NULL, FALSE, array(), NULL, NULL, NULL, 'ps_can_reactivate' ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
@@ -751,14 +809,14 @@ class _packages extends \IPS\Node\Controller
|
||||
// Note: Must cancel billing agreements when upgrading/downgrading purchases. Reflect that in the form
|
||||
|
||||
$values['id'] = $package->_id;
|
||||
$values['admin'] = \IPS\Member::loggedIn()->member_id;
|
||||
\IPS\Task::queue( 'nexus', 'MassChangePurchases', $values );
|
||||
$values['admin'] = Member::loggedIn()->member_id;
|
||||
Task::queue( 'nexus', 'MassChangePurchases', $values );
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=nexus&module=store&controller=packages" )->setQueryString( array( 'root' => ( $package->parent() ? $package->parent()->_id : '' ) ) ), 'mass_change_purchases_confirm' );
|
||||
Output::i()->redirect( Url::internal( "app=nexus&module=store&controller=packages" )->setQueryString( array( 'root' => ( $package->parent() ? $package->parent()->_id : '' ) ) ), 'mass_change_purchases_confirm' );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = $package->_title;
|
||||
\IPS\Output::i()->output = $form;
|
||||
Output::i()->title = $package->_title;
|
||||
Output::i()->output = $form;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -766,49 +824,49 @@ class _packages extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function emailPreview()
|
||||
public function emailPreview() : void
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
$functionName = 'emailPreview_' . mt_rand();
|
||||
\IPS\Theme::makeProcessFunction( \IPS\Request::i()->value, $functionName, '$purchase' );
|
||||
Theme::makeProcessFunction( Request::i()->value, $functionName, '$purchase' );
|
||||
|
||||
$dummyPurchase = new \IPS\nexus\Purchase;
|
||||
$dummyPurchase->name = \IPS\Member::loggedIn()->language()->addToStack('p_email_preview_example');
|
||||
$dummyPurchase->member = \IPS\Member::loggedIn();
|
||||
$dummyPurchase->expire = \IPS\DateTime::create()->add( new \DateInterval('P1M') );
|
||||
$dummyPurchase->renewals = new \IPS\nexus\Purchase\RenewalTerm( new \IPS\nexus\Money( 10, \IPS\nexus\Customer::loggedIn()->defaultCurrency() ), new \DateInterval('P1M') );
|
||||
$dummyPurchase->custom_fields = array_fill( 0, \IPS\Db::i()->select( 'MAX(cf_id)', 'nexus_package_fields' )->first(), \IPS\Member::loggedIn()->language()->addToStack('p_email_preview_example') );
|
||||
$dummyPurchase->licenseKey = new \IPS\nexus\Purchase\LicenseKey\Standard;
|
||||
$dummyPurchase = new Purchase;
|
||||
$dummyPurchase->name = Member::loggedIn()->language()->addToStack('p_email_preview_example');
|
||||
$dummyPurchase->member = Member::loggedIn();
|
||||
$dummyPurchase->expire = DateTime::create()->add( new DateInterval('P1M') );
|
||||
$dummyPurchase->renewals = new RenewalTerm( new Money( 10, Customer::loggedIn()->defaultCurrency() ), new DateInterval('P1M') );
|
||||
$dummyPurchase->custom_fields = array_fill( 0, Db::i()->select( 'MAX(cf_id)', 'nexus_package_fields' )->first(), Member::loggedIn()->language()->addToStack('p_email_preview_example') );
|
||||
$dummyPurchase->licenseKey = new Standard;
|
||||
$dummyPurchase->licenseKey->key = 'XXXX-XXXX-XXXX-XXXX';
|
||||
|
||||
try
|
||||
{
|
||||
$themeFunction = 'IPS\\Theme\\'. $functionName;
|
||||
$output = \IPS\Email::buildFromContent( 'Test', $themeFunction( $dummyPurchase ), NULL, \IPS\Email::TYPE_TRANSACTIONAL )->compileContent( 'html', \IPS\Member::loggedIn() );
|
||||
$output = Email::buildFromContent( 'Test', $themeFunction( $dummyPurchase ), NULL, Email::TYPE_TRANSACTIONAL )->compileContent( 'html', Member::loggedIn() );
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
catch ( Exception $e )
|
||||
{
|
||||
$output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->message( $e->getMessage(), 'error', $e->getMessage(), TRUE, TRUE );
|
||||
$output = Theme::i()->getTemplate( 'global', 'core' )->message( $e->getMessage(), 'error', $e->getMessage(), TRUE, TRUE );
|
||||
}
|
||||
\IPS\Output::i()->sendOutput( $output );
|
||||
Output::i()->sendOutput( $output );
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the form to mass move content
|
||||
*
|
||||
* @param \IPS\Helpers\Form $form The form helper object
|
||||
* @param Form $form The form helper object
|
||||
* @param mixed $data Data from the wizard helper
|
||||
* @param string $nodeClass Node class
|
||||
* @param \IPS\Node\Mode $node Node we are working with
|
||||
* @param Model $node Node we are working with
|
||||
* @param string $contentItemClass Content item class (if there is one)
|
||||
* @return \IPS\Helpers\Form
|
||||
* @return Form
|
||||
*/
|
||||
protected function _buildMassMoveForm( $form, $data, $nodeClass, $node, $contentItemClass )
|
||||
protected function _buildMassMoveForm(Form $form, mixed $data, string $nodeClass, Model $node, string $contentItemClass ): Form
|
||||
{
|
||||
$form->addHeader('node_mass_move_delete_then');
|
||||
$moveToClass = isset( $data['moveToClass'] ) ? $data['moveToClass'] : $nodeClass;
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'node_move_products', isset( $data['moveTo'] ) ? $moveToClass::load( $data['moveTo'] ) : 0, TRUE, array( 'class' => $nodeClass, 'disabledIds' => array( $node->_id ), 'disabledLang' => 'node_move_delete', 'zeroVal' => 'products_delete_content', 'subnodes' => FALSE ) ) );
|
||||
$moveToClass = $data['moveToClass'] ?? $nodeClass;
|
||||
$form->add( new Node( 'node_move_products', isset( $data['moveTo'] ) ? $moveToClass::load( $data['moveTo'] ) : 0, TRUE, array( 'class' => $nodeClass, 'disabledIds' => array( $node->_id ), 'disabledLang' => 'node_move_delete', 'zeroVal' => 'products_delete_content', 'subnodes' => FALSE ) ) );
|
||||
|
||||
return $form;
|
||||
}
|
||||
@@ -819,19 +877,19 @@ class _packages extends \IPS\Node\Controller
|
||||
* @param array $values Values from form submission
|
||||
* @param mixed $data Data from the wizard helper
|
||||
* @param string $nodeClass Node class
|
||||
* @param \IPS\Node\Mode $node Node we are working with
|
||||
* @param Model $node Node we are working with
|
||||
* @param string $contentItemClass Content item class (if there is one)
|
||||
* @return array Wizard helper data
|
||||
*/
|
||||
protected function _processMassMoveForm( $values, $data, $nodeClass, $node, $contentItemClass )
|
||||
protected function _processMassMoveForm(array $values, mixed $data, string $nodeClass, Model $node, string $contentItemClass ): array
|
||||
{
|
||||
$data['deleteWhenDone'] = FALSE;
|
||||
$data['class'] = \get_class( $node );
|
||||
$data['class'] = get_class( $node );
|
||||
$data['id'] = $node->_id;
|
||||
|
||||
if ( \is_object( $values['node_move_products'] ) )
|
||||
if ( is_object( $values['node_move_products'] ) )
|
||||
{
|
||||
$data['moveToClass'] = \get_class( $values['node_move_products'] );
|
||||
$data['moveToClass'] = get_class( $values['node_move_products'] );
|
||||
$data['moveTo'] = $values['node_move_products']->_id;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -12,30 +12,50 @@
|
||||
namespace IPS\nexus\modules\admin\store;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\CheckboxSet;
|
||||
use IPS\Helpers\Form\Custom;
|
||||
use IPS\Helpers\Form\Radio;
|
||||
use IPS\Helpers\Form\Stack;
|
||||
use IPS\Helpers\Form\Translatable;
|
||||
use IPS\Helpers\Form\YesNo;
|
||||
use IPS\Lang;
|
||||
use IPS\Member;
|
||||
use IPS\Member\Group;
|
||||
use IPS\nexus\Form\Money;
|
||||
use IPS\Output;
|
||||
use IPS\Session;
|
||||
use IPS\Settings as SettingsClass;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store Settings
|
||||
*/
|
||||
class _settings extends \IPS\Dispatcher\Controller
|
||||
class settings extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'settings_manage' );
|
||||
Dispatcher::i()->checkAcpPermission( 'settings_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -44,10 +64,10 @@ class _settings extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
$giftVouchers = array();
|
||||
foreach ( \IPS\Settings::i()->nexus_gift_vouchers ? ( json_decode( \IPS\Settings::i()->nexus_gift_vouchers, TRUE ) ?: array() ) : array() as $voucher )
|
||||
foreach ( SettingsClass::i()->nexus_gift_vouchers ? ( json_decode( SettingsClass::i()->nexus_gift_vouchers, TRUE ) ?: array() ) : array() as $voucher )
|
||||
{
|
||||
$amounts = array();
|
||||
foreach ( $voucher as $currency => $amount )
|
||||
@@ -58,43 +78,44 @@ class _settings extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
$groups = array();
|
||||
foreach ( \IPS\Member\Group::groups( FALSE, FALSE ) as $group )
|
||||
foreach ( Group::groups( FALSE, FALSE ) as $group )
|
||||
{
|
||||
$groups[ $group->g_id ] = $group->name;
|
||||
}
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form = new Form;
|
||||
$form->addTab('nexus_store_display');
|
||||
$form->addHeader('nexus_store_prices');
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_show_tax', \IPS\Settings::i()->nexus_show_tax ) );
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'nexus_tax_explain', NULL, FALSE, array( 'app' => 'nexus', 'key' => 'nexus_tax_explain_val', 'placeholder' => \IPS\Member::loggedIn()->language()->addToStack('nexus_tax_explain_placeholder') ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'nexus_show_renew_option_savings', \IPS\Settings::i()->nexus_show_renew_option_savings, FALSE, array( 'options' => array(
|
||||
$form->add( new YesNo( 'nexus_show_tax', SettingsClass::i()->nexus_show_tax ) );
|
||||
$form->add( new Translatable( 'nexus_tax_explain', NULL, FALSE, array( 'app' => 'nexus', 'key' => 'nexus_tax_explain_val', 'placeholder' => Member::loggedIn()->language()->addToStack('nexus_tax_explain_placeholder') ) ) );
|
||||
$form->add( new Radio( 'nexus_show_renew_option_savings', SettingsClass::i()->nexus_show_renew_option_savings, FALSE, array( 'options' => array(
|
||||
'none' => 'nexus_show_renew_option_savings_none',
|
||||
'amount' => 'nexus_show_renew_option_savings_amount',
|
||||
'percent' => 'nexus_show_renew_option_savings_percent',
|
||||
) ) ) );
|
||||
$form->addHeader( 'nexus_store_index' );
|
||||
$form->add( new \IPS\Helpers\Form\Custom( 'nexus_store_new', explode( ',', \IPS\Settings::i()->nexus_store_new ), FALSE, array(
|
||||
$form->add( new Custom( 'nexus_store_new', explode( ',', SettingsClass::i()->nexus_store_new ), FALSE, array(
|
||||
'getHtml' => function( $field )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'store' )->storeIndexProductsSetting( 'nexus_store_new_field', $field->name, $field->value );
|
||||
return Theme::i()->getTemplate( 'store' )->storeIndexProductsSetting( 'nexus_store_new_field', $field->name, $field->value );
|
||||
}
|
||||
) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Custom( 'nexus_store_popular', explode( ',', \IPS\Settings::i()->nexus_store_popular ), FALSE, array(
|
||||
$form->add( new Custom( 'nexus_store_popular', explode( ',', SettingsClass::i()->nexus_store_popular ), FALSE, array(
|
||||
'getHtml' => function( $field )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'store' )->storeIndexProductsSetting( 'nexus_store_popular_field', $field->name, $field->value );
|
||||
return Theme::i()->getTemplate( 'store' )->storeIndexProductsSetting( 'nexus_store_popular_field', $field->name, $field->value );
|
||||
}
|
||||
) ) );
|
||||
|
||||
$form->addHeader( 'nexus_stock' );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_show_stock', \IPS\Settings::i()->nexus_show_stock ) );
|
||||
$form->add( new YesNo( 'nexus_show_stock', SettingsClass::i()->nexus_show_stock ) );
|
||||
$form->addTab( 'nexus_purchase_settings' );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_reg_force', \IPS\Settings::i()->nexus_reg_force, FALSE ) );
|
||||
$form->add( new \IPS\nexus\Form\Money( 'nexus_minimum_order', json_decode( \IPS\Settings::i()->nexus_minimum_order, TRUE ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'cm_protected', explode( ',', \IPS\Settings::i()->cm_protected ), FALSE, array( 'options' => $groups, 'multiple' => TRUE ) ) );
|
||||
$form->add( new YesNo( 'nexus_reg_force', SettingsClass::i()->nexus_reg_force, FALSE ) );
|
||||
$form->add( new Money( 'nexus_minimum_order', json_decode( SettingsClass::i()->nexus_minimum_order, TRUE ) ) );
|
||||
$form->add( new CheckboxSet( 'cm_protected', explode( ',', SettingsClass::i()->cm_protected ), FALSE, array( 'options' => $groups, 'multiple' => TRUE ) ) );
|
||||
$form->addTab('nexus_gift_vouchers');
|
||||
$form->add( new \IPS\Helpers\Form\Stack( 'nexus_gift_vouchers', $giftVouchers, FALSE, array( 'stackFieldType' => 'IPS\nexus\Form\Money' ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_gift_vouchers_free', \IPS\Settings::i()->nexus_gift_vouchers_free ) );
|
||||
$form->add( new Stack( 'nexus_gift_vouchers', $giftVouchers, FALSE, array( 'stackFieldType' => 'IPS\nexus\Form\Money' ) ) );
|
||||
$form->add( new YesNo( 'nexus_gift_vouchers_free', SettingsClass::i()->nexus_gift_vouchers_free ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
@@ -110,7 +131,7 @@ class _settings extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
$values['nexus_gift_vouchers'] = json_encode( $giftVouchers );
|
||||
|
||||
\IPS\Lang::saveCustom( 'nexus', "nexus_tax_explain_val", $values['nexus_tax_explain'] );
|
||||
Lang::saveCustom( 'nexus', "nexus_tax_explain_val", $values['nexus_tax_explain'] );
|
||||
unset( $values['nexus_tax_explain'] );
|
||||
|
||||
$values['cm_protected'] = implode( ',', $values['cm_protected'] );
|
||||
@@ -121,12 +142,9 @@ class _settings extends \IPS\Dispatcher\Controller
|
||||
|
||||
$form->saveAsSettings( $values );
|
||||
|
||||
\IPS\Session::i()->log( 'acplogs__nexus_store_settings' );
|
||||
|
||||
/* Clear guest page caches */
|
||||
\IPS\Data\Cache::i()->clearAll();
|
||||
Session::i()->log( 'acplogs__nexus_store_settings' );
|
||||
}
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('store_settings');
|
||||
\IPS\Output::i()->output = $form;
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('store_settings');
|
||||
Output::i()->output = $form;
|
||||
}
|
||||
}
|
||||
@@ -12,30 +12,49 @@
|
||||
namespace IPS\nexus\modules\admin\subscriptions;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\DateTime;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\Helpers\Table\Db;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\nexus\Purchase;
|
||||
use IPS\nexus\Subscription;
|
||||
use IPS\nexus\Subscription\Package;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
use IPS\Theme;
|
||||
use OutOfRangeException;
|
||||
use function defined;
|
||||
use const IPS\Helpers\Table\SEARCH_CONTAINS_TEXT;
|
||||
use const IPS\Helpers\Table\SEARCH_DATE_RANGE;
|
||||
use const IPS\Helpers\Table\SEARCH_NODE;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribers
|
||||
*/
|
||||
class _subscribers extends \IPS\Dispatcher\Controller
|
||||
class subscribers extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'subscribers_manage' );
|
||||
Dispatcher::i()->checkAcpPermission( 'subscribers_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -44,10 +63,18 @@ class _subscribers extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
{
|
||||
protected function manage() : void
|
||||
{
|
||||
/* If we came from the Subscription Plans page, we might have a
|
||||
package ID passed in the URL */
|
||||
$where = [];
|
||||
if( isset( Request::i()->nexus_sub_package_id ) AND Request::i()->nexus_sub_package_id )
|
||||
{
|
||||
$where[] = array( 'sub_package_id=?', Request::i()->nexus_sub_package_id );
|
||||
}
|
||||
|
||||
/* Create the table */
|
||||
$table = new \IPS\Helpers\Table\Db( 'nexus_member_subscriptions', \IPS\Http\Url::internal( 'app=nexus&module=subscriptions&controller=subscribers' ) );
|
||||
$table = new Db( 'nexus_member_subscriptions', Url::internal( 'app=nexus&module=subscriptions&controller=subscribers' ), $where );
|
||||
$table->joins = array(
|
||||
array(
|
||||
'select' => 'core_members.*',
|
||||
@@ -72,26 +99,27 @@ class _subscribers extends \IPS\Dispatcher\Controller
|
||||
$table->parsers = array(
|
||||
'photo' => function( $val, $row )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate('customers')->rowPhoto( \IPS\Member::constructFromData( $row ) );
|
||||
return Theme::i()->getTemplate('customers')->rowPhoto( Member::constructFromData( $row ) );
|
||||
},
|
||||
'sub_member_id' => function( $val ) {
|
||||
return \IPS\Theme::i()->getTemplate('global', 'nexus')->userLink( \IPS\Member::load( $val ) );
|
||||
return Theme::i()->getTemplate('global', 'nexus')->userLink( Member::load( $val ) );
|
||||
},
|
||||
'sub_package_id' => function( $val ) {
|
||||
try
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate('subscription', 'nexus')->packageLink( \IPS\nexus\Subscription\Package::load( $val ) );
|
||||
return Theme::i()->getTemplate('subscription', 'nexus')->packageLink( Package::load( $val ) );
|
||||
}
|
||||
catch( \OutOfRangeException $e ) { }
|
||||
catch( OutOfRangeException ) { }
|
||||
return '';
|
||||
},
|
||||
'sub_start' => function( $val ) {
|
||||
return \IPS\DateTime::ts( $val );
|
||||
return DateTime::ts( $val );
|
||||
},
|
||||
'sub_expire' => function( $val, $row ) {
|
||||
return $val ? \IPS\nexus\Subscription::constructFromData( $row )->_expire : '';
|
||||
return $val ? Subscription::constructFromData( $row )->_expire : '';
|
||||
},
|
||||
'sub_active' => function( $val ) {
|
||||
return \IPS\Theme::i()->getTemplate('subscription', 'nexus')->status( $val );
|
||||
return Theme::i()->getTemplate('subscription', 'nexus')->status( $val );
|
||||
}
|
||||
);
|
||||
|
||||
@@ -103,7 +131,7 @@ class _subscribers extends \IPS\Dispatcher\Controller
|
||||
$return['purchase'] = array(
|
||||
'title' => 'nexus_subs_view_purchase',
|
||||
'icon' => 'search',
|
||||
'link' => \IPS\Http\Url::internal( "app=nexus&module=subscriptions&controller=subscribers&do=findPurchase&id=" . $row['sub_id'] )
|
||||
'link' => Url::internal( "app=nexus&module=subscriptions&controller=subscribers&do=findPurchase&id=" . $row['sub_id'] )
|
||||
);
|
||||
}
|
||||
|
||||
@@ -117,32 +145,32 @@ class _subscribers extends \IPS\Dispatcher\Controller
|
||||
);
|
||||
|
||||
$table->advancedSearch = array(
|
||||
'cm_first_name' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT,
|
||||
'cm_last_name' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT,
|
||||
'email' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT,
|
||||
'name' => \IPS\Helpers\Table\SEARCH_CONTAINS_TEXT,
|
||||
'sub_expire' => \IPS\Helpers\Table\SEARCH_DATE_RANGE,
|
||||
'sub_start' => \IPS\Helpers\Table\SEARCH_DATE_RANGE,
|
||||
'sub_package_id' => array( \IPS\Helpers\Table\SEARCH_NODE, array(
|
||||
'cm_first_name' => SEARCH_CONTAINS_TEXT,
|
||||
'cm_last_name' => SEARCH_CONTAINS_TEXT,
|
||||
'email' => SEARCH_CONTAINS_TEXT,
|
||||
'name' => SEARCH_CONTAINS_TEXT,
|
||||
'sub_expire' => SEARCH_DATE_RANGE,
|
||||
'sub_start' => SEARCH_DATE_RANGE,
|
||||
'sub_package_id' => array( SEARCH_NODE, array(
|
||||
'class' => '\IPS\nexus\Subscription\Package',
|
||||
'zeroVal' => 'any'
|
||||
) ),
|
||||
);
|
||||
|
||||
/* Breadcrumb? */
|
||||
if ( isset( \IPS\Request::i()->nexus_sub_package_id ) )
|
||||
if ( isset( Request::i()->nexus_sub_package_id ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$package = \IPS\nexus\Subscription\Package::load( \IPS\Request::i()->nexus_sub_package_id );
|
||||
\IPS\Output::i()->breadcrumb[] = array( \IPS\Http\Url::internal( "app=nexus&module=subscriptions&controller=subscriptions&id=" . $package->id ), $package->_title );
|
||||
$package = Package::load( Request::i()->nexus_sub_package_id );
|
||||
Output::i()->breadcrumb[] = array( Url::internal( "app=nexus&module=subscriptions&controller=subscriptions&id=" . $package->id ), $package->_title );
|
||||
}
|
||||
catch( \OutOfRangeException $e ) { }
|
||||
catch( OutOfRangeException ) { }
|
||||
}
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('r__subscribers');
|
||||
\IPS\Output::i()->output = (string) $table;
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('r__subscribers');
|
||||
Output::i()->output = (string) $table;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -150,17 +178,17 @@ class _subscribers extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function findPurchase()
|
||||
protected function findPurchase() : void
|
||||
{
|
||||
try
|
||||
{
|
||||
$sub = \IPS\nexus\Subscription::load( \IPS\Request::i()->id );
|
||||
$purchase = \IPS\nexus\Purchase::load( $sub->purchase_id );
|
||||
\IPS\Output::i()->redirect( $purchase->acpUrl() );
|
||||
$sub = Subscription::load( Request::i()->id );
|
||||
$purchase = Purchase::load( $sub->purchase_id );
|
||||
Output::i()->redirect( $purchase->acpUrl() );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
catch( OutOfRangeException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'nexus_sub_no_purchase', '2X378/2', 404, '' );
|
||||
Output::i()->error( 'nexus_sub_no_purchase', '2X378/2', 404, '' );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,26 +12,66 @@
|
||||
namespace IPS\nexus\modules\admin\subscriptions;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DateInterval;
|
||||
use Exception;
|
||||
use InvalidArgumentException;
|
||||
use IPS\Db;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\CheckboxSet;
|
||||
use IPS\Helpers\Form\Interval;
|
||||
use IPS\Helpers\Form\Matrix;
|
||||
use IPS\Helpers\Form\Node;
|
||||
use IPS\Helpers\Form\Radio;
|
||||
use IPS\Helpers\Form\Select;
|
||||
use IPS\Helpers\Form\YesNo;
|
||||
use IPS\Helpers\MultipleRedirect;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Lang;
|
||||
use IPS\Member;
|
||||
use IPS\Member\Group;
|
||||
use IPS\nexus\Customer;
|
||||
use IPS\nexus\Form\RenewalTerm;
|
||||
use IPS\nexus\Money;
|
||||
use IPS\nexus\Purchase;
|
||||
use IPS\nexus\Subscription;
|
||||
use IPS\nexus\Subscription\Package;
|
||||
use IPS\nexus\Tax;
|
||||
use IPS\Node\Controller;
|
||||
use IPS\Node\Model;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
use IPS\Session;
|
||||
use IPS\Settings;
|
||||
use IPS\Theme;
|
||||
use OutOfRangeException;
|
||||
use UnderflowException;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* subscriptions
|
||||
*/
|
||||
class _subscriptions extends \IPS\Node\Controller
|
||||
class subscriptions extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
protected $nodeClass = 'IPS\nexus\Subscription\Package';
|
||||
protected string $nodeClass = 'IPS\nexus\Subscription\Package';
|
||||
|
||||
/**
|
||||
* Fetch any additional HTML for this row
|
||||
@@ -39,12 +79,12 @@ class _subscriptions extends \IPS\Node\Controller
|
||||
* @param object $node Node returned from $nodeClass::load()
|
||||
* @return NULL|string
|
||||
*/
|
||||
public function _getRowHtml( $node )
|
||||
public function _getRowHtml( object $node ): ?string
|
||||
{
|
||||
$active = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_member_subscriptions', array( 'sub_package_id=? and sub_active=1', $node->id ) )->first();
|
||||
$inactive = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_member_subscriptions', array( 'sub_package_id=? and sub_active=0', $node->id ) )->first();
|
||||
$active = Db::i()->select( 'COUNT(*)', 'nexus_member_subscriptions', array( 'sub_package_id=? and sub_active=1', $node->id ) )->first();
|
||||
$inactive = Db::i()->select( 'COUNT(*)', 'nexus_member_subscriptions', array( 'sub_package_id=? and sub_active=0', $node->id ) )->first();
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'subscription', 'nexus' )->rowHtml( $node, $node->priceBlurb(), $active, $inactive );
|
||||
return Theme::i()->getTemplate( 'subscription', 'nexus' )->rowHtml( $node, $node->priceBlurb(), $active, $inactive );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,9 +92,9 @@ class _subscriptions extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'subscriptions_manage' );
|
||||
Dispatcher::i()->checkAcpPermission( 'subscriptions_manage' );
|
||||
|
||||
parent::execute();
|
||||
}
|
||||
@@ -64,22 +104,22 @@ class _subscriptions extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function manage()
|
||||
public function manage() : void
|
||||
{
|
||||
if ( \IPS\Settings::i()->nexus_subs_enabled )
|
||||
if ( Settings::i()->nexus_subs_enabled )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['actions']['settings'] = array(
|
||||
Output::i()->sidebar['actions']['settings'] = array(
|
||||
'primary' => false,
|
||||
'title' => 'settings',
|
||||
'icon' => 'cog',
|
||||
'link' => \IPS\Http\Url::internal('app=nexus&module=subscriptions&controller=subscriptions&do=settings')
|
||||
'link' => Url::internal('app=nexus&module=subscriptions&controller=subscriptions&do=settings')
|
||||
);
|
||||
|
||||
parent::manage();
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'subscription' )->disabled();
|
||||
Output::i()->output = Theme::i()->getTemplate( 'subscription' )->disabled();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,30 +128,30 @@ class _subscriptions extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function convertToSubscription()
|
||||
public function convertToSubscription() : void
|
||||
{
|
||||
try
|
||||
{
|
||||
$package = \IPS\nexus\Package::load( \IPS\Request::i()->id );
|
||||
$package = \IPS\nexus\Package::load( Request::i()->id );
|
||||
if ( $package->deleteOrMoveQueued() )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
throw new OutOfRangeException;
|
||||
}
|
||||
}
|
||||
catch( \OutOfRangeException $ex )
|
||||
catch( OutOfRangeException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X393/2', 404, '' );
|
||||
Output::i()->error( 'node_error', '2X393/2', 404, '' );
|
||||
}
|
||||
|
||||
$renewOptions = array();
|
||||
if ( $package->renew_options and $_renewOptions = json_decode( $package->renew_options, TRUE ) and \is_array( $_renewOptions ) )
|
||||
if ( $package->renew_options and $_renewOptions = json_decode( $package->renew_options, TRUE ) and is_array( $_renewOptions ) )
|
||||
{
|
||||
foreach ( $_renewOptions as $option )
|
||||
{
|
||||
$costs = array();
|
||||
foreach ( $option['cost'] as $cost )
|
||||
{
|
||||
$costs[ $cost['currency'] ] = new \IPS\nexus\Money( $cost['amount'], $cost['currency'] );
|
||||
$costs[ $cost['currency'] ] = new Money( $cost['amount'], $cost['currency'] );
|
||||
}
|
||||
|
||||
/* Figure out tax */
|
||||
@@ -121,37 +161,37 @@ class _subscriptions extends \IPS\Node\Controller
|
||||
{
|
||||
if( $package->tax )
|
||||
{
|
||||
$tax = \IPS\nexus\Tax::load( $package->tax );
|
||||
$tax = Tax::load( $package->tax );
|
||||
}
|
||||
}
|
||||
catch( \OutOfRangeException $e ){}
|
||||
catch( OutOfRangeException ){}
|
||||
|
||||
/* Catch any invalid renewal terms, these can occasionally appear from legacy IP.Subscriptions */
|
||||
try
|
||||
{
|
||||
$renewOptions[] = new \IPS\nexus\Purchase\RenewalTerm( $costs, new \DateInterval( "P{$option['term']}" . mb_strtoupper( $option['unit'] ) ), $tax, $option['add'] );
|
||||
$renewOptions[] = new Purchase\RenewalTerm( $costs, new DateInterval( "P{$option['term']}" . mb_strtoupper( $option['unit'] ) ), $tax, $option['add'] );
|
||||
}
|
||||
catch( \Exception $ex) {}
|
||||
catch( Exception ) {}
|
||||
}
|
||||
}
|
||||
|
||||
$useRenewals = array_pop( $renewOptions );
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form = new Form;
|
||||
$form->addHeader('nexus_subs_review_pricing');
|
||||
$form->add( new \IPS\nexus\Form\Money( 'sp_price', $package->base_price, TRUE ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'sp_renews', !empty( $useRenewals ), FALSE, array( 'togglesOn' => array( 'sp_renew_options' ) ), NULL, NULL, NULL, 'sp_renews' ) );
|
||||
$form->add( new \IPS\nexus\Form\RenewalTerm( 'sp_renew_options', $useRenewals, NULL, array( 'allCurrencies' => TRUE ), NULL, NULL, NULL, 'sp_renew_options' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'sp_tax', (int) $package->tax, FALSE, array( 'class' => 'IPS\nexus\Tax', 'zeroVal' => 'do_not_tax' ) ) );
|
||||
$form->add( new YesNo( 'sp_renews', !empty( $useRenewals ), FALSE, array( 'togglesOn' => array( 'sp_renew_options' ) ), NULL, NULL, NULL, 'sp_renews' ) );
|
||||
$form->add( new RenewalTerm( 'sp_renew_options', $useRenewals, NULL, array( 'allCurrencies' => TRUE ), NULL, NULL, NULL, 'sp_renew_options' ) );
|
||||
$form->add( new Node( 'sp_tax', (int) $package->tax, FALSE, array( 'class' => 'IPS\nexus\Tax', 'zeroVal' => 'do_not_tax' ) ) );
|
||||
$form->addHeader('nexus_subs_after_conversion');
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'sp_after_conversion_delete', FALSE, FALSE ) );
|
||||
$form->add( new YesNo( 'sp_after_conversion_delete', FALSE, FALSE ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
$sub = new \IPS\nexus\Subscription\Package;
|
||||
$sub = new Package;
|
||||
$sub->enabled = 1;
|
||||
$sub->tax = $values['sp_tax'] ? $values['sp_tax']->id : 0;
|
||||
$sub->gateways = ( isset( $values['sp_gateways'] ) and \is_array( $values['sp_gateways'] ) ) ? implode( ',', array_keys( $values['sp_gateways'] ) ) : '*';
|
||||
$sub->gateways = ( isset( $values['sp_gateways'] ) and is_array( $values['sp_gateways'] ) ) ? implode( ',', array_keys( $values['sp_gateways'] ) ) : '*';
|
||||
$sub->price = json_encode( $values['sp_price'] );
|
||||
|
||||
foreach( array( 'primary_group', 'secondary_group') as $thingsWotAreTheSame )
|
||||
@@ -180,17 +220,17 @@ class _subscriptions extends \IPS\Node\Controller
|
||||
$sub->save();
|
||||
|
||||
/* Language stuffs */
|
||||
\IPS\Lang::copyCustom( 'nexus', "nexus_package_{$package->id}", "nexus_subs_{$sub->id}" );
|
||||
\IPS\Lang::copyCustom( 'nexus', "nexus_package_{$package->id}_desc", "nexus_subs_{$sub->id}_desc" );
|
||||
Lang::copyCustom( 'nexus', "nexus_package_{$package->id}", "nexus_subs_{$sub->id}" );
|
||||
Lang::copyCustom( 'nexus', "nexus_package_{$package->id}_desc", "nexus_subs_{$sub->id}_desc" );
|
||||
|
||||
/* Purchases */
|
||||
foreach( \IPS\Db::i()->select( '*', 'nexus_purchases', array( 'ps_app=? and ps_type=? and ps_active=1 and ps_cancelled=0 and ps_item_id=?', 'nexus', 'package', $package->id ) ) as $purchase )
|
||||
foreach( Db::i()->select( '*', 'nexus_purchases', array( 'ps_app=? and ps_type=? and ps_active=1 and ps_cancelled=0 and ps_item_id=?', 'nexus', 'package', $package->id ) ) as $purchase )
|
||||
{
|
||||
try
|
||||
{
|
||||
$customer = \IPS\nexus\Customer::load( $purchase['ps_member'] );
|
||||
$customer = Customer::load( $purchase['ps_member'] );
|
||||
|
||||
\IPS\Db::i()->update( 'nexus_purchases', array( 'ps_type' => 'subscription', 'ps_item_id' => $sub->id ), array( 'ps_id=?', $purchase['ps_id'] ) );
|
||||
Db::i()->update( 'nexus_purchases', array( 'ps_type' => 'subscription', 'ps_item_id' => $sub->id ), array( 'ps_id=?', $purchase['ps_id'] ) );
|
||||
|
||||
$subscription = $sub->addMember( $customer );
|
||||
$subscription->purchase_id = $purchase['ps_id'];
|
||||
@@ -199,7 +239,7 @@ class _subscriptions extends \IPS\Node\Controller
|
||||
$subscription->start = $purchase['ps_start'];
|
||||
$subscription->save();
|
||||
}
|
||||
catch( \Exception $e ) { }
|
||||
catch( Exception ) { }
|
||||
}
|
||||
|
||||
/* Delete original product */
|
||||
@@ -208,13 +248,13 @@ class _subscriptions extends \IPS\Node\Controller
|
||||
$package->delete();
|
||||
}
|
||||
|
||||
\IPS\Session::i()->log( 'acplogs__nexus_sub_converted', array( "nexus_subs_{$sub->id}" => TRUE ) );
|
||||
Session::i()->log( 'acplogs__nexus_sub_converted', array( "nexus_subs_{$sub->id}" => TRUE ) );
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=subscriptions&controller=subscriptions'), 'nexus_package_converted_lovely' );
|
||||
Output::i()->redirect( Url::internal('app=nexus&module=subscriptions&controller=subscriptions'), 'nexus_package_converted_lovely' );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('nexus_subs_convert');
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'subscription', 'nexus' )->convert( $form, $package );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('nexus_subs_convert');
|
||||
Output::i()->output = Theme::i()->getTemplate( 'subscription', 'nexus' )->convert( $form, $package );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -222,15 +262,15 @@ class _subscriptions extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function enable()
|
||||
public function enable() : void
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
\IPS\Settings::i()->changeValues( array( 'nexus_subs_enabled' => true ) );
|
||||
Settings::i()->changeValues( array( 'nexus_subs_enabled' => true ) );
|
||||
|
||||
\IPS\Session::i()->log( 'acplog__subscription_settings' );
|
||||
Session::i()->log( 'acplog__subscription_settings' );
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=subscriptions&controller=subscriptions') );
|
||||
Output::i()->redirect( Url::internal('app=nexus&module=subscriptions&controller=subscriptions') );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -238,37 +278,38 @@ class _subscriptions extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
public function delete() : void
|
||||
{
|
||||
/* Load package */
|
||||
try
|
||||
{
|
||||
$package = \IPS\nexus\Subscription\Package::load( \IPS\Request::i()->id );
|
||||
$package = Package::load( Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
return parent::delete();
|
||||
parent::delete();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Are there any purchases of this product? */
|
||||
if ( !isset( \IPS\Request::i()->confirmImplications ) and \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=?', 'nexus', 'subscription', $package->id ) )->first() )
|
||||
if ( !isset( Request::i()->confirmImplications ) and Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=?', 'nexus', 'subscription', $package->id ) )->first() )
|
||||
{
|
||||
\IPS\Output::i()->bypassCsrfKeyCheck = TRUE;
|
||||
Output::i()->bypassCsrfKeyCheck = TRUE;
|
||||
$options = array(
|
||||
'product_delete_confirm' => \IPS\Http\Url::internal( "app=nexus&module=subscriptions&controller=subscriptions&do=delete&wasConfirmed=1&id={$package->_id}&confirmImplications=1" )->csrf(),
|
||||
'product_delete_confirm' => Url::internal( "app=nexus&module=subscriptions&controller=subscriptions&do=delete&wasConfirmed=1&id={$package->_id}&confirmImplications=1" )->csrf(),
|
||||
);
|
||||
if ( $package->enabled )
|
||||
{
|
||||
$options['product_delete_hide'] = \IPS\Http\Url::internal( "app=nexus&module=subscriptions&controller=subscriptions&do=hide&id={$package->_id}" )->csrf();
|
||||
$options['product_delete_hide'] = Url::internal( "app=nexus&module=subscriptions&controller=subscriptions&do=hide&id={$package->_id}" )->csrf();
|
||||
}
|
||||
$options['cancel'] = \IPS\Http\Url::internal( "app=nexus&module=subscriptions&controller=subscriptions" );
|
||||
$options['cancel'] = Url::internal( "app=nexus&module=subscriptions&controller=subscriptions" );
|
||||
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->decision( 'subscription_delete_blurb', $options );
|
||||
Output::i()->output = Theme::i()->getTemplate( 'global', 'core' )->decision( 'subscription_delete_blurb', $options );
|
||||
return;
|
||||
}
|
||||
|
||||
/* If not, just handle the delete as normal */
|
||||
return parent::delete();
|
||||
parent::delete();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -276,28 +317,28 @@ class _subscriptions extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function hide()
|
||||
public function hide() : void
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
/* Load package */
|
||||
try
|
||||
{
|
||||
$package = \IPS\nexus\Subscription\Package::load( \IPS\Request::i()->id );
|
||||
$package = Package::load( Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '1X393/2', 404, '' );
|
||||
Output::i()->error( 'node_error', '1X393/2', 404, '' );
|
||||
}
|
||||
|
||||
/* Do it */
|
||||
$package->enabled = FALSE;
|
||||
$package->save();
|
||||
|
||||
\IPS\Session::i()->log( 'aplogs__nexus_sub_hidden', array( "nexus_subs_{$package->id}" => TRUE ) );
|
||||
|
||||
Session::i()->log( 'aplogs__nexus_sub_hidden', array( "nexus_subs_{$package->id}" => TRUE ) );
|
||||
|
||||
/* Redirect */
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=nexus&module=subscriptions&controller=subscriptions" ) );
|
||||
Output::i()->redirect( Url::internal( "app=nexus&module=subscriptions&controller=subscriptions" ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -305,24 +346,24 @@ class _subscriptions extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function addMember()
|
||||
protected function addMember() : void
|
||||
{
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\Member( 'nexus_subs_member_to_add', NULL, TRUE, array(), function( $val )
|
||||
$form = new Form;
|
||||
$form->add( new Form\Member( 'nexus_subs_member_to_add', NULL, TRUE, array(), function($val )
|
||||
{
|
||||
if ( $val instanceof \IPS\Member )
|
||||
if ( $val instanceof Member )
|
||||
{
|
||||
$sub = \IPS\nexus\Subscription::loadByMember( $val, false );
|
||||
$sub = Subscription::loadByMember( $val, false );
|
||||
|
||||
/* We have cannot have duplicate active subscriptions, so error out */
|
||||
if( $sub !== NULL )
|
||||
{
|
||||
throw new \InvalidArgumentException( 'nexus_subs_add_member_already_subscribed' );
|
||||
throw new InvalidArgumentException( 'nexus_subs_add_member_already_subscribed' );
|
||||
}
|
||||
}
|
||||
}, NULL, NULL, 'nexus_subs_member_to_add' ) );
|
||||
|
||||
$package = \IPS\nexus\Subscription\Package::load( \IPS\Request::i()->id );
|
||||
$package = Package::load( Request::i()->id );
|
||||
if( $term = $package->renewalTerm() )
|
||||
{
|
||||
|
||||
@@ -331,45 +372,45 @@ class _subscriptions extends \IPS\Node\Controller
|
||||
$costs = array();
|
||||
foreach ( $newOption['cost'] as $data )
|
||||
{
|
||||
$costs[] = new \IPS\nexus\Money( $data['amount'], $data['currency'] );
|
||||
$costs[] = new Money( $data['amount'], $data['currency'] );
|
||||
}
|
||||
|
||||
switch ( $newOption['unit'] )
|
||||
{
|
||||
case 'd':
|
||||
$initialTerm = \IPS\Member::loggedIn()->language()->addToStack('renew_days_no_term', FALSE, array( 'pluralize' => array( $newOption['term'] ) ) );
|
||||
$term = \IPS\Member::loggedIn()->language()->addToStack('renew_days', FALSE, array( 'pluralize' => array( $newOption['term'] ) ) );
|
||||
$initialTerm = Member::loggedIn()->language()->addToStack('renew_days_no_term', FALSE, array( 'pluralize' => array( $newOption['term'] ) ) );
|
||||
$term = Member::loggedIn()->language()->addToStack('renew_days', FALSE, array( 'pluralize' => array( $newOption['term'] ) ) );
|
||||
break;
|
||||
case 'm':
|
||||
$initialTerm = \IPS\Member::loggedIn()->language()->addToStack('renew_months_no_term', FALSE, array( 'pluralize' => array( $newOption['term'] ) ) );
|
||||
$term = \IPS\Member::loggedIn()->language()->addToStack('renew_months', FALSE, array( 'pluralize' => array( $newOption['term'] ) ) );
|
||||
$initialTerm = Member::loggedIn()->language()->addToStack('renew_months_no_term', FALSE, array( 'pluralize' => array( $newOption['term'] ) ) );
|
||||
$term = Member::loggedIn()->language()->addToStack('renew_months', FALSE, array( 'pluralize' => array( $newOption['term'] ) ) );
|
||||
break;
|
||||
case 'y':
|
||||
$initialTerm = \IPS\Member::loggedIn()->language()->addToStack('renew_years_no_term', FALSE, array( 'pluralize' => array( $newOption['term'] ) ) );
|
||||
$term = \IPS\Member::loggedIn()->language()->addToStack('renew_years', FALSE, array( 'pluralize' => array( $newOption['term'] ) ) );
|
||||
$initialTerm = Member::loggedIn()->language()->addToStack('renew_years_no_term', FALSE, array( 'pluralize' => array( $newOption['term'] ) ) );
|
||||
$term = Member::loggedIn()->language()->addToStack('renew_years', FALSE, array( 'pluralize' => array( $newOption['term'] ) ) );
|
||||
break;
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'nexus_subs_free_period', NULL, TRUE, [
|
||||
$form->add( new Radio( 'nexus_subs_free_period', NULL, TRUE, [
|
||||
'options' => [
|
||||
0 => 'nexus_subs_forever',
|
||||
1 => \IPS\Member::loggedIn()->language()->addToStack( 'nexus_subs_until_renew', FALSE, [ 'sprintf' => [ $newOption['term'], $initialTerm, \IPS\Member::loggedIn()->language()->formatList( $costs, \IPS\Member::loggedIn()->language()->get('or_list_format') ), $term ] ] )
|
||||
1 => Member::loggedIn()->language()->addToStack( 'nexus_subs_until_renew', FALSE, [ 'sprintf' => [ $newOption['term'], $initialTerm, Member::loggedIn()->language()->formatList( $costs, Member::loggedIn()->language()->get('or_list_format') ), $term ] ] )
|
||||
]
|
||||
] ) );
|
||||
}
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
$customer = \IPS\nexus\Customer::load( $values['nexus_subs_member_to_add']->member_id );
|
||||
$sub = \IPS\nexus\Subscription\Package::load( \IPS\Request::i()->id )->addMember( $customer, TRUE, isset( $values[ 'nexus_subs_free_period' ] ) && (bool) $values[ 'nexus_subs_free_period' ] );
|
||||
$customer = Customer::load( $values['nexus_subs_member_to_add']->member_id );
|
||||
$sub = Package::load( Request::i()->id )->addMember( $customer, TRUE, isset( $values[ 'nexus_subs_free_period' ] ) && (bool) $values[ 'nexus_subs_free_period' ] );
|
||||
$sub->added_manually = 1;
|
||||
$sub->save();
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=subscriptions&controller=subscriptions'), 'nexus_sub_member_added' );
|
||||
Output::i()->redirect( Url::internal('app=nexus&module=subscriptions&controller=subscriptions'), 'nexus_sub_member_added' );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('nexus_subs_add_member');
|
||||
\IPS\Output::i()->output = $form;
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('nexus_subs_add_member');
|
||||
Output::i()->output = $form;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -377,39 +418,39 @@ class _subscriptions extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function settings()
|
||||
protected function settings() : void
|
||||
{
|
||||
$groups = array();
|
||||
foreach ( \IPS\Member\Group::groups( FALSE, FALSE ) as $group )
|
||||
foreach ( Group::groups( FALSE, FALSE ) as $group )
|
||||
{
|
||||
$groups[ $group->g_id ] = $group->name;
|
||||
}
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form = new Form;
|
||||
|
||||
$form->addHeader('subscription_basic_settings');
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_subs_enabled', \IPS\Settings::i()->nexus_subs_enabled, FALSE, array(), NULL, NULL, NULL, 'nexus_subs_enabled' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'nexus_subs_register', (int) \IPS\Settings::i()->nexus_subs_register, FALSE, [
|
||||
$form->add( new YesNo( 'nexus_subs_enabled', Settings::i()->nexus_subs_enabled, FALSE, array(), NULL, NULL, NULL, 'nexus_subs_enabled' ) );
|
||||
$form->add( new Radio( 'nexus_subs_register', (int) Settings::i()->nexus_subs_register, FALSE, [
|
||||
'options' => [
|
||||
0 => 'nexus_subs_register_none',
|
||||
1 => 'nexus_subs_register_reg',
|
||||
2 => 'nexus_subs_register_always'
|
||||
]
|
||||
], NULL, NULL, NULL, 'nexus_subs_register' ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_subs_show_public', \IPS\Settings::i()->nexus_subs_show_public, FALSE, array(), NULL, NULL, NULL, 'nexus_subs_show_public' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Interval( 'nexus_subs_invoice_grace', \IPS\Settings::i()->nexus_subs_invoice_grace ?: 0, FALSE, array( 'valueAs' => \IPS\Helpers\Form\Interval::DAYS ), NULL, NULL, NULL, 'nexus_subs_invoice_grace' ) );
|
||||
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'nexus_subs_exclude_groups', explode( ',', \IPS\Settings::i()->nexus_subs_exclude_groups ), FALSE, array( 'options' => $groups, 'multiple' => TRUE ) ) );
|
||||
$form->add( new YesNo( 'nexus_subs_show_public', Settings::i()->nexus_subs_show_public, FALSE, array(), NULL, NULL, NULL, 'nexus_subs_show_public' ) );
|
||||
$form->add( new Interval( 'nexus_subs_invoice_grace', Settings::i()->nexus_subs_invoice_grace ?: 0, FALSE, array( 'valueAs' => Interval::DAYS ), NULL, NULL, NULL, 'nexus_subs_invoice_grace' ) );
|
||||
$form->add( new CheckboxSet( 'nexus_subs_exclude_groups', explode( ',', Settings::i()->nexus_subs_exclude_groups ), FALSE, array( 'options' => $groups, 'multiple' => TRUE ) ) );
|
||||
|
||||
|
||||
$form->addHeader('package_upgrade_downgrade');
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_subs_upgrade_toggle', \IPS\Settings::i()->nexus_subs_upgrade > -1, FALSE, array( 'togglesOn' => array( 'nexus_subs_upgrade' ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'nexus_subs_upgrade', \IPS\Settings::i()->nexus_subs_upgrade, FALSE, array( 'options' => array(
|
||||
$form->add( new YesNo( 'nexus_subs_upgrade_toggle', Settings::i()->nexus_subs_upgrade > -1, FALSE, array( 'togglesOn' => array( 'nexus_subs_upgrade' ) ) ) );
|
||||
$form->add( new Radio( 'nexus_subs_upgrade', Settings::i()->nexus_subs_upgrade, FALSE, array( 'options' => array(
|
||||
0 => 'p_upgrade_charge_none',
|
||||
1 => 'p_upgrade_charge_full',
|
||||
2 => 'p_upgrade_charge_prorate'
|
||||
) ), NULL, NULL, NULL, 'nexus_subs_upgrade' ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_subs_downgrade_toggle', \IPS\Settings::i()->nexus_subs_downgrade > -1, FALSE, array( 'togglesOn' => array( 'nexus_subs_downgrade' ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'nexus_subs_downgrade', \IPS\Settings::i()->nexus_subs_downgrade, FALSE, array( 'options' => array(
|
||||
$form->add( new YesNo( 'nexus_subs_downgrade_toggle', Settings::i()->nexus_subs_downgrade > -1, FALSE, array( 'togglesOn' => array( 'nexus_subs_downgrade' ) ) ) );
|
||||
$form->add( new Radio( 'nexus_subs_downgrade', Settings::i()->nexus_subs_downgrade, FALSE, array( 'options' => array(
|
||||
0 => 'p_downgrade_refund_none',
|
||||
1 => 'p_downgrade_refund_full',
|
||||
2 => 'p_downgrade_refund_prorate'
|
||||
@@ -436,23 +477,23 @@ class _subscriptions extends \IPS\Node\Controller
|
||||
|
||||
$form->saveAsSettings( $values );
|
||||
|
||||
\IPS\Session::i()->log( 'acplog__nexus_subs_settings' );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=subscriptions&controller=subscriptions') );
|
||||
Session::i()->log( 'acplog__nexus_subs_settings' );
|
||||
Output::i()->redirect( Url::internal('app=nexus&module=subscriptions&controller=subscriptions') );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('settings');
|
||||
\IPS\Output::i()->output = $form;
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('settings');
|
||||
Output::i()->output = $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect after save
|
||||
*
|
||||
* @param \IPS\Node\Model $old A clone of the node as it was before or NULL if this is a creation
|
||||
* @param \IPS\Node\Model $new The node now
|
||||
* @param Model|null $old A clone of the node as it was before or NULL if this is a creation
|
||||
* @param Model $new The node now
|
||||
* @param string $lastUsedTab The tab last used in the form
|
||||
* @return void
|
||||
*/
|
||||
protected function _afterSave( ?\IPS\Node\Model $old, \IPS\Node\Model $new, $lastUsedTab = FALSE )
|
||||
protected function _afterSave( ?Model $old, Model $new, mixed $lastUsedTab = FALSE ): void
|
||||
{
|
||||
$changes = array();
|
||||
if ( $old )
|
||||
@@ -469,23 +510,23 @@ class _subscriptions extends \IPS\Node\Controller
|
||||
/* If something has changed, see if anyone has purchased */
|
||||
$purchases = 0;
|
||||
|
||||
if( \count( $changes ) )
|
||||
if( count( $changes ) )
|
||||
{
|
||||
$purchases = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_member_subscriptions', array( 'sub_package_id=? AND sub_active=1 and sub_added_manually=0', $new->id ) )->first();
|
||||
$purchases = Db::i()->select( 'COUNT(*)', 'nexus_member_subscriptions', array( 'sub_package_id=? AND sub_active=1 and sub_added_manually=0', $new->id ) )->first();
|
||||
}
|
||||
|
||||
/* Only show this screen if the package has been purchased. Otherwise even just copying a package and saving asks if you want to update
|
||||
existing purchases unnecessarily */
|
||||
if ( !empty( $changes ) AND $purchases )
|
||||
{
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->decision( 'product_change_blurb', array(
|
||||
'product_change_blurb_existing' => \IPS\Http\Url::internal( "app=nexus&module=subscriptions&controller=subscriptions&do=updateExisting&id={$new->_id}" )->setQueryString( 'changes', json_encode( $changes ) )->csrf(),
|
||||
Output::i()->output = Theme::i()->getTemplate( 'global', 'core' )->decision( 'product_change_blurb', array(
|
||||
'product_change_blurb_existing' => Url::internal( "app=nexus&module=subscriptions&controller=subscriptions&do=updateExisting&id={$new->_id}" )->setQueryString( 'changes', json_encode( $changes ) )->csrf(),
|
||||
'product_change_blurb_new' => $this->url->setQueryString( array( 'root' => ( $new->parent() ? $new->parent()->_id : '' ) ) ),
|
||||
) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return parent::_afterSave( $old, $new, $lastUsedTab );
|
||||
parent::_afterSave( $old, $new, $lastUsedTab );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -494,55 +535,55 @@ class _subscriptions extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function updateExisting()
|
||||
public function updateExisting() : void
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
try
|
||||
{
|
||||
$package = \IPS\nexus\Subscription\Package::load( \IPS\Request::i()->id );
|
||||
$package = Package::load( Request::i()->id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '1X393/1', 404, '' );
|
||||
Output::i()->error( 'node_error', '1X393/1', 404, '' );
|
||||
}
|
||||
|
||||
$changes = json_decode( \IPS\Request::i()->changes, TRUE );
|
||||
$changes = json_decode( Request::i()->changes, TRUE );
|
||||
|
||||
if ( !isset( \IPS\Request::i()->processing ) )
|
||||
if ( !isset( Request::i()->processing ) )
|
||||
{
|
||||
if ( isset( $changes['renew_options'] ) )
|
||||
{
|
||||
\IPS\Output::i()->bypassCsrfKeyCheck = TRUE;
|
||||
$matrix = new \IPS\Helpers\Form\Matrix( 'matrix', 'continue' );
|
||||
Output::i()->bypassCsrfKeyCheck = TRUE;
|
||||
$matrix = new Matrix( 'matrix', 'continue' );
|
||||
$matrix->manageable = FALSE;
|
||||
|
||||
$newOptions = array( '-' => \IPS\Member::loggedIn()->language()->addToStack('do_not_change') );
|
||||
$newOptions = array( '-' => Member::loggedIn()->language()->addToStack('do_not_change') );
|
||||
$newOption = json_decode( $package->renew_options, TRUE );
|
||||
|
||||
$costs = array();
|
||||
foreach ( $newOption['cost'] as $data )
|
||||
{
|
||||
$costs[] = new \IPS\nexus\Money( $data['amount'], $data['currency'] );
|
||||
$costs[] = new Money( $data['amount'], $data['currency'] );
|
||||
}
|
||||
|
||||
switch ( $newOption['unit'] )
|
||||
{
|
||||
case 'd':
|
||||
$term = \IPS\Member::loggedIn()->language()->addToStack('renew_days', FALSE, array( 'pluralize' => array( $newOption['term'] ) ) );
|
||||
$term = Member::loggedIn()->language()->addToStack('renew_days', FALSE, array( 'pluralize' => array( $newOption['term'] ) ) );
|
||||
break;
|
||||
case 'm':
|
||||
$term = \IPS\Member::loggedIn()->language()->addToStack('renew_months', FALSE, array( 'pluralize' => array( $newOption['term'] ) ) );
|
||||
$term = Member::loggedIn()->language()->addToStack('renew_months', FALSE, array( 'pluralize' => array( $newOption['term'] ) ) );
|
||||
break;
|
||||
case 'y':
|
||||
$term = \IPS\Member::loggedIn()->language()->addToStack('renew_years', FALSE, array( 'pluralize' => array( $newOption['term'] ) ) );
|
||||
$term = Member::loggedIn()->language()->addToStack('renew_years', FALSE, array( 'pluralize' => array( $newOption['term'] ) ) );
|
||||
break;
|
||||
}
|
||||
|
||||
$newOptions['o'] = \IPS\Member::loggedIn()->language()->addToStack( 'renew_option', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->formatList( $costs, \IPS\Member::loggedIn()->language()->get('or_list_format') ), $term ) ) );
|
||||
$newOptions['z'] = \IPS\Member::loggedIn()->language()->addToStack('remove_renewal_no_expire_leave');
|
||||
$newOptions['y'] = \IPS\Member::loggedIn()->language()->addToStack('remove_renewal_no_expire_reactivate');
|
||||
$newOptions['x'] = \IPS\Member::loggedIn()->language()->addToStack('remove_renewal_expire');
|
||||
$newOptions['o'] = Member::loggedIn()->language()->addToStack( 'renew_option', FALSE, array( 'sprintf' => array( Member::loggedIn()->language()->formatList( $costs, Member::loggedIn()->language()->get('or_list_format') ), $term ) ) );
|
||||
$newOptions['z'] = Member::loggedIn()->language()->addToStack('remove_renewal_no_expire_leave');
|
||||
$newOptions['y'] = Member::loggedIn()->language()->addToStack('remove_renewal_no_expire_reactivate');
|
||||
$newOptions['x'] = Member::loggedIn()->language()->addToStack('remove_renewal_expire');
|
||||
$matrix->columns = array(
|
||||
'customers_currently_paying' => function( $key, $value, $data )
|
||||
{
|
||||
@@ -550,7 +591,7 @@ class _subscriptions extends \IPS\Node\Controller
|
||||
},
|
||||
'now_pay' => function( $key, $value, $data ) use ( $newOptions )
|
||||
{
|
||||
return new \IPS\Helpers\Form\Select( $key, $data[1], TRUE, array( 'options' => $newOptions, 'noDefault' => TRUE ) );
|
||||
return new Select( $key, $data[1], TRUE, array( 'options' => $newOptions, 'noDefault' => TRUE ) );
|
||||
},
|
||||
);
|
||||
|
||||
@@ -561,23 +602,23 @@ class _subscriptions extends \IPS\Node\Controller
|
||||
|
||||
foreach ( $oldOption['cost'] as $data )
|
||||
{
|
||||
$costs[] = new \IPS\nexus\Money( $data['amount'], $data['currency'] );
|
||||
$costs[] = new Money( $data['amount'], $data['currency'] );
|
||||
}
|
||||
|
||||
switch ( $oldOption['unit'] )
|
||||
{
|
||||
case 'd':
|
||||
$term = \IPS\Member::loggedIn()->language()->addToStack('renew_days', FALSE, array( 'pluralize' => array( $oldOption['term'] ) ) );
|
||||
$term = Member::loggedIn()->language()->addToStack('renew_days', FALSE, array( 'pluralize' => array( $oldOption['term'] ) ) );
|
||||
break;
|
||||
case 'm':
|
||||
$term = \IPS\Member::loggedIn()->language()->addToStack('renew_months', FALSE, array( 'pluralize' => array( $oldOption['term'] ) ) );
|
||||
$term = Member::loggedIn()->language()->addToStack('renew_months', FALSE, array( 'pluralize' => array( $oldOption['term'] ) ) );
|
||||
break;
|
||||
case 'y':
|
||||
$term = \IPS\Member::loggedIn()->language()->addToStack('renew_years', FALSE, array( 'pluralize' => array( $oldOption['term'] ) ) );
|
||||
$term = Member::loggedIn()->language()->addToStack('renew_years', FALSE, array( 'pluralize' => array( $oldOption['term'] ) ) );
|
||||
break;
|
||||
}
|
||||
|
||||
$matrix->rows[ 1 ] = array( \IPS\Member::loggedIn()->language()->addToStack( 'renew_option', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->formatList( $costs, \IPS\Member::loggedIn()->language()->get('or_list_format') ), $term ) ) ), "o" );
|
||||
$matrix->rows[ 1 ] = array( Member::loggedIn()->language()->addToStack( 'renew_option', FALSE, array( 'sprintf' => array( Member::loggedIn()->language()->formatList( $costs, Member::loggedIn()->language()->get('or_list_format') ), $term ) ) ), "o" );
|
||||
}
|
||||
|
||||
if ( $values = $matrix->values() )
|
||||
@@ -591,17 +632,17 @@ class _subscriptions extends \IPS\Node\Controller
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->output .= $matrix;
|
||||
Output::i()->output .= $matrix;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ( isset( $changes['renew_options'] ) or isset( $changes['tax'] ) ) and !isset( \IPS\Request::i()->ba ) )
|
||||
if ( ( isset( $changes['renew_options'] ) or isset( $changes['tax'] ) ) and !isset( Request::i()->ba ) )
|
||||
{
|
||||
$needBaPrompt = FALSE;
|
||||
$canChangeOptions = FALSE;
|
||||
if ( isset( $changes['renew_options'] ) and !\in_array( $changes['renew_options']['new'], array( '-', 'x', 'y', 'z' ) ) )
|
||||
if ( isset( $changes['renew_options'] ) and !in_array( $changes['renew_options']['new'], array( '-', 'x', 'y', 'z' ) ) )
|
||||
{
|
||||
$needBaPrompt = TRUE;
|
||||
$canChangeOptions = TRUE;
|
||||
@@ -611,17 +652,17 @@ class _subscriptions extends \IPS\Node\Controller
|
||||
$needBaPrompt = TRUE;
|
||||
}
|
||||
|
||||
if ( $needBaPrompt and $withBillingAgreement = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=? AND ps_billing_agreement>0 AND ba_canceled=0', 'nexus', 'subscription', $package->id ) )->join( 'nexus_billing_agreements', 'ba_id=ps_billing_agreement' )->first() )
|
||||
if ( $needBaPrompt and $withBillingAgreement = Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( 'ps_app=? AND ps_type=? AND ps_item_id=? AND ps_billing_agreement>0 AND ba_canceled=0', 'nexus', 'subscription', $package->id ) )->join( 'nexus_billing_agreements', 'ba_id=ps_billing_agreement' )->first() )
|
||||
{
|
||||
$options = array(
|
||||
'change_renew_ba_skip' => \IPS\Http\Url::internal( "app=nexus&module=subscriptions&controller=subscriptions&do=updateExisting" )->setQueryString( array(
|
||||
'id' => \IPS\Request::i()->id,
|
||||
'change_renew_ba_skip' => Url::internal( "app=nexus&module=subscriptions&controller=subscriptions&do=updateExisting" )->setQueryString( array(
|
||||
'id' => Request::i()->id,
|
||||
'changes' => json_encode( $changes ),
|
||||
'processing'=> 1,
|
||||
'ba' => 0
|
||||
) )->csrf(),
|
||||
'change_renew_ba_cancel' => \IPS\Http\Url::internal( "app=nexus&module=subscriptions&controller=subscriptions&do=updateExisting" )->setQueryString( array(
|
||||
'id' => \IPS\Request::i()->id,
|
||||
'change_renew_ba_cancel' => Url::internal( "app=nexus&module=subscriptions&controller=subscriptions&do=updateExisting" )->setQueryString( array(
|
||||
'id' => Request::i()->id,
|
||||
'changes' => json_encode( $changes ),
|
||||
'processing'=> 1,
|
||||
'ba' => 1
|
||||
@@ -630,44 +671,44 @@ class _subscriptions extends \IPS\Node\Controller
|
||||
|
||||
if ( $canChangeOptions )
|
||||
{
|
||||
$options['change_renew_ba_go_back'] = \IPS\Http\Url::internal( "app=nexus&module=subscriptions&controller=subscriptions&do=updateExisting" )->setQueryString( array(
|
||||
'id' => \IPS\Request::i()->id,
|
||||
'changes' => \IPS\Request::i()->changes,
|
||||
$options['change_renew_ba_go_back'] = Url::internal( "app=nexus&module=subscriptions&controller=subscriptions&do=updateExisting" )->setQueryString( array(
|
||||
'id' => Request::i()->id,
|
||||
'changes' => Request::i()->changes,
|
||||
) )->csrf();
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->decision( 'change_renew_ba_blurb', $options );
|
||||
Output::i()->output = Theme::i()->getTemplate( 'global', 'core' )->decision( 'change_renew_ba_blurb', $options );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = new \IPS\Helpers\MultipleRedirect(
|
||||
\IPS\Http\Url::internal( "app=nexus&module=subscriptions&controller=subscriptions&do=updateExisting&id=1&changes=secondary_group" )->setQueryString( array(
|
||||
'id' => \IPS\Request::i()->id,
|
||||
Output::i()->output = new MultipleRedirect(
|
||||
Url::internal( "app=nexus&module=subscriptions&controller=subscriptions&do=updateExisting&id=1&changes=secondary_group" )->setQueryString( array(
|
||||
'id' => Request::i()->id,
|
||||
'changes' => json_encode( $changes ),
|
||||
'processing'=> 1,
|
||||
'ba' => isset( \IPS\Request::i()->ba ) ? \IPS\Request::i()->ba : 0
|
||||
'ba' => isset( Request::i()->ba ) ? Request::i()->ba : 0
|
||||
) )->csrf(),
|
||||
function( $data ) use ( $package, $changes )
|
||||
{
|
||||
if( !\is_array( $data ) )
|
||||
if( !is_array( $data ) )
|
||||
{
|
||||
$data['offset'] = 0;
|
||||
$data['lastId'] = 0;
|
||||
}
|
||||
|
||||
$select = \IPS\Db::i()->select( '*', 'nexus_purchases', array( "ps_id>? and ps_app=? and ps_type=? and ps_item_id=?", $data['lastId'], 'nexus', 'subscription', $package->id ), 'ps_id', 1 );
|
||||
$select = Db::i()->select( '*', 'nexus_purchases', array( "ps_id>? and ps_app=? and ps_type=? and ps_item_id=?", $data['lastId'], 'nexus', 'subscription', $package->id ), 'ps_id', 1 );
|
||||
|
||||
try
|
||||
{
|
||||
$purchase = \IPS\nexus\Purchase::constructFromData( $select->first() );
|
||||
$total = \IPS\Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( "ps_app=? and ps_type=? and ps_item_id=?", 'nexus', 'subscription', $package->id ) )->first();
|
||||
$purchase = Purchase::constructFromData( $select->first() );
|
||||
$total = Db::i()->select( 'COUNT(*)', 'nexus_purchases', array( "ps_app=? and ps_type=? and ps_item_id=?", 'nexus', 'subscription', $package->id ) )->first();
|
||||
|
||||
$package->updatePurchase( $purchase, $changes, \IPS\Request::i()->ba );
|
||||
$package->updatePurchase( $purchase, $changes, Request::i()->ba );
|
||||
|
||||
return array( [ 'offset' => ++$data['offset'], 'lastId' => $purchase->id ], \IPS\Member::loggedIn()->language()->get('processing'), 100 / $total * $data['offset'] );
|
||||
return array( [ 'offset' => ++$data['offset'], 'lastId' => $purchase->id ], Member::loggedIn()->language()->get('processing'), 100 / $total * $data['offset'] );
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
catch ( UnderflowException )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -675,7 +716,7 @@ class _subscriptions extends \IPS\Node\Controller
|
||||
},
|
||||
function() use ( $package )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=nexus&module=subscriptions&controller=subscriptions" )->setQueryString( array( 'root' => ( $package->parent() ? $package->parent()->_id : '' ) ) ) );
|
||||
Output::i()->redirect( Url::internal( "app=nexus&module=subscriptions&controller=subscriptions" )->setQueryString( array( 'root' => ( $package->parent() ? $package->parent()->_id : '' ) ) ) );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Autoresolve Settings
|
||||
* @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 25 Apr 2014
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\modules\admin\support;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Autoresolve Settings
|
||||
*/
|
||||
class _autoresolve extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Manage
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'autoresolve_manage' );
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_autoresolve_on', \IPS\Settings::i()->nexus_autoresolve_days, FALSE, array( 'togglesOn' => array( 'reply_request_resolved', 'nexus_autoresolve_departments', 'nexus_autoresolve_applicable', 'nexus_autoresolve_days', 'nexus_autoresolve_notify', 'nexus_autoresolve_status' ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'reply_request_resolved', \IPS\Settings::i()->reply_request_resolved, FALSE, array(
|
||||
'options' => array(
|
||||
'reopen' => 'reopen_request_autoresolve',
|
||||
'create' => 'create_new_request_autoresolve',
|
||||
'reject' => 'reject_notify_user_autoresolve'
|
||||
),
|
||||
'descriptions' => array(
|
||||
'create' => \IPS\Member::loggedIn()->language()->addToStack( 'create_new_request_autoresolve_desc' ),
|
||||
'reject' => \IPS\Member::loggedIn()->language()->addToStack( 'reject_notify_user_autoresolve_desc' )
|
||||
)
|
||||
) ) );
|
||||
$form->addSeparator();
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'nexus_autoresolve_departments', \IPS\Settings::i()->nexus_autoresolve_departments === '*' ? 0 : explode( ',', \IPS\Settings::i()->nexus_autoresolve_departments ), FALSE, array( 'class' => 'IPS\nexus\Support\Department', 'multiple' => TRUE, 'zeroVal' => 'any' ), NULL, NULL, NULL, 'nexus_autoresolve_departments' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'nexus_autoresolve_applicable', \IPS\Settings::i()->nexus_autoresolve_applicable, FALSE, array( 'class' => 'IPS\nexus\Support\Status', 'multiple' => TRUE ), NULL, NULL, NULL, 'nexus_autoresolve_applicable' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Interval( 'nexus_autoresolve_days', \IPS\Settings::i()->nexus_autoresolve_days, FALSE, array( 'valueAs' => \IPS\Helpers\Form\Interval::DAYS ), NULL, NULL, NULL, 'nexus_autoresolve_days' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'nexus_autoresolve_status', \IPS\Settings::i()->nexus_autoresolve_status, FALSE, array( 'class' => 'IPS\nexus\Support\Status' ), NULL, NULL, NULL, 'nexus_autoresolve_status' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'nexus_autoresolve_notify', \IPS\Settings::i()->nexus_autoresolve_notify, FALSE, array( 'unlimited' => 0, 'unlimitedLang' => 'never' ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('hours_before_resolving'), 'nexus_autoresolve_notify' ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_tasks', array( 'enabled' => (int) $values['nexus_autoresolve_on'] ), "`key`='supportAutoresolve'" );
|
||||
|
||||
if ( !$values['nexus_autoresolve_on'] )
|
||||
{
|
||||
$values['nexus_autoresolve_days'] = 0;
|
||||
}
|
||||
unset( $values['nexus_autoresolve_on'] );
|
||||
|
||||
$values['nexus_autoresolve_departments'] = $values['nexus_autoresolve_departments'] ? implode( ',' , array_keys( $values['nexus_autoresolve_departments'] ) ) : '*';
|
||||
$values['nexus_autoresolve_applicable'] = \is_array( $values['nexus_autoresolve_applicable'] ) ? implode( ',', array_keys( $values['nexus_autoresolve_applicable'] ) ) : $values['nexus_autoresolve_applicable'];
|
||||
$values['nexus_autoresolve_status'] = $values['nexus_autoresolve_status']->id;
|
||||
|
||||
$form->saveAsSettings( $values );
|
||||
\IPS\Session::i()->log( 'acplogs__autoresolve_settings' );
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=support&controller=settings&tab=autoresolve') );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('autoresolve');
|
||||
\IPS\Output::i()->output = $form;
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Customer Feedback Settings
|
||||
* @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 23 Apr 2014
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\modules\admin\support;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Customer Feedback Settings
|
||||
*/
|
||||
class _customerfeedback extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Manage
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'customerfeedback_manage' );
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_support_satisfaction', \IPS\Settings::i()->nexus_support_satisfaction ) );
|
||||
|
||||
if ( $form->values() )
|
||||
{
|
||||
$form->saveAsSettings();
|
||||
\IPS\Session::i()->log( 'acplogs__customerfeedback_settings' );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=nexus&module=support&controller=settings&tab=customerfeedback' ), 'saved' );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = $form;
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Support Departments
|
||||
* @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\modules\admin\support;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Support Departments
|
||||
*/
|
||||
class _departments extends \IPS\Node\Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
protected $nodeClass = 'IPS\nexus\Support\Department';
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'departments_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function delete()
|
||||
{
|
||||
try
|
||||
{
|
||||
$node = \IPS\nexus\Support\Department::load( \IPS\Request::i()->id );
|
||||
|
||||
if( \IPS\Settings::i()->contact_type == 'contact_nexus_department' AND \IPS\Settings::i()->contact_nexus_department == $node->id )
|
||||
{
|
||||
\IPS\Output::i()->error( 'nexus_nodeletedept_contactus', '1X344/1', 403, '' );
|
||||
}
|
||||
|
||||
if ( $node->canDelete() and \IPS\Db::i()->select( 'COUNT(*)', 'nexus_support_requests', array( 'r_department=?', $node->id ) ) )
|
||||
{
|
||||
$form = new \IPS\Helpers\Form( 'delete', 'delete' );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'move_existing_requests_to', NULL, TRUE, array( 'class' => 'IPS\nexus\Support\Department', 'permissionCheck' => function( $_node ) use ( $node )
|
||||
{
|
||||
return $node->id != $_node->id;
|
||||
} ) ) );
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
\IPS\Db::i()->update( 'nexus_support_requests', array( 'r_department' => $values['move_existing_requests_to']->id ), array( 'r_department=?', $node->id ) );
|
||||
\IPS\Request::i()->form_submitted = TRUE;
|
||||
\IPS\Request::i()->wasConfirmed = TRUE;
|
||||
return parent::delete();
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = $form;
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e ){}
|
||||
|
||||
return parent::delete();
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief 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 16 Apr 2014
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\modules\admin\support;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Support Custom Fields
|
||||
*/
|
||||
class _fields extends \IPS\Node\Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
protected $nodeClass = 'IPS\nexus\Support\CustomField';
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'scfields_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
}
|
||||
@@ -1,256 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Incoming Email Setup
|
||||
* @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 16 Apr 2014
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\modules\admin\support;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Incoming Email
|
||||
*/
|
||||
class _incomingemail extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'incomingemail_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
{
|
||||
$table = new \IPS\Helpers\Table\Db( 'core_incoming_emails', \IPS\Http\Url::internal( 'app=nexus&module=support&controller=settings&tab=incomingemail' ) );
|
||||
$table->include = array( 'rule_criteria_value' );
|
||||
$table->noSort = array( 'rule_criteria_value' );
|
||||
$table->parsers = array(
|
||||
'rule_criteria_value' => function( $val, $row )
|
||||
{
|
||||
$_langCf = 'ie_cf_' . $row['rule_criteria_field'];
|
||||
$_langCt = 'ie_ct_' . $row['rule_criteria_type'];
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( $_langCf ) . ' ' . \IPS\Member::loggedIn()->language()->addToStack( $_langCt ) . ' "' . $val . '"';
|
||||
}
|
||||
);
|
||||
$table->sortBy = $table->sortBy ?: 'rule_added_date';
|
||||
$table->sortDirection = $table->sortDirection ?: 'asc';
|
||||
|
||||
$table->rootButtons = array(
|
||||
'add' => array(
|
||||
'icon' => 'plus',
|
||||
'title' => 'incomingemail_add',
|
||||
'link' => \IPS\Http\Url::internal( 'app=nexus&module=support&controller=settings&tab=incomingemail&do=incomingEmailForm' ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('incomingemail_add') )
|
||||
)
|
||||
);
|
||||
|
||||
$table->rowButtons = function( $row )
|
||||
{
|
||||
return array(
|
||||
'edit' => array(
|
||||
'icon' => 'pencil',
|
||||
'title' => 'edit',
|
||||
'link' => \IPS\Http\Url::internal( 'app=nexus&module=support&controller=settings&tab=incomingemail&do=incomingEmailForm&id=' ) . $row['rule_id'],
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('edit') )
|
||||
),
|
||||
'delete' => array(
|
||||
'icon' => 'times-circle',
|
||||
'title' => 'delete',
|
||||
'link' => \IPS\Http\Url::internal( 'app=nexus&module=support&controller=settings&tab=incomingemail&do=incomingEmailDelete&id=' ) . $row['rule_id'],
|
||||
'data' => array( 'delete' => '' ),
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
if ( isset( \IPS\Request::i()->type ) )
|
||||
{
|
||||
if ( \IPS\Request::i()->type === 'piping' )
|
||||
{
|
||||
$content = \IPS\Theme::i()->getTemplate('incomingemailsetup')->piping();
|
||||
}
|
||||
elseif ( \IPS\Request::i()->type === 'pop3' )
|
||||
{
|
||||
$content = \IPS\Theme::i()->getTemplate('incomingemailsetup')->pop3( $this->_pop3() );
|
||||
}
|
||||
elseif ( \IPS\Request::i()->type === 'sendgrid' )
|
||||
{
|
||||
$content = \IPS\Theme::i()->getTemplate('incomingemailsetup')->sendgrid();
|
||||
}
|
||||
else
|
||||
{
|
||||
$content = \IPS\Theme::i()->getTemplate('incomingemailsetup')->splash( (string) $table );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$content = NULL;
|
||||
if ( \IPS\Settings::i()->pop3_server )
|
||||
{
|
||||
try
|
||||
{
|
||||
$task = \IPS\Db::i()->select( '*', 'core_tasks', array( 'app=? AND `key`=? AND enabled=1', 'core', 'pop' ) )->first();
|
||||
$pop3Form = $this->_pop3();
|
||||
$pop3Form->addButton( 'disable_pop3', 'link', \IPS\Http\Url::internal( 'app=nexus&module=support&controller=incomingemail&do=disablePop3' )->csrf(), '', array( 'data-confirm' => '' ) );
|
||||
$content = \IPS\Theme::i()->getTemplate('incomingemailsetup')->usingpop3( $pop3Form, (string) $table );
|
||||
}
|
||||
catch ( \UnderflowException $e ) { }
|
||||
}
|
||||
|
||||
$content = $content ?: \IPS\Theme::i()->getTemplate('incomingemailsetup')->splash( (string) $table );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'admin_support.js', 'nexus', 'admin' ) );
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('incomingemailsetup')->template( $content );
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable POP3
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function disablePop3()
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
\IPS\Settings::i()->changeValues( array( 'pop3_server' => '', 'pop3_port' => '', 'pop3_user' => '', 'pop3_password' => '' ) );
|
||||
\IPS\Session::i()->log( 'acplogs__pop3_settings' );
|
||||
\IPS\Db::i()->update( 'core_tasks', array( 'enabled' => 0 ), array( 'app=? AND `key`=?', 'core', 'pop' ) );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=support&controller=settings&tab=incomingemail') );
|
||||
}
|
||||
|
||||
/**
|
||||
* POP3
|
||||
*
|
||||
* @return \IPS\Helpers\Form
|
||||
*/
|
||||
protected function _pop3()
|
||||
{
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'pop3_server', \IPS\Settings::i()->pop3_server, TRUE ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'pop3_port', \IPS\Settings::i()->pop3_port, TRUE ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'pop3_user', \IPS\Settings::i()->pop3_user, TRUE ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'pop3_password', \IPS\Settings::i()->pop3_password, FALSE ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'pop3_tls', \IPS\Settings::i()->pop3_tls ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
try
|
||||
{
|
||||
$pop3 = new \IPS\Email\Incoming\PopImap( $values['pop3_server'], $values['pop3_tls'], $values['pop3_port'], $values['pop3_user'], $values['pop3_password'] );
|
||||
|
||||
$form->saveAsSettings();
|
||||
|
||||
\IPS\Session::i()->log( 'acplogs__pop3_settings' );
|
||||
\IPS\Db::i()->update( 'core_tasks', array( 'enabled' => 1 ), array( 'app=? AND `key`=?', 'core', 'pop' ) );
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=support&controller=settings&tab=incomingemail') );
|
||||
}
|
||||
catch ( \IPS\Email\Incoming\PopImapException $e )
|
||||
{
|
||||
$form->error = \IPS\Member::loggedIn()->language()->addToStack( $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add/Edit Incoming Email Rule Form
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function incomingEmailForm()
|
||||
{
|
||||
/* Load Rule */
|
||||
$rule = NULL;
|
||||
if ( \IPS\Request::i()->id )
|
||||
{
|
||||
try
|
||||
{
|
||||
$rule = \IPS\Db::i()->select( '*', 'core_incoming_emails', array( 'rule_id=?', \IPS\Request::i()->id ) )->first();
|
||||
}
|
||||
catch ( \UnderflowException $e ) { }
|
||||
}
|
||||
|
||||
/* Build form */
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->add( new \IPS\Helpers\Form\Custom( 'rule_criteria_value', array(
|
||||
'criteria_field' => $rule ? $rule['rule_criteria_field'] : '',
|
||||
'criteria_type' => $rule ? $rule['rule_criteria_type'] : '',
|
||||
'criteria_value' => $rule ? $rule['rule_criteria_value'] : ''
|
||||
), FALSE, array( 'getHtml' => function( $element )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'advancedsettings', 'core' )->ruleCriteriaForm( $element->name, $element->defaultValue['criteria_field'], $element->defaultValue['criteria_type'], $element->defaultValue['criteria_value'] );
|
||||
} ) ) );
|
||||
|
||||
/* Handle submissions */
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
$save = array(
|
||||
'rule_criteria_field' => $values['rule_criteria_value']['criteria_field'],
|
||||
'rule_criteria_type' => $values['rule_criteria_value']['criteria_type'],
|
||||
'rule_criteria_value' => $values['rule_criteria_value']['criteria_value'],
|
||||
'rule_app' => '',
|
||||
);
|
||||
|
||||
if ( $rule )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_incoming_emails', $save, array( 'rule_id=?', $rule['rule_id'] ) );
|
||||
\IPS\Session::i()->log( 'acplogs__incomingemail_edited' );
|
||||
}
|
||||
else
|
||||
{
|
||||
$save['rule_added_date'] = time();
|
||||
$save['rule_added_by'] = \IPS\Member::loggedIn()->member_id;
|
||||
|
||||
\IPS\Db::i()->insert( 'core_incoming_emails', $save );
|
||||
\IPS\Session::i()->log( 'acplogs__incomingemail_added' );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=nexus&module=support&controller=settings&tab=incomingemail&tab=incomingemail' ), 'saved' );
|
||||
}
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->output = $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete Incoming Email Rule
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function incomingEmailDelete()
|
||||
{
|
||||
/* Make sure the user confirmed the deletion */
|
||||
\IPS\Request::i()->confirmedDelete();
|
||||
|
||||
\IPS\Db::i()->delete( 'core_incoming_emails', array( 'rule_id=?', \IPS\Request::i()->id ) );
|
||||
\IPS\Session::i()->log( 'acplogs__incomingemail_deleted' );
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=nexus&module=support&controller=settings&tab=incomingemail&tab=incomingemail" ) );
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -1,77 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Outgoing Email Settings
|
||||
* @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 Apr 2014
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\modules\admin\support;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Outgoing Email Settings
|
||||
*/
|
||||
class _outgoingemail extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Manage
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'autoresolve_manage' );
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'nexus_sout_chrome', \IPS\Settings::i()->nexus_sout_chrome, FALSE, array(
|
||||
'options' => array(
|
||||
0 => \IPS\Theme::i()->resource( 'settings/email_no_chrome.png' ),
|
||||
1 => \IPS\Theme::i()->resource( 'settings/email_chrome.png' )
|
||||
),
|
||||
'parse' => 'image',
|
||||
'descriptions' => array(
|
||||
0 => \IPS\Member::loggedIn()->language()->addToStack('nexus_sout_chrome_no'),
|
||||
1 => \IPS\Member::loggedIn()->language()->addToStack('nexus_sout_chrome_yes'),
|
||||
)
|
||||
) ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'nexus_sout_from', \IPS\Settings::i()->nexus_sout_from, FALSE, array(
|
||||
'options' => array(
|
||||
'staff' => 'nexus_sout_from_staff',
|
||||
'dpt' => 'nexus_sout_from_department',
|
||||
'other' => 'nexus_sout_from_other',
|
||||
),
|
||||
'userSuppliedInput' => 'other',
|
||||
'toggles' => array(
|
||||
'other' => array( 'other_nexus_sout_from' )
|
||||
)
|
||||
) ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'nexus_sout_autoreply', \IPS\Settings::i()->nexus_sout_autoreply ) );
|
||||
|
||||
if ( $form->values() )
|
||||
{
|
||||
$form->saveAsSettings();
|
||||
\IPS\Session::i()->log( 'acplogs__outgoingemail_settings' );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=nexus&module=support&controller=settings&tab=outgoingemail' ), 'saved' );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = $form;
|
||||
}
|
||||
}
|
||||
@@ -1,467 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Support Reports
|
||||
* @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 23 Apr 2014
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\modules\admin\support;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Support Reports
|
||||
*/
|
||||
class _reports extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'reports_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Dashboard
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
{
|
||||
/* Tabs */
|
||||
$tabs = array(
|
||||
'overview' => 'overview',
|
||||
'replies' => 'latest_replies',
|
||||
'feedback_ratings' => 'feedback_ratings',
|
||||
'latest_feedback' => 'latest_feedback',
|
||||
);
|
||||
$activeTab = ( isset( \IPS\Request::i()->tab ) and array_key_exists( \IPS\Request::i()->tab, $tabs ) ) ? \IPS\Request::i()->tab : 'staff_productivity';
|
||||
$activeTabContents = '';
|
||||
|
||||
/* Staff Productivity */
|
||||
if ( $activeTab === 'overview' )
|
||||
{
|
||||
/* Filters */
|
||||
$filters = array(
|
||||
'last_24_hours' => \IPS\DateTime::create()->sub( new \DateInterval( 'P1D' ) )->getTimestamp(),
|
||||
'last_7_days' => \IPS\DateTime::create()->sub( new \DateInterval( 'P7D' ) )->getTimestamp(),
|
||||
'last_30_days' => \IPS\DateTime::create()->sub( new \DateInterval( 'P30D' ) )->getTimestamp(),
|
||||
);
|
||||
|
||||
/* Set default values */
|
||||
$data = array();
|
||||
foreach ( \IPS\nexus\Support\Request::staff() as $staffId => $name )
|
||||
{
|
||||
$data[ $staffId ] = array( 'name' => $name, 'reply_count' => 0 );
|
||||
if ( \IPS\Settings::i()->nexus_support_satisfaction )
|
||||
{
|
||||
$data[ $staffId ]['rating_count'] = 0;
|
||||
$data[ $staffId ]['rating_average'] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get their replies */
|
||||
$where = array( array( \IPS\Db::i()->in( 'reply_member', array_keys( $data ) ) ) );
|
||||
if ( isset( \IPS\Request::i()->filter ) and array_key_exists( \IPS\Request::i()->filter, $filters ) )
|
||||
{
|
||||
$where[] = array( 'reply_date>?', $filters[ \IPS\Request::i()->filter ] );
|
||||
}
|
||||
foreach ( \IPS\Db::i()->select( 'COUNT(*) AS count, reply_member', 'nexus_support_replies', $where, NULL, NULL, 'reply_member' ) as $row )
|
||||
{
|
||||
$data[ $row['reply_member'] ]['reply_count'] = $row['count'];
|
||||
}
|
||||
|
||||
/* And their ratings */
|
||||
if ( \IPS\Settings::i()->nexus_support_satisfaction )
|
||||
{
|
||||
$where = array( \IPS\Db::i()->in( 'rating_staff', array_keys( $data ) ) );
|
||||
if ( isset( \IPS\Request::i()->filter ) and array_key_exists( \IPS\Request::i()->filter, $filters ) )
|
||||
{
|
||||
$where[] = array( 'rating_date>?', $filters[ \IPS\Request::i()->filter ] );
|
||||
}
|
||||
foreach ( \IPS\Db::i()->select( 'COUNT(*) AS count, AVG(rating_rating) AS rating, rating_staff', 'nexus_support_ratings', $where, NULL, NULL, 'rating_staff' ) as $row )
|
||||
{
|
||||
$data[ $row['rating_staff'] ]['rating_count'] = $row['count'];
|
||||
$data[ $row['rating_staff'] ]['rating_average'] = $row['rating'];
|
||||
}
|
||||
}
|
||||
|
||||
/* Build the table */
|
||||
$staffProductivityTable = new \IPS\Helpers\Table\Custom( $data, \IPS\Http\Url::internal( 'app=nexus&module=support&controller=reports&tab=overview' ) );
|
||||
$staffProductivityTable->langPrefix = 'staff_';
|
||||
$staffProductivityTable->widths = \IPS\Settings::i()->nexus_support_satisfaction ? array( 'name' => 50, 'reply_count' => 25, 'rating_average' => 25 ) : array( 'name' => 75, 'reply_count' => 25 );
|
||||
if ( \IPS\Settings::i()->nexus_support_satisfaction )
|
||||
{
|
||||
$staffProductivityTable->parsers['rating_average'] = function( $val, $row ) {
|
||||
return \IPS\Theme::i()->getTemplate('supportreports')->averageRatingCell( $val, $row['rating_count'] );
|
||||
};
|
||||
$staffProductivityTable->include = array( 'name', 'reply_count', 'rating_average' );
|
||||
}
|
||||
$staffProductivityTable->sortBy = $staffProductivityTable->sortBy ?: 'reply_count';
|
||||
$staffProductivityTable->quickSearch = 'name';
|
||||
|
||||
/* Specify the filters and search options */
|
||||
$staffProductivityTable->filters = $filters;
|
||||
|
||||
/* Buttons for each member */
|
||||
$staffProductivityTable->rowButtons = function( $row, $id )
|
||||
{
|
||||
return array(
|
||||
'report' => array(
|
||||
'icon' => 'search',
|
||||
'title' => 'view_report',
|
||||
'link' => \IPS\Http\Url::internal('app=nexus&module=support&controller=reports&do=staff')->setQueryString( 'id', $id ),
|
||||
),
|
||||
);
|
||||
};
|
||||
|
||||
/* Output */
|
||||
$activeTabContents = (string) $staffProductivityTable;
|
||||
}
|
||||
|
||||
/* Replies */
|
||||
elseif ( $activeTab === 'replies' )
|
||||
{
|
||||
$staffRepliesChart = new \IPS\Helpers\Chart\Database( \IPS\Http\Url::internal( 'app=nexus&module=support&controller=reports&tab=replies' ), 'nexus_support_replies', 'reply_date', '',
|
||||
array(
|
||||
'vAxis' => array( 'title' => \IPS\Member::loggedIn()->language()->addToStack('replies_made') ),
|
||||
'height' => 700,
|
||||
'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', 'daily', array( 'start' => \IPS\DateTime::create()->sub( new \DateInterval( 'P1M' ) ), 'end' => 0 )
|
||||
);
|
||||
$staffRepliesChart->where[] = array( 'reply_type=?', \IPS\nexus\Support\Reply::REPLY_STAFF );
|
||||
$staffRepliesChart->groupBy = 'reply_member';
|
||||
foreach( \IPS\nexus\Support\Request::staff() as $id => $name )
|
||||
{
|
||||
$staffRepliesChart->addSeries( $name, 'number', 'COUNT(*)', TRUE, $id );
|
||||
}
|
||||
|
||||
$activeTabContents = (string) $staffRepliesChart;
|
||||
}
|
||||
|
||||
/* Replies */
|
||||
elseif ( $activeTab === 'feedback_ratings' )
|
||||
{
|
||||
$staffRatingsChart = new \IPS\Helpers\Chart\Database( \IPS\Http\Url::internal( 'app=nexus&module=support&controller=reports&tab=feedback_ratings' ), 'nexus_support_ratings', 'rating_date', '',
|
||||
array(
|
||||
'vAxis' => array( 'title' => \IPS\Member::loggedIn()->language()->addToStack('average_rating'), 'viewWindow' => array( 'min' => 0, 'max' => 5 ) ),
|
||||
'height' => 700,
|
||||
'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
|
||||
),
|
||||
'ColumnChart', 'monthly', array( 'start' => \IPS\DateTime::create()->sub( new \DateInterval( 'P1M' ) ), 'end' => \IPS\DateTime::create() )
|
||||
);
|
||||
$staffRatingsChart->plotZeros = FALSE;
|
||||
$staffRatingsChart->groupBy = 'rating_staff';
|
||||
foreach( \IPS\nexus\Support\Request::staff() as $id => $name )
|
||||
{
|
||||
$staffRatingsChart->addSeries( $name, 'number', 'AVG(rating_rating)', TRUE, $id );
|
||||
}
|
||||
|
||||
$activeTabContents = (string) $staffRatingsChart;
|
||||
}
|
||||
|
||||
/* Latest Feedback */
|
||||
elseif ( $activeTab === 'latest_feedback' )
|
||||
{
|
||||
$table = new \IPS\Helpers\Table\Db( 'nexus_support_ratings', \IPS\Http\Url::internal('app=nexus&module=support&controller=reports&tab=latest_feedback') );
|
||||
$table->joins = array(
|
||||
array(
|
||||
'from' => 'nexus_support_replies',
|
||||
'where' => 'reply_id=rating_reply'
|
||||
),
|
||||
array(
|
||||
'from' => 'nexus_support_requests',
|
||||
'where' => 'r_id=reply_request'
|
||||
)
|
||||
);
|
||||
$table->sortBy = 'rating_date';
|
||||
$table->sortDirection = 'desc';
|
||||
$table->parsers = array(
|
||||
'reply_post' => function( $val )
|
||||
{
|
||||
return $val;
|
||||
}
|
||||
);
|
||||
|
||||
$table->tableTemplate = array( \IPS\Theme::i()->getTemplate('support'), 'latestFeedback' );
|
||||
|
||||
$activeTabContents = (string) $table;
|
||||
}
|
||||
|
||||
/* Display */
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->output = $activeTabContents;
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('performance_reports');
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->tabs( $tabs, $activeTab, $activeTabContents, \IPS\Http\Url::internal( "app=nexus&module=support&controller=reports" ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Staff Report
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function staff()
|
||||
{
|
||||
/* Load */
|
||||
$id = \IPS\Request::i()->id;
|
||||
if ( !array_key_exists( $id, \IPS\nexus\Support\Request::staff() ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2X207/1', 404, '' );
|
||||
}
|
||||
$staff = \IPS\Member::load( $id );
|
||||
|
||||
/* Tabs */
|
||||
$tabs = array(
|
||||
'productivity' => 'productivity',
|
||||
'latest_replies' => 'latest_replies',
|
||||
'feedback_ratings' => 'feedback_ratings',
|
||||
'latest_feedback' => 'latest_feedback'
|
||||
);
|
||||
$activeTab = ( isset( \IPS\Request::i()->tab ) and array_key_exists( \IPS\Request::i()->tab, $tabs ) ) ? \IPS\Request::i()->tab : 'productivity';
|
||||
$activeTabContents = '';
|
||||
|
||||
/* Daily Productivity */
|
||||
if ( $activeTab === 'productivity' )
|
||||
{
|
||||
/* Date Range */
|
||||
$where = array( array( 'reply_type=?', \IPS\nexus\Support\Reply::REPLY_STAFF ) );
|
||||
$timeframe = isset( \IPS\Request::i()->timeframe ) ? \IPS\Request::i()->timeframe : 'last_30_days';
|
||||
switch ( $timeframe )
|
||||
{
|
||||
case 'last_24_hours':
|
||||
$daysInTimeframe = 1;
|
||||
break;
|
||||
case 'last_7_days':
|
||||
$daysInTimeframe = 7;
|
||||
break;
|
||||
case 'last_30_days':
|
||||
$daysInTimeframe = 30;
|
||||
break;
|
||||
}
|
||||
$where[] = array( 'reply_date>?', \IPS\DateTime::ts( time() )->sub( new \DateInterval( "P{$daysInTimeframe}D" ) )->getTimestamp() );
|
||||
|
||||
/* Init */
|
||||
$numberOfStaffMembers = \IPS\Db::i()->select( 'COUNT(DISTINCT reply_member)', 'nexus_support_replies', $where )->first();
|
||||
$now = \IPS\DateTime::ts( time() );
|
||||
$myOffset = $now->getTimezone()->getOffset( $now ) / 3600;
|
||||
|
||||
/* Group */
|
||||
$span = isset( \IPS\Request::i()->span ) ? \IPS\Request::i()->span : 'day';
|
||||
$group = $span === 'day' ? '%H' : '%w';
|
||||
|
||||
/* Type */
|
||||
$type = isset( \IPS\Request::i()->type ) ? \IPS\Request::i()->type : 'total';
|
||||
|
||||
/* Get average replies by hour for this staff member */
|
||||
$thisStaffMember = array();
|
||||
$thisStaffMemberCount = array();
|
||||
foreach( \IPS\Db::i()->select( "COUNT(*) AS count, reply_date AS unixtime, DATE_FORMAT( FROM_UNIXTIME( reply_date ), '{$group}' ) AS hour", 'nexus_support_replies', array_merge( $where, array( array( 'reply_member=?', $staff->member_id ) ) ), NULL, NULL, array( 'hour', 'reply_date' ) ) as $row )
|
||||
{
|
||||
$_group = $span === 'day' ? \IPS\DateTime::ts( $row['unixtime'] )->format('G') : \IPS\DateTime::ts( $row['unixtime'] )->format('w');
|
||||
|
||||
if ( !isset( $thisStaffMemberCount[ $_group ] ) )
|
||||
{
|
||||
$thisStaffMemberCount[ $_group ] = 0;
|
||||
}
|
||||
|
||||
$thisStaffMemberCount[ $_group ] = $thisStaffMemberCount[ $_group ] + $row['count'];
|
||||
}
|
||||
|
||||
foreach( $thisStaffMemberCount AS $_group => $count )
|
||||
{
|
||||
$thisStaffMember[ $_group ] = round( ( $type === 'average' ) ? ( $count / $daysInTimeframe ) : $count, 1 );
|
||||
}
|
||||
|
||||
/* Get average replies by hour for all staff members */
|
||||
if ( $numberOfStaffMembers > 1 )
|
||||
{
|
||||
$allStaffMembers = array();
|
||||
$allStaffMembersCount = array();
|
||||
foreach( \IPS\Db::i()->select( "COUNT(*) AS count, reply_date AS unixtime, DATE_FORMAT( FROM_UNIXTIME( reply_date ), '{$group}' ) AS hour", 'nexus_support_replies', $where, NULL, NULL, array( 'hour', 'reply_date' ) ) as $row )
|
||||
{
|
||||
$_group = $span === 'day' ? \IPS\DateTime::ts( $row['unixtime'] )->format('G') : \IPS\DateTime::ts( $row['unixtime'] )->format('w');
|
||||
|
||||
if ( !isset( $allStaffMembersCount[ $_group ] ) )
|
||||
{
|
||||
$allStaffMembersCount[ $_group ] = 0;
|
||||
}
|
||||
|
||||
$allStaffMembersCount[ $_group ] = $allStaffMembersCount[ $_group ] + $row['count'];
|
||||
}
|
||||
|
||||
foreach( $allStaffMembersCount AS $_group => $count )
|
||||
{
|
||||
$allStaffMembers[ $_group ] = round( ( ( $type === 'average' ) ? ( $count / $daysInTimeframe ) : $count ) / $numberOfStaffMembers, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Build Chart */
|
||||
$chart = new \IPS\Helpers\Chart;
|
||||
$chart->addHeader( \IPS\Member::loggedIn()->language()->addToStack('hour'), 'string' );
|
||||
$chart->addHeader( $staff->name, 'number' );
|
||||
if ( $numberOfStaffMembers > 1 )
|
||||
{
|
||||
$chart->addHeader( \IPS\Member::loggedIn()->language()->addToStack('all_staff_average'), 'number' );
|
||||
}
|
||||
if ( $span === 'day' )
|
||||
{
|
||||
foreach ( range( 0 - $myOffset, 23 - $myOffset ) as $hour )
|
||||
{
|
||||
$timestamp = mktime( 0, 0, 0 ) + ( $hour * 3600 );
|
||||
|
||||
if ( $numberOfStaffMembers > 1 )
|
||||
{
|
||||
$chart->addRow( array(
|
||||
\IPS\DateTime::ts( $timestamp )->localeTime( FALSE, FALSE ),
|
||||
isset( $thisStaffMember[ $hour + $myOffset ] ) ? $thisStaffMember[ $hour + $myOffset ] : 0,
|
||||
isset( $allStaffMembers[ $hour + $myOffset ] ) ? $allStaffMembers[ $hour + $myOffset ] : 0
|
||||
) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$chart->addRow( array(
|
||||
\IPS\DateTime::ts( $timestamp )->localeTime( FALSE, FALSE ),
|
||||
isset( $thisStaffMember[ $hour + $myOffset ] ) ? $thisStaffMember[ $hour + $myOffset ] : 0
|
||||
) );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ( range( 0, 6 ) as $day )
|
||||
{
|
||||
if ( $numberOfStaffMembers > 1 )
|
||||
{
|
||||
$chart->addRow( array(
|
||||
\IPS\Member::loggedIn()->language()->addToStack("weekday_{$day}"),
|
||||
isset( $thisStaffMember[ $day ] ) ? $thisStaffMember[ $day ] : 0,
|
||||
isset( $allStaffMembers[ $day ] ) ? $allStaffMembers[ $day ] : 0
|
||||
) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$chart->addRow( array(
|
||||
\IPS\Member::loggedIn()->language()->addToStack("weekday_{$day}"),
|
||||
isset( $thisStaffMember[ $day ] ) ? $thisStaffMember[ $day ] : 0
|
||||
) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Display */
|
||||
$activeTabContents = \IPS\Theme::i()->getTemplate('supportreports')->timeChart(
|
||||
$chart->render( 'SteppedAreaChart', array(
|
||||
'legend' => array( 'position' => 'none' ),
|
||||
'areaOpacity' => 0.4,
|
||||
'lineWidth' => 1,
|
||||
'backgroundColor' => '#ffffff',
|
||||
'colors' => array( '#10967e' ),
|
||||
'hAxis' => array( 'gridlines' => array( 'color' => '#f5f5f5' ) ),
|
||||
) ),
|
||||
\IPS\Http\Url::internal( "app=nexus&module=support&controller=reports&do=staff&id={$staff->member_id}&tab=productivity" )->setQueryString( array(
|
||||
'span' => $span,
|
||||
'timeframe' => $timeframe,
|
||||
'type' => $type
|
||||
) )
|
||||
);
|
||||
}
|
||||
|
||||
/* Latest Replies */
|
||||
elseif ( $activeTab === 'latest_replies' )
|
||||
{
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'support.css', 'nexus', 'admin' ) );
|
||||
$table = new \IPS\Helpers\Table\Content( 'IPS\nexus\Support\Reply', \IPS\Http\Url::internal( "app=nexus&module=support&controller=reports&do=staff&id={$staff->member_id}&tab=latest_replies" ), array( array( 'reply_type=? AND reply_member=?', \IPS\nexus\Support\Reply::REPLY_STAFF, $staff->member_id ) ) );
|
||||
$table->tableTemplate = array( \IPS\Theme::i()->getTemplate( 'tables', 'core', 'front' ), 'table' );
|
||||
$table->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'supportreports' ), 'supportReplyRows' );
|
||||
$table->sortBy = 'reply_date';
|
||||
$activeTabContents = (string) $table;
|
||||
}
|
||||
|
||||
/* Feedback */
|
||||
elseif ( $activeTab === 'feedback_ratings' )
|
||||
{
|
||||
$staffRatingsChart = new \IPS\Helpers\Chart\Database( \IPS\Http\Url::internal( "app=nexus&module=support&controller=reports&do=staff&id={$staff->member_id}&tab=feedback_ratings" ), 'nexus_support_ratings', 'rating_date', '',
|
||||
array(
|
||||
'vAxis' => array( 'title' => \IPS\Member::loggedIn()->language()->addToStack('average_rating'), 'viewWindow' => array( 'min' => 0, 'max' => 5 ) ),
|
||||
'legend' => 'none'
|
||||
),
|
||||
'LineChart', 'monthly'
|
||||
);
|
||||
$staffRatingsChart->plotZeros = FALSE;
|
||||
$staffRatingsChart->addSeries( $staff->name, 'number', 'AVG(rating_rating)', FALSE );
|
||||
|
||||
$activeTabContents = (string) $staffRatingsChart;
|
||||
}
|
||||
|
||||
/* Latest Feedback */
|
||||
elseif ( $activeTab === 'latest_feedback' )
|
||||
{
|
||||
$table = new \IPS\Helpers\Table\Db( 'nexus_support_ratings', \IPS\Http\Url::internal("app=nexus&module=support&controller=reports&do=staff&id={$staff->member_id}&tab=latest_feedback"), array( 'rating_staff=?', $staff->member_id ) );
|
||||
$table->joins = array(
|
||||
array(
|
||||
'from' => 'nexus_support_replies',
|
||||
'where' => 'reply_id=rating_reply'
|
||||
),
|
||||
array(
|
||||
'from' => 'nexus_support_requests',
|
||||
'where' => 'r_id=reply_request'
|
||||
)
|
||||
);
|
||||
$table->sortBy = 'rating_date';
|
||||
$table->sortDirection = 'desc';
|
||||
$table->parsers = array(
|
||||
'reply_post' => function( $val )
|
||||
{
|
||||
return $val;
|
||||
}
|
||||
);
|
||||
|
||||
$table->tableTemplate = array( \IPS\Theme::i()->getTemplate('support'), 'latestFeedback' );
|
||||
|
||||
$activeTabContents = (string) $table;
|
||||
}
|
||||
|
||||
/* Display */
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->output = $activeTabContents;
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->title = $staff->name;
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->tabs( $tabs, $activeTab, $activeTabContents, \IPS\Http\Url::internal( "app=nexus&module=support&controller=reports&do=staff&id={$staff->member_id}" ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -1,111 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Support Settings
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) Invision Power Services, Inc.
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
* @package Invision Community
|
||||
* @subpackage Nexus
|
||||
* @since 15 Apr 2014
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\modules\admin\support;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Payment Settings
|
||||
*/
|
||||
class _settings extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Call
|
||||
*
|
||||
* @param string $method Method called
|
||||
* @param array $args Arguments
|
||||
* @return void
|
||||
*/
|
||||
public function __call( $method, $args )
|
||||
{
|
||||
$tabs = array();
|
||||
if( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'support', 'departments_manage' ) )
|
||||
{
|
||||
$tabs['departments'] = 'departments';
|
||||
}
|
||||
if( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'support', 'stockactions_manage' ) )
|
||||
{
|
||||
$tabs['stockactions'] = 'stock_actions';
|
||||
}
|
||||
if( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'support', 'scfields_manage' ) )
|
||||
{
|
||||
$tabs['fields'] = 'custom_support_fields';
|
||||
}
|
||||
if( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'support', 'severities_manage' ) )
|
||||
{
|
||||
$tabs['severities'] = 'severities';
|
||||
}
|
||||
if( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'support', 'statuses_manage' ) )
|
||||
{
|
||||
$tabs['statuses'] = 'statuses';
|
||||
}
|
||||
if( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'support', 'autoresolve_manage' ) )
|
||||
{
|
||||
$tabs['autoresolve'] = 'autoresolve';
|
||||
}
|
||||
if( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'support', 'customerfeedback_manage' ) )
|
||||
{
|
||||
$tabs['customerfeedback'] = 'customer_feedback';
|
||||
}
|
||||
if( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'support', 'outgoingemail_manage' ) )
|
||||
{
|
||||
$tabs['outgoingemail'] = 'outgoing_emails';
|
||||
}
|
||||
if( \IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'support', 'incomingemail_manage' ) )
|
||||
{
|
||||
$tabs['incomingemail'] = 'incoming_emails';
|
||||
}
|
||||
|
||||
if ( isset( \IPS\Request::i()->tab ) and isset( $tabs[ \IPS\Request::i()->tab ] ) )
|
||||
{
|
||||
$activeTab = \IPS\Request::i()->tab;
|
||||
}
|
||||
else
|
||||
{
|
||||
$_tabs = array_keys( $tabs ) ;
|
||||
$activeTab = array_shift( $_tabs );
|
||||
}
|
||||
|
||||
$classname = 'IPS\nexus\modules\admin\support\\' . $activeTab;
|
||||
$class = new $classname;
|
||||
$class->url = \IPS\Http\Url::internal("app=nexus&module=support&controller=settings&tab={$activeTab}");
|
||||
$class->execute();
|
||||
|
||||
if ( $method === 'manage' and \IPS\Member::loggedIn()->language()->checkKeyExists( $tabs[ $activeTab ] . '_blurb' ) )
|
||||
{
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'forms', 'core' )->blurb( $tabs[ $activeTab ] . '_blurb', TRUE, TRUE ) . \IPS\Output::i()->output;
|
||||
}
|
||||
|
||||
if ( $method !== 'form' )
|
||||
{
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->paddedBlock( \IPS\Output::i()->output );
|
||||
}
|
||||
|
||||
if ( $method !== 'manage' or \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('support_settings');
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->tabs( $tabs, $activeTab, \IPS\Output::i()->output, \IPS\Http\Url::internal( "app=nexus&module=support&controller=settings" ) );
|
||||
}
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief severities
|
||||
* @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\modules\admin\support;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* severities
|
||||
*/
|
||||
class _severities extends \IPS\Node\Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
protected $nodeClass = 'IPS\nexus\Support\Severity';
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'severities_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
{
|
||||
parent::manage();
|
||||
|
||||
if ( isset( \IPS\Request::i()->nexus_severities ) )
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
\IPS\Settings::i()->changeValues( array( 'nexus_severities' => \IPS\Request::i()->nexus_severities ) );
|
||||
\IPS\Session::i()->log( 'acplogs__severity_settings' );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal('app=nexus&module=support&controller=settings&tab=severities') );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('support')->severities( \IPS\Output::i()->output );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function delete()
|
||||
{
|
||||
try
|
||||
{
|
||||
$node = \IPS\nexus\Support\Severity::load( \IPS\Request::i()->id );
|
||||
if ( $node->default )
|
||||
{
|
||||
\IPS\Output::i()->error( 'cannot_delete_default_severity', '1X211/1', 403, '' );
|
||||
}
|
||||
|
||||
if ( $node->canDelete() )
|
||||
{
|
||||
if ( \IPS\Db::i()->select( 'COUNT(*)', 'nexus_support_requests', array( 'r_severity=?', $node->id ) ) )
|
||||
{
|
||||
$form = new \IPS\Helpers\Form( 'delete', 'delete' );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'set_existing_requests_to', NULL, TRUE, array( 'class' => 'IPS\nexus\Support\Severity', 'permissionCheck' => function( $_node ) use ( $node )
|
||||
{
|
||||
return $node->id != $_node->id;
|
||||
} ) ) );
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
/* Update */
|
||||
\IPS\Db::i()->update( 'nexus_support_requests', array( 'r_severity' => $values['set_existing_requests_to']->id ), array( 'r_severity=?', $node->id ) );
|
||||
|
||||
/* Delete it */
|
||||
\IPS\Session::i()->log( 'acplog__node_deleted', array( $this->title => TRUE, $node->titleForLog() => FALSE ) );
|
||||
$node->delete();
|
||||
|
||||
/* Clear out member's cached "Create Menu" contents */
|
||||
\IPS\Member::clearCreateMenu();
|
||||
|
||||
/* Boink */
|
||||
if( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->json( "OK" );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->redirect( $this->url->setQueryString( array( 'root' => ( $node->parent() ? $node->parent()->_id : '' ) ) ), 'deleted' );
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = $form;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
return parent::delete();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return parent::delete();
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
return parent::delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Support Statuses
|
||||
* @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\modules\admin\support;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Support Departments
|
||||
*/
|
||||
class _statuses extends \IPS\Node\Controller
|
||||
{
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
protected $nodeClass = 'IPS\nexus\Support\Status';
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'statuses_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function delete()
|
||||
{
|
||||
try
|
||||
{
|
||||
$node = \IPS\nexus\Support\Status::load( \IPS\Request::i()->id );
|
||||
if ( $node->default_staff or $node->default_member )
|
||||
{
|
||||
\IPS\Output::i()->error( 'cannot_delete_default_status', '1X210/1', 403, '' );
|
||||
}
|
||||
|
||||
if ( $node->canDelete() and \IPS\Db::i()->select( 'COUNT(*)', 'nexus_support_requests', array( 'r_status=?', $node->id ) )->first() )
|
||||
{
|
||||
$form = new \IPS\Helpers\Form( 'delete', 'delete' );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'set_existing_requests_to', NULL, TRUE, array( 'class' => 'IPS\nexus\Support\Status', 'permissionCheck' => function( $_node ) use ( $node )
|
||||
{
|
||||
return $node->id != $_node->id;
|
||||
} ) ) );
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
\IPS\Db::i()->update( 'nexus_support_requests', array( 'r_status' => $values['set_existing_requests_to']->id ), array( 'r_status=?', $node->id ) );
|
||||
return parent::delete();
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = $form;
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e ){}
|
||||
|
||||
return parent::delete();
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief stockactions
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) Invision Power Services, Inc.
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
* @package Invision Community
|
||||
* @subpackage Nexus
|
||||
* @since 15 Apr 2014
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\modules\admin\support;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* stockactions
|
||||
*/
|
||||
class _stockactions extends \IPS\Node\Controller
|
||||
{
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
protected $nodeClass = 'IPS\nexus\Support\StockAction';
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'stockactions_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief New Support Request Volumme
|
||||
* @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 25 Apr 2014
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\modules\admin\support;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* volume
|
||||
*/
|
||||
class _volume extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'volume_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* View
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
{
|
||||
$chart = \IPS\core\Statistics\Chart::loadFromExtension( 'nexus', 'Support' )->getChart( \IPS\Http\Url::internal( "app=nexus&module=support&controller=volume" ) );
|
||||
\IPS\Output::i()->output = (string) $chart;
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__nexus_support_volume');
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user