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

@@ -12,7 +12,7 @@
namespace IPS\nexus\Support\Author;
/* 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;
@@ -56,10 +56,6 @@ class _Email
*/
public function photo()
{
if ( \IPS\Settings::i()->allow_gravatars )
{
return \IPS\Http\Url::external( "https://secure.gravatar.com/avatar/" . md5( trim( mb_strtolower( $this->email ) ) ) )->setQueryString( 'd', (string) \IPS\Theme::i()->resource( 'default_photo.png', 'core', 'global' ) )->makeSafeForAcp( TRUE );
}
return NULL;
}
@@ -96,9 +92,11 @@ class _Email
/**
* Get latest invoices
*
* @return \IPS\Patterns\ActiveRecordIterator|NULL
* @param int $limit Number of invoices
* @param bool $count Return the total count
* @return \IPS\Patterns\ActiveRecordIterator|NULL|int
*/
public function invoices( $limit=10 )
public function invoices( $limit = 10, $count = FALSE )
{
return NULL;
}
@@ -107,18 +105,24 @@ class _Email
* Support Requests
*
* @param int $limit Number to get
* @para, \IPS\nexus\Support\Request $exclude A request to exclude
* @param \IPS\nexus\Support\Request $exclude A request to exclude
* @param string $order Order clause
* @return \IPS\Patterns\ActiveRecordIterator
* @param bool $count Return the total count
* @return \IPS\Patterns\ActiveRecordIterator|int
*/
public function supportRequests( $limit, \IPS\nexus\Support\Request $exclude = NULL, $order='r_started DESC' )
public function supportRequests( $limit, \IPS\nexus\Support\Request $exclude = NULL, $order='r_started DESC', $count = FALSE )
{
$where = array( array( 'r_email=?', $this->email ) );
if ( $exclude )
{
$where[] = array( 'r_id<>?', $exclude->id );
}
return \IPS\nexus\Support\Request::getItemsWithPermission( $where, $order, $limit, 'read', \IPS\Content\Hideable::FILTER_AUTOMATIC, \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS );
if( $count === TRUE )
{
return \IPS\nexus\Support\Request::getItemsWithPermission( $where, $order, NULL, 'read', \IPS\Content\Hideable::FILTER_AUTOMATIC, 0, NULL, FALSE, FALSE, FALSE, TRUE );
}
return \IPS\nexus\Support\Request::getItemsWithPermission( $where, $order, $limit, 'read', \IPS\Content\Hideable::FILTER_AUTOMATIC );
}
}
@@ -12,7 +12,7 @@
namespace IPS\nexus\Support\Author;
/* 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;
@@ -86,7 +86,7 @@ class _Member
*/
public function meta()
{
if( !\IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customer', 'customers_view_statistics' ) )
if( !\IPS\Member::loggedIn()->hasAcpRestriction( 'nexus', 'customers', 'customers_view_statistics' ) )
{
return array( $this->customer->email );
}
@@ -111,29 +111,42 @@ class _Member
/**
* Get latest invoices
*
* @return \IPS\Patterns\ActiveRecordIterator|NULL
* @param int $limit Number of invoices
* @param bool $count Return the total count
* @return \IPS\Patterns\ActiveRecordIterator|NULL|int
*/
public function invoices( $limit=10 )
{
return new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_invoices', array( 'i_member=?', $this->customer->member_id ), 'i_date DESC', $limit, NULL, NULL, \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS ), 'IPS\nexus\Invoice' );
public function invoices( $limit = 10, $count = FALSE )
{
if( $count === TRUE )
{
return \IPS\Db::i()->select( 'COUNT(*)', 'nexus_invoices', array( 'i_member=?', $this->customer->member_id ) )->first();
}
return new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_invoices', array( 'i_member=?', $this->customer->member_id ), 'i_date DESC', $limit ), 'IPS\nexus\Invoice' );
}
/**
* Support Requests
*
* @param int $limit Number to get
* @para, \IPS\nexus\Support\Request $exclude A request to exclude
* @param \IPS\nexus\Support\Request $exclude A request to exclude
* @param string $order Order clause
* @return \IPS\Patterns\ActiveRecordIterator
* @param bool $count Return the total count
* @return \IPS\Patterns\ActiveRecordIterator|int
*/
public function supportRequests( $limit, \IPS\nexus\Support\Request $exclude = NULL, $order='r_started DESC' )
public function supportRequests( $limit, \IPS\nexus\Support\Request $exclude = NULL, $order='r_started DESC', $count = FALSE )
{
$where = array( array( 'r_member=?', $this->customer->member_id ) );
if ( $exclude )
{
$where[] = array( 'r_id<>?', $exclude->id );
}
if( $count === TRUE )
{
return \IPS\nexus\Support\Request::getItemsWithPermission( $where, $order, NULL, 'read', \IPS\Content\Hideable::FILTER_AUTOMATIC, 0, NULL, FALSE, FALSE, FALSE, TRUE );
}
return \IPS\nexus\Support\Request::getItemsWithPermission( $where, $order, $limit, 'read', \IPS\Content\Hideable::FILTER_AUTOMATIC, \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS );
return \IPS\nexus\Support\Request::getItemsWithPermission( $where, $order, $limit, 'read', \IPS\Content\Hideable::FILTER_AUTOMATIC );
}
}
@@ -12,7 +12,7 @@
namespace IPS\nexus\Support;
/* 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;
@@ -141,12 +141,12 @@ class _CustomField extends \IPS\CustomField
parent::form( $form );
$form->add( new \IPS\Helpers\Form\Node( 'sf_departments', $this->departments === '*' ? 0 : explode( ',', $this->departments ), TRUE, array( 'class' => 'IPS\nexus\Support\Department', 'multiple' => TRUE, 'zeroVal' => 'all' ) ), 'pf_desc' );
$form->add( new \IPS\Helpers\Form\YesNo( 'sf_validate_ftp', extension_loaded('ftp') ? $this->validate : FALSE, FALSE, array( 'disabled' => !extension_loaded('ftp') ), NULL, NULL, NULL, 'sf_validate_ftp' ), 'pf_not_null' );
if ( !extension_loaded('ftp') )
$form->add( new \IPS\Helpers\Form\YesNo( 'sf_validate_ftp', \extension_loaded('ftp') ? $this->validate : FALSE, FALSE, array( 'disabled' => !\extension_loaded('ftp') ), NULL, NULL, NULL, 'sf_validate_ftp' ), 'pf_not_null' );
if ( !\extension_loaded('ftp') )
{
\IPS\Member::loggedIn()->language()->words['sf_validate_ftp_desc'] = \IPS\Member::loggedIn()->language()->addToStack( 'sf_validate_ftp_noftp' );
}
elseif( !extension_loaded('ssh2') )
elseif( !\extension_loaded('ssh2') )
{
\IPS\Member::loggedIn()->language()->words['sf_validate_ftp_warning'] = \IPS\Member::loggedIn()->language()->addToStack( 'sf_validate_ftp_nosftp' );
}
@@ -194,9 +194,10 @@ class _CustomField extends \IPS\CustomField
*
* @param mixed $value The value
* @param callback $customValidationCode Custom validation code
* @param \IPS\Content|NULL $content The associated content, if editing
* @return \IPS\Helpers\Form\FormAbstract
*/
public function buildHelper( $value=NULL, $customValidationCode=NULL )
public function buildHelper( $value=NULL, $customValidationCode=NULL, \IPS\Content $content = NULL )
{
if ( $this->type === 'UserPass' )
{
@@ -207,7 +208,7 @@ class _CustomField extends \IPS\CustomField
return new \IPS\Helpers\Form\Ftp( static::$langKey . '_' . $this->id, $value, $this->not_null, array( 'validate' => $this->validate ), NULL, NULL, NULL, static::$langKey . '_' . $this->id );
}
return parent::buildHelper( $value, $customValidationCode );
return parent::buildHelper( $value, $customValidationCode, $content );
}
/**
@@ -221,7 +222,7 @@ class _CustomField extends \IPS\CustomField
{
if ( $this->type === 'UserPass' )
{
if ( !is_array( $value ) )
if ( !\is_array( $value ) )
{
$value = json_decode( \IPS\Text\Encrypt::fromTag( $value )->decrypt(), TRUE );
}
@@ -12,7 +12,7 @@
namespace IPS\nexus\Support;
/* 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;
@@ -98,7 +98,7 @@ class _Department extends \IPS\Node\Model
/**
* Get the permission array used to get the departments that a staff member has access to
*
* @param \IPS\Member|NULL $staff The staff member
* @param \IPS\Member|NULL $member The staff member
* @return array|NULL NULL indicates all departments
*/
public static function staffDepartmentPerms( \IPS\Member $member = NULL )
@@ -120,6 +120,7 @@ class _Department extends \IPS\Node\Model
/**
* Departments that a staff member has access to
*
* @param \IPS\Member|NULL $member The staff member
* @return \IPS\Patterns\ActiveRecordIterator
*/
public static function departmentsWithPermission( \IPS\Member $member = NULL )
@@ -263,7 +264,7 @@ class _Department extends \IPS\Node\Model
if ( array_key_exists( 'dpt_packages', $values ) )
{
$values['dpt_packages'] = is_array( $values['dpt_packages'] ) ? implode( ',', array_map( function( $val )
$values['dpt_packages'] = \is_array( $values['dpt_packages'] ) ? implode( ',', array_map( function( $val )
{
return ltrim( $val, 's' );
}, array_keys( $values['dpt_packages'] ) ) ) : 0;
@@ -271,14 +272,14 @@ class _Department extends \IPS\Node\Model
if ( array_key_exists( 'dpt_subscriptions', $values ) )
{
$values['dpt_subscriptions'] = is_array( $values['dpt_subscriptions'] ) ? implode( ',', array_keys( $values['dpt_subscriptions'] ) ) : 0;
$values['dpt_subscriptions'] = \is_array( $values['dpt_subscriptions'] ) ? implode( ',', array_keys( $values['dpt_subscriptions'] ) ) : 0;
}
else
{
$values['dpt_subscriptions'] = 0;
}
if ( ( array_key_exists( 'dpt_require_package', $values ) AND is_null( $values['dpt_require_package'] ) ) or $values['dpt_packages'] == 0 )
if ( ( array_key_exists( 'dpt_require_package', $values ) AND \is_null( $values['dpt_require_package'] ) ) or ( $values['dpt_packages'] == 0 and $values['dpt_subscriptions'] == 0 ) )
{
$values['dpt_require_package'] = 0;
}
@@ -327,7 +328,7 @@ class _Department extends \IPS\Node\Model
{
if ( $severity->public )
{
if ( !$severity->departments or $severity->departments === '*' or in_array( $this->id, explode( ',', $severity->departments ) ) )
if ( !$severity->departments or $severity->departments === '*' or \in_array( $this->id, explode( ',', $severity->departments ) ) )
{
$this->_availableSeverities[] = $severity;
}
@@ -383,6 +384,32 @@ class _Department extends \IPS\Node\Model
return NULL;
}
/**
* [ActiveRecord] Delete
*
* @return void
*/
public function delete()
{
foreach( \IPS\Db::i()->select( '*', 'nexus_support_fields', array( \IPS\Db::i()->findInSet( 'sf_departments', array( $this->id ) ) ) ) AS $field )
{
$newValue = array();
foreach( explode( ',', $field['sf_departments'] ) AS $dpt )
{
if ( $dpt == $this->id )
{
continue;
}
$newValue[] = $dpt;
}
\IPS\Db::i()->update( 'nexus_support_fields', array( 'sf_departments' => implode( ',', $newValue ) ), array( "sf_id=?", $field['sf_id'] ) );
}
parent::delete();
}
/**
* [Node] Get buttons to display in tree
* Example code explains return value
+1 -1
View File
@@ -12,7 +12,7 @@
namespace IPS\nexus\Support;
/* 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;
+8 -6
View File
@@ -12,7 +12,7 @@
namespace IPS\nexus\Support;
/* 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,7 +130,7 @@ class _Reply extends \IPS\Content\Comment implements \IPS\Content\Hideable
*/
public static function create( $item, $comment, $first=FALSE, $guestName=NULL, $incrementPostCount=NULL, $member=NULL, \IPS\DateTime $time=NULL, $ipAddress=NULL, $hiddenStatus=NULL )
{
$obj = call_user_func_array( 'parent::create', func_get_args() );
$obj = parent::create( $item, $comment, $first, $guestName, $incrementPostCount, $member, $time, $ipAddress, $hiddenStatus );
if ( $obj->type === static::REPLY_MEMBER and $obj->author()->member_id !== $obj->item()->author()->member_id )
{
@@ -296,7 +296,7 @@ class _Reply extends \IPS\Content\Comment implements \IPS\Content\Hideable
$alternativeContactWhere[] = '( r_member=' . $contact->main_id->member_id . ' AND ' . \IPS\Db::i()->in( 'r_purchase', $contact->purchaseIds() ) . ' )';
}
}
if ( count( $alternativeContactWhere ) )
if ( \count( $alternativeContactWhere ) )
{
$extraClause[0] = '( ' . $extraClause[0] . ' OR ( ' . implode( ' OR ', $alternativeContactWhere ) . ' ) )';
}
@@ -365,13 +365,13 @@ class _Reply extends \IPS\Content\Comment implements \IPS\Content\Hideable
foreach ( $staffToSendTo as $staffId )
{
if ( in_array( $staffId, $staffIds ) )
if ( \in_array( $staffId, $staffIds ) )
{
/* The department may only be available to specific members OR groups - we need to load an \IPS\Member object here so that we can check both and send the notification as appropriate. */
$staff = \IPS\Member::load( $staffId );
$departmentStaff = $this->item()->department->staff;
if ( !in_array( $staffId, $sentTo ) and ( $this->item()->department->staff === '*' or count( array_intersect( explode( ',', $departmentStaff ), Department::staffDepartmentPerms( $staff ) ) ) ) )
if ( !\in_array( $staffId, $sentTo ) and ( $this->item()->department->staff === '*' or \count( array_intersect( explode( ',', $departmentStaff ), Department::staffDepartmentPerms( $staff ) ) ) ) )
{
$fromEmail = ( $this->item()->department->email ) ? $this->item()->department->email : \IPS\Settings::i()->email_out;
switch ( \IPS\Settings::i()->nexus_sout_from )
@@ -380,7 +380,7 @@ class _Reply extends \IPS\Content\Comment implements \IPS\Content\Hideable
$fromName = $this->member ? $this->author()->name : $fromEmail;
break;
case 'dpt':
$member = is_int( $this->member ) ? \IPS\Member::load( $this->member ) : $this->member;
$member = \is_int( $this->member ) ? \IPS\Member::load( $this->member ) : $this->member;
$fromName = $this->member
? $member->language()->get( 'nexus_department_' . $this->item()->department->_id )
: \IPS\Lang::load( \IPS\Lang::defaultLanguage() )->get( 'nexus_department_' . $this->item()->department->_id );
@@ -402,6 +402,8 @@ class _Reply extends \IPS\Content\Comment implements \IPS\Content\Hideable
\IPS\Db::i()->delete( 'nexus_support_notify', array( 'staff_id=?', $staffId ) );
}
}
\IPS\core\AdminNotification::send( 'nexus', 'Support', NULL, TRUE, NULL, TRUE );
}
/**
+162 -71
View File
@@ -12,7 +12,7 @@
namespace IPS\nexus\Support;
/* 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;
@@ -92,6 +92,11 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
* @brief Node Class
*/
public static $containerNodeClass = 'IPS\nexus\Support\Department';
/**
* @brief Check posts per day limits? Useful for things that use the content system, but aren't necessarily content themselves.
*/
public static $checkPostsPerDay = FALSE;
/* !Generic */
@@ -123,7 +128,7 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
$members = array();
/* Get the members who are admins for being in an admin group */
if ( count( $administrators['g'] ) )
if ( \count( $administrators['g'] ) )
{
foreach ( \IPS\Db::i()->select( array( 'member_id', 'name' ), 'core_members', '( ' . \IPS\Db::i()->in( 'member_group_id', array_keys( $administrators['g'] ) ) . ' ) OR ( ' . \IPS\Db::i()->findInSet( 'mgroup_others', array_keys( $administrators['g'] ) ) . ' )' ) as $row )
{
@@ -164,9 +169,9 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
{
$num = mt_rand( 48, 122 );
}
while ( in_array( $num, array( 58, 59, 60, 61, 62, 63, 64, 91, 92, 93, 94, 95, 96 ) ) );
while ( \in_array( $num, array( 58, 59, 60, 61, 62, 63, 64, 91, 92, 93, 94, 95, 96 ) ) );
$emailKey .= chr( $num );
$emailKey .= \chr( $num );
}
$this->email_key = $emailKey;
@@ -189,7 +194,7 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
/**
* Set department
*
* @param \IPS\nexus\Support\Department
* @param \IPS\nexus\Support\Department $department Department for request
* @return void
*/
public function set_department( Department $department )
@@ -217,7 +222,7 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
/**
* Set purchase
*
* @param \IPS\nexus\Purchase
* @param \IPS\nexus\Purchase $purchase Purchase to associate
* @return void
*/
public function set_purchase( \IPS\nexus\Purchase $purchase = NULL )
@@ -238,7 +243,7 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
/**
* Set purchase
*
* @param \IPS\nexus\Support\Status
* @param \IPS\nexus\Support\Status $status Status to set
* @return void
*/
public function set_status( Status $status )
@@ -259,7 +264,7 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
/**
* Set severity
*
* @param \IPS\nexus\Support\Severity
* @param \IPS\nexus\Support\Severity $severity Severity to set
* @return void
*/
public function set_severity( Severity $severity )
@@ -270,7 +275,7 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
/**
* Set last reply by
*
* @param int $lastReplyBy
* @param int $lastReplyBy Last reply author
* @return void
*/
public function set_last_reply_by( $lastReplyBy )
@@ -371,7 +376,7 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
/**
* Set PPI invoice
*
* @param \IPS\nexus\Invoice|NULL
* @param \IPS\nexus\Invoice|NULL $invoice Invoice to set for PPI
* @return void
*/
public function set_ppi_invoice( \IPS\nexus\Invoice $invoice = NULL )
@@ -423,7 +428,7 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
$purchaseWhere[] = "ps_id={$id}";
}
}
if ( count( $purchaseWhere ) )
if ( \count( $purchaseWhere ) )
{
$purchaseWhere = array( array( "( ps_member={$account->member_id} OR ( " . implode( ' OR ', $purchaseWhere ) . ' ) )' ) );
}
@@ -444,7 +449,7 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
$doNotShowPurchasesForDepartments = array();
foreach ( Department::roots( NULL, NULL, 'dpt_open=1' ) as $department )
{
if ( !\IPS\nexus\Customer::loggedIn()->member_id or !count( \IPS\Db::i()->select( '*', 'nexus_purchases', array_merge( $purchaseWhere, array( array( 'ps_app=? AND ps_type=?', 'nexus', 'package' ) ), array( \IPS\Db::i()->in( 'ps_item_id', explode( ',', $department->packages ) ) ) ) ) ) )
if ( !\IPS\nexus\Customer::loggedIn()->member_id or !\count( \IPS\Db::i()->select( '*', 'nexus_purchases', array_merge( $purchaseWhere, array( array( 'ps_app=? AND ps_type=?', 'nexus', 'package' ) ), array( \IPS\Db::i()->in( 'ps_item_id', explode( ',', $department->packages ) ) ) ) ) ) )
{
if ( $department->require_package )
{
@@ -463,7 +468,7 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
{
foreach ( Department::roots( NULL, NULL, 'dpt_open=1' ) as $department )
{
if ( !\IPS\nexus\Customer::loggedIn()->member_id or !count( \IPS\Db::i()->select( '*', 'nexus_purchases', array_merge( $purchaseWhere, array(array('ps_app=? AND ps_type=?', 'nexus', 'subscription')), array(\IPS\Db::i()->in( 'ps_item_id', explode( ',', $department->subscriptions ) ) ) ) ) ) )
if ( !\IPS\nexus\Customer::loggedIn()->member_id or !\count( \IPS\Db::i()->select( '*', 'nexus_purchases', array_merge( $purchaseWhere, array(array('ps_app=? AND ps_type=?', 'nexus', 'subscription')), array(\IPS\Db::i()->in( 'ps_item_id', explode( ',', $department->subscriptions ) ) ) ) ) ) )
{
if ( $department->require_package )
{
@@ -479,7 +484,7 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
}
}
if ( !count( $availableDepartments ) )
if ( !\count( $availableDepartments ) )
{
\IPS\Output::i()->error( \IPS\nexus\Customer::loggedIn()->member_id ? 'no_module_permission' : 'no_module_permission_guest', '1X248/1', 403, 'no_support_departments' );
}
@@ -487,21 +492,36 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
/* What custom fields need to be triggered by departments? */
$customFields = \IPS\nexus\Support\CustomField::roots( NULL, NULL, "sf_departments='*' OR " . \IPS\Db::i()->findInSet( 'sf_departments', array_keys( $availableDepartments ) ) );
/* Closure to reduce duplication */
$assignToggle = function( $departmentId, $fieldId ) use ( &$departmentToggles )
{
if ( !isset( $departmentToggles[ $departmentId ] ) )
{
$departmentToggles[ $departmentId ] = array();
}
$departmentToggles[ $departmentId ][] = "nexus_cfield_{$fieldId}";
};
/* Cycle custom fields and add relevant toggles */
foreach ( $customFields as $field )
{
if ( $field->departments and $field->departments !== '*' )
{
foreach ( explode( ',', $field->departments ) as $departmentId )
{
if ( !isset( $departmentToggles[ $departmentId ] ) )
{
$departmentToggles[ $departmentId ] = array();
}
$departmentToggles[ $departmentId ][] = "nexus_cfield_{$field->id}";
$assignToggle( $departmentId, $field->id );
}
}
elseif( $field->departments === '*' )
{
foreach ( $availableDepartments as $department )
{
$assignToggle( $department->id, $field->id );
}
}
}
/* What purchase fields need to be triggered by departments? */
$departments = array();
$purchaseFields = array();
@@ -524,11 +544,48 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
$content->error = NULL;
}
$ppiDepartments[] = $department->id;
foreach ( $customFields as $field )
{
/* PPI Departments - Remove any custom fields from PPI departments */
if ( ( $fieldId = array_search( "nexus_cfield_{$field->id}", $departmentToggles[ $department->id ] ) ) !== FALSE )
{
/* If this field belongs only to this one paid department, we can just remove it from the custom fields array to prevent that it's going to be shown in all departments */
$fieldDepartments = explode( ',', $field->departments );
if ( \count( $fieldDepartments ) == 1 )
{
unset( $customFields[$field->id]);
}
else if ( \count( $fieldDepartments ) > 1 )
{
$hasFree = FALSE;
foreach ( $fieldDepartments as $fieldDepartment )
{
try
{
if ( !\IPS\nexus\Support\Department::load( $fieldDepartment )->ppiCost() )
{
$hasFree = TRUE;
}
}
catch( \OutOfRangeException $e ) {}
if ( !$hasFree )
{
unset( $customFields[$field->id]);
}
}
}
unset( $departmentToggles[ $department->id ][ $fieldId ] );
}
}
}
else
{
$departmentToggles[ $department->id ][] = static::$formLangPrefix . 'content_editor';
if ( $department->packages and !in_array( $department->id, $doNotShowPurchasesForDepartments ) )
if ( $department->packages and !\in_array( $department->id, $doNotShowPurchasesForDepartments ) )
{
$allowedPackageIds = explode( ',', $department->packages );
$allowedSubscriptionIds = explode( ',', $department->subscriptions );
@@ -538,7 +595,7 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
{
$field = new \IPS\Helpers\Form\Node(
'support_purchase_' . $allowedPackages,
isset( \IPS\Request::i()->purchase ) ? intval( \IPS\Request::i()->purchase ) : NULL,
isset( \IPS\Request::i()->purchase ) ? \intval( \IPS\Request::i()->purchase ) : NULL,
TRUE,
array(
'class' => 'IPS\nexus\Purchase',
@@ -546,8 +603,8 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
'permissionCheck' => function( $node ) use ( $allowedPackageIds, $allowedSubscriptionIds )
{
return (
( $node->active and $node->app === 'nexus' and ( $node->type === 'package' and in_array( $node->item_id, $allowedPackageIds ) ) )
or ( $node->active and $node->app === 'nexus' and ( $node->type === 'subscription' and in_array( $node->item_id, $allowedSubscriptionIds ) ) )
( $node->active and $node->app === 'nexus' and ( $node->type === 'package' and \in_array( $node->item_id, $allowedPackageIds ) ) )
or ( $node->active and $node->app === 'nexus' and ( $node->type === 'subscription' and \in_array( $node->item_id, $allowedSubscriptionIds ) ) )
);
},
'forceOwner' => FALSE,
@@ -555,7 +612,7 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
),
$department->require_package ? function( $val ) use ( $allowedPackages, $departmentToggles )
{
if ( !$val and isset( $departmentToggles[ \IPS\Request::i()->support_department ] ) and in_array( 'support_purchase_' . $allowedPackages, $departmentToggles[ \IPS\Request::i()->support_department ] ) )
if ( !$val and isset( $departmentToggles[ \IPS\Request::i()->support_department ] ) and \in_array( 'support_purchase_' . $allowedPackages, $departmentToggles[ \IPS\Request::i()->support_department ] ) )
{
throw new \DomainException('support_purchase_required');
}
@@ -578,7 +635,7 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
$defaultSeverityId = Severity::load( TRUE, 'sev_default' )->id;
foreach ( $availableDepartments as $department )
{
if ( count( $department->availableSeverities() ) > 1 )
if ( \count( $department->availableSeverities() ) > 1 )
{
$serialized = "severity_{$department->serializedSeverityIds()}";
@@ -590,7 +647,7 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
$options[ $severity->id ] = "nexus_severity_{$severity->id}";
}
$field = new \IPS\Helpers\Form\Radio( 'support_' . $serialized, in_array( $defaultSeverityId, array_keys( $options ) ) ? $defaultSeverityId : NULL, FALSE, array( 'options' => $options ), NULL, NULL, NULL, 'support_' . $serialized );
$field = new \IPS\Helpers\Form\Radio( 'support_' . $serialized, \in_array( $defaultSeverityId, array_keys( $options ) ) ? $defaultSeverityId : NULL, FALSE, array( 'options' => $options ), NULL, NULL, NULL, 'support_' . $serialized );
$field->label = \IPS\Member::loggedIn()->language()->addToStack('support_severity');
$severityFields[ $serialized ] = $field;
}
@@ -603,9 +660,10 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
}
}
}
/* Add department */
if ( !empty( $ppiDepartments ) and count( $departments ) == count( $ppiDepartments ) )
if ( !empty( $ppiDepartments ) and \count( $departments ) == \count( $ppiDepartments ) )
{
$departmentFieldOptions = array( 'options' => array_merge( array( 0 => 'support_department' ), $departments ), 'toggles' => array_merge( array( 0 => array( static::$formLangPrefix . 'content_editor' ) ), $departmentToggles ), 'disabled' => array( 0 ) );
}
@@ -613,7 +671,7 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
{
$departmentFieldOptions = array( 'options' => $departments, 'toggles' => $departmentToggles );
}
$return['department'] = new \IPS\Helpers\Form\Select( 'support_department', isset( \IPS\Request::i()->department ) ? intval( \IPS\Request::i()->department ) : NULL, TRUE, $departmentFieldOptions );
$return['department'] = new \IPS\Helpers\Form\Select( 'support_department', isset( \IPS\Request::i()->department ) ? \intval( \IPS\Request::i()->department ) : NULL, TRUE, $departmentFieldOptions );
foreach ( $availableDepartments as $department )
{
if ( \IPS\Member::loggedIn()->language()->checkKeyExists("nexus_department_{$department->id}_desc") )
@@ -627,7 +685,7 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
/* Purchase */
$return = array_merge( $return, $purchaseFields );
/* Custom Fields */
foreach ( $customFields as $field )
{
@@ -635,14 +693,24 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
if ( $field->required )
{
$validation = function( $val ) use ( $field, $departmentToggles ) {
if ( $val === '' and ( !isset( \IPS\Request::i()->support_department ) or in_array( "nexus_cfield_{$field->id}", $departmentToggles[ \IPS\Request::i()->support_department ] ) ) )
if ( !$val and ( !isset( \IPS\Request::i()->support_department ) or \in_array( "nexus_cfield_{$field->id}", $departmentToggles[ \IPS\Request::i()->support_department ] ) ) )
{
throw new \DomainException('form_required');
}
};
}
$helper = $field->buildHelper( NULL, $validation );
if ( $field->type === 'Editor' )
{
$attachIds = array( NULL, NULL, NULL );
if ( $item )
{
$attachIds = array( $item->id, $field->id, 'fields' );
}
$field::$editorOptions = array_merge( $field::$editorOptions, array( 'attachIds' => $attachIds ) );
}
$return[] = $field->buildHelper( NULL, $validation );
$return[] = $helper;
}
/* Return */
@@ -729,7 +797,7 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
else
{
$availableSeverities = $department->availableSeverities();
if ( count( $availableSeverities ) === 1 )
if ( \count( $availableSeverities ) === 1 )
{
$this->severity = array_pop( $availableSeverities );
}
@@ -780,6 +848,16 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
{
$cfields[ $k ] = $class::stringValue( $v );
}
if ( $customFieldObjects[ $k ]->type === 'Editor' )
{
$idColumn = static::$databaseColumnId;
if ( !$this->$idColumn )
{
$this->save();
}
$customFieldObjects[ $k ]->claimAttachments( $this->$idColumn, 'fields' );
}
}
}
$this->cfields = $cfields;
@@ -802,7 +880,7 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
/**
* Log that the request was created
*
* @param \IPS\nexus\Support\Reply The first message
* @param \IPS\nexus\Support\Reply $reply The first message
* @return void
*/
public function afterCreateLog( $reply )
@@ -869,12 +947,12 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
$order = isset( \IPS\Request::i()->order ) ? \IPS\Request::i()->order : ( isset( \IPS\Request::i()->cookie['support_replies_order'] ) ? \IPS\Request::i()->cookie['support_replies_order'] : 'desc' );
if ( $order === 'asc' )
{
$lastPageUrl = $lastPageUrl->setQueryString( 'page', $this->commentPageCount() );
$lastPageUrl = $lastPageUrl->setPage( 'page', $this->commentPageCount() );
}
if ( $pending )
{
$lastPageUrl = $lastPageUrl->setQueryString( 'pending', 1 );
if ( is_array( $pending ) )
if ( \is_array( $pending ) )
{
$lastPageUrl = $lastPageUrl->setQueryString( $pending );
}
@@ -952,7 +1030,7 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
$this->_staffFormRedirect( FALSE, TRUE );
}
}
return $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'support', 'nexus' ) ), 'noteForm' ), $this );
return $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'support', 'nexus' ), 'noteForm' ), $this );
}
/**
@@ -986,13 +1064,14 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
{
$defaultContent = \IPS\Db::i()->select( 'content', 'nexus_support_staff_preferences', array( 'staff_id=?', \IPS\Member::loggedIn()->member_id ) )->first();
$defaultContent = str_replace(
array( '{customer_first_name}', '{customer_last_name}', '{customer_full_name}', '{department_name}', '{department_email}' ),
array( '{customer_first_name}', '{customer_last_name}', '{customer_full_name}', '{department_name}', '{department_email}', '{default_content}' ),
array(
( $this->supportAuthor() instanceof \IPS\nexus\Support\Author\Member ) ? \IPS\nexus\Customer::load( $this->author()->member_id )->cm_first_name : '',
( $this->supportAuthor() instanceof \IPS\nexus\Support\Author\Member ) ? \IPS\nexus\Customer::load( $this->author()->member_id )->cm_last_name : '',
$this->supportAuthor()->name(),
$this->department->_title,
$this->department->email
$this->department->email,
'<br>'
),
$defaultContent
);
@@ -1003,7 +1082,7 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
}
/* Attributes */
if ( count( \IPS\nexus\Support\StockAction::roots() ) )
if ( \count( \IPS\nexus\Support\StockAction::roots() ) )
{
$form->add( new \IPS\Helpers\Form\Select( 'stock_action', NULL, FALSE, array( 'options' => $stockActions ), NULL, NULL, NULL, 'stock_action' ) );
}
@@ -1114,7 +1193,7 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
}
/* Display */
return $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'support', 'nexus' ) ), 'staffReplyForm' ), $this );
return $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'support', 'nexus' ), 'staffReplyForm' ), $this );
}
/**
@@ -1185,7 +1264,7 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
$alternativeContactWhere[] = '( r_member=' . $contact->main_id->member_id . ' AND ' . \IPS\Db::i()->in( 'r_purchase', $contact->purchaseIds() ) . ' )';
}
}
if ( count( $alternativeContactWhere ) )
if ( \count( $alternativeContactWhere ) )
{
$extraClause[0] = '( ' . $extraClause[0] . ' OR ( ' . implode( ' OR ', $alternativeContactWhere ) . ' ) )';
}
@@ -1264,19 +1343,30 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
}
/* Staff */
elseif ( ( !\IPS\Dispatcher::hasInstance() or \IPS\Dispatcher::i()->controllerLocation === 'admin' ) and $member->isAdmin() and ( $this->department->staff === '*' or count( array_intersect( explode( ',', $this->department->staff ), Department::staffDepartmentPerms( $member ) ) ) ) )
elseif ( ( !\IPS\Dispatcher::hasInstance() or \IPS\Dispatcher::i()->controllerLocation === 'admin' ) and $member->isAdmin() and ( $this->department->staff === '*' or \count( array_intersect( explode( ',', $this->department->staff ), Department::staffDepartmentPerms( $member ) ) ) ) )
{
return TRUE;
}
/* Altcontact */
elseif ( in_array( $this->author()->member_id, array_keys( iterator_to_array( $member->parentContacts( $this->purchase ? array( '( support=1 OR ' . \IPS\Db::i()->findInSet( 'purchases', array( $this->purchase->id ) ) . ' )' ) : array( 'support=1' ) ) ) ) ) )
elseif ( \in_array( $this->author()->member_id, array_keys( iterator_to_array( $member->parentContacts( $this->purchase ? array( '( support=1 OR ' . \IPS\Db::i()->findInSet( 'purchases', array( $this->purchase->id ) ) . ' )' ) : array( 'support=1' ) ) ) ) ) )
{
return TRUE;
}
return FALSE;
}
/**
* Can Merge?
*
* @param \IPS\Member|NULL $member The member to check for (NULL for currently logged in member)
* @return bool
*/
public function canMerge( $member=NULL )
{
return FALSE;
}
/**
* Can view hidden comments on this item?
@@ -1294,7 +1384,7 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
$return = parent::canViewHiddenComments( $member );
/* Is the member a staff member with access to this department? They may not be a moderator on the front-end, so the parent method will return false */
if ( $return === FALSE and ( !\IPS\Dispatcher::hasInstance() or \IPS\Dispatcher::i()->controllerLocation === 'admin' ) and $member->isAdmin() and ( $this->department->staff === '*' or count( array_intersect( explode( ',', $this->department->staff ), Department::staffDepartmentPerms( $member ) ) ) ) )
if ( $return === FALSE and ( !\IPS\Dispatcher::hasInstance() or \IPS\Dispatcher::i()->controllerLocation === 'admin' ) and $member->isAdmin() and ( $this->department->staff === '*' or \count( array_intersect( explode( ',', $this->department->staff ), Department::staffDepartmentPerms( $member ) ) ) ) )
{
$return = TRUE;
}
@@ -1306,12 +1396,13 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
/**
* Can comment?
*
* @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 canComment( $member=NULL )
public function canComment( $member=NULL, $considerPostBeforeRegistering = TRUE )
{
return parent::canComment( $member ) and !$this->status->is_locked;
return parent::canComment( $member, $considerPostBeforeRegistering ) and !$this->status->is_locked;
}
/**
@@ -1361,10 +1452,11 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
/**
* Should new comments 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 moderateNewComments( \IPS\Member $member )
public function moderateNewComments( \IPS\Member $member, $considerPostBeforeRegistering = FALSE )
{
return FALSE; // Even if the member is on mod queue, that doesn't apply to support requests
}
@@ -1418,11 +1510,11 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
foreach ( \IPS\Db::i()->select( 'staff_id', 'nexus_support_notify', array( array( 'type=?', 'n' ), array( "(departments='*' OR " . \IPS\Db::i()->findInSet( 'departments', array( $this->department->id ) ) . ')' ) ) ) as $staffId )
{
if ( in_array( $staffId, $staffIds ) )
if ( \in_array( $staffId, $staffIds ) )
{
$member = \IPS\Member::load( $staffId );
if ( $this->department->staff === '*' or count( array_intersect( \IPS\nexus\Support\Department::staffDepartmentPerms( $member ), explode( ',', $this->department->staff ) ) ) )
if ( $this->department->staff === '*' or \count( array_intersect( \IPS\nexus\Support\Department::staffDepartmentPerms( $member ), explode( ',', $this->department->staff ) ) ) )
{
$fromEmail = ( $this->department->email ) ? $this->department->email : \IPS\Settings::i()->email_out;
switch ( \IPS\Settings::i()->nexus_sout_from )
@@ -1448,6 +1540,8 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
\IPS\Db::i()->delete( 'nexus_support_notify', array( 'staff_id=?', $staffId ) );
}
}
\IPS\core\AdminNotification::send( 'nexus', 'Support', NULL, TRUE, NULL, TRUE );
}
/* !Other */
@@ -1610,7 +1704,7 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
*/
public function nextPrevious( $type=0, $excludeAssignedToOther=FALSE )
{
if ( !array_key_exists( intval( $type ), $this->nextPrevious ) )
if ( !array_key_exists( \intval( $type ), $this->nextPrevious ) )
{
/* Get out stream */
$stream = \IPS\nexus\Support\Stream::myStream();
@@ -1621,8 +1715,8 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
}
/* And figure out our order */
$sortBy = ( isset( \IPS\Request::i()->cookie['support_sort'] ) and in_array( \IPS\Request::i()->cookie['support_sort'], array( 'r_started', 'r_last_new_reply', 'r_last_reply', 'r_last_staff_reply' ) ) ) ? \IPS\Request::i()->cookie['support_sort'] : 'r_last_new_reply';
$sortDir = ( isset( \IPS\Request::i()->cookie['support_order'] ) and in_array( \IPS\Request::i()->cookie['support_order'], array( 'ASC', 'DESC' ) ) ) ? \IPS\Request::i()->cookie['support_order'] : 'ASC';
$sortBy = ( isset( \IPS\Request::i()->cookie['support_sort'] ) and \in_array( \IPS\Request::i()->cookie['support_sort'], array( 'r_started', 'r_last_new_reply', 'r_last_reply', 'r_last_staff_reply' ) ) ) ? \IPS\Request::i()->cookie['support_sort'] : 'r_last_new_reply';
$sortDir = ( isset( \IPS\Request::i()->cookie['support_order'] ) and \in_array( \IPS\Request::i()->cookie['support_order'], array( 'ASC', 'DESC' ) ) ) ? \IPS\Request::i()->cookie['support_order'] : 'ASC';
if ( $type == 1 )
{
$sortDir = ( $sortDir === 'ASC' ) ? 'DESC' : 'ASC';
@@ -1679,16 +1773,16 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
$result = $query->first();
}
$this->nextPrevious[ intval( $type ) ] = \IPS\nexus\Support\Request::constructFromData( $result );
return $this->nextPrevious[ intval( $type ) ];
$this->nextPrevious[ \intval( $type ) ] = \IPS\nexus\Support\Request::constructFromData( $result );
return $this->nextPrevious[ \intval( $type ) ];
}
catch ( \UnderflowException $e ) { }
/* If we're still here and we were after the first in the list, we can go no further */
if ( $type == 2 )
{
$this->nextPrevious[ intval( $type ) ] = NULL;
return $this->nextPrevious[ intval( $type ) ];
$this->nextPrevious[ \intval( $type ) ] = NULL;
return $this->nextPrevious[ \intval( $type ) ];
}
/* Still here? Try with the next/previous severity */
@@ -1702,8 +1796,8 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
try
{
$result = \IPS\Db::i()->select( '*', 'nexus_support_requests', $whereClause, "{$sortBy} {$sortDir}" )->first();
$this->nextPrevious[ intval( $type ) ] = \IPS\nexus\Support\Request::constructFromData( $result );
return $this->nextPrevious[ intval( $type ) ];
$this->nextPrevious[ \intval( $type ) ] = \IPS\nexus\Support\Request::constructFromData( $result );
return $this->nextPrevious[ \intval( $type ) ];
}
catch ( \UnderflowException $e ) { }
}
@@ -1727,18 +1821,18 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
{
$result = \IPS\Db::i()->select( '*', 'nexus_support_requests', $whereClause, "sev_position " . ( $type == 1 ? 'DESC' : 'ASC' ) . ", {$sortBy} {$sortDir}" )
->join( 'nexus_support_severities', 'sev_id=r_severity' )->first();
$this->nextPrevious[ intval( $type ) ] = \IPS\nexus\Support\Request::constructFromData( $result );
return $this->nextPrevious[ intval( $type ) ];
$this->nextPrevious[ \intval( $type ) ] = \IPS\nexus\Support\Request::constructFromData( $result );
return $this->nextPrevious[ \intval( $type ) ];
}
catch ( \UnderflowException $e ) { }
}
}
/* Still here? We got nothing */
$this->nextPrevious[ intval( $type ) ] = NULL;
return $this->nextPrevious[ intval( $type ) ];
$this->nextPrevious[ \intval( $type ) ] = NULL;
return $this->nextPrevious[ \intval( $type ) ];
}
return $this->nextPrevious[ intval( $type ) ];
return $this->nextPrevious[ \intval( $type ) ];
}
/**
@@ -1747,10 +1841,7 @@ class _Request extends \IPS\Content\Item implements \IPS\Content\ReadMarkers
* @param string $action What changed
* @param mixed $old Old value
* @param mixed $new New value
* @param \IPS\Member|NULL|FALSE The member
* FALSE if there is no member
* NULL to use currently logged in member
*
* @param \IPS\Member|NULL|FALSE $member The member (FALSE if there is no member, NULL to use currently logged in member )
* @return void
*/
public function log( $action, $old, $new, $member = NULL )
@@ -12,7 +12,7 @@
namespace IPS\nexus\Support;
/* 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;
@@ -12,7 +12,7 @@
namespace IPS\nexus\Support;
/* 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;
@@ -242,7 +242,7 @@ class _Status extends \IPS\Node\Model
{
foreach ( array( 'member', 'staff' ) as $k )
{
if ( isset( $values[ "status_{$k}" ] ) and in_array( $k, $values[ "status_{$k}" ] ) )
if ( isset( $values[ "status_{$k}" ] ) and \in_array( $k, $values[ "status_{$k}" ] ) )
{
$values["default_{$k}"] = TRUE;
\IPS\Db::i()->update( 'nexus_support_statuses', array( 'default_member' => 0 ) );
@@ -256,12 +256,12 @@ class _Status extends \IPS\Node\Model
if( isset( $values['status_default'] ) )
{
if ( in_array( 'member', $values['status_default'] ) )
if ( \in_array( 'member', $values['status_default'] ) )
{
$this->default_member = TRUE;
\IPS\Db::i()->update( 'nexus_support_statuses', array( 'status_default_member' => 0 ) );
}
if ( in_array( 'staff', $values['status_default'] ) )
if ( \in_array( 'staff', $values['status_default'] ) )
{
$this->default_staff = TRUE;
\IPS\Db::i()->update( 'nexus_support_statuses', array( 'status_default_staff' => 0 ) );
@@ -12,7 +12,7 @@
namespace IPS\nexus\Support;
/* 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;
@@ -182,7 +182,7 @@ class _StockAction extends \IPS\Node\Model
$form->add( new \IPS\Helpers\Form\Translatable( 'action_name', NULL, TRUE, array( 'app' => 'nexus', 'key' => ( $this->id ? "nexus_stockaction_{$this->id}" : NULL ) ) ) );
$form->add( new \IPS\Helpers\Form\Node( 'action_status', $this->status ?: 0, FALSE, array( 'class' => 'IPS\nexus\Support\Status', 'zeroVal' => 'do_not_change' ) ) );
$form->add( new \IPS\Helpers\Form\Node( 'action_department', $this->department ?: 0, FALSE, array( 'class' => 'IPS\nexus\Support\Department', 'zeroVal' => 'do_not_move' ) ) );
$form->add( new \IPS\Helpers\Form\Select( 'action_staff', $this->staff ? $this->staff->member_id : 0, FALSE, array( 'parse' => 'normal', 'options' => array_merge( array( 0 => 'do_not_change' ), \IPS\nexus\Support\Request::staff() ) ) ) );
$form->add( new \IPS\Helpers\Form\Select( 'action_staff', $this->staff ? $this->staff->member_id : 0, FALSE, array( 'parse' => 'normal', 'options' => array_merge( array( 0 => \IPS\Member::loggedIn()->language()->addToStack( 'do_not_change' ) ), \IPS\nexus\Support\Request::staff() ) ) ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'action_message_on', $this->message, FALSE, array( 'togglesOn' => array( 'action_message_editor' ) ) ) );
$form->add( new \IPS\Helpers\Form\Editor( 'action_message', $this->message, FALSE, array( 'app' => 'nexus', 'key' => 'Support', 'autoSaveKey' => md5( 'stockaction-' . ( $this->id ?: 'new' ) ) ), NULL, NULL, NULL, 'action_message_editor' ) );
$form->add( new \IPS\Helpers\Form\Node( 'action_show_in', ( !$this->show_in or $this->show_in === '*' ) ? 0 : explode( ',', $this->show_in ), FALSE, array( 'class' => 'IPS\nexus\Support\Department', 'zeroVal' => 'all', 'multiple' => TRUE ) ) );
+47 -20
View File
@@ -12,7 +12,7 @@
namespace IPS\nexus\Support;
/* 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;
@@ -69,7 +69,7 @@ class _Stream extends \IPS\Patterns\ActiveRecord
/**
* Get my stream
*
* @return \IPS\nexus\Support\Stream
* @return static
*/
public static function myStream()
{
@@ -88,7 +88,9 @@ class _Stream extends \IPS\Patterns\ActiveRecord
/**
* Load
*
* @param mixed $keyOrId The key or ID number
* @param mixed $id The key or ID number
* @param string|NULL $idField The field to search `$id` in
* @param mixed $extraWhereClause Extra where clause or NULL
* @return \IPS\nexus\Support\Stream
*/
public static function load( $id, $idField=NULL, $extraWhereClause=NULL )
@@ -155,12 +157,12 @@ class _Stream extends \IPS\Patterns\ActiveRecord
* Customer Stream
*
* @param \IPS\nexus\Customer $customer The customer
* @return \IPS\nexus\Support\Stream
* @return static
*/
public static function customer( \IPS\nexus\Customer $customer )
{
$return = new static;
$return->title = sprintf( \IPS\Member::loggedIn()->language()->get( 'members_support_requests' ), $customer->cm_name );
$return->title = sprintf( \IPS\Member::loggedIn()->language()->get( 'members_support_requests' ), $customer->member_id ? $customer->cm_name : $customer->email );
$return->departments = NULL;
$return->statuses = NULL;
$return->severities = NULL;
@@ -179,7 +181,7 @@ class _Stream extends \IPS\Patterns\ActiveRecord
* Create from form
*
* @param array $values Values from the form
* @return \IPS\nexus\Support\Stream
* @return static
*/
public static function createFromForm( $values )
{
@@ -200,16 +202,25 @@ class _Stream extends \IPS\Patterns\ActiveRecord
*/
public function updateFromForm( $values )
{
foreach ( array( 'r_started', 'r_last_new_reply', 'r_last_reply', 'r_last_staff_reply' ) as $k )
{
if ( \is_array( $values[ $k ] ) and isset( $values[ $k ][2] ) and $values[ $k ][2] != 'h' )
{
$values[ $k ][1] = \IPS\Helpers\Form\Interval::convertValue( $values[ $k ][1], $values[ $k ][2], \IPS\Helpers\Form\Interval::HOURS );
unset( $values[ $k ][2] );
}
}
$this->departments = $values['r_department'] ?: NULL;
$this->statuses = $values['r_status'] ?: NULL;
$this->severities = $values['r_severity'] ?: NULL;
$this->staff = $values['r_staff'] ?: NULL;
$this->from_email = $values['r_email'] ?: NULL;
$this->search_term = $values['r_search'] ?: NULL;
$this->started = $values['r_started'] ?: NULL;
$this->last_new_reply = $values['r_last_new_reply'] ?: NULL;
$this->last_reply = $values['r_last_reply'] ?: NULL;
$this->last_staff_reply = $values['r_last_staff_reply'] ?: NULL;
$this->started = $values['r_started'][1] ? json_encode($values['r_started']): NULL;
$this->last_new_reply = $values['r_last_new_reply'][1] ? json_encode($values['r_last_new_reply']): NULL;
$this->last_reply = $values['r_last_reply'][1] ? json_encode($values['r_last_reply']): NULL;
$this->last_staff_reply = $values['r_last_staff_reply'][1] ? json_encode($values['r_last_staff_reply']): NULL;
$this->tracked = (bool) $values['r_tracked'];
}
@@ -223,7 +234,7 @@ class _Stream extends \IPS\Patterns\ActiveRecord
{
$return = parent::__get( $key );
if ( $return !== NULL and in_array( $key, array( 'departments', 'statuses', 'severities', 'staff' ) ) and $return !== 'me' )
if ( $return !== NULL and \in_array( $key, array( 'departments', 'statuses', 'severities', 'staff' ) ) and $return !== 'me' )
{
$return = explode( ',', $return );
}
@@ -241,7 +252,7 @@ class _Stream extends \IPS\Patterns\ActiveRecord
*/
public function __set( $key, $value )
{
if ( is_array( $value ) and in_array( $key, array( 'departments', 'statuses', 'severities', 'staff' ) ) )
if ( \is_array( $value ) and \in_array( $key, array( 'departments', 'statuses', 'severities', 'staff' ) ) )
{
$value = implode( ',', $value );
}
@@ -265,7 +276,7 @@ class _Stream extends \IPS\Patterns\ActiveRecord
/* Streams */
$form->addTab('streams');
$form->add( new \IPS\Helpers\Form\Custom( 'stream', $selectedStream ? $selectedStream->id : 'custom', FALSE, array(
'getHtml' => function( $input ) {
'getHtml' => function( $input ) {
return \IPS\Theme::i()->getTemplate('support')->filterFormStream( $input, \IPS\nexus\Support\Stream::myStreams( \IPS\Member::loggedIn() ) );
}
) ) );
@@ -322,10 +333,11 @@ class _Stream extends \IPS\Patterns\ActiveRecord
return \IPS\Theme::i()->getTemplate('support')->filterFormTime( $input );
}
);
$form->add( new \IPS\Helpers\Form\Custom( 'r_started', $this->started, FALSE, $timeFrameOptions ) );
$form->add( new \IPS\Helpers\Form\Custom( 'r_last_new_reply', $this->last_new_reply, FALSE, $timeFrameOptions ) );
$form->add( new \IPS\Helpers\Form\Custom( 'r_last_reply', $this->last_reply, FALSE, $timeFrameOptions ) );
$form->add( new \IPS\Helpers\Form\Custom( 'r_last_staff_reply', $this->last_staff_reply, FALSE, $timeFrameOptions ) );
$form->add( new \IPS\Helpers\Form\Custom( 'r_started', \is_int( $this->started ) ? array( 0 => '<', 1 => $this->started ) : json_decode( $this->started ), FALSE, $timeFrameOptions ) );
$form->add( new \IPS\Helpers\Form\Custom( 'r_last_new_reply', \is_int( $this->last_new_reply ) ? array( 0 => '<', 1 => $this->last_new_reply ) : json_decode( $this->last_new_reply ), FALSE, $timeFrameOptions ) );
$form->add( new \IPS\Helpers\Form\Custom( 'r_last_reply', \is_int( $this->last_reply ) ? array( 0 => '<', 1 => $this->last_reply ) : json_decode( $this->last_reply ), FALSE, $timeFrameOptions ) );
$form->add( new \IPS\Helpers\Form\Custom( 'r_last_staff_reply', \is_int( $this->last_staff_reply ) ? array( 0 => '<', 1 => $this->last_staff_reply ) : json_decode( $this->last_staff_reply ), FALSE, $timeFrameOptions ) );
/* Return */
return $form;
@@ -421,7 +433,19 @@ class _Stream extends \IPS\Patterns\ActiveRecord
{
if ( $this->$k )
{
$where[] = array( "r_{$k}<?", time() - ( 3600 * $this->$k ) );
if ( \is_int( $this->$k ) )
{
$operand = $this->$k;
$operator = '<';
}
else
{
$limit = json_decode( $this->$k );
// This looks backwards, but if we say "greater than 5 days" we want to know if the date is less than the resulting timestamp
$operator = ( $limit[0] == 'gt' ) ? '<' : '>';
$operand = $limit[1];
}
$where[] = array( "r_{$k}{$operator}?", time() - ( 3600 * $operand ) );
}
}
@@ -433,7 +457,7 @@ class _Stream extends \IPS\Patterns\ActiveRecord
* Get count
*
* @param $member Staff member, or NULL for no permission restriction
* @return \IPS\Patterns\ActiveRecordIterator
* @return int
*/
public function count( $member = NULL )
{
@@ -443,7 +467,10 @@ class _Stream extends \IPS\Patterns\ActiveRecord
/**
* Get results
*
* @param $member Staff member, or NULL for no permission restriction
* @param \IPS\Member|NULL $member Staff member, or NULL for no permission restriction
* @param string $order Order by clause
* @param int $page Page number
* @param int $perPage Number of results per page
* @return \IPS\Patterns\ActiveRecordIterator
*/
public function results( $member = NULL, $order='r_id DESC', $page = 1, $perPage = 25 )