[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/phriction/controller/ -> PhrictionDiffController.php (source)

   1  <?php
   2  
   3  final class PhrictionDiffController extends PhrictionController {
   4  
   5    private $id;
   6  
   7    public function shouldAllowPublic() {
   8      return true;
   9    }
  10  
  11    public function willProcessRequest(array $data) {
  12      $this->id = $data['id'];
  13    }
  14  
  15    public function processRequest() {
  16      $request = $this->getRequest();
  17      $user = $request->getUser();
  18  
  19      $document = id(new PhrictionDocumentQuery())
  20        ->setViewer($user)
  21        ->withIDs(array($this->id))
  22        ->needContent(true)
  23        ->executeOne();
  24      if (!$document) {
  25        return new Aphront404Response();
  26      }
  27  
  28      $current = $document->getContent();
  29  
  30      $l = $request->getInt('l');
  31      $r = $request->getInt('r');
  32  
  33      $ref = $request->getStr('ref');
  34      if ($ref) {
  35        list($l, $r) = explode(',', $ref);
  36      }
  37  
  38      $content = id(new PhrictionContent())->loadAllWhere(
  39        'documentID = %d AND version IN (%Ld)',
  40        $document->getID(),
  41        array($l, $r));
  42      $content = mpull($content, null, 'getVersion');
  43  
  44      $content_l = idx($content, $l, null);
  45      $content_r = idx($content, $r, null);
  46  
  47      if (!$content_l || !$content_r) {
  48        return new Aphront404Response();
  49      }
  50  
  51      $text_l = $content_l->getContent();
  52      $text_r = $content_r->getContent();
  53  
  54      $text_l = phutil_utf8_hard_wrap($text_l, 80);
  55      $text_l = implode("\n", $text_l);
  56      $text_r = phutil_utf8_hard_wrap($text_r, 80);
  57      $text_r = implode("\n", $text_r);
  58  
  59      $engine = new PhabricatorDifferenceEngine();
  60      $changeset = $engine->generateChangesetFromFileContent($text_l, $text_r);
  61  
  62      $changeset->setOldProperties(
  63        array(
  64          'Title'   => $content_l->getTitle(),
  65        ));
  66      $changeset->setNewProperties(
  67        array(
  68          'Title'   => $content_r->getTitle(),
  69        ));
  70  
  71      $whitespace_mode = DifferentialChangesetParser::WHITESPACE_SHOW_ALL;
  72  
  73      $parser = new DifferentialChangesetParser();
  74      $parser->setChangeset($changeset);
  75      $parser->setRenderingReference("{$l},{$r}");
  76      $parser->setWhitespaceMode($whitespace_mode);
  77  
  78      $engine = new PhabricatorMarkupEngine();
  79      $engine->setViewer($user);
  80      $engine->process();
  81      $parser->setMarkupEngine($engine);
  82  
  83      $spec = $request->getStr('range');
  84      list($range_s, $range_e, $mask) =
  85        DifferentialChangesetParser::parseRangeSpecification($spec);
  86      $output = $parser->render($range_s, $range_e, $mask);
  87  
  88      if ($request->isAjax()) {
  89        return id(new PhabricatorChangesetResponse())
  90          ->setRenderedChangeset($output);
  91      }
  92  
  93      require_celerity_resource('differential-changeset-view-css');
  94      require_celerity_resource('syntax-highlighting-css');
  95      require_celerity_resource('phriction-document-css');
  96  
  97      Javelin::initBehavior('differential-show-more', array(
  98        'uri'         => '/phriction/diff/'.$document->getID().'/',
  99        'whitespace'  => $whitespace_mode,
 100      ));
 101  
 102      $slug = $document->getSlug();
 103  
 104      $revert_l = $this->renderRevertButton($content_l, $current);
 105      $revert_r = $this->renderRevertButton($content_r, $current);
 106  
 107      $crumbs = $this->buildApplicationCrumbs();
 108      $crumb_views = $this->renderBreadcrumbs($slug);
 109      foreach ($crumb_views as $view) {
 110        $crumbs->addCrumb($view);
 111      }
 112  
 113      $crumbs->addTextCrumb(
 114        pht('History'),
 115        PhrictionDocument::getSlugURI($slug, 'history'));
 116  
 117      $title = pht('Version %s vs %s', $l, $r);
 118  
 119      $header = id(new PHUIHeaderView())
 120        ->setHeader($title);
 121  
 122      $crumbs->addTextCrumb($title, $request->getRequestURI());
 123  
 124  
 125      $comparison_table = $this->renderComparisonTable(
 126        array(
 127          $content_r,
 128          $content_l,
 129        ));
 130  
 131      $navigation_table = null;
 132      if ($l + 1 == $r) {
 133        $nav_l = ($l > 1);
 134        $nav_r = ($r != $current->getVersion());
 135  
 136        $uri = $request->getRequestURI();
 137  
 138        if ($nav_l) {
 139          $link_l = phutil_tag(
 140            'a',
 141            array(
 142              'href' => $uri->alter('l', $l - 1)->alter('r', $r - 1),
 143              'class' => 'button',
 144            ),
 145            pht("\xC2\xAB Previous Change"));
 146        } else {
 147          $link_l = phutil_tag(
 148            'a',
 149            array(
 150              'href' => '#',
 151              'class' => 'button grey disabled',
 152            ),
 153            pht('Original Change'));
 154        }
 155  
 156        $link_r = null;
 157        if ($nav_r) {
 158          $link_r = phutil_tag(
 159            'a',
 160            array(
 161              'href' => $uri->alter('l', $l + 1)->alter('r', $r + 1),
 162              'class' => 'button',
 163            ),
 164            pht("Next Change \xC2\xBB"));
 165        } else {
 166          $link_r = phutil_tag(
 167            'a',
 168            array(
 169              'href' => '#',
 170              'class' => 'button grey disabled',
 171            ),
 172            pht('Most Recent Change'));
 173        }
 174  
 175        $navigation_table = phutil_tag(
 176          'table',
 177          array('class' => 'phriction-history-nav-table'),
 178          phutil_tag('tr', array(), array(
 179            phutil_tag('td', array('class' => 'nav-prev'), $link_l),
 180            phutil_tag('td', array('class' => 'nav-next'), $link_r),
 181          )));
 182      }
 183  
 184  
 185      $output = hsprintf(
 186        '<div class="phriction-document-history-diff">'.
 187          '%s%s'.
 188          '<table class="phriction-revert-table">'.
 189            '<tr><td>%s</td><td>%s</td>'.
 190          '</table>'.
 191          '%s'.
 192        '</div>',
 193        $comparison_table->render(),
 194        $navigation_table,
 195        $revert_l,
 196        $revert_r,
 197        $output);
 198  
 199  
 200      $object_box = id(new PHUIObjectBoxView())
 201        ->setHeader($header)
 202        ->appendChild($output);
 203  
 204      return $this->buildApplicationPage(
 205        array(
 206          $crumbs,
 207          $object_box,
 208        ),
 209        array(
 210          'title'     => pht('Document History'),
 211        ));
 212  
 213    }
 214  
 215    private function renderRevertButton(
 216      PhrictionContent $content,
 217      PhrictionContent $current) {
 218  
 219      $document_id = $content->getDocumentID();
 220      $version = $content->getVersion();
 221  
 222      $hidden_statuses = array(
 223        PhrictionChangeType::CHANGE_DELETE    => true, // Silly
 224        PhrictionChangeType::CHANGE_MOVE_AWAY => true, // Plain silly
 225        PhrictionChangeType::CHANGE_STUB      => true, // Utterly silly
 226      );
 227      if (isset($hidden_statuses[$content->getChangeType()])) {
 228        // Don't show an edit/revert button for changes which deleted, moved or
 229        // stubbed the content since it's silly.
 230        return null;
 231      }
 232  
 233      if ($content->getID() == $current->getID()) {
 234        return phutil_tag(
 235          'a',
 236          array(
 237            'href'  => '/phriction/edit/'.$document_id.'/',
 238            'class' => 'button grey',
 239          ),
 240          pht('Edit Current Version'));
 241      }
 242  
 243  
 244      return phutil_tag(
 245        'a',
 246        array(
 247          'href'  => '/phriction/edit/'.$document_id.'/?revert='.$version,
 248          'class' => 'button grey',
 249        ),
 250        pht('Revert to Version %s...', $version));
 251    }
 252  
 253    private function renderComparisonTable(array $content) {
 254      assert_instances_of($content, 'PhrictionContent');
 255  
 256      $user = $this->getRequest()->getUser();
 257  
 258      $phids = mpull($content, 'getAuthorPHID');
 259      $handles = $this->loadViewerHandles($phids);
 260  
 261      $list = new PHUIObjectItemListView();
 262      $list->setFlush(true);
 263  
 264      $first = true;
 265      foreach ($content as $c) {
 266        $author = $handles[$c->getAuthorPHID()]->renderLink();
 267        $item = id(new PHUIObjectItemView())
 268          ->setHeader(pht('%s by %s, %s',
 269            PhrictionChangeType::getChangeTypeLabel($c->getChangeType()),
 270            $author,
 271            pht('Version %s', $c->getVersion())))
 272          ->addAttribute(pht('%s %s',
 273            phabricator_date($c->getDateCreated(), $user),
 274            phabricator_time($c->getDateCreated(), $user)));
 275  
 276        if ($c->getDescription()) {
 277          $item->addAttribute($c->getDescription());
 278        }
 279  
 280        if ($first == true) {
 281          $item->setBarColor('green');
 282          $first = false;
 283        } else {
 284          $item->setBarColor('red');
 285        }
 286  
 287        $list->addItem($item);
 288      }
 289  
 290      return $list;
 291    }
 292  
 293  }


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