<?php
/**
  * Ahead WebSoft Technologies Pvt Ltd.
  * @copyright  Copyright 2006-2026 Ahead WebSoft Technologies Pvt Ltd.
  * @license    https://www.socialengine.com/policies
*/
class Event_TopicController extends Core_Controller_Action_Standard
{
  public function init()
  {
    if( Engine_Api::_()->core()->hasSubject() ) return;

    /*
    if( 0 !== ($post_id = (int) $this->_getParam('post_id')) &&
        null !== ($post = Engine_Api::_()->getItem('event_post', $post_id)) )
    {
      Engine_Api::_()->core()->setSubject($post);
    }
    
    else */if( 0 !== ($topic_id = (int) $this->_getParam('topic_id')) &&
        null !== ($topic = Engine_Api::_()->getItem('event_topic', $topic_id)) )
    {
      Engine_Api::_()->core()->setSubject($topic);
    }
    
    else if( 0 !== ($event_id = (int) $this->_getParam('event_id')) &&
        null !== ($event = Engine_Api::_()->getItem('event', $event_id)) )
    {
      Engine_Api::_()->core()->setSubject($event);
    }

    $this->_helper->requireUser->addActionRequires(array(
      'close', 'create', 'delete', 'post', 'rename', 'reply', 'sticky', 'watch',
    ));

    $this->_helper->requireSubject->setActionRequireTypes(array(
      'close' => 'event_topic',
      'create' => 'event',
      'delete' => 'event_topic',
      'index' => 'event',
      'post' => 'event_topic',
      'rename' => 'event_topic',
      'reply' => 'event_topic',
      'sticky' => 'event_topic',
      'view' => 'event_topic',
      'watch' => 'event_topic',
    ));
  }
  
  public function indexAction()
  {
    if( !$this->_helper->requireSubject('event')->isValid() ) return;
    if( !$this->_helper->requireAuth()->setAuthParams(null, null, 'view')->isValid() ) return;

    $this->view->event = $event = Engine_Api::_()->core()->getSubject();
    
    $table = Engine_Api::_()->getDbtable('topics', 'event');
    $select = $table->select()
      ->where('event_id = ?', $event->getIdentity())
      ->order('sticky DESC')
      ->order('modified_date DESC');

    $this->view->paginator = $paginator = Zend_Paginator::factory($select);
    $this->view->can_post = $can_post = $this->_helper->requireAuth->setAuthParams(null, null, 'comment')->checkRequire();
    $paginator->setCurrentPageNumber($this->_getParam('page'));
  }
  
  public function viewAction()
  {
    if( !$this->_helper->requireSubject('event_topic')->isValid() ) return;
    if( !$this->_helper->requireAuth()->setAuthParams(null, null, 'view')->isValid() ) return;

    $this->view->viewer = $viewer = Engine_Api::_()->user()->getViewer();
    $this->view->topic = $topic = Engine_Api::_()->core()->getSubject();
    $this->view->event = $event = $topic->getParentEvent();
    $this->view->canEdit = $topic->canEdit($viewer);
    $this->view->canDelete = $topic->canDelete($viewer);
    $this->view->canPostCreate = $canPostCreate = $topic->canPostCreate($viewer);
    $this->view->canPostEdit = $topic->canPostEdit($viewer);
    $this->view->canPostDelete = $topic->canPostDelete($viewer);
    $this->view->canAdminEdit = Engine_Api::_()->authorization()->isAllowed($event, null, 'edit');
    $this->view->canPost = $canPost = $event->authorization()->isAllowed(null,  'topic_create');

    //$this->view->canEdit = $canEdit = $event->authorization()->isAllowed($viewer, 'edit');
    $this->view->canPost = $canPost = $event->authorization()->isAllowed($viewer, 'comment');
    $this->view->canAdminEdit = Engine_Api::_()->authorization()->isAllowed($event, null, 'edit');
    
    if( !$event || !$event->getIdentity() || ((!$event->approved) && !$event->isOwner($viewer)) ) {
      if(!empty($viewer->getIdentity()) && $viewer->isAdmin()) {
      } else
        return $this->_helper->requireSubject->forward();
    }

    if( !$viewer || !$viewer->getIdentity() || $viewer->getIdentity() != $topic->user_id ) {
      $topic->view_count = new Zend_Db_Expr('view_count + 1');
      $topic->save();
    }

    $isWatching = null;
    if( $viewer->getIdentity() ) {
      $topicWatchesTable = Engine_Api::_()->getDbtable('topicWatches', 'event');
      $isWatching = $topicWatchesTable
        ->select()
        ->from($topicWatchesTable->info('name'), 'watch')
        ->where('resource_id = ?', $event->getIdentity())
        ->where('topic_id = ?', $topic->getIdentity())
        ->where('user_id = ?', $viewer->getIdentity())
        ->limit(1)
        ->query()
        ->fetchColumn(0)
        ;
      if( false === $isWatching ) {
        $isWatching = null;
      } else {
        $isWatching = (bool) $isWatching;
      }
    }
    $this->view->isWatching = $isWatching;

    // @todo implement scan to post
    $this->view->post_id = $post_id = (int) $this->_getParam('post');

    $settings = Engine_Api::_()->getApi('settings', 'core');
    $this->view->decode_bbcode = $settings->getSetting('forum_bbcode');

    $table = Engine_Api::_()->getDbtable('posts', 'event');
    $select = $table->select()
      ->where('event_id = ?', $event->getIdentity())
      ->where('topic_id = ?', $topic->getIdentity())
      ->order('creation_date ASC');
    
    $this->view->paginator = $paginator = Zend_Paginator::factory($select);

    // Skip to page of specified post
    if( 0 !== ($post_id = (int) $this->_getParam('post_id')) &&
        null !== ($post = Engine_Api::_()->getItem('event_post', $post_id)) )
    {
      $icpp = $paginator->getItemCountPerPage();
      $page = ceil(($post->getPostIndex() + 1) / $icpp);
      $paginator->setCurrentPageNumber($page);
    }

    // Use specified page
    else if( 0 !== ($page = (int) $this->_getParam('page')) )
    {
      $paginator->setCurrentPageNumber($this->_getParam('page'));
    }

    if( $canPostCreate && !$topic->closed ) {
      $this->view->form = $form = new Event_Form_Post_Create();
      $form->populate(array(
        'topic_id' => $topic->getIdentity(),
        'ref' => $topic->getHref(),
        'watch' => ( false === $isWatching ? '0' : '1' ),
      ));
    }
  }

  public function createAction()
  {
    if( !$this->_helper->requireUser()->isValid() ) return;
    if( !$this->_helper->requireSubject('event')->isValid() ) return;
    if( !$this->_helper->requireAuth()->setAuthParams(null, null, 'comment')->isValid() ) return;

    $this->view->event = $event = Engine_Api::_()->core()->getSubject();
    $this->view->viewer = $viewer = Engine_Api::_()->user()->getViewer();

    // Make form
    $this->view->form = $form = new Event_Form_Topic_Create();

    // Check method/data
    if( !$this->getRequest()->isPost() ) {
      return;
    }

    if( !$form->isValid($this->getRequest()->getPost()) ) {
      $validateFields = Engine_Api::_()->core()->validateFormFields($form);
      if(is_countable($validateFields) && engine_count($validateFields)){
        echo json_encode(array('status' => false, 'error_message' => $validateFields));die;
      }
    }

    // Process
    $values = $form->getValues();
    $values['user_id'] = $viewer->getIdentity();
    $values['event_id'] = $event->getIdentity();

    $topicTable = Engine_Api::_()->getDbtable('topics', 'event');
    $topicWatchesTable = Engine_Api::_()->getDbtable('topicWatches', 'event');
    $postTable = Engine_Api::_()->getDbtable('posts', 'event');

    $db = $event->getTable()->getAdapter();
    $db->beginTransaction();

    try
    {
      // Create topic
      $topic = $topicTable->createRow();
      $topic->setFromArray($values);
      $topic->save();

      // Create post
      $values['topic_id'] = $topic->topic_id;
      
      $post = $postTable->createRow();
      $values['body'] = Engine_Text_BBCode::prepare($values['body']);
      $post->setFromArray($values);
      $post->save();
      
      //Save editor images
      Engine_Api::_()->core()->saveTinyMceImages($values['body'], $post);

      // Create topic watch
      $topicWatchesTable->insert(array(
        'resource_id' => $event->getIdentity(),
        'topic_id' => $topic->getIdentity(),
        'user_id' => $viewer->getIdentity(),
        'watch' => (bool) $values['watch'],
      ));
      
      // Add activity
      $activityApi = Engine_Api::_()->getDbtable('actions', 'activity');
      $action = $activityApi->addActivity($viewer, $event, 'event_topic_create', null, array('child_id' => $topic->getIdentity()));
      if( $action ) {
        $action->attach($topic, Activity_Model_Action::ATTACH_DESCRIPTION);
      }

      $db->commit();
    }

    catch( Exception $e )
    {
      $db->rollBack();
      //throw $e;
      $errors[] = array('errorMessage' => $e->getMessage());
      echo json_encode(array('status' => false, 'error_message' => $errors));die;
    }

    // Redirect to the post
    //$this->_redirectCustom($post);
    echo json_encode(array('status' => true, 'redirectURL' => $post->getHref()));die;
  }
  
  public function postAction()
  {
    if( !$this->_helper->requireUser()->isValid() ) return;
    if( !$this->_helper->requireSubject('event_topic')->isValid() ) return;
    if( !$this->_helper->requireAuth()->setAuthParams(null, null, 'comment')->isValid() ) return;

    $this->view->topic = $topic = Engine_Api::_()->core()->getSubject();
    $this->view->event = $event = $topic->getParentEvent();

    if( $topic->closed ) {
      $this->view->status = false;
      $this->view->message = Zend_Registry::get('Zend_Translate')->_('This has been closed for posting.');
      return;
    }
    
    // Make form
    $this->view->form = $form = new Event_Form_Post_Create();

    // Check method/data
    if( !$this->getRequest()->isPost() ) {
      return;
    }

    if( !$form->isValid($this->getRequest()->getPost()) ) {
      return;
    }

    // Process
    $viewer = Engine_Api::_()->user()->getViewer();
    $topicOwner = $topic->getOwner();
    $isOwnTopic = $viewer->isSelf($topicOwner);

    $postTable = Engine_Api::_()->getDbtable('posts', 'event');
    $topicWatchesTable = Engine_Api::_()->getDbtable('topicWatches', 'event');
    $userTable = Engine_Api::_()->getItemTable('user');
    $notifyApi = Engine_Api::_()->getDbtable('notifications', 'activity');
    $activityApi = Engine_Api::_()->getDbtable('actions', 'activity');

    $values = $form->getValues();
    $values['user_id'] = $viewer->getIdentity();
    $values['event_id'] = $event->getIdentity();
    $values['topic_id'] = $topic->getIdentity();

    $watch = (bool) $values['watch'];
    $isWatching = $topicWatchesTable
      ->select()
      ->from($topicWatchesTable->info('name'), 'watch')
      ->where('resource_id = ?', $event->getIdentity())
      ->where('topic_id = ?', $topic->getIdentity())
      ->where('user_id = ?', $viewer->getIdentity())
      ->limit(1)
      ->query()
      ->fetchColumn(0)
      ;

    $db = $event->getTable()->getAdapter();
    $db->beginTransaction();

    try
    {
      // Create post
      $post = $postTable->createRow();
      $post->setFromArray($values);
      $post->save();
      
      //Save editor images
      Engine_Api::_()->core()->saveTinyMceImages($values['body'], $post);

      // Watch
      if( false === $isWatching ) {
        $topicWatchesTable->insert(array(
          'resource_id' => $event->getIdentity(),
          'topic_id' => $topic->getIdentity(),
          'user_id' => $viewer->getIdentity(),
          'watch' => (bool) $watch,
        ));
      } else if( $watch != $isWatching ) {
        $topicWatchesTable->update(array(
          'watch' => (bool) $watch,
        ), array(
          'resource_id = ?' => $event->getIdentity(),
          'topic_id = ?' => $topic->getIdentity(),
          'user_id = ?' => $viewer->getIdentity(),
        ));
      }
      

      // Activity
      $action = $activityApi->addActivity($viewer, $event, 'event_topic_reply', null, array('child_id' => $topic->getIdentity()));
      if( $action ) {
        $action->attach($post, Activity_Model_Action::ATTACH_DESCRIPTION);
      }

      // Notifications
      $notifyUserIds = $topicWatchesTable->select()
        ->from($topicWatchesTable->info('name'), 'user_id')
        ->where('resource_id = ?', $event->getIdentity())
        ->where('topic_id = ?', $topic->getIdentity())
        ->where('watch = ?', 1)
        ->query()
        ->fetchAll(Zend_Db::FETCH_COLUMN)
        ;

      foreach( $userTable->find($notifyUserIds) as $notifyUser ) {
        // Don't notify self
        if( $notifyUser->isSelf($viewer) ) {
          continue;
        }

        if( $notifyUser->isSelf($topicOwner) ) {
          $type = 'event_discussion_response';
        } else {
          $type = 'event_discussion_reply';
        }
        $notifyApi->addNotification($notifyUser, $viewer, $topic, $type, array(
          'message' => $this->view->BBCode($post->body),
        ));
      }
      
      $db->commit();
    }

    catch( Exception $e )
    {
      $db->rollBack();
      throw $e;
    }

    // Redirect to the post
    echo json_encode(array('status' => true, 'redirectURL' => $post->getHref()));die;
    //$this->_redirectCustom($post);
  }

  public function stickyAction()
  {
    $topic = Engine_Api::_()->core()->getSubject('event_topic');
    $viewer = Engine_Api::_()->user()->getViewer();

    if( !$this->_helper->requireSubject('event_topic')->isValid() ) return;
    if( $viewer->getIdentity() != $topic->user_id){
      if( !$this->_helper->requireAuth()->setAuthParams(null, null, 'topic_edit')->isValid() ) return;
    }
    
    $table = $topic->getTable();
    $db = $table->getAdapter();
    $db->beginTransaction();

    try
    {
      $topic = Engine_Api::_()->core()->getSubject();
      $topic->sticky = ( null === $this->_getParam('sticky') ? !$topic->sticky : (bool) $this->_getParam('sticky') );
      $topic->save();

      $db->commit();
    }

    catch( Exception $e )
    {
      $db->rollBack();
      throw $e;
    }
    //echo json_encode(array('status' => true, 'redirectURL' => $topic->getHref()));die;
    $this->_redirectCustom($topic);
  }

  public function closeAction() {
 
    $topic = Engine_Api::_()->core()->getSubject();
    $viewer = Engine_Api::_()->user()->getViewer();

    if( !$this->_helper->requireSubject('event_topic')->isValid() ) return;
    if( $viewer->getIdentity() != $topic->user_id){
      if( !$this->_helper->requireAuth()->setAuthParams(null, null, 'topic_edit')->isValid() ) return;
    }
       
    $table = $topic->getTable();
    $db = $table->getAdapter();
    $db->beginTransaction();

    try
    {
      $topic = Engine_Api::_()->core()->getSubject();
      $topic->closed = ( null === $this->_getParam('closed') ? !$topic->closed : (bool) $this->_getParam('closed') );
      $topic->save();

      $db->commit();
    }

    catch( Exception $e )
    {
      $db->rollBack();
      throw $e;
    }
    //echo json_encode(array('status' => true, 'redirectURL' => $topic->getHref()));die;
    $this->_redirectCustom($topic);
  }

  public function renameAction()
  {
    $topic = Engine_Api::_()->core()->getSubject('event_topic');
    $viewer = Engine_Api::_()->user()->getViewer();

    if( !$this->_helper->requireSubject('event_topic')->isValid() ) return;
    if( $viewer->getIdentity() != $topic->user_id){
      if( !$this->_helper->requireAuth()->setAuthParams(null, null, 'topic_edit')->isValid() ) return;
    }

    $this->view->form = $form = new Event_Form_Topic_Rename();

    if( !$this->getRequest()->isPost() )
    {
      $form->title->setValue(htmlspecialchars_decode($topic->title));
      return;
    }

    if( !$form->isValid($this->getRequest()->getPost()) )
    {
      return;
    }

    $table = $topic->getTable();
    $db = $table->getAdapter();
    $db->beginTransaction();

    try
    {
      $title = $form->getValue('title');

      $topic = Engine_Api::_()->core()->getSubject();
      $topic->title = htmlspecialchars($title);
      $topic->save();

      $db->commit();
    }

    catch( Exception $e )
    {
      $db->rollBack();
      throw $e;
    }

    return $this->_forward('success', 'utility', 'core', array(
      'messages' => array(Zend_Registry::get('Zend_Translate')->_('Topic renamed.')),
      'layout' => 'default-simple',
      'parentRefresh' => true,
    ));
  }

  public function deleteAction()
  {

    $topic = Engine_Api::_()->core()->getSubject('event_topic');
    $viewer = Engine_Api::_()->user()->getViewer();

    if( !$this->_helper->requireSubject('event_topic')->isValid() ) return;
    if( $viewer->getIdentity() != $topic->user_id){
      if( !$this->_helper->requireAuth()->setAuthParams(null, null, 'topic_delete')->isValid() ) return;
    }

    $this->view->form = $form = new Event_Form_Topic_Delete();

    if( !$this->getRequest()->isPost() )
    {
      return;
    }

    if( !$form->isValid($this->getRequest()->getPost()) )
    {
      return;
    }

    $table = $topic->getTable();
    $db = $table->getAdapter();
    $db->beginTransaction();

    try
    {
      $topic = Engine_Api::_()->core()->getSubject();
      $event = $topic->getParent('event');
      $topic->delete();

      $db->commit();
    }

    catch( Exception $e )
    {
      $db->rollBack();
      throw $e;
    }

    return $this->_forward('success', 'utility', 'core', array(
      'messages' => array(Zend_Registry::get('Zend_Translate')->_('Topic deleted.')),
      'layout' => 'default-simple',
      'parentRedirect' => $event->getHref(),
    ));
  }

  public function watchAction()
  {
    $topic = Engine_Api::_()->core()->getSubject();
    $event = Engine_Api::_()->getItem('event', $topic->event_id);
    $viewer = Engine_Api::_()->user()->getViewer();
    if( !$this->_helper->requireAuth()->setAuthParams($event, null, 'view')->isValid() ) {
      return;
    }

    $watch = $this->_getParam('watch', true);

    $topicWatchesTable = Engine_Api::_()->getDbtable('topicWatches', 'event');
    $db = $topicWatchesTable->getAdapter();
    $db->beginTransaction();

    try
    {
      $isWatching = $topicWatchesTable
        ->select()
        ->from($topicWatchesTable->info('name'), 'watch')
        ->where('resource_id = ?', $event->getIdentity())
        ->where('topic_id = ?', $topic->getIdentity())
        ->where('user_id = ?', $viewer->getIdentity())
        ->limit(1)
        ->query()
        ->fetchColumn(0)
        ;

      if( false === $isWatching ) {
        $topicWatchesTable->insert(array(
          'resource_id' => $event->getIdentity(),
          'topic_id' => $topic->getIdentity(),
          'user_id' => $viewer->getIdentity(),
          'watch' => (bool) $watch,
        ));
      } else if( $watch != $isWatching ) {
        $topicWatchesTable->update(array(
          'watch' => (bool) $watch,
        ), array(
          'resource_id = ?' => $event->getIdentity(),
          'topic_id = ?' => $topic->getIdentity(),
          'user_id = ?' => $viewer->getIdentity(),
        ));
      }

      $db->commit();
    }

    catch( Exception $e )
    {
      $db->rollBack();
      throw $e;
    }

    // echo json_encode(array('status' => true, 'redirectURL' => $topic->getHref()));die;
    $this->_redirectCustom($topic);
  }
}
