Version 4.0.13.1
This commit is contained in:
1 parent
f9e857d255
commit
c6a86f0d9b
7517 files changed
+597400
-668041
No files matched your search
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Support Author Model - Email
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Nexus
|
||||
* @since 15 Apr 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\Support\Author;
|
||||
|
||||
/* 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 Author Model - Email
|
||||
*/
|
||||
class _Email
|
||||
{
|
||||
/**
|
||||
* @brief Email Address
|
||||
*/
|
||||
protected $email;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $email Email address
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( $email )
|
||||
{
|
||||
$this->email = $email;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function name()
|
||||
{
|
||||
return $this->email;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get photo
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
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 \IPS\Theme::i()->resource( 'default_photo.png', 'core', 'global' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get email
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function email()
|
||||
{
|
||||
return $this->email;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get url
|
||||
*
|
||||
* @return \IPS\Http\Url
|
||||
*/
|
||||
public function url()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get meta data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function meta()
|
||||
{
|
||||
return array( 'email' => $this->email );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get latest invoices
|
||||
*
|
||||
* @return \IPS\Patterns\ActiveRecordIterator|NULL
|
||||
*/
|
||||
public function invoices( $limit=10 )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Support Requests
|
||||
*
|
||||
* @param int $limit Number to get
|
||||
* @para, \IPS\nexus\Support\Request $exclude A request to exclude
|
||||
* @param string $order Order clause
|
||||
* @return \IPS\Patterns\ActiveRecordIterator
|
||||
*/
|
||||
public function supportRequests( $limit, \IPS\nexus\Support\Request $exclude = NULL, $order='r_started DESC' )
|
||||
{
|
||||
$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', NULL, \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Support Author Model - Member
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Nexus
|
||||
* @since 10 Apr 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\Support\Author;
|
||||
|
||||
/* 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 Author Model - Member
|
||||
*/
|
||||
class _Member
|
||||
{
|
||||
/**
|
||||
* @brief Customer object
|
||||
*/
|
||||
protected $customer;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param \IPS\nexus\Customer $customer Customer object
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( \IPS\nexus\Customer $customer )
|
||||
{
|
||||
$this->customer = $customer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function name()
|
||||
{
|
||||
return $this->customer->cm_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get email
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function email()
|
||||
{
|
||||
return $this->customer->email;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get photo
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function photo()
|
||||
{
|
||||
return $this->customer->photo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get url
|
||||
*
|
||||
* @return \IPS\Http\Url
|
||||
*/
|
||||
public function url()
|
||||
{
|
||||
return $this->customer->acpUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get meta data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function meta()
|
||||
{
|
||||
return array(
|
||||
$this->customer->email,
|
||||
\IPS\Member::loggedIn()->language()->addToStack( 'transaction_customer_since', FALSE, array( 'sprintf' => array( $this->customer->joined->localeDate() ) ) ),
|
||||
\IPS\Member::loggedIn()->language()->addToStack( 'transaction_spent', FALSE, array( 'sprintf' => array( $this->customer->totalSpent() ) ) ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get nuber of notes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function noteCount()
|
||||
{
|
||||
return \IPS\Db::i()->select( 'COUNT(*)', 'nexus_notes', array( 'note_member=?', $this->customer->member_id ) )->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get latest invoices
|
||||
*
|
||||
* @return \IPS\Patterns\ActiveRecordIterator|NULL
|
||||
*/
|
||||
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' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Support Requests
|
||||
*
|
||||
* @param int $limit Number to get
|
||||
* @para, \IPS\nexus\Support\Request $exclude A request to exclude
|
||||
* @param string $order Order clause
|
||||
* @return \IPS\Patterns\ActiveRecordIterator
|
||||
*/
|
||||
public function supportRequests( $limit, \IPS\nexus\Support\Request $exclude = NULL, $order='r_started DESC' )
|
||||
{
|
||||
$where = array( array( 'r_member=?', $this->customer->member_id ) );
|
||||
if ( $exclude )
|
||||
{
|
||||
$where[] = array( 'r_id<>?', $exclude->id );
|
||||
}
|
||||
|
||||
return \IPS\nexus\Support\Request::getItemsWithPermission( $where, $order, $limit, 'read', NULL, \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS );
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,219 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Custom Support Field Node
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @since 16 Apr 2013
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom Profile Field Node
|
||||
*/
|
||||
class _CustomField extends \IPS\CustomField
|
||||
{
|
||||
/**
|
||||
* @brief [ActiveRecord] Multiton Store
|
||||
*/
|
||||
protected static $multitons;
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Table
|
||||
*/
|
||||
public static $databaseTable = 'nexus_support_fields';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Prefix
|
||||
*/
|
||||
public static $databasePrefix = 'sf_';
|
||||
|
||||
/**
|
||||
* @brief [Node] Order Database Column
|
||||
*/
|
||||
public static $databaseColumnOrder = 'position';
|
||||
|
||||
/**
|
||||
* @brief [CustomField] Title/Description lang prefix
|
||||
*/
|
||||
protected static $langKey = 'nexus_cfield';
|
||||
|
||||
/**
|
||||
* @brief [Node] ACP Restrictions
|
||||
* @code
|
||||
array(
|
||||
'app' => 'core', // The application key which holds the restrictrions
|
||||
'module' => 'foo', // The module key which holds the restrictions
|
||||
'map' => array( // [Optional] The key for each restriction - can alternatively use "prefix"
|
||||
'add' => 'foo_add',
|
||||
'edit' => 'foo_edit',
|
||||
'permissions' => 'foo_perms',
|
||||
'delete' => 'foo_delete'
|
||||
),
|
||||
'all' => 'foo_manage', // [Optional] The key to use for any restriction not provided in the map (only needed if not providing all 4)
|
||||
'prefix' => 'foo_', // [Optional] Rather than specifying each key in the map, you can specify a prefix, and it will automatically look for restrictions with the key "[prefix]_add/edit/permissions/delete"
|
||||
* @endcode
|
||||
*/
|
||||
protected static $restrictions = array(
|
||||
'app' => 'nexus',
|
||||
'module' => 'support',
|
||||
'all' => 'scfields_manage'
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief [Node] Node Title
|
||||
*/
|
||||
public static $nodeTitle = 'custom_support_fields';
|
||||
|
||||
/**
|
||||
* @brief [Node] Title prefix. If specified, will look for a language key with "{$key}_title" as the key
|
||||
*/
|
||||
public static $titleLangPrefix = 'nexus_cfield_';
|
||||
|
||||
/**
|
||||
* @brief [CustomField] Column Map
|
||||
*/
|
||||
public static $databaseColumnMap = array(
|
||||
'content' => 'extra',
|
||||
'not_null' => 'required',
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief [CustomField] Additional Field Classes
|
||||
*/
|
||||
public static $additionalFieldTypes = array(
|
||||
'UserPass' => 'sf_type_UserPass',
|
||||
'Ftp' => 'sf_type_Ftp'
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief [CustomField] Additional Field Toggles
|
||||
*/
|
||||
public static $additionalFieldToggles = array(
|
||||
'Ftp' => array( 'pf_not_null', 'sf_validate_ftp' )
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief [CustomField] Upload Field Storage Extension
|
||||
*/
|
||||
public static $uploadStorageExtension = 'nexus_Support';
|
||||
|
||||
/**
|
||||
* @brief [CustomField] Editor Options
|
||||
*/
|
||||
public static $editorOptions = array( 'app' => 'nexus', 'key' => 'Support' );
|
||||
|
||||
/**
|
||||
* Get
|
||||
*
|
||||
* @param string $key Key
|
||||
* @return mixed $value Value
|
||||
*/
|
||||
public function __get( $key )
|
||||
{
|
||||
/* Required fields aren't actually required because they may be department specific */
|
||||
if ( $key == 'not_null' )
|
||||
{
|
||||
return $this->required ? NULL : FALSE;
|
||||
}
|
||||
|
||||
return parent::__get( $key );
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Add/Edit Form
|
||||
*
|
||||
* @param \IPS\Helpers\Form $form The form
|
||||
* @return void
|
||||
*/
|
||||
public function form( &$form )
|
||||
{
|
||||
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') )
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words['sf_validate_ftp_desc'] = \IPS\Member::loggedIn()->language()->addToStack( 'sf_validate_ftp_noftp' );
|
||||
}
|
||||
elseif( !extension_loaded('ssh2') )
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words['sf_validate_ftp_warning'] = \IPS\Member::loggedIn()->language()->addToStack( 'sf_validate_ftp_nosftp' );
|
||||
}
|
||||
|
||||
unset( $form->elements[''][1] );
|
||||
unset( $form->elements['']['pf_search_type'] );
|
||||
unset( $form->elements['']['pf_format'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Format form values from add/edit form for save
|
||||
*
|
||||
* @param array $values Values from the form
|
||||
* @return array
|
||||
*/
|
||||
public function formatFormValues( $values )
|
||||
{
|
||||
if( isset( $values['sf_validate_ftp'] ) )
|
||||
{
|
||||
$values['departments'] = $values['sf_departments'] ? implode( ',', array_keys( $values['sf_departments'] ) ) : '*';
|
||||
unset( $values['sf_departments'] );
|
||||
}
|
||||
|
||||
if( isset( $values['sf_validate_ftp'] ) )
|
||||
{
|
||||
$values['validate'] = $values['sf_validate_ftp'];
|
||||
unset( $values['sf_validate_ftp'] );
|
||||
}
|
||||
|
||||
return parent::formatFormValues( $values );
|
||||
}
|
||||
|
||||
/**
|
||||
* Build Form Helper
|
||||
*
|
||||
* @param mixed $value The value
|
||||
* @param callback $customValidationCode Custom validation code
|
||||
* @return \IPS\Helpers\Form\FormAbstract
|
||||
*/
|
||||
public function buildHelper( $value=NULL, $customValidationCode=NULL )
|
||||
{
|
||||
if ( $this->type === 'UserPass' )
|
||||
{
|
||||
return new \IPS\nexus\Form\UserPass( static::$langKey . '_' . $this->id, $value, $this->not_null, array(), NULL, NULL, NULL, static::$langKey . '_' . $this->id );
|
||||
}
|
||||
elseif ( $this->type === 'Ftp' )
|
||||
{
|
||||
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 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Display Value
|
||||
*
|
||||
* @param mixed $value The value
|
||||
* @return string
|
||||
*/
|
||||
public function displayValue( $value=NULL )
|
||||
{
|
||||
if ( $this->type === 'UserPass' )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'forms', 'nexus', 'global' )->usernamePasswordDisplay( json_decode( \IPS\Text\Encrypt::fromTag( $value )->decrypt(), TRUE ) );
|
||||
}
|
||||
|
||||
return parent::displayValue( $value );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,383 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Support Department Model
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Nexus
|
||||
* @since 8 Apr 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\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 Department Model
|
||||
*/
|
||||
class _Department extends \IPS\Node\Model
|
||||
{
|
||||
/**
|
||||
* @brief [ActiveRecord] Multiton Store
|
||||
*/
|
||||
protected static $multitons;
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Table
|
||||
*/
|
||||
public static $databaseTable = 'nexus_support_departments';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Prefix
|
||||
*/
|
||||
public static $databasePrefix = 'dpt_';
|
||||
|
||||
/**
|
||||
* @brief [Node] Order Database Column
|
||||
*/
|
||||
public static $databaseColumnOrder = 'position';
|
||||
|
||||
/**
|
||||
* @brief [Node] Node Title
|
||||
*/
|
||||
public static $nodeTitle = 'departments';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database ID Fields
|
||||
*/
|
||||
protected static $databaseIdFields = array( 'dpt_email' );
|
||||
|
||||
/**
|
||||
* @brief [Node] Title prefix. If specified, will look for a language key with "{$key}_title" as the key
|
||||
*/
|
||||
public static $titleLangPrefix = 'nexus_department_';
|
||||
|
||||
/**
|
||||
* @brief [Node] ACP Restrictions
|
||||
* @code
|
||||
array(
|
||||
'app' => 'core', // The application key which holds the restrictrions
|
||||
'module' => 'foo', // The module key which holds the restrictions
|
||||
'map' => array( // [Optional] The key for each restriction - can alternatively use "prefix"
|
||||
'add' => 'foo_add',
|
||||
'edit' => 'foo_edit',
|
||||
'permissions' => 'foo_perms',
|
||||
'delete' => 'foo_delete'
|
||||
),
|
||||
'all' => 'foo_manage', // [Optional] The key to use for any restriction not provided in the map (only needed if not providing all 4)
|
||||
'prefix' => 'foo_', // [Optional] Rather than specifying each key in the map, you can specify a prefix, and it will automatically look for restrictions with the key "[prefix]_add/edit/permissions/delete"
|
||||
* @endcode
|
||||
*/
|
||||
protected static $restrictions = array(
|
||||
'app' => 'nexus',
|
||||
'module' => 'support',
|
||||
'all' => 'departments_manage'
|
||||
);
|
||||
|
||||
/**
|
||||
* Set Default Values
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setDefaultValues()
|
||||
{
|
||||
$this->ppi = json_encode( array() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the permission array used to get the departments that a staff member has access to
|
||||
*
|
||||
* @param \IPS\Member|NULL $staff The staff member
|
||||
* @return array|NULL NULL indicates all departments
|
||||
*/
|
||||
public static function staffDepartmentPerms( \IPS\Member $member = NULL )
|
||||
{
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
$return = array( "m{$member->member_id}" );
|
||||
foreach ( $member->groups as $groupId )
|
||||
{
|
||||
$return[] = "g{$groupId}";
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache for departmentsWithPermission()
|
||||
*/
|
||||
protected static $departmentsWithPermission = array();
|
||||
|
||||
/**
|
||||
* Departments that a staff member has access to
|
||||
*
|
||||
* @return \IPS\Patterns\ActiveRecordIterator
|
||||
*/
|
||||
public static function departmentsWithPermission( \IPS\Member $member = NULL )
|
||||
{
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
if ( !isset( static::$departmentsWithPermission[ $member->member_id ] ) )
|
||||
{
|
||||
static::$departmentsWithPermission[ $member->member_id ] = new \IPS\Patterns\ActiveRecordIterator(
|
||||
\IPS\Db::i()->select( '*', 'nexus_support_departments', array( "( dpt_staff='*' OR " . \IPS\Db::i()->findInSet( 'dpt_staff', \IPS\nexus\Support\Department::staffDepartmentPerms( $member ) ) . ')' ) )->setKeyField( 'dpt_id' ),
|
||||
'IPS\nexus\Support\Department'
|
||||
);
|
||||
}
|
||||
return static::$departmentsWithPermission[ $member->member_id ];
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Add/Edit Form
|
||||
*
|
||||
* @param \IPS\Helpers\Form $form The form
|
||||
* @return void
|
||||
*/
|
||||
public function form( &$form )
|
||||
{
|
||||
$form->addHeader('department_settings');
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'dpt_name', NULL, TRUE, array( 'app' => 'nexus', 'key' => ( $this->id ? "nexus_department_{$this->id}" : NULL ) ) ) );
|
||||
|
||||
/* PHP 5.3 does not allow the use of $this in anonymous functions */
|
||||
$obj = &$this;
|
||||
$form->add( new \IPS\Helpers\Form\Email( 'dpt_email', $this->email, FALSE, array( 'placeholder' => 'support@example.com' ), function ( $val ) use ( $obj )
|
||||
{
|
||||
if ( $val )
|
||||
{
|
||||
try
|
||||
{
|
||||
$other = \IPS\Db::i()->select( '*', 'nexus_support_departments', array( 'dpt_email=? AND dpt_id<>?', $val, $obj->id ?: 0 ) )->first();
|
||||
throw new \DomainException( \IPS\Member::loggedIn()->language()->addToStack( 'dpt_email_error', FALSE, array( 'sprintf' => array( \IPS\nexus\Support\Department::constructFromData( $other)->_title ) ) ) );
|
||||
}
|
||||
catch ( \UnderflowException $e ) { }
|
||||
}
|
||||
} ) );
|
||||
$form->addHeader( 'department_submissions' );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'dpt_open', $this->id ? $this->open : TRUE, FALSE, array( 'togglesOn' => array( 'dpt_desc_editor', 'dpt_ppi' ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'dpt_desc', NULL, FALSE, array(
|
||||
'app' => 'nexus',
|
||||
'key' => ( $this->id ? "nexus_department_{$this->id}_desc" : NULL ),
|
||||
'editor' => array(
|
||||
'app' => 'nexus',
|
||||
'key' => 'Admin',
|
||||
'autoSaveKey' => ( $this->id ? "nexus-dpt-{$this->id}" : "nexus-new-dpt" ),
|
||||
'attachIds' => $this->id ? array( $this->id, NULL, 'dpt' ) : NULL, 'minimize' => 'dpt_desc_placeholder'
|
||||
)
|
||||
), NULL, NULL, NULL, 'dpt_desc_editor' ) );
|
||||
$form->add( new \IPS\nexus\Form\Money( 'dpt_ppi', ( !$this->ppi or $this->ppi === '*' ) ? '*' : json_decode( $this->ppi, TRUE ), FALSE, array( 'unlimitedLang' => 'no_charge', 'unlimitedTogglesOff' => array( 'dpt_ppi_tax' ) ), NULL, NULL, NULL, 'dpt_ppi' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'dpt_ppi_tax', $this->ppi_tax ?: 0, FALSE, array( 'class' => 'IPS\nexus\Tax', 'zeroVal' => 'do_not_tax' ), NULL, NULL, NULL, 'dpt_ppi_tax' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'dpt_packages', $this->packages ? array_filter( array_map( function( $val )
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\nexus\Package::load( $val );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}, explode( ',', $this->packages ) ) ) : 0, FALSE, array( 'zeroVal' => 'do_not_associate_requests', 'multiple' => TRUE, 'class' => 'IPS\nexus\Package\Group', 'zeroValTogglesOff' => array( 'dpt_require_package' ), 'permissionCheck' => function( $node )
|
||||
{
|
||||
return !( $node instanceof \IPS\nexus\Package\Group );
|
||||
} ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'dpt_require_package', $this->require_package, FALSE, array(), NULL, NULL, NULL, 'dpt_require_package' ) );
|
||||
|
||||
$form->addHeader( 'department_staff' );
|
||||
$admins = array();
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_admin_permission_rows' ) as $row )
|
||||
{
|
||||
if ( $row['row_id_type'] === 'group' )
|
||||
{
|
||||
$admins[ 'dpt_staff_group' ][ 'g' . $row['row_id'] ] = \IPS\Member\Group::load( $row['row_id'] )->name;
|
||||
}
|
||||
else
|
||||
{
|
||||
$admins[ 'dpt_staff_member' ][ 'm' . $row['row_id'] ] = \IPS\Member::load( $row['row_id'] )->name;
|
||||
}
|
||||
}
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'dpt_staff', ( $this->id and $this->staff !== '*' ) ? explode( ',', $this->staff ) : '*', TRUE, array( 'options' => $admins, 'multiple' => TRUE, 'unlimited' => '*' ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Format form values from add/edit form for save
|
||||
*
|
||||
* @param array $values Values from the form
|
||||
* @return array
|
||||
*/
|
||||
public function formatFormValues( $values )
|
||||
{
|
||||
if ( !$this->id )
|
||||
{
|
||||
$this->save();
|
||||
\IPS\File::claimAttachments( 'nexus-new-dpt', $this->id, NULL, 'dpt', TRUE );
|
||||
}
|
||||
|
||||
if( isset( $values['dpt_name'] ) )
|
||||
{
|
||||
\IPS\Lang::saveCustom( 'nexus', "nexus_department_{$this->id}", $values['dpt_name'] );
|
||||
unset( $values['dpt_name'] );
|
||||
}
|
||||
|
||||
if( isset( $values['dpt_desc'] ) )
|
||||
{
|
||||
\IPS\Lang::saveCustom( 'nexus', "nexus_department_{$this->id}_desc", $values['dpt_desc'] );
|
||||
unset( $values['dpt_desc'] );
|
||||
}
|
||||
|
||||
if( isset( $values['dpt_ppi'] ) )
|
||||
{
|
||||
$values['dpt_ppi'] = $values['dpt_ppi'] === '*' ? '*' : json_encode( $values['dpt_ppi'] );
|
||||
}
|
||||
|
||||
if( isset( $values['dpt_staff'] ) )
|
||||
{
|
||||
$values['dpt_staff'] = $values['dpt_staff'] === '*' ? '*' : implode( ',', $values['dpt_staff'] );
|
||||
}
|
||||
|
||||
if( isset( $values['dpt_ppi_tax'] ) )
|
||||
{
|
||||
$values['dpt_ppi_tax'] = $values['dpt_ppi_tax'] ? $values['dpt_ppi_tax']->id : NULL;
|
||||
}
|
||||
|
||||
if( isset( $values['dpt_packages'] ) )
|
||||
{
|
||||
$values['dpt_packages'] = is_array( $values['dpt_packages'] ) ? implode( ',', array_map( function( $val )
|
||||
{
|
||||
return ltrim( $val, 's' );
|
||||
}, array_keys( $values['dpt_packages'] ) ) ) : 0;
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get serialised package IDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function serializedPackageIds()
|
||||
{
|
||||
if ( $this->packages and $this->packages !== '*' )
|
||||
{
|
||||
$allowedPackages = explode( ',', $this->packages );
|
||||
sort( $allowedPackages );
|
||||
$allowedPackages = array_filter( $allowedPackages );
|
||||
$allowedPackages = array_unique( $allowedPackages );
|
||||
return md5( implode( ',', $allowedPackages ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return '*';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Available severities
|
||||
*/
|
||||
protected $_availableSeverities = NULL;
|
||||
|
||||
/**
|
||||
* Get available severities
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function availableSeverities()
|
||||
{
|
||||
if ( $this->_availableSeverities === NULL )
|
||||
{
|
||||
$this->_availableSeverities = array();
|
||||
|
||||
foreach ( Severity::roots( NULL, NULL, array( 'sev_public=1' ) ) as $severity )
|
||||
{
|
||||
if ( $severity->public )
|
||||
{
|
||||
if ( !$severity->departments or $severity->departments === '*' or in_array( $this->id, explode( ',', $severity->departments ) ) )
|
||||
{
|
||||
$this->_availableSeverities[] = $severity;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_availableSeverities;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get serialised severity IDs
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function serializedSeverityIds()
|
||||
{
|
||||
$allowedSeverityIds = array_keys( $this->availableSeverities() );
|
||||
sort( $allowedSeverityIds );
|
||||
$allowedSeverityIds = array_filter( $allowedSeverityIds );
|
||||
$allowedSeverityIds = array_unique( $allowedSeverityIds );
|
||||
return md5( implode( ',', $allowedSeverityIds ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom fields
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function customFields()
|
||||
{
|
||||
return CustomField::roots( NULL, NULL, "sf_departments='*' OR " . \IPS\Db::i()->findInSet( 'sf_departments', array( $this->id ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Pay-Per-Incident Cost
|
||||
*
|
||||
* @param string|NULL $currency Desired currency (NULL for the current user's preference)
|
||||
* @return \IPS\nexus\Money|NULL
|
||||
*/
|
||||
public function ppiCost( $currency = NULL )
|
||||
{
|
||||
if ( $this->ppi and $this->ppi !== '*' )
|
||||
{
|
||||
$costs = json_decode( $this->ppi, TRUE );
|
||||
|
||||
if( isset( $costs[ $currency ?: \IPS\nexus\Customer::loggedIn()->defaultCurrency() ] ) )
|
||||
{
|
||||
$cost = $costs[ $currency ?: \IPS\nexus\Customer::loggedIn()->defaultCurrency() ];
|
||||
return new \IPS\nexus\Money( $cost['amount'], $cost['currency'] );
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get buttons to display in tree
|
||||
* Example code explains return value
|
||||
*
|
||||
* @code
|
||||
array(
|
||||
array(
|
||||
'icon' => 'plus-circle', // Name of FontAwesome icon to use
|
||||
'title' => 'foo', // Language key to use for button's title parameter
|
||||
'link' => \IPS\Http\Url::internal( 'app=foo...' ) // URI to link to
|
||||
'class' => 'modalLink' // CSS Class to use on link (Optional)
|
||||
),
|
||||
... // Additional buttons
|
||||
);
|
||||
* @endcode
|
||||
* @param string $url Base URL
|
||||
* @param bool $subnode Is this a subnode?
|
||||
* @return array
|
||||
*/
|
||||
public function getButtons( $url, $subnode=FALSE )
|
||||
{
|
||||
$buttons = parent::getButtons( $url, $subnode );
|
||||
if ( isset( $buttons['delete'] ) and \IPS\Db::i()->select( 'COUNT(*)', 'nexus_support_requests', array( 'r_department=?', $this->id ) ) )
|
||||
{
|
||||
$buttons['delete']['data'] = array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('delete') );
|
||||
}
|
||||
|
||||
return $buttons;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Support Log Model
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Nexus
|
||||
* @since 14 Nov 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\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 Log Model
|
||||
*/
|
||||
class _Log extends \IPS\Patterns\ActiveRecord
|
||||
{
|
||||
/**
|
||||
* @brief [ActiveRecord] Multiton Store
|
||||
*/
|
||||
protected static $multitons;
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Table
|
||||
*/
|
||||
public static $databaseTable = 'nexus_support_request_log';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Prefix
|
||||
*/
|
||||
public static $databasePrefix = 'rlog_';
|
||||
|
||||
/**
|
||||
* Set request
|
||||
*
|
||||
* @param \IPS\nexus\Support\Request $request The request
|
||||
* @return void
|
||||
*/
|
||||
public function set_request( \IPS\nexus\Support\Request $request )
|
||||
{
|
||||
$this->_data['request'] = $request->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get request
|
||||
*
|
||||
* @return \IPS\nexus\Support\Request
|
||||
*/
|
||||
public function get_request()
|
||||
{
|
||||
return \IPS\nexus\Support\Request::load( $this->_data['request'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set member performing the action
|
||||
*
|
||||
* @param \IPS\nexus\Support\Request $member The member performing the action
|
||||
* @return void
|
||||
*/
|
||||
public function set_member( \IPS\Member $member )
|
||||
{
|
||||
$this->_data['member'] = $member->member_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get member performing the action
|
||||
*
|
||||
* @return \IPS\nexus\Customer
|
||||
*/
|
||||
public function get_member()
|
||||
{
|
||||
return \IPS\nexus\Customer::load( $this->_data['member'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set old value
|
||||
*
|
||||
* @param mixed $old The old value
|
||||
* @return void
|
||||
*/
|
||||
public function set_old( $old )
|
||||
{
|
||||
$this->_data['old'] = $old ? $old->id : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get old value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get_old()
|
||||
{
|
||||
return $this->getValue( $this->_data['old'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set new value
|
||||
*
|
||||
* @param mixed $new The new value
|
||||
* @return void
|
||||
*/
|
||||
public function set_new( $new )
|
||||
{
|
||||
if ( $new )
|
||||
{
|
||||
if ( $new instanceof \IPS\Member )
|
||||
{
|
||||
$this->_data['new'] = $new->member_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->_data['new'] = $new->id;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->_data['new'] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get new value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get_new()
|
||||
{
|
||||
return $this->getValue( $this->_data['new'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set date
|
||||
*
|
||||
* @param \IPS\DateTime $date The date
|
||||
* @return void
|
||||
*/
|
||||
public function set_date( \IPS\DateTime $date )
|
||||
{
|
||||
$this->_data['date'] = $date->getTimestamp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get old value
|
||||
*
|
||||
* @return \IPS\DateTime
|
||||
*/
|
||||
public function get_date()
|
||||
{
|
||||
return \IPS\DateTime::ts( $this->_data['date'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get object from ID
|
||||
*
|
||||
* @param int $id
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getValue( $id )
|
||||
{
|
||||
if ( !$id )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
switch ( $this->action )
|
||||
{
|
||||
case 'status':
|
||||
return \IPS\nexus\Support\Status::load( $id );
|
||||
case 'department':
|
||||
return \IPS\nexus\Support\Department::load( $id );
|
||||
case 'purchase':
|
||||
return \IPS\nexus\Purchase::load( $id );
|
||||
case 'severity':
|
||||
return \IPS\nexus\Support\Severity::load( $id );
|
||||
case 'staff':
|
||||
return \IPS\Member::load( $id );
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException( $this->action );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,402 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Support Reply Model
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Nexus
|
||||
* @since 9 Apr 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\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 Reply Model
|
||||
*/
|
||||
class _Reply extends \IPS\Content\Comment implements \IPS\Content\Hideable
|
||||
{
|
||||
const REPLY_MEMBER = 'm';
|
||||
const REPLY_ALTCONTACT = 'a';
|
||||
const REPLY_STAFF = 's';
|
||||
const REPLY_HIDDEN = 'h';
|
||||
const REPLY_EMAIL = 'e';
|
||||
const REPLY_PENDING = 'p';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Multiton Store
|
||||
*/
|
||||
protected static $multitons;
|
||||
|
||||
/**
|
||||
* @brief Application
|
||||
*/
|
||||
public static $application = 'nexus';
|
||||
|
||||
/**
|
||||
* @brief [Content\Comment] Item Class
|
||||
*/
|
||||
public static $itemClass = 'IPS\nexus\Support\Request';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Table
|
||||
*/
|
||||
public static $databaseTable = 'nexus_support_replies';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Prefix
|
||||
*/
|
||||
public static $databasePrefix = 'reply_';
|
||||
|
||||
/**
|
||||
* @brief Database Column Map
|
||||
*/
|
||||
public static $databaseColumnMap = array(
|
||||
'item' => 'request',
|
||||
'author' => 'member',
|
||||
'content' => 'post',
|
||||
'date' => 'date',
|
||||
'ip_address' => 'ip_address',
|
||||
'hidden' => 'hidden'
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief [Content\Comment] Comment Template
|
||||
*/
|
||||
public static $commentTemplate = array( array( 'support', 'nexus' ), 'replyContainer' );
|
||||
|
||||
/**
|
||||
* @brief Icon
|
||||
*/
|
||||
public static $icon = 'life-ring';
|
||||
|
||||
/**
|
||||
* @brief Title
|
||||
*/
|
||||
public static $title = 'support_request';
|
||||
|
||||
/**
|
||||
* @brief Rating data
|
||||
*/
|
||||
public $ratingData;
|
||||
|
||||
/**
|
||||
* Construct ActiveRecord from database row
|
||||
*
|
||||
* @param array $data Row from database table
|
||||
* @param bool $updateMultitonStoreIfExists Replace current object in multiton store if it already exists there?
|
||||
* @return static
|
||||
*/
|
||||
public static function constructFromData( $data, $updateMultitonStoreIfExists = TRUE )
|
||||
{
|
||||
$obj = parent::constructFromData( $data, $updateMultitonStoreIfExists );
|
||||
if ( isset( $data['nexus_support_ratings'] ) and $data['nexus_support_ratings']['rating_rating'] )
|
||||
{
|
||||
$obj->ratingData = $data['nexus_support_ratings'];
|
||||
}
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Default Values
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setDefaultValues()
|
||||
{
|
||||
$this->type = static::REPLY_MEMBER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create comment
|
||||
*
|
||||
* @param \IPS\Content\Item $item The content item just created
|
||||
* @param string $comment The comment
|
||||
* @param bool $first Is the first comment?
|
||||
* @param string $guestName If author is a guest, the name to use
|
||||
* @param bool|NULL $incrementPostCount Increment post count? If NULL, will use static::incrementPostCount()
|
||||
* @param \IPS\Member|NULL $member The author of this comment. If NULL, uses currently logged in member.
|
||||
* @param \IPS\DateTime|NULL $time The time
|
||||
* @return \IPS\Content\Comment
|
||||
*/
|
||||
public static function create( $item, $comment, $first=FALSE, $guestName=NULL, $incrementPostCount=NULL, $member=NULL, \IPS\DateTime $time=NULL )
|
||||
{
|
||||
$obj = call_user_func_array( 'parent::create', func_get_args() );
|
||||
|
||||
if ( $obj->type === static::REPLY_MEMBER and $obj->author()->member_id !== $obj->item()->author()->member_id )
|
||||
{
|
||||
$obj->type = static::REPLY_ALTCONTACT;
|
||||
$obj->save();
|
||||
|
||||
$notify = $obj->item()->notify;
|
||||
$in = FALSE;
|
||||
foreach ( $notify as $n )
|
||||
{
|
||||
if ( $n['type'] === 'm' and $n['value'] == $obj->author()->member_id )
|
||||
{
|
||||
$in = TRUE;
|
||||
}
|
||||
}
|
||||
if ( !$in )
|
||||
{
|
||||
$notify[] = array( 'type' => 'm', 'value' => $obj->author()->member_id );
|
||||
$obj->item()->notify = $notify;
|
||||
$obj->item()->save();
|
||||
}
|
||||
}
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Joins (when loading comments)
|
||||
*
|
||||
* @param \IPS\Content\Item $item The item
|
||||
* @return array
|
||||
*/
|
||||
public static function joins( \IPS\Content\Item $item )
|
||||
{
|
||||
$return = parent::joins( $item );
|
||||
if ( \IPS\Settings::i()->nexus_support_satisfaction )
|
||||
{
|
||||
$return['nexus_support_ratings'] = array(
|
||||
'select' => 'nexus_support_ratings.*',
|
||||
'from' => 'nexus_support_ratings',
|
||||
'where' => 'rating_reply=reply_id'
|
||||
);
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can delete?
|
||||
*
|
||||
* @param \IPS\Member|NULL $member The member to check for (NULL for currently logged in member)
|
||||
* @return bool
|
||||
*/
|
||||
public function canDelete( $member=NULL )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can split this comment off?
|
||||
*
|
||||
* @param \IPS\Member|NULL $member The member to check for (NULL for currently logged in member)
|
||||
* @return bool
|
||||
*/
|
||||
public function canSplit( $member=NULL )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get author
|
||||
*
|
||||
* @return \IPS\nexus\Customer
|
||||
*/
|
||||
public function author()
|
||||
{
|
||||
if ( $this->member )
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\nexus\Customer::load( $this->member );
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
}
|
||||
return new \IPS\nexus\Customer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can see moderation tools
|
||||
*
|
||||
* @note This is used generally to control if the user has permission to see multi-mod tools. Individual content items may have specific permissions
|
||||
* @param \IPS\Member|NULL $member The member to check for or NULL for the currently logged in member
|
||||
* @param \IPS\Node\Model|NULL $container The container
|
||||
* @return bool
|
||||
*/
|
||||
public static function canSeeMultiModTools( \IPS\Member $member = NULL, \IPS\Node\Model $container = NULL )
|
||||
{
|
||||
// If we decide to support multimod in future, we need to make sure it either doesn't show, or shows correctly when viewing a staff member's latest replies in the "Performance" section
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send if it's pending
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function sendPending()
|
||||
{
|
||||
if ( $this->type === static::REPLY_PENDING )
|
||||
{
|
||||
$this->type = static::REPLY_STAFF;
|
||||
$this->save();
|
||||
|
||||
$defaultRecipients = $this->item()->getDefaultRecipients();
|
||||
$this->sendCustomerNotifications( $defaultRecipients['to'], $defaultRecipients['cc'], $defaultRecipients['bcc'] );
|
||||
|
||||
$this->sendNotifications();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send staff notifications
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function sendNotifications()
|
||||
{
|
||||
$staffIds = array_keys( Request::staff() );
|
||||
$type = array( 'type=?', 'r' );
|
||||
if ( $assignedTo = $this->item()->staff )
|
||||
{
|
||||
$type[0] .= ' OR ( type=? AND staff_id=? )';
|
||||
$type[] = 'a';
|
||||
$type[] = $assignedTo->member_id;
|
||||
}
|
||||
$sentTo = array( $this->member );
|
||||
foreach ( \IPS\Db::i()->select( 'staff_id', 'nexus_support_notify', array( $type, array( "departments='*' OR " . \IPS\Db::i()->findInSet( 'departments', array( $this->item()->department->id ) ) ) ) ) as $staffId )
|
||||
{
|
||||
if ( in_array( $staffId, $staffIds ) )
|
||||
{
|
||||
if ( !in_array( $staffId, $sentTo ) and ( $this->item()->department->staff === '*' or in_array( $staffId, explode( ',', $this->item()->department->staff ) ) ) )
|
||||
{
|
||||
$email = \IPS\Email::buildFromTemplate( 'nexus', $this->type === static::REPLY_HIDDEN ? 'staffNotifyNote' : 'staffNotifyReply', array( $this ) );
|
||||
$email->from = $this->item()->department->email;
|
||||
switch ( \IPS\Settings::i()->nexus_sout_from )
|
||||
{
|
||||
case 'staff':
|
||||
if ( $this->member )
|
||||
{
|
||||
$email->fromName = $this->author()->name;
|
||||
}
|
||||
break;
|
||||
case 'dpt':
|
||||
$email->fromName = $email->language->get( 'nexus_department_' . $this->item()->department->_id );
|
||||
break;
|
||||
default:
|
||||
$email->fromName = \IPS\Settings::i()->nexus_sout_from;
|
||||
break;
|
||||
}
|
||||
$email->unsubscribe = array( 'text' => 'manage_notification_settings', 'link' => \IPS\Http\Url::internal( 'app=nexus&module=support&controller=requests&do=notifications', 'admin' ) );
|
||||
$email->send( \IPS\Member::load( $staffId ) );
|
||||
|
||||
$sentTo[] = $staffId;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Db::i()->delete( 'nexus_support_notify', array( 'staff_id=?', $staffId ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send Customer Notifications
|
||||
*
|
||||
* @param string $to Primary "To" email address
|
||||
* @param array $cc Emails to Cc
|
||||
* @param array $bcc Emails to Bcc
|
||||
* @return void
|
||||
*/
|
||||
public function sendCustomerNotifications( $to, $cc, $bcc )
|
||||
{
|
||||
if ( \IPS\Settings::i()->nexus_sout_chrome )
|
||||
{
|
||||
$email = \IPS\Email::buildFromTemplate( 'nexus', 'staffReply', array( $this ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$email = \IPS\Email::buildFromTemplate( 'nexus', 'staffReplyNoChrome', array( $this ) );
|
||||
$email->useWrapper = FALSE;
|
||||
}
|
||||
$email->from = $this->item()->department->email ?: \IPS\Settings::i()->email_out;
|
||||
switch ( \IPS\Settings::i()->nexus_sout_from )
|
||||
{
|
||||
case 'staff':
|
||||
$email->fromName = $this->author()->name;
|
||||
break;
|
||||
case 'dpt':
|
||||
$email->fromName = $email->language->get( 'nexus_department_' . $this->item()->department->_id );
|
||||
break;
|
||||
default:
|
||||
$email->fromName = \IPS\Settings::i()->nexus_sout_from;
|
||||
break;
|
||||
}
|
||||
$email->send( $to, $cc, $bcc );
|
||||
}
|
||||
|
||||
/**
|
||||
* Do stuff after creating (abstracted as comments and reviews need to do different things)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function postCreate()
|
||||
{
|
||||
$item = $this->item();
|
||||
|
||||
if ( $this->type === Reply::REPLY_MEMBER or $this->type === Reply::REPLY_ALTCONTACT )
|
||||
{
|
||||
$item->status = Status::load( TRUE, 'status_default_member' );
|
||||
}
|
||||
|
||||
return parent::postCreate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ACP URL
|
||||
*
|
||||
* @param string|NULL $action Action
|
||||
* @return \IPS\Http\Url
|
||||
*/
|
||||
public function acpUrl( $action=NULL )
|
||||
{
|
||||
$url = \IPS\Http\Url::internal( "app=nexus&module=support&controller=request&id={$this->id}", 'admin' );
|
||||
if( $action )
|
||||
{
|
||||
return $url->setQueryString( 'do', $action . 'Comment' )->setQueryString( 'comment', $this->id );
|
||||
}
|
||||
else
|
||||
{
|
||||
$commentPosition = \IPS\Db::i()->select( 'COUNT(*) AS position', static::$databaseTable, array( static::$databasePrefix . static::$databaseColumnMap['item'] . '=? AND ' . static::$databasePrefix . static::$databaseColumnId . '<=?', $this->request, $this->id ), static::$databasePrefix . static::$databaseColumnMap['date'] . ' asc' )->first();
|
||||
$page = ceil( $commentPosition / \IPS\nexus\Support\Request::getCommentsPerPage() );
|
||||
if ( $page != 1 )
|
||||
{
|
||||
$url = $url->setQueryString( 'page', $page );
|
||||
}
|
||||
return $url->setFragment( 'comment-' . $this->id );
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,180 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Support Severity Model
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Nexus
|
||||
* @since 9 Apr 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\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 Severity Model
|
||||
*/
|
||||
class _Severity extends \IPS\Node\Model
|
||||
{
|
||||
/**
|
||||
* @brief [ActiveRecord] Multiton Store
|
||||
*/
|
||||
protected static $multitons;
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Table
|
||||
*/
|
||||
public static $databaseTable = 'nexus_support_severities';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Prefix
|
||||
*/
|
||||
public static $databasePrefix = 'sev_';
|
||||
|
||||
/**
|
||||
* @brief [Node] Order Database Column
|
||||
*/
|
||||
public static $databaseColumnOrder = 'position';
|
||||
|
||||
/**
|
||||
* @brief [Node] Node Title
|
||||
*/
|
||||
public static $nodeTitle = 'severities';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database ID Fields
|
||||
*/
|
||||
protected static $databaseIdFields = array( 'sev_default' );
|
||||
|
||||
/**
|
||||
* @brief [Node] Title prefix. If specified, will look for a language key with "{$key}_title" as the key
|
||||
*/
|
||||
public static $titleLangPrefix = 'nexus_severity_';
|
||||
|
||||
/**
|
||||
* @brief [Node] ACP Restrictions
|
||||
* @code
|
||||
array(
|
||||
'app' => 'core', // The application key which holds the restrictrions
|
||||
'module' => 'foo', // The module key which holds the restrictions
|
||||
'map' => array( // [Optional] The key for each restriction - can alternatively use "prefix"
|
||||
'add' => 'foo_add',
|
||||
'edit' => 'foo_edit',
|
||||
'permissions' => 'foo_perms',
|
||||
'delete' => 'foo_delete'
|
||||
),
|
||||
'all' => 'foo_manage', // [Optional] The key to use for any restriction not provided in the map (only needed if not providing all 4)
|
||||
'prefix' => 'foo_', // [Optional] Rather than specifying each key in the map, you can specify a prefix, and it will automatically look for restrictions with the key "[prefix]_add/edit/permissions/delete"
|
||||
* @endcode
|
||||
*/
|
||||
protected static $restrictions = array(
|
||||
'app' => 'nexus',
|
||||
'module' => 'support',
|
||||
'all' => 'severities_manage'
|
||||
);
|
||||
|
||||
/**
|
||||
* [Node] Add/Edit Form
|
||||
*
|
||||
* @param \IPS\Helpers\Form $form The form
|
||||
* @return void
|
||||
*/
|
||||
public function form( &$form )
|
||||
{
|
||||
$form->addHeader( 'severity_settings' );
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'sev_name', NULL, TRUE, array( 'app' => 'nexus', 'key' => ( $this->id ? "nexus_severity_{$this->id}" : NULL ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'sev_default', $this->default ) );
|
||||
$form->addHeader( 'severity_submissions' );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'sev_public', $this->public, FALSE, array( 'togglesOn' => array( 'sev_departments', 'sev_desc' ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'sev_departments', ( $this->departments and $this->departments !== '*' ) ? explode( ',', $this->departments ) : 0, FALSE, array( 'class' => 'IPS\nexus\Support\Department', 'multiple' => TRUE, 'zeroVal' => 'all' ), NULL, NULL, NULL, 'sev_departments' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'sev_desc', NULL, FALSE, array(
|
||||
'app' => 'nexus',
|
||||
'key' => ( $this->id ? "nexus_severity_{$this->id}_desc" : NULL ),
|
||||
'textArea' => TRUE
|
||||
), NULL, NULL, NULL, 'sev_desc' ) );
|
||||
$form->addHeader( 'severity_acp_list' );
|
||||
$form->add( new \IPS\Helpers\Form\Upload( 'sev_icon', $this->icon ? \IPS\File::get( 'nexus_Support', $this->icon ) : NULL, FALSE, array( 'storageExtension' => 'nexus_Support', 'image' => TRUE ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Color( 'sev_color', $this->color ?: '000' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Format form values from add/edit form for save
|
||||
*
|
||||
* @param array $values Values from the form
|
||||
* @return array
|
||||
*/
|
||||
public function formatFormValues( $values )
|
||||
{
|
||||
if ( !$this->id )
|
||||
{
|
||||
$this->save();
|
||||
}
|
||||
|
||||
if( isset( $values['sev_name'] ) )
|
||||
{
|
||||
\IPS\Lang::saveCustom( 'nexus', "nexus_severity_{$this->id}", $values['sev_name'] );
|
||||
unset( $values['sev_name'] );
|
||||
}
|
||||
|
||||
if( isset( $values['sev_desc'] ) )
|
||||
{
|
||||
\IPS\Lang::saveCustom( 'nexus', "nexus_severity_{$this->id}_desc", $values['sev_desc'] );
|
||||
unset( $values['sev_desc'] );
|
||||
}
|
||||
|
||||
if ( isset( $values['sev_default'] ) AND $values['sev_default'] )
|
||||
{
|
||||
\IPS\Db::i()->update( 'nexus_support_severities', array( 'sev_default' => 0 ) );
|
||||
}
|
||||
|
||||
if( isset( $values['sev_color'] ) )
|
||||
{
|
||||
$values['sev_color'] = ltrim( $values['sev_color'], '#' );
|
||||
}
|
||||
|
||||
if( isset( $values['sev_departments'] ) )
|
||||
{
|
||||
$values['sev_departments'] = $values['sev_departments'] == 0 ? '*' : implode( ',', array_keys( $values['sev_departments'] ) );
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get buttons to display in tree
|
||||
* Example code explains return value
|
||||
*
|
||||
* @code
|
||||
array(
|
||||
array(
|
||||
'icon' => 'plus-circle', // Name of FontAwesome icon to use
|
||||
'title' => 'foo', // Language key to use for button's title parameter
|
||||
'link' => \IPS\Http\Url::internal( 'app=foo...' ) // URI to link to
|
||||
'class' => 'modalLink' // CSS Class to use on link (Optional)
|
||||
),
|
||||
... // Additional buttons
|
||||
);
|
||||
* @endcode
|
||||
* @param string $url Base URL
|
||||
* @param bool $subnode Is this a subnode?
|
||||
* @return array
|
||||
*/
|
||||
public function getButtons( $url, $subnode=FALSE )
|
||||
{
|
||||
$buttons = parent::getButtons( $url, $subnode );
|
||||
if ( isset( $buttons['delete'] ) and \IPS\Db::i()->select( 'COUNT(*)', 'nexus_support_requests', array( 'r_severity=?', $this->id ) ) )
|
||||
{
|
||||
$buttons['delete']['data'] = array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('delete') );
|
||||
}
|
||||
|
||||
return $buttons;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Support Status Model
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Nexus
|
||||
* @since 8 Apr 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\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 Status Model
|
||||
*/
|
||||
class _Status extends \IPS\Node\Model
|
||||
{
|
||||
/**
|
||||
* @brief [ActiveRecord] Multiton Store
|
||||
*/
|
||||
protected static $multitons;
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Table
|
||||
*/
|
||||
public static $databaseTable = 'nexus_support_statuses';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Prefix
|
||||
*/
|
||||
public static $databasePrefix = 'status_';
|
||||
|
||||
/**
|
||||
* @brief [Node] Order Database Column
|
||||
*/
|
||||
public static $databaseColumnOrder = 'position';
|
||||
|
||||
/**
|
||||
* @brief [Node] Node Title
|
||||
*/
|
||||
public static $nodeTitle = 'statuses';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database ID Fields
|
||||
*/
|
||||
protected static $databaseIdFields = array( 'status_default_member', 'status_default_staff' );
|
||||
|
||||
/**
|
||||
* @brief [Node] ACP Restrictions
|
||||
* @code
|
||||
array(
|
||||
'app' => 'core', // The application key which holds the restrictrions
|
||||
'module' => 'foo', // The module key which holds the restrictions
|
||||
'map' => array( // [Optional] The key for each restriction - can alternatively use "prefix"
|
||||
'add' => 'foo_add',
|
||||
'edit' => 'foo_edit',
|
||||
'permissions' => 'foo_perms',
|
||||
'delete' => 'foo_delete'
|
||||
),
|
||||
'all' => 'foo_manage', // [Optional] The key to use for any restriction not provided in the map (only needed if not providing all 4)
|
||||
'prefix' => 'foo_', // [Optional] Rather than specifying each key in the map, you can specify a prefix, and it will automatically look for restrictions with the key "[prefix]_add/edit/permissions/delete"
|
||||
* @endcode
|
||||
*/
|
||||
protected static $restrictions = array(
|
||||
'app' => 'nexus',
|
||||
'module' => 'support',
|
||||
'all' => 'statuses_manage'
|
||||
);
|
||||
|
||||
/**
|
||||
* Statuses that the member can set
|
||||
*
|
||||
* @param \IPS\nexus\Support\Request|NULL $request If provided, the status of that request will be excluded
|
||||
* @return array
|
||||
*/
|
||||
public static function publicSetStatuses( \IPS\nexus\Support\Request $request = NULL )
|
||||
{
|
||||
$return = array();
|
||||
foreach ( parent::roots() as $status )
|
||||
{
|
||||
if ( \IPS\Member::loggedIn()->language()->checkKeyExists("nexus_status_{$status->id}_set") and ( $request === NULL or $request->status->id != $status->id ) )
|
||||
{
|
||||
$return[ $status->id ] = \IPS\Member::loggedIn()->language()->addToStack("nexus_status_{$status->id}_set");
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get__title()
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'nexus_status_' . $this->id . '_' . \IPS\Dispatcher::i()->controllerLocation );
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Add/Edit Form
|
||||
*
|
||||
* @param \IPS\Helpers\Form $form The form
|
||||
* @return void
|
||||
*/
|
||||
public function form( &$form )
|
||||
{
|
||||
$form->addHeader( 'internal_settings' );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'status_name', NULL, TRUE, array( 'app' => 'nexus', 'key' => ( $this->id ? "nexus_status_{$this->id}_admin" : NULL ) ) ) );
|
||||
$defaults = array();
|
||||
if ( $this->id )
|
||||
{
|
||||
if ( $this->default_member )
|
||||
{
|
||||
$defaults[] = 'member';
|
||||
}
|
||||
if ( $this->default_staff )
|
||||
{
|
||||
$defaults[] = 'staff';
|
||||
}
|
||||
}
|
||||
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'status_default', $defaults, FALSE, array( 'options' => array( 'member' => 'status_default_member', 'staff' => 'status_default_staff' ) ), function( $val ) use ( $defaults )
|
||||
{
|
||||
$diff = array_diff( $defaults, $val );
|
||||
if ( !empty( $diff ) )
|
||||
{
|
||||
throw new \DomainException( 'status_default_change' );
|
||||
}
|
||||
} ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'status_open', $this->open ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'status_assign', $this->assign ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'status_log', $this->log ) );
|
||||
$form->add( new \IPS\Helpers\Form\Color( 'status_color', $this->color ?: 'C04848' ) );
|
||||
$form->addHeader( 'public_settings' );
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'status_public_name', NULL, TRUE, array( 'app' => 'nexus', 'key' => ( $this->id ? "nexus_status_{$this->id}_front" : NULL ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'status_public_set', $this->id ? \IPS\Member::loggedIn()->language()->checkKeyExists("nexus_status_{$this->id}_set") : FALSE, FALSE, array( 'togglesOn' => array( 'status_public_set_text' ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'status_public_set_text', NULL, FALSE, array( 'app' => 'nexus', 'key' => ( $this->id ? "nexus_status_{$this->id}_set" : NULL ) ), NULL, NULL, NULL, 'status_public_set_text' ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'status_is_locked', $this->id ? !$this->is_locked : FALSE ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Format form values from add/edit form for save
|
||||
*
|
||||
* @param array $values Values from the form
|
||||
* @return array
|
||||
*/
|
||||
public function formatFormValues( $values )
|
||||
{
|
||||
if ( !$this->id )
|
||||
{
|
||||
$this->save();
|
||||
}
|
||||
|
||||
if( isset( $values['status_name'] ) )
|
||||
{
|
||||
\IPS\Lang::saveCustom( 'nexus', "nexus_status_{$this->id}_admin", $values['status_name'] );
|
||||
unset( $values['status_name'] );
|
||||
}
|
||||
|
||||
if( isset( $values['status_public_name'] ) )
|
||||
{
|
||||
\IPS\Lang::saveCustom( 'nexus', "nexus_status_{$this->id}_front", $values['status_public_name'] );
|
||||
unset( $values['status_public_name'] );
|
||||
}
|
||||
|
||||
if( isset( $values['status_public_set'] ) )
|
||||
{
|
||||
if ( $values['status_public_set'] )
|
||||
{
|
||||
\IPS\Lang::saveCustom( 'nexus', "nexus_status_{$this->id}_set", $values['status_public_set_text'] );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_sys_lang_words', array( 'word_app=? AND word_key=?', 'nexus', "nexus_status_{$this->id}_set" ) );
|
||||
}
|
||||
unset( $values['status_public_set_text'] );
|
||||
}
|
||||
|
||||
if( isset( $values['status_is_locked'] ) )
|
||||
{
|
||||
$values['status_is_locked'] = !$values['status_is_locked'];
|
||||
}
|
||||
|
||||
if( isset( $values[ "status_member" ] ) OR isset( $values['status_staff'] ) )
|
||||
{
|
||||
foreach ( array( 'member', 'staff' ) as $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 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$values["default_{$k}"] = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( isset( $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'] ) )
|
||||
{
|
||||
$this->default_staff = TRUE;
|
||||
\IPS\Db::i()->update( 'nexus_support_statuses', array( 'status_default_staff' => 0 ) );
|
||||
}
|
||||
unset( $values['status_default'] );
|
||||
}
|
||||
|
||||
if( isset( $values['status_color'] ) )
|
||||
{
|
||||
$values['status_color'] = ltrim( $values['status_color'], '#' );
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get buttons to display in tree
|
||||
* Example code explains return value
|
||||
*
|
||||
* @code
|
||||
array(
|
||||
array(
|
||||
'icon' => 'plus-circle', // Name of FontAwesome icon to use
|
||||
'title' => 'foo', // Language key to use for button's title parameter
|
||||
'link' => \IPS\Http\Url::internal( 'app=foo...' ) // URI to link to
|
||||
'class' => 'modalLink' // CSS Class to use on link (Optional)
|
||||
),
|
||||
... // Additional buttons
|
||||
);
|
||||
* @endcode
|
||||
* @param string $url Base URL
|
||||
* @param bool $subnode Is this a subnode?
|
||||
* @return array
|
||||
*/
|
||||
public function getButtons( $url, $subnode=FALSE )
|
||||
{
|
||||
$buttons = parent::getButtons( $url, $subnode );
|
||||
if ( isset( $buttons['delete'] ) and \IPS\Db::i()->select( 'COUNT(*)', 'nexus_support_requests', array( 'r_status=?', $this->id ) ) )
|
||||
{
|
||||
$buttons['delete']['data'] = array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('delete') );
|
||||
}
|
||||
|
||||
return $buttons;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Support Stock Action Model
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Nexus
|
||||
* @since 15 Apr 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\nexus\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 Stock Action Model
|
||||
*/
|
||||
class _StockAction extends \IPS\Node\Model
|
||||
{
|
||||
/**
|
||||
* @brief [ActiveRecord] Multiton Store
|
||||
*/
|
||||
protected static $multitons;
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Table
|
||||
*/
|
||||
public static $databaseTable = 'nexus_support_stock_actions';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Prefix
|
||||
*/
|
||||
public static $databasePrefix = 'action_';
|
||||
|
||||
/**
|
||||
* @brief [Node] Order Database Column
|
||||
*/
|
||||
public static $databaseColumnOrder = 'position';
|
||||
|
||||
/**
|
||||
* @brief [Node] Node Title
|
||||
*/
|
||||
public static $nodeTitle = 'stock_actions';
|
||||
|
||||
/**
|
||||
* @brief [Node] Title prefix. If specified, will look for a language key with "{$key}_title" as the key
|
||||
*/
|
||||
public static $titleLangPrefix = 'nexus_stockaction_';
|
||||
|
||||
/**
|
||||
* @brief [Node] ACP Restrictions
|
||||
* @code
|
||||
array(
|
||||
'app' => 'core', // The application key which holds the restrictrions
|
||||
'module' => 'foo', // The module key which holds the restrictions
|
||||
'map' => array( // [Optional] The key for each restriction - can alternatively use "prefix"
|
||||
'add' => 'foo_add',
|
||||
'edit' => 'foo_edit',
|
||||
'permissions' => 'foo_perms',
|
||||
'delete' => 'foo_delete'
|
||||
),
|
||||
'all' => 'foo_manage', // [Optional] The key to use for any restriction not provided in the map (only needed if not providing all 4)
|
||||
'prefix' => 'foo_', // [Optional] Rather than specifying each key in the map, you can specify a prefix, and it will automatically look for restrictions with the key "[prefix]_add/edit/permissions/delete"
|
||||
* @endcode
|
||||
*/
|
||||
protected static $restrictions = array(
|
||||
'app' => 'nexus',
|
||||
'module' => 'support',
|
||||
'all' => 'stockactions_manage'
|
||||
);
|
||||
|
||||
/**
|
||||
* Set Default Values
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setDefaultValues()
|
||||
{
|
||||
$this->status = NULL;
|
||||
$this->department = NULL;
|
||||
$this->staff = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get department
|
||||
*
|
||||
* @return \IPS\nexus\Support\Department|NULL
|
||||
*/
|
||||
public function get_department()
|
||||
{
|
||||
try
|
||||
{
|
||||
return $this->_data['department'] ? Department::load( $this->_data['department'] ) : NULL;
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set department
|
||||
*
|
||||
* @param \IPS\nexus\Support\Department|NULL $department The department
|
||||
* @return void
|
||||
*/
|
||||
public function set_department( Department $department = NULL )
|
||||
{
|
||||
$this->_data['department'] = $department ? $department->id : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get status
|
||||
*
|
||||
* @return \IPS\nexus\Support\Status|NULL
|
||||
*/
|
||||
public function get_status()
|
||||
{
|
||||
try
|
||||
{
|
||||
return $this->_data['status'] ? Status::load( $this->_data['status'] ) : NULL;
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set purchase
|
||||
*
|
||||
* @param \IPS\nexus\Support\Status|NULL $status The status
|
||||
* @return void
|
||||
*/
|
||||
public function set_status( Status $status = NULL )
|
||||
{
|
||||
$this->_data['status'] = $status ? $status->id : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get staff
|
||||
*
|
||||
* @return \IPS\Member|NULL
|
||||
*/
|
||||
public function get_staff()
|
||||
{
|
||||
try
|
||||
{
|
||||
return $this->_data['staff'] ? \IPS\Member::load( $this->_data['staff'] ) : NULL;
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set staff
|
||||
*
|
||||
* @param \IPS\Member|NULL $member The staff member to assign to
|
||||
* @return void
|
||||
*/
|
||||
public function set_staff( \IPS\Member $member = NULL )
|
||||
{
|
||||
$this->_data['staff'] = $member ? $member->member_id : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Add/Edit Form
|
||||
*
|
||||
* @param \IPS\Helpers\Form $form The form
|
||||
* @return void
|
||||
*/
|
||||
public function form( &$form )
|
||||
{
|
||||
$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( 'options' => array_merge( array( 0 => '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 ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Format form values from add/edit form for save
|
||||
*
|
||||
* @param array $values Values from the form
|
||||
* @return array
|
||||
*/
|
||||
public function formatFormValues( $values )
|
||||
{
|
||||
if ( !$this->id )
|
||||
{
|
||||
$this->save();
|
||||
}
|
||||
|
||||
if( isset( $values['action_name'] ) )
|
||||
{
|
||||
\IPS\Lang::saveCustom( 'nexus', "nexus_stockaction_{$this->id}", $values['action_name'] );
|
||||
unset( $values['action_name'] );
|
||||
}
|
||||
|
||||
if ( isset( $values['action_message_on'] ) AND !$values['action_message_on'] )
|
||||
{
|
||||
$values['action_message'] = NULL;
|
||||
}
|
||||
unset( $values['action_message_on'] );
|
||||
|
||||
foreach ( array( 'status', 'department' ) as $k )
|
||||
{
|
||||
if( isset( $values["action_{$k}"] ) )
|
||||
{
|
||||
$values["action_{$k}"] = $values["action_{$k}"] ?: NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if( isset( $values['action_staff'] ) )
|
||||
{
|
||||
$values['action_staff'] = $values['action_staff'] ? \IPS\Member::load( $values['action_staff'] ) : NULL;
|
||||
}
|
||||
|
||||
if( isset( $values['action_show_in'] ) )
|
||||
{
|
||||
$values['action_show_in'] = $values['action_show_in'] ? implode( ',', array_keys( $values['action_show_in'] ) ) : '*';
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
Reference in new issue
Block a user