Seditio Source
Root |
./othercms/ips_4.3.4/applications/nexus/sources/Support/Stream.php
<?php
/**
 * @brief        Support Requests Stream
 * @author        <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
 * @copyright    (c) Invision Power Services, Inc.
 * @license        https://www.invisioncommunity.com/legal/standards/
 * @package        Invision Community
 * @subpackage    Nexus
 * @since        11 Sep 2016
 */

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 Requests Stream
 */
class _Stream extends \IPS\Patterns\ActiveRecord
{
   
/**
     * @brief    [ActiveRecord] Multiton Store
     */
   
protected static $multitons;
   
   
/**
     * @brief    [ActiveRecord] Database Table
     */
   
public static $databaseTable = 'nexus_support_streams';
   
   
/**
     * @brief    [ActiveRecord] Database Prefix
     */
   
public static $databasePrefix = 'stream_';
   
   
/**
     * @brief    [Node] Order Database Column
     */
   
public static $databaseColumnOrder = 'position';
   
   
/**
     * Get streams for a member
     *
     * @param    \IPS\Member    $member    The member
     * @return    array
     */
   
public static function myStreams( \IPS\Member $member )
    {
       
$return = array();
       
        foreach ( array(
'open', 'assigned', 'tracked' ) as $k )
        {
           
$return[] = static::load( $k );
        }
       
        foreach ( new \
IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'nexus_support_streams', array( 'stream_owner=?', $member->member_id ) ), 'IPS\nexus\Support\Stream' ) as $stream )
        {
           
$return[] = $stream;
        }
       
        return
$return;
    }
       
   
/**
     * Get my stream
     *
     * @return    \IPS\nexus\Support\Stream
     */
   
public static function myStream()
    {
       
$streamId = isset( \IPS\Request::i()->cookie['support_stream'] ) ? \IPS\Request::i()->cookie['support_stream'] : 'open';
        try
        {
           
$stream = \IPS\nexus\Support\Stream::load( $streamId );
        }
        catch ( \
OutOfRangeException $e )
        {
           
$stream = \IPS\nexus\Support\Stream::load( 'open' );
        }
        return
$stream;
    }
   
   
/**
     * Load
     *
     * @param    mixed    $keyOrId    The key or ID number
     * @return    \IPS\nexus\Support\Stream
     */
   
public static function load( $id, $idField=NULL, $extraWhereClause=NULL )
    {
        switch (
$id )
        {
            case
'open':
               
$return = new static;
               
$return->id = 'open';
               
$return->title = \IPS\Member::loggedIn()->language()->addToStack('support_stream_open');
               
$return->departments = NULL;
               
$return->statuses = iterator_to_array( \IPS\Db::i()->select( 'status_id', 'nexus_support_statuses', array( 'status_open=1' ) ) );
               
$return->severities = NULL;
               
$return->staff = NULL;
               
$return->from_email = NULL;
               
$return->search_term = NULL;
               
$return->started = NULL;
               
$return->last_new_reply = NULL;
               
$return->last_reply = NULL;
               
$return->last_staff_reply = NULL;
               
$return->tracked = FALSE;
                return
$return;
               
            case
'assigned':
               
$return = new static;
               
$return->id = 'assigned';
               
$return->title = \IPS\Member::loggedIn()->language()->addToStack('support_stream_assigned');
               
$return->departments = NULL;
               
$return->statuses = iterator_to_array( \IPS\Db::i()->select( 'status_id', 'nexus_support_statuses', array( 'status_open=1' ) ) );
               
$return->severities = NULL;
               
$return->staff = 'me';
               
$return->from_email = NULL;
               
$return->search_term = NULL;
               
$return->started = NULL;
               
$return->last_new_reply = NULL;
               
$return->last_reply = NULL;
               
$return->last_staff_reply = NULL;
               
$return->tracked = FALSE;
                return
$return;
               
            case
'tracked':
               
$return = new static;
               
$return->id = 'tracked';
               
$return->title = \IPS\Member::loggedIn()->language()->addToStack('support_stream_tracked');
               
$return->departments = NULL;
               
$return->statuses = NULL;
               
$return->severities = NULL;
               
$return->staff = NULL;
               
$return->from_email = NULL;
               
$return->search_term = NULL;
               
$return->started = NULL;
               
$return->last_new_reply = NULL;
               
$return->last_reply = NULL;
               
$return->last_staff_reply = NULL;
               
$return->tracked = TRUE;
                return
$return;            

            default:
                return
parent::load( $id, $idField, $extraWhereClause );
        }
    }
   
   
/**
     * Customer Stream
     *
     * @param    \IPS\nexus\Customer    $customer    The customer
     * @return    \IPS\nexus\Support\Stream
     */
   
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->departments = NULL;
       
$return->statuses = NULL;
       
$return->severities = NULL;
       
$return->staff = NULL;
       
$return->from_email = $customer->email;
       
$return->search_term = NULL;
       
$return->started = NULL;
       
$return->last_new_reply = NULL;
       
$return->last_reply = NULL;
       
$return->last_staff_reply = NULL;
       
$return->tracked = FALSE;
        return
$return;
    }
   
   
/**
     * Create from form
     *
     * @param    array    $values    Values from the form
     * @return    \IPS\nexus\Support\Stream
     */
   
public static function createFromForm( $values )
    {
       
$return = new static;
       
$return->updateFromForm( $values );
       
$return->temporary = TRUE;
       
$return->owner = \IPS\Member::loggedIn()->member_id;
       
$return->title = \IPS\Member::loggedIn()->language()->get('stream_default_title');
       
$return->save();
        return
$return;            
    }
   
   
/**
     * Update from form
     *
     * @param    array    $values    Values from the form
     * @return    void
     */
   
public function updateFromForm( $values )
    {
       
$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->tracked = (bool) $values['r_tracked'];
    }
   
   
/**
     * Convert arrays
     *
     * @param    mixed    $key    Key
     * @return    mixed    Value from the datastore
     */
   
public function __get( $key )
    {
       
$return = parent::__get( $key );
       
        if (
$return !== NULL and in_array( $key, array( 'departments', 'statuses', 'severities', 'staff' ) ) and $return !== 'me' )
        {
           
$return = explode( ',', $return );
        }
       
        return
$return;
    }
   
   
/**
     * Set value in data store
     *
     * @see        \IPS\Patterns\ActiveRecord::save
     * @param    mixed    $key    Key
     * @param    mixed    $value    Value
     * @return    void
     */
   
public function __set( $key, $value )
    {
        if (
is_array( $value ) and in_array( $key, array( 'departments', 'statuses', 'severities', 'staff' ) ) )
        {
           
$value = implode( ',', $value );
        }
       
        return
parent::__set( $key, $value );
    }
   
   
/**
     * Get form
     *
     * @param    \IPS\nexus\Support\Stream    $selectedStream    The stream to show as selected
     * @param    \IPS\Http\Url                $url            The URL to submit to
     * @return    \IPS\Helpers\Form
     */
   
public function form( Stream $selectedStream = NULL, \IPS\Http\Url $url )
    {
       
/* Init */
       
$form = new \IPS\Helpers\Form( 'form', 'show_results', $url );
       
$form->class = 'ipsForm_vertical';
       
       
/* Streams */
       
$form->addTab('streams');
       
$form->add( new \IPS\Helpers\Form\Custom( 'stream', $selectedStream ? $selectedStream->id : 'custom', FALSE, array(
           
'getHtml'    => function( $input ) {
                return \
IPS\Theme::i()->getTemplate('support')->filterFormStream( $input, \IPS\nexus\Support\Stream::myStreams( \IPS\Member::loggedIn() ) );
            }
        ) ) );
       
       
/* Departments */
       
$form->addTab('first');
       
$departments = array();
        foreach ( \
IPS\nexus\Support\Department::departmentsWithPermission() as $department )
        {
           
$departments[ $department->_id ] = $department->_title;
        }
       
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'r_department', $this->departments ?: array_keys( $departments ), FALSE, array( 'options' => $departments ) ) );
       
       
/* Statuses */
       
$statuses = array();
       
$openStatuses = array();
        foreach ( \
IPS\nexus\Support\Status::roots() as $status )
        {
           
$statuses[ $status->_id ] = $status->_title;
            if (
$status->open )
            {
               
$openStatuses[] = $status->_id;
            }
        }
       
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'r_status', $this->statuses ?: $openStatuses, FALSE, array( 'options' => $statuses ) ) );
       
       
/* Severities */
       
$form->addTab('second');
       
$severities = array();
        foreach ( \
IPS\nexus\Support\Severity::roots() as $severity )
        {
           
$severities[ $severity->_id ] = $severity->_title;
        }
       
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'r_severity', $this->severities ?: array_keys( $severities ), FALSE, array( 'options' => $severities ) ) );
       
       
/* Assigned To */
       
$staff = \IPS\nexus\Support\Request::staff();
       
$staff[0] = 'unassigned';
       
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'r_staff', $this->staff ?: array_keys( $staff ), FALSE, array( 'options' => $staff ) ) );
       
       
/* Tracked */
       
$form->add( new \IPS\Helpers\Form\YesNo( 'r_tracked', $this->tracked, FALSE ) );
       
       
/* Customer email */
       
$form->addTab('third');
       
$form->add( new \IPS\Helpers\Form\Email( 'r_email', $this->from_email ) );
       
       
/* Search text */
       
$form->add( new \IPS\Helpers\Form\Text( 'r_search', $this->search_term ) );

       
/* Time frame */
       
$timeFrameOptions = array(
           
'getHtml'    => function( $input ) {
                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 ) );
       
       
/* Return */
       
return $form;
    }
   
   
/**
     * Get where clause for results
     *
     * @param    $member        Staff member, or NULL for no permission restriction
     * @return    array
     */
   
public function _whereClause( $member )
    {
       
/* Init where clause */
       
$where = array();

       
/* Departments */
       
$departments = NULL;
        if (
$this->departments )
        {
            if (
$member )
            {
               
$departments = array_intersect( $this->departments, array_keys( iterator_to_array( \IPS\nexus\Support\Department::departmentsWithPermission( $member ) ) ) );
            }
            else
            {
               
$departments = $this->departments;
            }
        }
        elseif (
$member )
        {
           
$departments = array_keys( iterator_to_array( \IPS\nexus\Support\Department::departmentsWithPermission( $member ) ) );
        }
        if (
$departments )
        {
           
$where[] = array( \IPS\Db::i()->in( 'r_department', $departments ) );
        }
       
       
/* Statuses */
       
if ( $this->statuses )
        {
           
$where[] = array( \IPS\Db::i()->in( 'r_status', $this->statuses ) );
        }
       
       
/* Severities */
       
if ( $this->severities )
        {
           
$where[] = array( \IPS\Db::i()->in( 'r_severity', $this->severities ) );
        }
       
       
/* Staff */
       
if ( $this->staff )
        {
            if (
$this->staff === 'me' )
            {
               
$where[] = array( 'r_staff=?', $member->member_id );
            }
            else
            {
               
$where[] = array( \IPS\Db::i()->in( 'r_staff', $this->staff ) );
            }
        }
               
       
/* From */
       
if ( $this->from_email )
        {
           
$fromMember = \IPS\Member::load( $this->from_email, 'email' );
            if (
$fromMember->member_id )
            {
               
$where[] = array( '( r_member=? OR r_email=? )', $fromMember->member_id, $fromMember->email );
            }
            else
            {
               
$where[] = array( '( r_email=? )', $this->from_email );
            }
        }
       
       
/* Search term */
       
if ( $this->search_term )
        {
           
$subQuery= \IPS\Content\Search\Mysql\Query::matchClause('reply_post', $this->search_term);
           
$where[] = array( 'r_id IN(?)', \IPS\Db::i()->select( 'reply_request', 'nexus_support_replies', $subQuery ) );
        }
       
       
/* Tracked? */
       
if ( $this->tracked and $member )
        {
           
$where[] = array( 'r_id IN(?)', \IPS\Db::i()->select( 'request_id', 'nexus_support_tracker', array( 'member_id=?', $member->member_id ) ) );
        }
       
       
/* Time limits */
       
foreach ( array( 'started', 'last_new_reply', 'last_reply', 'last_staff_reply' ) as $k )
        {
            if (
$this->$k )
            {
               
$where[] = array( "r_{$k}<?", time() - ( 3600 * $this->$k ) );
            }
        }
       
       
/* Return */
       
return $where;
    }
   
   
/**
     * Get count
     *
     * @param    $member        Staff member, or NULL for no permission restriction
     * @return    \IPS\Patterns\ActiveRecordIterator
     */
   
public function count( $member = NULL )
    {        
        return \
IPS\Db::i()->select( 'COUNT(*)', 'nexus_support_requests', $this->_whereClause( $member ) )->first();
    }
   
   
/**
     * Get results
     *
     * @param    $member        Staff member, or NULL for no permission restriction
     * @return    \IPS\Patterns\ActiveRecordIterator
     */
   
public function results( $member = NULL, $order='r_id DESC', $page = 1, $perPage = 25 )
    {
       
$query = \IPS\Db::i()->select( '*', 'nexus_support_requests', $this->_whereClause( $member ), $order, array( ( $page - 1 ) * $perPage, $perPage ) );
       
        if (
mb_strpos( $order, 'dpt_position' ) !== FALSE )
        {
           
$query->join( 'nexus_support_staff_dpt_order', 'nexus_support_staff_dpt_order.department_id=r_department AND nexus_support_staff_dpt_order.staff_id=' . $member->member_id );
           
$query->join( 'nexus_support_departments', 'dpt_id=r_department' );
        }
        if (
mb_strpos( $order, 'sev_position' ) !== FALSE )
        {
           
$query->join( 'nexus_support_severities', 'sev_id=r_severity' );
        }
       
       
$query->setKeyField('r_id');
       
       
$results = new \IPS\Patterns\ActiveRecordIterator( $query, 'IPS\nexus\Support\Request' );        
        return
$results;
    }
}