[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/conpherence/controller/ -> ConpherenceListController.php (source)

   1  <?php
   2  
   3  final class ConpherenceListController extends ConpherenceController {
   4  
   5    const SELECTED_MODE = 'selected';
   6    const UNSELECTED_MODE = 'unselected';
   7    const PAGING_MODE = 'paging';
   8  
   9    private $conpherenceID;
  10  
  11    public function setConpherenceID($conpherence_id) {
  12      $this->conpherenceID = $conpherence_id;
  13      return $this;
  14    }
  15    public function getConpherenceID() {
  16      return $this->conpherenceID;
  17    }
  18  
  19    public function willProcessRequest(array $data) {
  20      $this->setConpherenceID(idx($data, 'id'));
  21    }
  22  
  23    /**
  24     * Three main modes of operation...
  25     *
  26     * 1 - /conpherence/ - UNSELECTED_MODE
  27     * 2 - /conpherence/<id>/ - SELECTED_MODE
  28     * 3 - /conpherence/?direction='up'&... - PAGING_MODE
  29     *
  30     * UNSELECTED_MODE is not an Ajax request while the other two are Ajax
  31     * requests.
  32     */
  33    private function determineMode() {
  34      $request = $this->getRequest();
  35  
  36      $mode = self::UNSELECTED_MODE;
  37      if ($request->isAjax()) {
  38        if ($request->getStr('direction')) {
  39          $mode = self::PAGING_MODE;
  40        } else {
  41          $mode = self::SELECTED_MODE;
  42        }
  43      }
  44  
  45      return $mode;
  46    }
  47    public function processRequest() {
  48      $request = $this->getRequest();
  49      $user = $request->getUser();
  50      $title = pht('Conpherence');
  51      $conpherence = null;
  52  
  53      $scroll_up_participant = $this->getEmptyParticipant();
  54      $scroll_down_participant = $this->getEmptyParticipant();
  55      $too_many = ConpherenceParticipantQuery::LIMIT + 1;
  56      $all_participation = array();
  57  
  58      $mode = $this->determineMode();
  59      switch ($mode) {
  60        case self::SELECTED_MODE:
  61          $conpherence_id = $this->getConpherenceID();
  62          $conpherence = id(new ConpherenceThreadQuery())
  63            ->setViewer($user)
  64            ->withIDs(array($conpherence_id))
  65            ->executeOne();
  66          if (!$conpherence) {
  67            return new Aphront404Response();
  68          }
  69          if ($conpherence->getTitle()) {
  70            $title = $conpherence->getTitle();
  71          }
  72          $cursor = $conpherence->getParticipant($user->getPHID());
  73          $data = $this->loadParticipationWithMidCursor($cursor);
  74          $all_participation = $data['participation'];
  75          $scroll_up_participant = $data['scroll_up_participant'];
  76          $scroll_down_participant = $data['scroll_down_participant'];
  77          break;
  78        case self::PAGING_MODE:
  79          $direction = $request->getStr('direction');
  80          $id = $request->getInt('participant_id');
  81          $date_touched = $request->getInt('date_touched');
  82          $conpherence_phid = $request->getStr('conpherence_phid');
  83          if ($direction == 'up') {
  84            $order = ConpherenceParticipantQuery::ORDER_NEWER;
  85          } else {
  86            $order = ConpherenceParticipantQuery::ORDER_OLDER;
  87          }
  88          $scroller_participant = id(new ConpherenceParticipant())
  89            ->makeEphemeral()
  90            ->setID($id)
  91            ->setDateTouched($date_touched)
  92            ->setConpherencePHID($conpherence_phid);
  93          $participation = id(new ConpherenceParticipantQuery())
  94            ->withParticipantPHIDs(array($user->getPHID()))
  95            ->withParticipantCursor($scroller_participant)
  96            ->setOrder($order)
  97            ->setLimit($too_many)
  98            ->execute();
  99          if (count($participation) == $too_many) {
 100            if ($direction == 'up') {
 101              $node = $scroll_up_participant = reset($participation);
 102            } else {
 103              $node = $scroll_down_participant = end($participation);
 104            }
 105            unset($participation[$node->getConpherencePHID()]);
 106          }
 107          $all_participation = $participation;
 108          break;
 109        case self::UNSELECTED_MODE:
 110        default:
 111          $too_many = ConpherenceParticipantQuery::LIMIT + 1;
 112          $all_participation = id(new ConpherenceParticipantQuery())
 113            ->withParticipantPHIDs(array($user->getPHID()))
 114            ->setLimit($too_many)
 115            ->execute();
 116          if (count($all_participation) == $too_many) {
 117            $node = end($all_participation);
 118            unset($all_participation[$node->getConpherencePHID()]);
 119            $scroll_down_participant = $node;
 120          }
 121          break;
 122      }
 123  
 124      $threads = $this->loadConpherenceThreadData(
 125        $all_participation);
 126  
 127      $thread_view = id(new ConpherenceThreadListView())
 128        ->setUser($user)
 129        ->setBaseURI($this->getApplicationURI())
 130        ->setThreads($threads)
 131        ->setScrollUpParticipant($scroll_up_participant)
 132        ->setScrollDownParticipant($scroll_down_participant);
 133  
 134      switch ($mode) {
 135        case self::SELECTED_MODE:
 136          $response = id(new AphrontAjaxResponse())->setContent($thread_view);
 137          break;
 138        case self::PAGING_MODE:
 139          $thread_html = $thread_view->renderThreadsHTML();
 140          $phids = array_keys($participation);
 141          $content = array(
 142            'html' => $thread_html,
 143            'phids' => $phids,
 144          );
 145          $response = id(new AphrontAjaxResponse())->setContent($content);
 146          break;
 147        case self::UNSELECTED_MODE:
 148        default:
 149          $layout = id(new ConpherenceLayoutView())
 150            ->setBaseURI($this->getApplicationURI())
 151            ->setThreadView($thread_view)
 152            ->setRole('list');
 153          if ($conpherence) {
 154            $layout->setHeader($this->buildHeaderPaneContent($conpherence));
 155            $layout->setThread($conpherence);
 156          } else {
 157            $layout->setHeader(
 158              $this->buildHeaderPaneContent(
 159                id(new ConpherenceThread())
 160                ->makeEphemeral()));
 161          }
 162          $response = $this->buildApplicationPage(
 163            $layout,
 164            array(
 165              'title' => $title,
 166            ));
 167          break;
 168      }
 169  
 170      return $response;
 171  
 172    }
 173  
 174    /**
 175     * Handles the curious case when we are visiting a conpherence directly
 176     * by issuing two separate queries. Otherwise, additional conpherences
 177     * are fetched asynchronously. Note these can be earlier or later
 178     * (up or down), depending on what conpherence was selected on initial
 179     * load.
 180     */
 181    private function loadParticipationWithMidCursor(
 182      ConpherenceParticipant $cursor) {
 183  
 184      $user = $this->getRequest()->getUser();
 185  
 186      $scroll_up_participant = $this->getEmptyParticipant();
 187      $scroll_down_participant = $this->getEmptyParticipant();
 188  
 189      // Note this is a bit dodgy since there may be less than this
 190      // amount in either the up or down direction, thus having us fail
 191      // to fetch LIMIT in total. Whatevs for now and re-visit if we're
 192      // fine-tuning this loading process.
 193      $too_many = ceil(ConpherenceParticipantQuery::LIMIT / 2) + 1;
 194      $participant_query = id(new ConpherenceParticipantQuery())
 195        ->withParticipantPHIDs(array($user->getPHID()))
 196        ->setLimit($too_many);
 197      $current_selection_epoch = $cursor->getDateTouched();
 198      $set_one = $participant_query
 199        ->withParticipantCursor($cursor)
 200        ->setOrder(ConpherenceParticipantQuery::ORDER_NEWER)
 201        ->execute();
 202  
 203      if (count($set_one) == $too_many) {
 204        $node = reset($set_one);
 205        unset($set_one[$node->getConpherencePHID()]);
 206        $scroll_up_participant = $node;
 207      }
 208  
 209      $set_two = $participant_query
 210        ->withParticipantCursor($cursor)
 211        ->setOrder(ConpherenceParticipantQuery::ORDER_OLDER)
 212        ->execute();
 213  
 214      if (count($set_two) == $too_many) {
 215        $node = end($set_two);
 216        unset($set_two[$node->getConpherencePHID()]);
 217        $scroll_down_participant = $node;
 218      }
 219  
 220      $participation = array_merge(
 221        $set_one,
 222        $set_two);
 223  
 224      return array(
 225        'scroll_up_participant' => $scroll_up_participant,
 226        'scroll_down_participant' => $scroll_down_participant,
 227        'participation' => $participation,
 228      );
 229    }
 230  
 231    private function loadConpherenceThreadData($participation) {
 232      $user = $this->getRequest()->getUser();
 233      $conpherence_phids = array_keys($participation);
 234      $conpherences = array();
 235      if ($conpherence_phids) {
 236        $conpherences = id(new ConpherenceThreadQuery())
 237          ->setViewer($user)
 238          ->withPHIDs($conpherence_phids)
 239          ->needParticipantCache(true)
 240          ->execute();
 241  
 242        // this will re-sort by participation data
 243        $conpherences = array_select_keys($conpherences, $conpherence_phids);
 244      }
 245  
 246      return $conpherences;
 247    }
 248  
 249    private function getEmptyParticipant() {
 250      return id(new ConpherenceParticipant())
 251        ->makeEphemeral();
 252    }
 253  
 254  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1