Version 4.5.0

This commit is contained in:
Neo committed 2025-12-19 05:51:58 -08:00
1 parent 1a0c7fd3c2
commit f79dcf067a
3791 files changed
+248032 -76372

No files matched your search

+126 -38
View File
@@ -12,7 +12,7 @@
namespace IPS\nexus\Package;
/* To prevent PHP errors (extending class does not exist) revealing path */
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' );
exit;
@@ -130,6 +130,33 @@ class _Item extends \IPS\Content\Item implements \IPS\Content\Featurable, \IPS\C
$member = $member ?: \IPS\Member::loggedIn();
return $this->member_groups === '*' or $member->inGroup( explode( ',', $this->member_groups ) );
}
/**
* Delete Package Data
*
* @return void
*/
public function delete()
{
/* Delete Images */
foreach( \IPS\Db::i()->select( '*', 'nexus_package_images', array( 'image_product=?', $this->id ) ) as $image )
{
try
{
\IPS\File::get( 'nexus_Products', $image['image_location'] )->delete();
}
catch ( \Exception $e ) { }
}
\IPS\Db::i()->delete( 'nexus_package_images', array( 'image_product=?', $this->id ) );
/* Delete Product Options */
\IPS\Db::i()->delete( 'nexus_product_options', array( 'opt_package=?', $this->id ) );
/* Delete Base Prices */
\IPS\Db::i()->delete( 'nexus_package_base_prices', array( 'id=?', $this->id ) );
parent::delete();
}
/**
* Get items with permisison check
@@ -196,10 +223,11 @@ class _Item extends \IPS\Content\Item implements \IPS\Content\Featurable, \IPS\C
/**
* Can review?
*
* @param \IPS\Member\NULL $member The member (NULL for currently logged in member)
* @param \IPS\Member\NULL $member The member (NULL for currently logged in member)
* @param bool $considerPostBeforeRegistering If TRUE, and $member is a guest, will return TRUE if "Post Before Registering" feature is enabled
* @return bool
*/
public function canReview( $member=NULL )
public function canReview( $member=NULL, $considerPostBeforeRegistering = TRUE )
{
if ( !$this->reviewable )
{
@@ -208,7 +236,7 @@ class _Item extends \IPS\Content\Item implements \IPS\Content\Featurable, \IPS\C
$member = $member ?: \IPS\Member::loggedIn();
if ( !parent::canReview( $member ) )
if ( !parent::canReview( $member, $considerPostBeforeRegistering ) )
{
return FALSE;
}
@@ -224,17 +252,18 @@ class _Item extends \IPS\Content\Item implements \IPS\Content\Featurable, \IPS\C
/**
* Should new reviews be moderated?
*
* @param \IPS\Member $member The member posting
* @param \IPS\Member $member The member posting
* @param bool $considerPostBeforeRegistering If TRUE, and $member is a guest, will check if a newly registered member would be moderated
* @return bool
*/
public function moderateNewReviews( \IPS\Member $member )
public function moderateNewReviews( \IPS\Member $member, $considerPostBeforeRegistering = FALSE )
{
if ( $this->review_moderate )
{
return TRUE;
}
return parent::moderateNewReviews( $member );
return parent::moderateNewReviews( $member, $considerPostBeforeRegistering );
}
/**
@@ -257,16 +286,16 @@ class _Item extends \IPS\Content\Item implements \IPS\Content\Featurable, \IPS\C
*/
public function embedContent( $params )
{
$memberCurrency = ( ( isset( $_SESSION['currency'] ) and in_array( $_SESSION['currency'], \IPS\nexus\Money::currencies() ) ) ? $_SESSION['currency'] : \IPS\nexus\Customer::loggedIn()->defaultCurrency() );
$memberCurrency = ( ( isset( \IPS\Request::i()->cookie['currency'] ) and \in_array( \IPS\Request::i()->cookie['currency'], \IPS\nexus\Money::currencies() ) ) ? \IPS\Request::i()->cookie['currency'] : \IPS\nexus\Customer::loggedIn()->defaultCurrency() );
$package = \IPS\nexus\Package::load( $this->id );
/* Do we have renewal terms? */
$renewalTerm = NULL;
$renewOptions = $package->renew_options ? json_decode( $package->renew_options, TRUE ) : array();
if ( count( $renewOptions ) )
if ( \count( $renewOptions ) )
{
$renewalTerm = TRUE;
if ( count( $renewOptions ) === 1 )
if ( \count( $renewOptions ) === 1 )
{
$renewalTerm = array_pop( $renewOptions );
$renewalTerm = new \IPS\nexus\Purchase\RenewalTerm( new \IPS\nexus\Money( $renewalTerm['cost'][ $memberCurrency ]['amount'], $memberCurrency ), new \DateInterval( 'P' . $renewalTerm['term'] . mb_strtoupper( $renewalTerm['unit'] ) ), $package->tax ? \IPS\nexus\Tax::load( $package->tax ) : NULL, $renewalTerm['add'] );
@@ -373,7 +402,7 @@ class _Item extends \IPS\Content\Item implements \IPS\Content\Featurable, \IPS\C
*/
public static function basicDataColumns()
{
return array( 'p_id', 'p_base_price', 'p_reviews', 'p_discounts', 'p_renew_options', 'p_tax', 'p_stock' );
return array( 'p_id', 'p_base_price', 'p_reviews', 'p_discounts', 'p_renew_options', 'p_tax', 'p_stock', 'p_initial_term' );
}
/**
@@ -381,9 +410,10 @@ class _Item extends \IPS\Content\Item implements \IPS\Content\Featurable, \IPS\C
*
* @param array $indexData Data from the search index
* @param array $itemData Basic data about the item. Only includes columns returned by item::basicDataColumns()
* @param string|NULL $action Action
* @return \IPS\Http\Url
*/
public static function urlFromIndexData( $indexData, $itemData )
public static function urlFromIndexData( $indexData, $itemData, $action = NULL )
{
return \IPS\Http\Url::internal( "app=nexus&module=store&controller=product&id={$indexData['index_item_id']}", 'front', 'store_product', \IPS\Member::loggedIn()->language()->addToStack( 'nexus_package_' . $indexData['index_item_id'], FALSE, array( 'seotitle' => TRUE ) ) );
}
@@ -463,33 +493,14 @@ class _Item extends \IPS\Content\Item implements \IPS\Content\Featurable, \IPS\C
{
$url = static::urlFromIndexData( $indexData, $itemData );
/* Work out the price to display @todo - make this more efficient */
try
{
$customer = \IPS\nexus\Customer::loggedIn();
$currency = ( isset( $_SESSION['currency'] ) and in_array( $_SESSION['currency'], \IPS\nexus\Money::currencies() ) ) ? $_SESSION['currency'] : $customer->defaultCurrency();
$priceMayChange = FALSE;
$priceNotIncludingDiscounts = NULL;
$renewOptions = $itemData['p_renew_options'] ? json_decode( $itemData['p_renew_options'], TRUE ) : array();
$price = \IPS\nexus\Package::lowestPriceFromData( $customer, $currency, $indexData['index_item_id'], json_decode( $itemData['p_base_price'], TRUE ), json_decode( $itemData['p_discounts'], TRUE ), $renewOptions, $itemData['p_stock'], $itemData['extra']['tax'] ? \IPS\nexus\Tax::constructFromData( $itemData['extra']['tax'] ) : NULL, $priceMayChange, $priceNotIncludingDiscounts );
if ( $price < $priceNotIncludingDiscounts )
{
$price = \IPS\Theme::i()->getTemplate( 'store', 'nexus' )->priceDiscounted( new \IPS\nexus\Money( $priceNotIncludingDiscounts, $currency ), new \IPS\nexus\Money( $price, $currency ), $priceMayChange, TRUE, 'ipsStream_price' );
}
else
{
$price = \IPS\Theme::i()->getTemplate( 'store', 'nexus' )->price( new \IPS\nexus\Money( $price, $currency ), $priceMayChange, TRUE, 'ipsStream_price' );
}
}
catch ( \OutOfRangeException $e )
{
$price = NULL;
}
/* Work out the price to display */
$customer = \IPS\nexus\Customer::loggedIn();
$currency = ( isset( \IPS\Request::i()->cookie['currency'] ) and \in_array( \IPS\Request::i()->cookie['currency'], \IPS\nexus\Money::currencies() ) ) ? \IPS\Request::i()->cookie['currency'] : $customer->defaultCurrency();
$renewOptions = $itemData['p_renew_options'] ? json_decode( $itemData['p_renew_options'], TRUE ) : array();
$priceInfo = \IPS\nexus\Package::fullPriceInfoFromData( $customer, $currency, $indexData['index_item_id'], json_decode( $itemData['p_base_price'], TRUE ), json_decode( $itemData['p_discounts'], TRUE ), $renewOptions, $itemData['p_stock'], $itemData['extra']['tax'] ? \IPS\nexus\Tax::constructFromData( $itemData['extra']['tax'] ) : NULL, $itemData['p_initial_term'] ? new \DateInterval("P{$itemData['p_initial_term']}") : NULL );
/* Display */
return \IPS\Theme::i()->getTemplate( 'global', 'nexus', 'front' )->searchResultProductSnippet( $indexData, $itemData, isset( $itemData['extra']['image'] ) ? $itemData['extra']['image'] : NULL, $url, $price, $view == 'condensed' );
return \IPS\Theme::i()->getTemplate( 'global', 'nexus', 'front' )->searchResultProductSnippet( $indexData, $itemData, isset( $itemData['extra']['image'] ) ? $itemData['extra']['image'] : NULL, $url, $priceInfo, $view == 'condensed' );
}
/**
@@ -504,7 +515,7 @@ class _Item extends \IPS\Content\Item implements \IPS\Content\Featurable, \IPS\C
{
/* Commerce Items have no own content type, so we can use only the general mod permissions */
$member = $member ?: \IPS\Member::loggedIn();
if ( in_array( $type, array( 'hide', 'unhide', 'delete' ) ) and $container )
if ( \in_array( $type, array( 'hide', 'unhide', 'delete' ) ) and $container )
{
if ( $member->modPermission( "can_{$type}" ) )
{
@@ -514,4 +525,81 @@ class _Item extends \IPS\Content\Item implements \IPS\Content\Featurable, \IPS\C
return parent::modPermission( $type, $member, $container );
}
/**
* Should posting this increment the poster's post count?
*
* @param \IPS\Node\Model|NULL $container Container
* @return void
*/
public static function incrementPostCount( \IPS\Node\Model $container = NULL )
{
return FALSE;
}
/**
* Can edit?
*
* @param \IPS\Member|NULL $member The member to check for (NULL for currently logged in member)
* @return bool
*/
public function canEdit( $member=NULL )
{
return FALSE;
}
/**
* Do Moderator Action
*
* @param string $action The action
* @param \IPS\Member|NULL $member The member doing the action (NULL for currently logged in member)
* @param string|NULL $reason Reason (for hides)
* @param bool $immediately Delete immediately
* @return void
* @throws \OutOfRangeException|\InvalidArgumentException|\RuntimeException
*/
public function modAction( $action, \IPS\Member $member = NULL, $reason = NULL, $immediately = FALSE )
{
throw new \InvalidArgumentException;
}
/**
* Can move?
*
* @param \IPS\Member|NULL $member The member to check for (NULL for currently logged in member)
* @return bool
*/
public function canMove( $member=NULL )
{
return FALSE;
}
/**
* Returns the meta description
*
* @param string|NULL $return Specific description to use (useful for paginated displays to prevent having to run extra queries)
* @return string
* @throws \BadMethodCallException
*/
public function metaDescription( $return = NULL )
{
return \IPS\Member::loggedIn()->language()->addToStack("nexus_package_{$this->id}_desc", FALSE, array( 'striptags' => TRUE ) );
}
/**
* Get container
*
* @return \IPS\Node\Model
* @note Certain functionality requires a valid container but some areas do not use this functionality (e.g. messenger)
* @throws \OutOfRangeException|\BadMethodCallException
*/
public function container()
{
if( $this->custom > 0 )
{
throw new \BadMethodCallException;
}
return parent::container();
}
}