402 lines
11 KiB
PHP
402 lines
11 KiB
PHP
<?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 );
|
|
}
|
|
}
|
|
} |