[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/diffusion/controller/ -> DiffusionLintController.php (source)

   1  <?php
   2  
   3  final class DiffusionLintController extends DiffusionController {
   4  
   5    public function shouldAllowPublic() {
   6      return true;
   7    }
   8  
   9    public function processRequest() {
  10      $request = $this->getRequest();
  11      $user = $this->getRequest()->getUser();
  12      $drequest = $this->diffusionRequest;
  13  
  14      if ($request->getStr('lint') !== null) {
  15        $controller = new DiffusionLintDetailsController();
  16        $controller->setDiffusionRequest($drequest);
  17        $controller->setCurrentApplication($this->getCurrentApplication());
  18        return $this->delegateToController($controller);
  19      }
  20  
  21      $owners = array();
  22      if (!$drequest) {
  23        if (!$request->getArr('owner')) {
  24          $owners = array($user->getPHID());
  25        } else {
  26          $owners = array(head($request->getArr('owner')));
  27        }
  28        $owner_handles = $this->loadViewerHandles($owners);
  29      }
  30  
  31      $codes = $this->loadLintCodes($owners);
  32  
  33      if ($codes && !$drequest) {
  34        // TODO: Build some real Query classes for this stuff.
  35  
  36        $branches = id(new PhabricatorRepositoryBranch())->loadAllWhere(
  37          'id IN (%Ld)',
  38          array_unique(ipull($codes, 'branchID')));
  39  
  40        $repositories = id(new PhabricatorRepositoryQuery())
  41          ->setViewer($user)
  42          ->withIDs(mpull($branches, 'getRepositoryID'))
  43          ->execute();
  44  
  45        $drequests = array();
  46        foreach ($branches as $id => $branch) {
  47          if (empty($repositories[$branch->getRepositoryID()])) {
  48            continue;
  49          }
  50  
  51          $drequests[$id] = DiffusionRequest::newFromDictionary(array(
  52            'user' => $user,
  53            'repository' => $repositories[$branch->getRepositoryID()],
  54            'branch' => $branch->getName(),
  55          ));
  56        }
  57      }
  58  
  59      $rows = array();
  60      $total = 0;
  61      foreach ($codes as $code) {
  62        if (!$this->diffusionRequest) {
  63          $drequest = idx($drequests, $code['branchID']);
  64        }
  65  
  66        if (!$drequest) {
  67          continue;
  68        }
  69  
  70        $total += $code['n'];
  71  
  72        $href_lint = $drequest->generateURI(array(
  73          'action' => 'lint',
  74          'lint' => $code['code'],
  75        ));
  76        $href_browse = $drequest->generateURI(array(
  77          'action' => 'browse',
  78          'lint' => $code['code'],
  79        ));
  80        $href_repo = $drequest->generateURI(array('action' => 'lint'));
  81  
  82        $rows[] = array(
  83          phutil_tag('a', array('href' => $href_lint), $code['n']),
  84          phutil_tag('a', array('href' => $href_browse), $code['files']),
  85          phutil_tag('a', array('href' => $href_repo), $drequest->getCallsign()),
  86          ArcanistLintSeverity::getStringForSeverity($code['maxSeverity']),
  87          $code['code'],
  88          $code['maxName'],
  89          $code['maxDescription'],
  90        );
  91      }
  92  
  93      $table = id(new AphrontTableView($rows))
  94        ->setHeaders(array(
  95          pht('Problems'),
  96          pht('Files'),
  97          pht('Repository'),
  98          pht('Severity'),
  99          pht('Code'),
 100          pht('Name'),
 101          pht('Example'),
 102        ))
 103        ->setColumnVisibility(array(true, true, !$this->diffusionRequest))
 104        ->setColumnClasses(array('n', 'n', '', '', 'pri', '', ''));
 105  
 106      $content = array();
 107  
 108      $link = null;
 109      if (!$this->diffusionRequest) {
 110        $form = id(new AphrontFormView())
 111          ->setUser($user)
 112          ->setMethod('GET')
 113          ->appendChild(
 114            id(new AphrontFormTokenizerControl())
 115              ->setDatasource(new PhabricatorPeopleDatasource())
 116              ->setLimit(1)
 117              ->setName('owner')
 118              ->setLabel(pht('Owner'))
 119              ->setValue($owner_handles))
 120          ->appendChild(
 121            id(new AphrontFormSubmitControl())
 122              ->setValue('Filter'));
 123        $content[] = id(new AphrontListFilterView())->appendChild($form);
 124      }
 125  
 126      $content[] = id(new AphrontPanelView())
 127        ->setNoBackground(true)
 128        ->setCaption($link)
 129        ->appendChild($table);
 130  
 131      $title = array('Lint');
 132      $crumbs = $this->buildCrumbs(
 133        array(
 134          'branch' => true,
 135          'path'   => true,
 136          'view'   => 'lint',
 137        ));
 138  
 139      if ($this->diffusionRequest) {
 140        $title[] = $drequest->getCallsign();
 141      } else {
 142        $crumbs->addTextCrumb(pht('All Lint'));
 143      }
 144  
 145      if ($this->diffusionRequest) {
 146        $branch = $drequest->loadBranch();
 147  
 148        $header = id(new PHUIHeaderView())
 149          ->setHeader($this->renderPathLinks($drequest, 'lint'))
 150          ->setUser($user)
 151          ->setPolicyObject($drequest->getRepository());
 152        $actions = $this->buildActionView($drequest);
 153        $properties = $this->buildPropertyView(
 154          $drequest,
 155          $branch,
 156          $total,
 157          $actions);
 158  
 159        $object_box = id(new PHUIObjectBoxView())
 160          ->setHeader($header)
 161          ->addPropertyList($properties);
 162      } else {
 163        $object_box = null;
 164      }
 165  
 166  
 167      return $this->buildApplicationPage(
 168        array(
 169          $crumbs,
 170          $object_box,
 171          $content,
 172        ),
 173        array(
 174          'title' => $title,
 175          'device' => false,
 176        ));
 177    }
 178  
 179    private function loadLintCodes(array $owner_phids) {
 180      $drequest = $this->diffusionRequest;
 181      $conn = id(new PhabricatorRepository())->establishConnection('r');
 182      $where = array('1 = 1');
 183  
 184      if ($drequest) {
 185        $branch = $drequest->loadBranch();
 186        if (!$branch) {
 187          return array();
 188        }
 189  
 190        $where[] = qsprintf($conn, 'branchID = %d', $branch->getID());
 191  
 192        if ($drequest->getPath() != '') {
 193          $path = '/'.$drequest->getPath();
 194          $is_dir = (substr($path, -1) == '/');
 195          $where[] = ($is_dir
 196            ? qsprintf($conn, 'path LIKE %>', $path)
 197            : qsprintf($conn, 'path = %s', $path));
 198        }
 199      }
 200  
 201      if ($owner_phids) {
 202        $or = array();
 203        $or[] = qsprintf($conn, 'authorPHID IN (%Ls)', $owner_phids);
 204  
 205        $paths = array();
 206        $packages = id(new PhabricatorOwnersOwner())
 207          ->loadAllWhere('userPHID IN (%Ls)', $owner_phids);
 208        if ($packages) {
 209          $paths = id(new PhabricatorOwnersPath())->loadAllWhere(
 210            'packageID IN (%Ld)',
 211            mpull($packages, 'getPackageID'));
 212        }
 213  
 214        if ($paths) {
 215          $repositories = id(new PhabricatorRepositoryQuery())
 216            ->setViewer($this->getRequest()->getUser())
 217            ->withPHIDs(mpull($paths, 'getRepositoryPHID'))
 218            ->execute();
 219          $repositories = mpull($repositories, 'getID', 'getPHID');
 220  
 221          $branches = id(new PhabricatorRepositoryBranch())->loadAllWhere(
 222            'repositoryID IN (%Ld)',
 223            $repositories);
 224          $branches = mgroup($branches, 'getRepositoryID');
 225        }
 226  
 227        foreach ($paths as $path) {
 228          $branch = idx(
 229            $branches,
 230            idx(
 231              $repositories,
 232              $path->getRepositoryPHID()));
 233          if ($branch) {
 234            $condition = qsprintf(
 235              $conn,
 236              '(branchID IN (%Ld) AND path LIKE %>)',
 237              array_keys($branch),
 238              $path->getPath());
 239            if ($path->getExcluded()) {
 240              $where[] = 'NOT '.$condition;
 241            } else {
 242              $or[] = $condition;
 243            }
 244          }
 245        }
 246        $where[] = '('.implode(' OR ', $or).')';
 247      }
 248  
 249      return queryfx_all(
 250        $conn,
 251        'SELECT
 252            branchID,
 253            code,
 254            MAX(severity) AS maxSeverity,
 255            MAX(name) AS maxName,
 256            MAX(description) AS maxDescription,
 257            COUNT(DISTINCT path) AS files,
 258            COUNT(*) AS n
 259          FROM %T
 260          WHERE %Q
 261          GROUP BY branchID, code
 262          ORDER BY n DESC',
 263        PhabricatorRepository::TABLE_LINTMESSAGE,
 264        implode(' AND ', $where));
 265    }
 266  
 267    protected function buildActionView(DiffusionRequest $drequest) {
 268      $viewer = $this->getRequest()->getUser();
 269  
 270      $view = id(new PhabricatorActionListView())
 271        ->setUser($viewer);
 272  
 273      $list_uri = $drequest->generateURI(
 274        array(
 275          'action' => 'lint',
 276          'lint' => '',
 277        ));
 278  
 279      $view->addAction(
 280        id(new PhabricatorActionView())
 281          ->setName(pht('View As List'))
 282          ->setHref($list_uri)
 283          ->setIcon('fa-list'));
 284  
 285      $history_uri = $drequest->generateURI(
 286        array(
 287          'action' => 'history',
 288        ));
 289  
 290      $view->addAction(
 291        id(new PhabricatorActionView())
 292          ->setName(pht('View History'))
 293          ->setHref($history_uri)
 294          ->setIcon('fa-clock-o'));
 295  
 296      $browse_uri = $drequest->generateURI(
 297        array(
 298          'action' => 'browse',
 299        ));
 300  
 301      $view->addAction(
 302        id(new PhabricatorActionView())
 303          ->setName(pht('Browse Content'))
 304          ->setHref($browse_uri)
 305          ->setIcon('fa-files-o'));
 306  
 307      return $view;
 308    }
 309  
 310    protected function buildPropertyView(
 311      DiffusionRequest $drequest,
 312      PhabricatorRepositoryBranch $branch,
 313      $total,
 314      PhabricatorActionListView $actions) {
 315  
 316      $viewer = $this->getRequest()->getUser();
 317  
 318      $view = id(new PHUIPropertyListView())
 319        ->setUser($viewer)
 320        ->setActionList($actions);
 321  
 322      $callsign = $drequest->getRepository()->getCallsign();
 323      $lint_commit = $branch->getLintCommit();
 324  
 325      $view->addProperty(
 326        pht('Lint Commit'),
 327        phutil_tag(
 328          'a',
 329          array(
 330            'href' => $drequest->generateURI(
 331              array(
 332                'action' => 'commit',
 333                'commit' => $lint_commit,
 334              )),
 335          ),
 336          $drequest->getRepository()->formatCommitName($lint_commit)));
 337  
 338      $view->addProperty(
 339        pht('Total Messages'),
 340        pht('%s', new PhutilNumber($total)));
 341  
 342      return $view;
 343    }
 344  
 345  
 346  }


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