Version 5.0.13

This commit is contained in:
Neo committed 2025-12-19 19:04:57 -08:00
1 parent b89858b2ff
commit 5efe744c5f
1407 files changed
+69690 -30177

No files matched your search

@@ -271,7 +271,7 @@ abstract class Gateway extends Model
$return = array();
foreach ( static::roots() as $gateway )
{
if ( $gateway->canStoreCards( $adminCreatableOnly ) )
if ( $gateway->canStoreCards( $adminCreatableOnly ) and $gateway->active )
{
$return[ $gateway->id ] = $gateway;
}
@@ -308,7 +308,7 @@ abstract class Gateway extends Model
$return = array();
foreach ( static::roots() as $gateway )
{
if ( $gateway->billingAgreements() )
if ( $gateway->billingAgreements() and $gateway->active )
{
$return[ $gateway->id ] = $gateway;
}
@@ -362,7 +362,7 @@ class Stripe extends Gateway
'data-zip' => $invoice->billaddress?->postalCode,
'data-country' => $invoice->billaddress?->country,
'data-email' => $member ? $member->email : $invoice->member->email,
'data-phone' => isset( $member->cm_phone ) ? $member->cm_phone : NULL,
'data-phone' => isset( $member->cm_phone ) ? $member->cm_phone : ( $invoice->member->cm_phone ?? null ),
'data-amount' => static::_amountAsCents( $amount ),
'data-currency' => $amount->currency,
'data-setupIntent' => $setupIntent ? $setupIntent['id'] : NULL,
@@ -469,47 +469,47 @@ class Stripe extends Gateway
}
}
if ( !isset( $data['customer'] ) )
{
if ( $member->member_id )
{
$response = $this->api( 'customers', array(
'name' => $member->cm_name,
'email' => $member->email,
'metadata' => array(
"Customer ID" => $member->member_id
)
) );
$profiles[ $this->id ] = $response['id'];
$member->cm_profiles = $profiles;
$member->save();
}
else
{
$response = $this->api( 'customers', array(
'name' => $invoice->member->cm_name,
'email' => $invoice->member->email,
) );
$profiles[ $this->id ] = $response['id'];
$guestData = $invoice->guest_data;
$guestData['member']['cm_profiles'] = $profiles;
$guestData['cards'][] = array(
'card_method' => $this->id,
'card_data' => $paymentMethod
);
$invoice->guest_data = $guestData;
$invoice->save();
}
$data['customer'] = $profiles[ $this->id ];
}
if ( $savePaymentMethod )
{
$data['save_payment_method'] = 'true';
$data['setup_future_usage'] = 'off_session';
if ( !isset( $data['customer'] ) )
{
if ( $member->member_id )
{
$response = $this->api( 'customers', array(
'name' => $member->cm_name,
'email' => $member->email,
'metadata' => array(
"Customer ID" => $member->member_id
)
) );
$profiles[ $this->id ] = $response['id'];
$member->cm_profiles = $profiles;
$member->save();
}
else
{
$response = $this->api( 'customers', array(
'name' => $invoice->member->cm_name,
'email' => $invoice->member->email,
) );
$profiles[ $this->id ] = $response['id'];
$guestData = $invoice->guest_data;
$guestData['member']['cm_profiles'] = $profiles;
$guestData['cards'][] = array(
'card_method' => $this->id,
'card_data' => $paymentMethod
);
$invoice->guest_data = $guestData;
$invoice->save();
}
$data['customer'] = $profiles[ $this->id ];
}
}
$response = $this->api( 'payment_intents', $data );
@@ -24,6 +24,7 @@ use IPS\nexus\Money;
use IPS\nexus\Transaction;
use LogicException;
use function defined;
use const IPS\NEXUS_TEST_GATEWAYS;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
@@ -523,6 +523,7 @@ class Invoice extends ActiveRecord
public function set_guest_data( ?array $data ) : void
{
$this->_data['guest_data'] = $data ? json_encode( $data ) : NULL;
$this->_member = null;
}
/**
@@ -735,6 +736,9 @@ class Invoice extends ActiveRecord
/* Increase the total */
$this->recalculateTotal();
/* Fire an event */
Event::fire( 'onAddToInvoice', $item, [ $this ] );
/* Return the ID */
return $id;
+87 -133
View File
@@ -13,16 +13,14 @@ namespace IPS\nexus\Package;
/* To prevent PHP errors (extending class does not exist) revealing path */
use IPS\Application;
use IPS\core\AdminNotification;
use IPS\core\Advertisement;
use IPS\Db;
use IPS\Extensions\AdvertisementLocationsAbstract;
use IPS\Helpers\Form;
use IPS\Helpers\Form\CheckboxSet;
use IPS\Helpers\Form\Custom;
use IPS\Helpers\Form\Node;
use IPS\Helpers\Form\Number;
use IPS\Helpers\Form\Radio;
use IPS\Helpers\Form\Text;
use IPS\Helpers\Form\Upload;
use IPS\Helpers\Form\WidthHeight;
use IPS\Helpers\Form\YesNo;
@@ -60,7 +58,7 @@ class Ad extends Package
/**
* @brief Which columns belong to the local table
*/
protected static array $packageDatabaseColumns = array( 'p_locations', 'p_exempt', 'p_expire', 'p_expire_unit', 'p_max_height', 'p_max_width', 'p_settings' );
protected static array $packageDatabaseColumns = array( 'p_locations', 'p_exempt', 'p_expire', 'p_expire_unit', 'p_max_height', 'p_max_width', 'p_settings', 'p_email' );
/**
* @brief Icon
@@ -85,85 +83,46 @@ class Ad extends Package
public static function acpFormFields( Package $package, bool $custom=FALSE, bool $customEdit=FALSE ): array
{
$return = array();
$currentValues = ( $package->id AND $package->settings ) ? json_decode( $package->settings, true ) : array();
$settingFields = Advertisement::locationFields( $currentValues, ( ( $package->id and $package->locations ) ? explode( ",", $package->locations ) : [] ) );
$emailFields = Advertisement::emailFields( $currentValues );
$settingToggles = [];
foreach( $settingFields as $field )
{
$settingToggles[] = $field->htmlId;
}
$emailToggles = [];
foreach( $emailFields as $field )
{
$emailToggles[] = $field->htmlId;
}
$return['package_settings']['ad_type'] = new Radio( 'ad_type', ( $package->id and $package->email ) ? 'emails' : 'site', true, [
'options' => [
'site' => 'advertisements_site',
'emails' => 'advertisements_emails'
],
'toggles' => [
'site' => $settingToggles,
'emails' => $emailToggles
],
'disabled' => (bool) ( $package->id )
], id: 'ad_type' );
if ( !$customEdit ) // If we're editing a custom package, they can get to this by editing the advertisement
{
$currentValues = ( $package->id AND $package->settings ) ? json_decode( $package->settings, true ) : array();
/* Add the location fields, remember to call extensions for additional locations.
Array format: location => array of toggle fields to show */
$defaultLocations = array(
'ad_global_header' => array( 'ad_apps' ),
'ad_global_footer' => array( 'ad_apps' ),
'ad_sidebar' => array( 'ad_apps' ),
);
$settingFields = [];
/* Add a field to restrict by app */
$settingFields[] = new Node( 'ad_apps', $currentValues['ad_apps'] ?? 0, false, array(
'class' => Application::class,
'multiple' => true,
'zeroVal' => 'all',
'subnodes' => false
), null, null, null, 'ad_apps' );
/* Now grab ad location extensions */
foreach ( Application::allExtensions( 'core', 'AdvertisementLocations', FALSE, 'core' ) as $key => $extension )
{
/* @var AdvertisementLocationsAbstract $extension */
$result = $extension->getSettings( $currentValues );
$defaultLocations = array_merge( $defaultLocations, $result['locations'] );
/* If this is a list view, add setting fields for interaval and repeat */
if( $extension::$listView )
{
$settingFields[] = new Number( 'ad_view_number', ( isset( $currentValues['ad_view_number'] ) AND $currentValues['ad_view_number'] ) ? $currentValues['ad_view_number'] : 1, FALSE, array( 'min' => 1 ), NULL, NULL, Member::loggedIn()->language()->addToStack('ad_view_number_suffix'), 'ad_view_number' );
$settingFields[] = new Number( 'ad_view_repeat', $currentValues['ad_view_repeat'] ?? 1, FALSE, array( 'unlimited' => -1 ), NULL, NULL, Member::loggedIn()->language()->addToStack('ad_view_repeat_suffix'), 'ad_view_repeat' );
foreach( $result['locations'] as $location => $toggles )
{
$defaultLocations[$location][] = 'ad_view_number';
$defaultLocations[$location][] = 'ad_view_repeat';
}
}
if( isset( $result['settings'] ) )
{
$settingFields = $settingFields + $result['settings'];
}
}
/* Add the locations to the form, and make sure the toggles get set properly */
$locations = array();
if ( $package->id )
{
$locations = $package->locations ? explode( ',', $package->locations ) : [];
$locations = array_intersect( $locations, array_keys( $defaultLocations ) );
}
/* Make locations optional so that we can have ads for widgets only */
$return['package_settings']['p_locations'] = new CheckboxSet( 'p_locations',
$locations,
false,
array(
'options' => array_combine( array_keys( $defaultLocations ), array_keys( $defaultLocations ) ),
'toggles' => $defaultLocations,
'noDefault' => true
),
NULL,
NULL,
NULL,
'p_locations'
);
foreach( $settingFields as $settingField )
{
$return['package_settings'][ $settingField->name ] = $settingField;
}
foreach( $emailFields as $emailField )
{
$return['package_settings'][ $emailField->name ] = $emailField;
}
$return['package_settings']['p_exempt'] = new CheckboxSet( 'p_exempt', ( $package->id and $package->exempt ) ? ( $package->exempt == '*' ? '*' : explode( ',', $package->exempt ) ) : '*', FALSE, array( 'options' => Group::groups(), 'parse' => 'normal', 'multiple' => TRUE, 'unlimited' => '*', 'unlimitedLang' => 'everyone', 'impliedUnlimited' => TRUE ) );
$return['package_settings']['p_expire'] = new Custom( 'p_expire', array( 'value' => ( $package->id and $package->expire ) ? $package->expire : -1, 'type' => ( $package->id ) ? $package->expire_unit : 'i' ), FALSE, array(
@@ -184,7 +143,7 @@ class Ad extends Package
if ( !$custom )
{
$return['package_settings']['p_max_dims'] = new WidthHeight( 'p_max_dims', ( $package->id and $package->width ) ? array( $package->max_width, $package->max_height ) : null, FALSE, array( 'unlimited' => array( 0, 0 ), 'resizableDiv' => FALSE ) );
$return['package_settings']['p_max_dims'] = new WidthHeight( 'p_max_dims', ( $package->id and $package->max_width ) ? array( $package->max_width, $package->max_height ) : null, FALSE, array( 'unlimited' => array( 0, 0 ), 'resizableDiv' => FALSE ) );
}
}
@@ -218,51 +177,31 @@ class Ad extends Package
unset( $values['p_max_dims'] );
}
if ( isset( $values['p_locations'] ) )
if ( isset( $values['ad_location'] ) )
{
$values['p_locations'] = is_array( $values['p_locations'] ) ? implode( ',', $values['p_locations'] ) : '';
$values['p_locations'] = is_array( $values['ad_location'] ) ? implode( ',', $values['ad_location'] ) : '';
}
$additionalSettings = array(
'ad_apps' => ( isset( $values['ad_apps'] ) AND $values['ad_apps'] != 0 ) ? array_keys( $values['ad_apps'] ) : 0
);
foreach ( Application::allExtensions( 'core', 'AdvertisementLocations', FALSE, 'core' ) as $key => $extension )
$values['p_email'] = ( $values['ad_type'] == 'emails' );
if( $values['p_email'] )
{
/* @var AdvertisementLocationsAbstract $extension */
if( $extension::$listView )
$additionalSettings = Advertisement::processEmailFields( $values );
}
else
{
$additionalSettings = Advertisement::processLocationFields( $values );
}
/* Unset any elements that were added */
foreach( $values as $k => $v )
{
if( str_starts_with( $k, 'ad_' ) or str_starts_with( $k, '_ad' ) )
{
$additionalSettings['ad_view_number'] = $values['ad_view_number'] ?? 1;
$additionalSettings['ad_view_repeat'] = $values['ad_view_repeat'] ?? 0;
}
$settings = $extension->parseSettings( $values );
$additionalSettings = array_merge( $additionalSettings, $settings );
/* Unset any elements that were added */
$result = $extension->getSettings( $values );
if( isset( $result['settings'] ) )
{
foreach( $result['settings'] as $settingField )
{
if( isset( $values[ $settingField->name ] ) )
{
unset( $values[ $settingField->name ] );
}
}
unset( $values[ $k ] );
}
}
$values['p_settings'] = json_encode( $additionalSettings );
foreach( array( 'ad_apps', 'ad_view_number', 'ad_view_repeat' ) as $field )
{
if( isset( $values[ $field ] ) )
{
unset( $values[ $field ] );
}
}
return parent::formatFormValues( $values );
}
@@ -384,10 +323,15 @@ class Ad extends Package
{
Member::loggedIn()->language()->words['advertisement_image_desc'] = Member::loggedIn()->language()->addToStack( 'advertisement_image_max_w', FALSE, array( 'sprintf' => array( $this->max_width ) ) );
}
$form->add( new YesNo( 'ad_image_more', FALSE, FALSE, array( 'togglesOn' => array( 'ad_image_small', 'ad_image_medium' ) ), NULL, NULL, NULL, 'ad_image_more' ) );
$form->add( new Upload( 'ad_image_small', NULL, FALSE, array( 'image' => TRUE, 'storageExtension' => 'nexus_Ads' ), NULL, NULL, NULL, 'ad_image_small' ) );
$form->add( new Upload( 'ad_image_medium', NULL, FALSE, array( 'image' => TRUE, 'storageExtension' => 'nexus_Ads' ), NULL, NULL, NULL, 'ad_image_medium' ) );
$form->add( new Text( 'ad_image_alt', NULL, FALSE, array(), NULL, NULL, NULL, 'ad_image_alt' ) );
if( !$this->email )
{
$form->add( new YesNo( 'ad_image_more', FALSE, FALSE, array( 'togglesOn' => array( 'ad_image_small', 'ad_image_medium' ) ), NULL, NULL, NULL, 'ad_image_more' ) );
$form->add( new Upload( 'ad_image_small', NULL, FALSE, array( 'image' => TRUE, 'storageExtension' => 'nexus_Ads' ), NULL, NULL, NULL, 'ad_image_small' ) );
$form->add( new Upload( 'ad_image_medium', NULL, FALSE, array( 'image' => TRUE, 'storageExtension' => 'nexus_Ads' ), NULL, NULL, NULL, 'ad_image_medium' ) );
}
}
/**
@@ -400,8 +344,9 @@ class Ad extends Package
*/
public function addToCart(\IPS\nexus\Invoice\Item $item, array $values, string $memberCurrency ): array
{
$item->extra['image'] = json_encode( array( 'large' => (string) $values['advertisement_image'], 'medium' => (string) $values['ad_image_medium'], 'small' => (string) $values['ad_image_small'] ) );
$item->extra['image'] = json_encode( array( 'large' => (string) $values['advertisement_image'], 'medium' => (string) ( $values['ad_image_medium'] ?? '' ), 'small' => (string) ( $values['ad_image_small'] ?? '' ) ) );
$item->extra['link'] = (string) $values['advertisement_url'];
$item->extra['alt'] = $values['ad_image_alt'];
return parent::addToCart( $item, $values, $memberCurrency );
}
@@ -432,7 +377,7 @@ class Ad extends Package
$advertisement = Advertisement::load( $purchase->extra['ad'] );
return array(
'packageInfo' => $parent['packageInfo'],
'packageInfo' => $parent['packageInfo'] . Theme::i()->getTemplate( 'purchases' )->advertisementType( $purchase, $advertisement ),
'purchaseInfo' => $parent['purchaseInfo'] . Theme::i()->getTemplate('purchases')->advertisement( $purchase, $advertisement ),
);
}
@@ -461,18 +406,25 @@ class Ad extends Package
$field = new Upload( 'ad_image' . $k, NULL, TRUE, array( 'image' => TRUE, 'storageExtension' => 'nexus_Ads' ) );
$field->label = Member::loggedIn()->language()->addToStack('ad_image');
$form->add( $field );
$field = new YesNo( 'ad_image_more' . $k, FALSE, FALSE, array( 'togglesOn' => array( 'ad_image_small' . $k, 'ad_image_medium' . $k ) ) );
$field->label = Member::loggedIn()->language()->addToStack('ad_image_more');
$field = new Text( 'ad_image_alt' . $k, NULL, FALSE );
$field->label = Member::loggedIn()->language()->addToStack( 'ad_image_alt' );
$form->add( $field );
$field = new Upload( 'ad_image_small' . $k, NULL, FALSE, array( 'image' => TRUE, 'storageExtension' => 'nexus_Ads' ), NULL, NULL, NULL, 'ad_image_small' . $k );
$field->label = Member::loggedIn()->language()->addToStack('ad_image_small');
$form->add( $field );
$field = new Upload( 'ad_image_medium' . $k, NULL, FALSE, array( 'image' => TRUE, 'storageExtension' => 'nexus_Ads' ), NULL, NULL, NULL, 'ad_image_medium' . $k );
$field->label = Member::loggedIn()->language()->addToStack('ad_image_medium');
$form->add( $field );
if( !$this->email )
{
$field = new YesNo( 'ad_image_more' . $k, FALSE, FALSE, array( 'togglesOn' => array( 'ad_image_small' . $k, 'ad_image_medium' . $k ) ) );
$field->label = Member::loggedIn()->language()->addToStack('ad_image_more');
$form->add( $field );
$field = new Upload( 'ad_image_small' . $k, NULL, FALSE, array( 'image' => TRUE, 'storageExtension' => 'nexus_Ads' ), NULL, NULL, NULL, 'ad_image_small' . $k );
$field->label = Member::loggedIn()->language()->addToStack('ad_image_small');
$form->add( $field );
$field = new Upload( 'ad_image_medium' . $k, NULL, FALSE, array( 'image' => TRUE, 'storageExtension' => 'nexus_Ads' ), NULL, NULL, NULL, 'ad_image_medium' . $k );
$field->label = Member::loggedIn()->language()->addToStack('ad_image_medium');
$form->add( $field );
}
}
/**
@@ -486,8 +438,9 @@ class Ad extends Package
*/
public function acpAddToInvoice(\IPS\nexus\Invoice\Item $item, array $values, string $k, Invoice $invoice ): void
{
$item->extra['image'] = json_encode( array( 'large' => (string) $values[ 'ad_image' . $k ], 'medium' => (string) $values[ 'ad_image_medium' . $k ], 'small' => (string) $values[ 'ad_image_small' . $k ] ) );
$item->extra['image'] = json_encode( array( 'large' => (string) $values[ 'ad_image' . $k ], 'medium' => (string) ( $values[ 'ad_image_medium' . $k ] ?? '' ), 'small' => (string) ( $values[ 'ad_image_small' . $k ] ?? '' ) ) );
$item->extra['link'] = (string) $values[ 'advertisement_url' . $k ];
$item->extra['alt'] = $values['ad_image_alt' . $k ];
}
/**
@@ -547,6 +500,7 @@ class Ad extends Package
'ad_html' => NULL,
'ad_images' => $purchase->extra['image'],
'ad_link' => $purchase->extra['link'],
'ad_image_alt' => $purchase->extra['alt'] ?? '',
'ad_impressions' => 0,
'ad_clicks' => 0,
'ad_exempt' => $this->exempt === '*' ? '*' : json_encode( explode( ',', $this->exempt ) ),
@@ -559,7 +513,7 @@ class Ad extends Package
'ad_additional_settings'=> $this->settings,
'ad_html_https_set' => 0,
'ad_member' => $purchase->member->member_id,
'ad_type' => Advertisement::AD_IMAGES,
'ad_type' => ( $this->email ? Advertisement::AD_EMAIL : Advertisement::AD_IMAGES ),
) );
$extra = $purchase->extra;
@@ -155,7 +155,8 @@ class Package extends Model
foreach( Application::allExtensions( 'nexus', 'PackageType', null, null, null, false ) as $key => $ext )
{
$return[ $key ] = $ext;
$className = mb_substr( $ext, mb_strrpos( $ext, '\\' ) + 1 );
$return[ IPS::mb_ucfirst( mb_strtolower( $className ) ) ] = $ext;
}
return $return;
@@ -19,6 +19,7 @@ use IPS\Db;
use IPS\IPS;
use IPS\nexus\Purchase;
use IPS\Patterns\ActiveRecord;
use OutOfRangeException;
use function count;
use function defined;
use function get_class;
@@ -97,7 +98,13 @@ abstract class LicenseKey extends ActiveRecord
public static function constructFromData( array $data, bool $updateMultitonStoreIfExists = TRUE ): static
{
$types = static::licenseKeyTypes();
$classname = $types[ IPS::mb_ucfirst( $data['lkey_type'] ) ];
$licenseKeyType = IPS::mb_ucfirst( $data['lkey_type'] );
if( !array_key_exists( $licenseKeyType, $types ) )
{
throw new OutOfRangeException;
}
$classname = $types[ $licenseKeyType ];
/* Initiate an object */
$obj = new $classname;
@@ -1106,7 +1106,7 @@ class Transaction extends ActiveRecord
* @apiresponse \IPS\nexus\Money amount Amount
* @apiresponse \IPS\nexus\Money refundAmount If partially refunded, the amount that has been refunded
* @apiresponse \IPS\nexus\Money credit If credited, the amount that has been credited
* @apiresponse \IPS\nexus\Gateway gateway The gateway
* @apiresponse \IPS\nexus\Gateway gateway The used gateway, or null if account credit was used
* @clientapiresponse string gatewayId Any ID number provided by the gateway to identify the transaction on their end
* @apiresponse datetime date Date
* @apiresponse \IPS\nexus\Customer customer Customer