コード例 #1
0
 public function run()
 {
     static $color_map = array('Closed' => 'cyan', 'Needs Review' => 'magenta', 'Needs Revision' => 'red', 'Changes Planned' => 'red', 'Accepted' => 'green', 'No Revision' => 'blue', 'Abandoned' => 'default');
     $revisions = $this->getConduit()->callMethodSynchronous('differential.query', array('authors' => array($this->getUserPHID()), 'status' => 'status-open'));
     if (!$revisions) {
         echo pht('You have no open Differential revisions.') . "\n";
         return 0;
     }
     $repository_api = $this->getRepositoryAPI();
     $info = array();
     foreach ($revisions as $key => $revision) {
         $revision_path = Filesystem::resolvePath($revision['sourcePath']);
         $current_path = Filesystem::resolvePath($repository_api->getPath());
         if ($revision_path == $current_path) {
             $info[$key]['exists'] = 1;
         } else {
             $info[$key]['exists'] = 0;
         }
         $info[$key]['sort'] = sprintf('%d%04d%08d', $info[$key]['exists'], $revision['status'], $revision['id']);
         $info[$key]['statusName'] = $revision['statusName'];
         $info[$key]['color'] = idx($color_map, $revision['statusName'], 'default');
     }
     $table = id(new PhutilConsoleTable())->setShowHeader(false)->addColumn('exists', array('title' => ''))->addColumn('status', array('title' => pht('Status')))->addColumn('title', array('title' => pht('Title')));
     $info = isort($info, 'sort');
     foreach ($info as $key => $spec) {
         $revision = $revisions[$key];
         $table->addRow(array('exists' => $spec['exists'] ? phutil_console_format('**%s**', '*') : '', 'status' => phutil_console_format("<fg:{$spec['color']}>%s</fg>", $spec['statusName']), 'title' => phutil_console_format('**D%d:** %s', $revision['id'], $revision['title'])));
     }
     $table->draw();
     return 0;
 }
コード例 #2
0
 public static function sortAndGroupInlines(array $inlines, array $changesets)
 {
     assert_instances_of($inlines, 'DifferentialTransaction');
     assert_instances_of($changesets, 'DifferentialChangeset');
     $changesets = mpull($changesets, null, 'getID');
     $changesets = msort($changesets, 'getFilename');
     // Group the changesets by file and reorder them by display order.
     $inline_groups = array();
     foreach ($inlines as $inline) {
         $changeset_id = $inline->getComment()->getChangesetID();
         $inline_groups[$changeset_id][] = $inline;
     }
     $inline_groups = array_select_keys($inline_groups, array_keys($changesets));
     foreach ($inline_groups as $changeset_id => $group) {
         // Sort the group of inlines by line number.
         $items = array();
         foreach ($group as $inline) {
             $comment = $inline->getComment();
             $num = $comment->getLineNumber();
             $len = $comment->getLineLength();
             $id = $comment->getID();
             $items[] = array('inline' => $inline, 'sort' => sprintf('~%010d%010d%010d', $num, $len, $id));
         }
         $items = isort($items, 'sort');
         $items = ipull($items, 'inline');
         $inline_groups[$changeset_id] = $items;
     }
     return $inline_groups;
 }
コード例 #3
0
 protected function executeQuery()
 {
     $drequest = $this->getRequest();
     $repository = $drequest->getRepository();
     $commit = $drequest->loadCommit();
     $raw_changes = queryfx_all($repository->establishConnection('r'), 'SELECT c.*, p.path pathName, t.path targetPathName
     FROM %T c
       LEFT JOIN %T p ON c.pathID = p.id
       LEFT JOIN %T t on c.targetPathID = t.id
     WHERE c.commitID = %d AND isDirect = 1', PhabricatorRepository::TABLE_PATHCHANGE, PhabricatorRepository::TABLE_PATH, PhabricatorRepository::TABLE_PATH, $commit->getID());
     $changes = array();
     $raw_changes = isort($raw_changes, 'pathName');
     foreach ($raw_changes as $raw_change) {
         $type = $raw_change['changeType'];
         if ($type == DifferentialChangeType::TYPE_CHILD) {
             continue;
         }
         $change = new DiffusionPathChange();
         $change->setPath(ltrim($raw_change['pathName'], '/'));
         $change->setChangeType($raw_change['changeType']);
         $change->setFileType($raw_change['fileType']);
         $change->setCommitIdentifier($commit->getCommitIdentifier());
         $changes[] = $change;
     }
     return $changes;
 }
コード例 #4
0
 public static function getPatchList()
 {
     $root = dirname(phutil_get_library_root('phabricator'));
     // Find the patch files
     $patches_dir = $root . '/resources/sql/patches/';
     $finder = new FileFinder($patches_dir);
     $results = $finder->find();
     $versions = array();
     $patches = array();
     foreach ($results as $path) {
         $matches = array();
         if (!preg_match('/(\\d+)\\..*\\.(sql|php)$/', $path, $matches)) {
             continue;
         }
         $version = (int) $matches[1];
         $patches[] = array('version' => $version, 'path' => $patches_dir . $path);
         if (empty($versions[$version])) {
             $versions[$version] = true;
         } else {
             throw new Exception("Two patches have version {$version}!");
         }
     }
     // Files are in some 'random' order returned by the operating system
     // We need to apply them in proper order
     $patches = isort($patches, 'version');
     return $patches;
 }
コード例 #5
0
 public function run()
 {
     $revisions = $this->getConduit()->callMethodSynchronous('differential.query', array('authors' => array($this->getUserPHID()), 'status' => 'status-open'));
     if (!$revisions) {
         echo "You have no open Differential revisions.\n";
         return 0;
     }
     $repository_api = $this->getRepositoryAPI();
     $info = array();
     $status_len = 0;
     foreach ($revisions as $key => $revision) {
         $revision_path = Filesystem::resolvePath($revision['sourcePath']);
         $current_path = Filesystem::resolvePath($repository_api->getPath());
         if ($revision_path == $current_path) {
             $info[$key]['here'] = 1;
         } else {
             $info[$key]['here'] = 0;
         }
         $info[$key]['sort'] = sprintf('%d%04d%08d', $info[$key]['here'], $revision['status'], $revision['id']);
         $info[$key]['statusColorized'] = BranchInfo::renderColorizedRevisionStatus($revision['statusName']);
         $status_len = max($status_len, strlen($info[$key]['statusColorized']));
     }
     $info = isort($info, 'sort');
     foreach ($info as $key => $spec) {
         $revision = $revisions[$key];
         printf("%s %-" . ($status_len + 4) . "s D%d: %s\n", $spec['here'] ? phutil_console_format('**%s**', '*') : ' ', $spec['statusColorized'], $revision['id'], $revision['title']);
     }
     return 0;
 }
 public function processRequest(AphrontRequest $request)
 {
     $viewer = $this->getViewer();
     $user = $this->getUser();
     $preferences = $this->getPreferences();
     $value_email = PhabricatorEmailTagsSetting::VALUE_EMAIL;
     $errors = array();
     if ($request->isFormPost()) {
         $new_tags = $request->getArr('mailtags');
         $mailtags = $preferences->getPreference('mailtags', array());
         $all_tags = $this->getAllTags($user);
         foreach ($all_tags as $key => $label) {
             $mailtags[$key] = (int) idx($new_tags, $key, $value_email);
         }
         $this->writeSetting($preferences, PhabricatorEmailTagsSetting::SETTINGKEY, $mailtags);
         return id(new AphrontRedirectResponse())->setURI($this->getPanelURI('?saved=true'));
     }
     $mailtags = $preferences->getSettingValue(PhabricatorEmailTagsSetting::SETTINGKEY);
     $form = id(new AphrontFormView())->setUser($viewer);
     $form->appendRemarkupInstructions(pht('You can adjust **Application Settings** here to customize when ' . 'you are emailed and notified.' . "\n\n" . "| Setting | Effect\n" . "| ------- | -------\n" . "| Email | You will receive an email and a notification, but the " . "notification will be marked \"read\".\n" . "| Notify | You will receive an unread notification only.\n" . "| Ignore | You will receive nothing.\n" . "\n\n" . 'If an update makes several changes (like adding CCs to a task, ' . 'closing it, and adding a comment) you will receive the strongest ' . 'notification any of the changes is configured to deliver.' . "\n\n" . 'These preferences **only** apply to objects you are connected to ' . '(for example, Revisions where you are a reviewer or tasks you are ' . 'CC\'d on). To receive email alerts when other objects are created, ' . 'configure [[ /herald/ | Herald Rules ]].'));
     $editors = $this->getAllEditorsWithTags($user);
     // Find all the tags shared by more than one application, and put them
     // in a "common" group.
     $all_tags = array();
     foreach ($editors as $editor) {
         foreach ($editor->getMailTagsMap() as $tag => $name) {
             if (empty($all_tags[$tag])) {
                 $all_tags[$tag] = array('count' => 0, 'name' => $name);
             }
             $all_tags[$tag]['count'];
         }
     }
     $common_tags = array();
     foreach ($all_tags as $tag => $info) {
         if ($info['count'] > 1) {
             $common_tags[$tag] = $info['name'];
         }
     }
     // Build up the groups of application-specific options.
     $tag_groups = array();
     foreach ($editors as $editor) {
         $tag_groups[] = array($editor->getEditorObjectsDescription(), array_diff_key($editor->getMailTagsMap(), $common_tags));
     }
     // Sort them, then put "Common" at the top.
     $tag_groups = isort($tag_groups, 0);
     if ($common_tags) {
         array_unshift($tag_groups, array(pht('Common'), $common_tags));
     }
     // Finally, build the controls.
     foreach ($tag_groups as $spec) {
         list($label, $map) = $spec;
         $control = $this->buildMailTagControl($label, $map, $mailtags);
         $form->appendChild($control);
     }
     $form->appendChild(id(new AphrontFormSubmitControl())->setValue(pht('Save Preferences')));
     $form_box = id(new PHUIObjectBoxView())->setHeaderText(pht('Email Preferences'))->setFormSaved($request->getStr('saved'))->setFormErrors($errors)->setForm($form);
     return $form_box;
 }
コード例 #7
0
 public function renderValueForRevisionView()
 {
     $diff = $this->getDiff();
     $ustar = DifferentialRevisionUpdateHistoryView::renderDiffUnitStar($diff);
     $umsg = DifferentialRevisionUpdateHistoryView::getDiffUnitMessage($diff);
     $rows = array();
     $rows[] = array('style' => 'star', 'name' => $ustar, 'value' => $umsg, 'show' => true);
     $excuse = $this->getUnitExcuse();
     if ($excuse) {
         $rows[] = array('style' => 'excuse', 'name' => 'Excuse', 'value' => nl2br(phutil_escape_html($excuse)), 'show' => true);
     }
     $show_limit = 10;
     $hidden = array();
     $udata = $this->getDiffProperty('arc:unit');
     if ($udata) {
         $sort_map = array(ArcanistUnitTestResult::RESULT_BROKEN => 0, ArcanistUnitTestResult::RESULT_FAIL => 1, ArcanistUnitTestResult::RESULT_UNSOUND => 2, ArcanistUnitTestResult::RESULT_SKIP => 3, ArcanistUnitTestResult::RESULT_POSTPONED => 4, ArcanistUnitTestResult::RESULT_PASS => 5);
         foreach ($udata as $key => $test) {
             $udata[$key]['sort'] = idx($sort_map, idx($test, 'result'));
         }
         $udata = isort($udata, 'sort');
         foreach ($udata as $test) {
             $result = idx($test, 'result');
             $default_hide = false;
             switch ($result) {
                 case ArcanistUnitTestResult::RESULT_POSTPONED:
                 case ArcanistUnitTestResult::RESULT_PASS:
                     $default_hide = true;
                     break;
             }
             if ($show_limit && !$default_hide) {
                 --$show_limit;
                 $show = true;
             } else {
                 $show = false;
                 if (empty($hidden[$result])) {
                     $hidden[$result] = 0;
                 }
                 $hidden[$result]++;
             }
             $rows[] = array('style' => $this->getResultStyle($result), 'name' => phutil_escape_html(ucwords($result)), 'value' => phutil_escape_html(idx($test, 'name')), 'show' => $show);
             $userdata = idx($test, 'userdata');
             if ($userdata) {
                 $engine = PhabricatorMarkupEngine::newDifferentialMarkupEngine();
                 $userdata = $engine->markupText($userdata);
                 $rows[] = array('style' => 'details', 'value' => $userdata, 'show' => false);
                 if (empty($hidden['details'])) {
                     $hidden['details'] = 0;
                 }
                 $hidden['details']++;
             }
         }
     }
     $show_string = $this->renderShowString($hidden);
     $view = new DifferentialResultsTableView();
     $view->setRows($rows);
     $view->setShowMoreString($show_string);
     return $view->render();
 }
コード例 #8
0
 protected function executeQuery()
 {
     $drequest = $this->getRequest();
     $repository = $drequest->getRepository();
     $commit = $drequest->loadCommit();
     $conn_r = $repository->establishConnection('r');
     $limit = '';
     if ($this->limit) {
         $limit = qsprintf($conn_r, 'LIMIT %d', $this->limit + 1);
     }
     $raw_changes = queryfx_all($conn_r, 'SELECT c.*, p.path pathName, t.path targetPathName,
       i.commitIdentifier targetCommitIdentifier
     FROM %T c
       LEFT JOIN %T p ON c.pathID = p.id
       LEFT JOIN %T t ON c.targetPathID = t.id
       LEFT JOIN %T i ON c.targetCommitID = i.id
     WHERE c.commitID = %d AND isDirect = 1 %Q', PhabricatorRepository::TABLE_PATHCHANGE, PhabricatorRepository::TABLE_PATH, PhabricatorRepository::TABLE_PATH, $commit->getTableName(), $commit->getID(), $limit);
     $limited = $this->limit && count($raw_changes) > $this->limit;
     if ($limited) {
         $raw_changes = array_slice($raw_changes, 0, $this->limit);
     }
     $changes = array();
     $raw_changes = isort($raw_changes, 'pathName');
     foreach ($raw_changes as $raw_change) {
         $type = $raw_change['changeType'];
         if ($type == DifferentialChangeType::TYPE_CHILD) {
             continue;
         }
         $change = new DiffusionPathChange();
         $change->setPath(ltrim($raw_change['pathName'], '/'));
         $change->setChangeType($raw_change['changeType']);
         $change->setFileType($raw_change['fileType']);
         $change->setCommitIdentifier($commit->getCommitIdentifier());
         $change->setTargetPath(ltrim($raw_change['targetPathName'], '/'));
         $change->setTargetCommitIdentifier($raw_change['targetCommitIdentifier']);
         $id = $raw_change['pathID'];
         $changes[$id] = $change;
     }
     // Deduce the away paths by examining all the changes, if we loaded them
     // all.
     if (!$limited) {
         $away = array();
         foreach ($changes as $change) {
             if ($change->getTargetPath()) {
                 $away[$change->getTargetPath()][] = $change->getPath();
             }
         }
         foreach ($changes as $change) {
             if (isset($away[$change->getPath()])) {
                 $change->setAwayPaths($away[$change->getPath()]);
             }
         }
     }
     return $changes;
 }
コード例 #9
0
ファイル: parser.php プロジェクト: mops1k/NextFW
 function start()
 {
     $this->tpl->setBlock("breadcrumb", '<a href="/parser">Freelance.ru parser</a>');
     $pQ = new Engine\pQuery();
     $pages = 5;
     $host = "https://freelance.ru";
     $main_url = "https://freelance.ru/projects/";
     $url = "https://freelance.ru/projects/?spec=4";
     $only_pub = true;
     $dom = $pQ->file_get_html($url);
     $pagination = $dom->find("ul.pagination li a");
     $array = [];
     for ($i = 0; $i <= $pages; $i++) {
         $array[] = $main_url . str_replace(".", "", $pagination[$i]->href);
     }
     $dom = null;
     $info_array = [];
     foreach ($array as $url) {
         $array = "";
         $str = file_get_contents($url);
         $str = iconv('cp1251', 'utf-8', $str);
         $dom = $pQ->str_get_html($str);
         $proj_list = $dom->find("div.projects .proj");
         foreach ($proj_list as $value) {
             $type = str_replace("proj ", "", $value->class);
             if ($type == "public" and $only_pub === true or $only_pub === false) {
             } else {
                 continue;
             }
             $array[] = ["id" => str_replace(" ", "", str_replace("/", "", str_replace("projects", "", $value->find("a.descr")[0]->href))), "title" => $value->find("a.ptitle span")[0]->plaintext, "avatr" => $host . $value->find("a.avatr img")[0]->src, "cost" => $value->find("span.cost")[0]->plaintext, "href" => $host . $value->find("a.descr")[0]->href, "date" => $value->find("ul li.pdata")[0]->title, "replies" => $value->find("ul li.messages a i")[0]->plaintext, "descr" => $value->find("a.descr")[0]->plaintext, "type" => $type];
         }
         $dom = null;
         $info_array = array_merge($info_array, $array);
     }
     function isort(&$a, $field, $dir = true)
     {
         $t = call_user_func_array('array_merge_recursive', $a);
         asort($t[$field]);
         $so = array_keys($t[$field]);
         asort($so);
         # исправлено 2012-08-31
         $so = array_keys($so);
         $a = array_combine($so, $a);
         $dir ? ksort($a) : krsort($a);
     }
     isort($info_array, 'date', false);
     $content = "";
     foreach ($info_array as $val) {
         $this->tpl->setAll(['avatr' => $val['avatr'], 'title' => $val['title'], 'cost' => $val['cost'], 'href' => $val['href'], 'date' => $val['date'], 'reply' => $val['replies'], 'descr' => $val['descr']]);
         $content .= $this->tpl->subLoad('parser.tpl');
     }
     $this->tpl->setBlock('content', $content);
 }
コード例 #10
0
 public function render()
 {
     DarkConsoleXHProfPluginAPI::includeXHProfLib();
     $data = $this->profileData;
     $GLOBALS['display_calls'] = true;
     $totals = array();
     $flat = xhprof_compute_flat_info($data, $totals);
     unset($GLOBALS['display_calls']);
     $symbol = $this->symbol;
     $children = array();
     $parents = array();
     foreach ($this->profileData as $key => $counters) {
         if (strpos($key, '==>') !== false) {
             list($parent, $child) = explode('==>', $key, 2);
         } else {
             continue;
         }
         if ($parent == $symbol) {
             $children[$key] = $child;
         } else {
             if ($child == $symbol) {
                 $parents[$key] = $parent;
             }
         }
     }
     $base_uri = $this->baseURI;
     $rows = array();
     $rows[] = array('Metrics for this Call', '', '', '');
     $rows[] = array(phutil_render_tag('a', array('href' => $base_uri . '?symbol=' . $symbol), phutil_escape_html($symbol)), $flat[$symbol]['ct'], $flat[$symbol]['wt'], '100%');
     $rows[] = array('Parent Calls', '', '', '');
     foreach ($parents as $key => $name) {
         $rows[] = array(phutil_render_tag('a', array('href' => $base_uri . '?symbol=' . $name), phutil_escape_html($name)), $data[$key]['ct'], $data[$key]['wt'], '');
     }
     $rows[] = array('Child Calls', '', '', '');
     $child_rows = array();
     foreach ($children as $key => $name) {
         $child_rows[] = array($name, $data[$key]['ct'], $data[$key]['wt'], $data[$key]['wt'] / $flat[$symbol]['wt']);
     }
     $child_rows = isort($child_rows, 2);
     $child_rows = array_reverse($child_rows);
     $rows = array_merge($rows, $this->formatRows($child_rows));
     $table = new AphrontTableView($rows);
     $table->setHeaders(array('Symbol', 'Count', 'Wall Time', '%'));
     $table->setColumnClasses(array('wide pri', 'n', 'n', 'n'));
     $panel = new AphrontPanelView();
     $panel->setHeader('XHProf Profile');
     $panel->appendChild($table);
     return $panel->render();
 }
コード例 #11
0
 public function render()
 {
     DarkConsoleXHProfPluginAPI::includeXHProfLib();
     $data = $this->profileData;
     $GLOBALS['display_calls'] = true;
     $totals = array();
     $flat = xhprof_compute_flat_info($data, $totals);
     unset($GLOBALS['display_calls']);
     $symbol = $this->symbol;
     $children = array();
     $parents = array();
     foreach ($this->profileData as $key => $counters) {
         if (strpos($key, '==>') !== false) {
             list($parent, $child) = explode('==>', $key, 2);
         } else {
             continue;
         }
         if ($parent == $symbol) {
             $children[$key] = $child;
         } else {
             if ($child == $symbol) {
                 $parents[$key] = $parent;
             }
         }
     }
     $rows = array();
     $rows[] = array(pht('Metrics for this Call'), '', '', '');
     $rows[] = $this->formatRow(array($symbol, $flat[$symbol]['ct'], $flat[$symbol]['wt'], 1.0));
     $rows[] = array(pht('Parent Calls'), '', '', '');
     foreach ($parents as $key => $name) {
         $rows[] = $this->formatRow(array($name, $data[$key]['ct'], $data[$key]['wt'], ''));
     }
     $rows[] = array(pht('Child Calls'), '', '', '');
     $child_rows = array();
     foreach ($children as $key => $name) {
         $child_rows[] = array($name, $data[$key]['ct'], $data[$key]['wt'], $data[$key]['wt'] / $flat[$symbol]['wt']);
     }
     $child_rows = isort($child_rows, 2);
     $child_rows = array_reverse($child_rows);
     $rows = array_merge($rows, array_map(array($this, 'formatRow'), $child_rows));
     $table = new AphrontTableView($rows);
     $table->setHeaders(array(pht('Symbol'), pht('Count'), pht('Wall Time'), '%'));
     $table->setColumnClasses(array('wide pri', 'n', 'n', 'n'));
     $panel = new PHUIObjectBoxView();
     $panel->setHeaderText(pht('XHProf Profile'));
     $panel->setTable($table);
     return $panel->render();
 }
コード例 #12
0
 public function render()
 {
     DarkConsoleXHProfPluginAPI::includeXHProfLib();
     $GLOBALS['display_calls'] = true;
     $totals = array();
     $flat = xhprof_compute_flat_info($this->profileData, $totals);
     unset($GLOBALS['display_calls']);
     $aggregated = array();
     foreach ($flat as $call => $counters) {
         $parts = explode('@', $call, 2);
         $agg_call = reset($parts);
         if (empty($aggregated[$agg_call])) {
             $aggregated[$agg_call] = $counters;
         } else {
             foreach ($aggregated[$agg_call] as $key => $val) {
                 if ($key != 'wt') {
                     $aggregated[$agg_call][$key] += $counters[$key];
                 }
             }
         }
     }
     $flat = $aggregated;
     $flat = isort($flat, 'wt');
     $flat = array_reverse($flat);
     $rows = array();
     $rows[] = array(pht('Total'), number_format($totals['ct']), number_format($totals['wt']) . ' us', '100.0%', number_format($totals['wt']) . ' us', '100.0%');
     if ($this->limit) {
         $flat = array_slice($flat, 0, $this->limit);
     }
     foreach ($flat as $call => $counters) {
         $rows[] = array($this->renderSymbolLink($call), number_format($counters['ct']), number_format($counters['wt']) . ' us', sprintf('%.1f%%', 100 * $counters['wt'] / $totals['wt']), number_format($counters['excl_wt']) . ' us', sprintf('%.1f%%', 100 * $counters['excl_wt'] / $totals['wt']));
     }
     Javelin::initBehavior('phabricator-tooltips');
     $table = new AphrontTableView($rows);
     $table->setHeaders(array(pht('Symbol'), pht('Count'), javelin_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => pht('Total wall time spent in this function and all of ' . 'its children (children are other functions it called ' . 'while executing).'), 'size' => 200)), pht('Wall Time (Inclusive)')), '%', javelin_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => pht('Wall time spent in this function, excluding time ' . 'spent in children (children are other functions it ' . 'called while executing).'), 'size' => 200)), pht('Wall Time (Exclusive)')), '%'));
     $table->setColumnClasses(array('wide pri', 'n', 'n', 'n', 'n', 'n'));
     $panel = new PHUIObjectBoxView();
     $header = id(new PHUIHeaderView())->setHeader(pht('XHProf Profile'));
     if ($this->file) {
         $button = id(new PHUIButtonView())->setHref($this->file->getBestURI())->setText(pht('Download %s Profile', '.xhprof'))->setTag('a');
         $header->addActionLink($button);
     }
     $panel->setHeader($header);
     $panel->appendChild($table);
     return $panel->render();
 }
コード例 #13
0
 private function renderDataBox()
 {
     $cache = PhabricatorDataCacheSpec::getActiveCacheSpec();
     $properties = id(new PHUIPropertyListView());
     $this->renderCommonProperties($properties, $cache);
     $table = null;
     if ($cache->getName() !== null) {
         $total_memory = $cache->getTotalMemory();
         $summary = $cache->getCacheSummary();
         $summary = isort($summary, 'total');
         $summary = array_reverse($summary, true);
         $rows = array();
         foreach ($summary as $key => $info) {
             $rows[] = array($key, pht('%s', new PhutilNumber($info['count'])), phutil_format_bytes($info['max']), phutil_format_bytes($info['total']), sprintf('%.1f%%', 100 * ($info['total'] / $total_memory)));
         }
         $table = id(new AphrontTableView($rows))->setHeaders(array(pht('Pattern'), pht('Count'), pht('Largest'), pht('Total'), pht('Usage')))->setColumnClasses(array('wide', 'n', 'n', 'n', 'n'));
     }
     return id(new PHUIObjectBoxView())->setHeaderText(pht('Data Cache'))->addPropertyList($properties)->setTable($table);
 }
コード例 #14
0
 private function renderTable()
 {
     $rows = array();
     foreach ($this->groups as $group => $items) {
         $has_where = false;
         foreach ($items as $item) {
             if (!empty($item['where'])) {
                 $has_where = true;
                 break;
             }
         }
         $rows[] = '<tr>' . '<th colspan="3">' . phutil_escape_html($group) . '</th>' . '</tr>';
         foreach ($items as $item) {
             $items = isort($items, 'line');
             $line = $item['line'];
             $length = $item['length'];
             if ($length) {
                 $lines = $line . "–" . ($line + $length);
             } else {
                 $lines = $line;
             }
             if (isset($item['href'])) {
                 $href = $item['href'];
                 $target = '_blank';
                 $tail = " ↗";
             } else {
                 $href = '#inline-' . $item['id'];
                 $target = null;
                 $tail = null;
             }
             $lines = phutil_escape_html($lines);
             if ($href) {
                 $lines = phutil_render_tag('a', array('href' => $href, 'target' => $target, 'class' => 'num'), $lines . $tail);
             }
             $where = idx($item, 'where');
             $colspan = $has_where ? '' : ' colspan="2"';
             $rows[] = '<tr>' . '<td class="inline-line-number">' . $lines . '</td>' . ($has_where ? '<td class="inline-which-diff">' . phutil_escape_html($where) . '</td>' : null) . '<td class="inline-summary-content"' . $colspan . '>' . '<div class="phabricator-remarkup">' . $item['content'] . '</div>' . '</td>' . '</tr>';
         }
     }
     return phutil_render_tag('table', array('class' => 'phabricator-inline-summary-table'), implode("\n", $rows));
 }
 public function execute(PhutilArgumentParser $args)
 {
     $console = PhutilConsole::getConsole();
     $console->writeErr("%s\n", pht('Analyzing table sizes (this may take a moment)...'));
     $api = $this->getAPI();
     $patches = $this->getPatches();
     $databases = $api->getDatabaseList($patches, $only_living = true);
     $conn_r = $api->getConn(null);
     $data = array();
     foreach ($databases as $database) {
         queryfx($conn_r, 'USE %C', $database);
         $tables = queryfx_all($conn_r, 'SHOW TABLE STATUS');
         $tables = ipull($tables, null, 'Name');
         $data[$database] = $tables;
     }
     $totals = array_fill_keys(array_keys($data), 0);
     $overall = 0;
     foreach ($data as $db => $tables) {
         foreach ($tables as $table => $info) {
             $table_size = $info['Data_length'] + $info['Index_length'];
             $data[$db][$table]['_totalSize'] = $table_size;
             $totals[$db] += $table_size;
             $overall += $table_size;
         }
     }
     asort($totals);
     $table = id(new PhutilConsoleTable())->setShowHeader(false)->setPadding(2)->addColumn('name', array('title' => pht('Database / Table')))->addColumn('size', array('title' => pht('Size')))->addColumn('percentage', array('title' => pht('Percentage')));
     foreach ($totals as $db => $size) {
         list($database_size, $database_percentage) = $this->formatSize($totals[$db], $overall);
         $table->addRow(array('name' => tsprintf('**%s**', $db), 'size' => tsprintf('**%s**', $database_size), 'percentage' => tsprintf('**%s**', $database_percentage)));
         $data[$db] = isort($data[$db], '_totalSize');
         foreach ($data[$db] as $table_name => $info) {
             list($table_size, $table_percentage) = $this->formatSize($info['_totalSize'], $overall);
             $table->addRow(array('name' => '    ' . $table_name, 'size' => $table_size, 'percentage' => $table_percentage));
         }
     }
     list($overall_size, $overall_percentage) = $this->formatSize($overall, $overall);
     $table->addRow(array('name' => tsprintf('**%s**', pht('TOTAL')), 'size' => tsprintf('**%s**', $overall_size), 'percentage' => tsprintf('**%s**', $overall_percentage)));
     $table->draw();
     return 0;
 }
 public function render()
 {
     DarkConsoleXHProfPluginAPI::includeXHProfLib();
     $GLOBALS['display_calls'] = true;
     $totals = array();
     $flat = xhprof_compute_flat_info($this->profileData, $totals);
     unset($GLOBALS['display_calls']);
     $aggregated = array();
     foreach ($flat as $call => $counters) {
         $parts = explode('@', $call, 2);
         $agg_call = reset($parts);
         if (empty($aggregated[$agg_call])) {
             $aggregated[$agg_call] = $counters;
         } else {
             foreach ($aggregated[$agg_call] as $key => $val) {
                 if ($key != 'wt') {
                     $aggregated[$agg_call][$key] += $counters[$key];
                 }
             }
         }
     }
     $flat = $aggregated;
     $flat = isort($flat, 'wt');
     $flat = array_reverse($flat);
     $rows = array();
     $rows[] = array('Total', number_format($totals['ct']), number_format($totals['wt']) . ' us', '100.0%', number_format($totals['wt']) . ' us', '100.0%');
     if ($this->limit) {
         $flat = array_slice($flat, 0, $this->limit);
     }
     $base_uri = $this->baseURI;
     foreach ($flat as $call => $counters) {
         $rows[] = array(phutil_render_tag('a', array('href' => $base_uri . '?symbol=' . $call), phutil_escape_html($call)), number_format($counters['ct']), number_format($counters['wt']) . ' us', sprintf('%.1f%%', 100 * $counters['wt'] / $totals['wt']), number_format($counters['excl_wt']) . ' us', sprintf('%.1f%%', 100 * $counters['excl_wt'] / $totals['wt']));
     }
     $table = new AphrontTableView($rows);
     $table->setHeaders(array('Symbol', 'Count', 'Incl Wall Time', '%', 'Excl Wall Time', '%'));
     $table->setColumnClasses(array('wide pri', 'n', 'n', 'n', 'n', 'n'));
     $panel = new AphrontPanelView();
     $panel->setHeader('XHProf Profile');
     $panel->appendChild($table);
     return $panel->render();
 }
コード例 #17
0
 public function execute(PhutilArgumentParser $args)
 {
     $console = PhutilConsole::getConsole();
     $console->writeErr("%s\n", pht('Analyzing table sizes (this may take a moment)...'));
     $api = $this->getAPI();
     $patches = $this->getPatches();
     $databases = $api->getDatabaseList($patches, $only_living = true);
     $conn_r = $api->getConn(null);
     $data = array();
     foreach ($databases as $database) {
         queryfx($conn_r, 'USE %C', $database);
         $tables = queryfx_all($conn_r, 'SHOW TABLE STATUS');
         $tables = ipull($tables, null, 'Name');
         $data[$database] = $tables;
     }
     $totals = array_fill_keys(array_keys($data), 0);
     $overall = 0;
     foreach ($data as $db => $tables) {
         foreach ($tables as $table => $info) {
             $table_size = $info['Data_length'] + $info['Index_length'];
             $data[$db][$table]['_totalSize'] = $table_size;
             $totals[$db] += $table_size;
             $overall += $table_size;
         }
     }
     $console->writeOut("%s\n", pht('APPROXIMATE TABLE SIZES'));
     asort($totals);
     foreach ($totals as $db => $size) {
         $database_size = $this->formatSize($totals[$db], $overall);
         $console->writeOut("**%s**\n", sprintf('%-32.32s %18s', $db, $database_size));
         $data[$db] = isort($data[$db], '_totalSize');
         foreach ($data[$db] as $table => $info) {
             $table_size = $this->formatSize($info['_totalSize'], $overall);
             $console->writeOut("%s\n", sprintf('    %-28.28s %18s', $table, $table_size));
         }
     }
     $overall_size = $this->formatSize($overall, $overall);
     $console->writeOut("**%s**\n", sprintf('%-32.32s %18s', pht('TOTAL'), $overall_size));
     return 0;
 }
コード例 #18
0
 public function renderExample()
 {
     $rows = array(array('make' => 'Honda', 'model' => 'Civic', 'year' => 2004, 'price' => 3199, 'color' => pht('Blue')), array('make' => 'Ford', 'model' => 'Focus', 'year' => 2001, 'price' => 2549, 'color' => pht('Red')), array('make' => 'Toyota', 'model' => 'Camry', 'year' => 2009, 'price' => 4299, 'color' => pht('Black')), array('make' => 'NASA', 'model' => 'Shuttle', 'year' => 1998, 'price' => 1000000000, 'color' => pht('White')));
     $request = $this->getRequest();
     $orders = array('make', 'model', 'year', 'price');
     $sort = $request->getStr('sort');
     list($sort, $reverse) = AphrontTableView::parseSort($sort);
     if (!in_array($sort, $orders)) {
         $sort = 'make';
     }
     $rows = isort($rows, $sort);
     if ($reverse) {
         $rows = array_reverse($rows);
     }
     $table = new AphrontTableView($rows);
     $table->setHeaders(array(pht('Make'), pht('Model'), pht('Year'), pht('Price'), pht('Color')));
     $table->setColumnClasses(array('', 'wide', 'n', 'n', ''));
     $table->makeSortable($request->getRequestURI(), 'sort', $sort, $reverse, $orders);
     $panel = new PHUIObjectBoxView();
     $panel->setHeaderText(pht('Sortable Table of Vehicles'));
     $panel->appendChild($table);
     return $panel;
 }
コード例 #19
0
 private function generate()
 {
     if ($this->generated) {
         return;
     }
     $multi_row = true;
     $multi_col = true;
     $margin_w = 1;
     $margin_h = 1;
     $type = $this->type;
     switch ($type) {
         case self::TYPE_STANDARD:
             break;
         case self::TYPE_REPEAT_X:
             $multi_col = false;
             $margin_w = 0;
             $width = null;
             foreach ($this->sprites as $sprite) {
                 if ($width === null) {
                     $width = $sprite->getSourceW();
                 } else {
                     if ($width !== $sprite->getSourceW()) {
                         throw new Exception(pht("All sprites in a '%s' sheet must have the same width.", 'repeat-x'));
                     }
                 }
             }
             break;
         case self::TYPE_REPEAT_Y:
             $multi_row = false;
             $margin_h = 0;
             $height = null;
             foreach ($this->sprites as $sprite) {
                 if ($height === null) {
                     $height = $sprite->getSourceH();
                 } else {
                     if ($height !== $sprite->getSourceH()) {
                         throw new Exception(pht("All sprites in a '%s' sheet must have the same height.", 'repeat-y'));
                     }
                 }
             }
             break;
         default:
             throw new Exception(pht("Unknown sprite sheet type '%s'!", $type));
     }
     $css = array();
     if ($this->cssHeader) {
         $css[] = $this->cssHeader;
     }
     $out_w = 0;
     $out_h = 0;
     // Lay out the sprite sheet. We attempt to build a roughly square sheet
     // so it's easier to manage, since 2000x20 is more cumbersome for humans
     // to deal with than 200x200.
     //
     // To do this, we use a simple greedy algorithm, adding sprites one at a
     // time. For each sprite, if the sheet is at least as wide as it is tall
     // we create a new row. Otherwise, we try to add it to an existing row.
     //
     // This isn't optimal, but does a reasonable job in most cases and isn't
     // too messy.
     // Group the sprites by their sizes. We lay them out in the sheet as
     // boxes, but then put them into the boxes in the order they were added
     // so similar sprites end up nearby on the final sheet.
     $boxes = array();
     foreach (array_reverse($this->sprites) as $sprite) {
         $s_w = $sprite->getSourceW() + $margin_w;
         $s_h = $sprite->getSourceH() + $margin_h;
         $boxes[$s_w][$s_h][] = $sprite;
     }
     $rows = array();
     foreach ($this->sprites as $sprite) {
         $s_w = $sprite->getSourceW() + $margin_w;
         $s_h = $sprite->getSourceH() + $margin_h;
         // Choose a row for this sprite.
         $maybe = array();
         foreach ($rows as $key => $row) {
             if ($row['h'] < $s_h) {
                 // We can only add it to a row if the row is at least as tall as the
                 // sprite.
                 continue;
             }
             // We prefer rows which have the same height as the sprite, and then
             // rows which aren't yet very wide.
             $wasted_v = $row['h'] - $s_h;
             $wasted_h = $row['w'] / $out_w;
             $maybe[$key] = $wasted_v + $wasted_h;
         }
         $row_key = null;
         if ($maybe && $multi_col) {
             // If there were any candidate rows, pick the best one.
             asort($maybe);
             $row_key = head_key($maybe);
         }
         if ($row_key !== null && $multi_row) {
             // If there's a candidate row, but adding the sprite to it would make
             // the sprite wider than it is tall, create a new row instead. This
             // generally keeps the sprite square-ish.
             if ($rows[$row_key]['w'] + $s_w > $out_h) {
                 $row_key = null;
             }
         }
         if ($row_key === null) {
             // Add a new row.
             $rows[] = array('w' => 0, 'h' => $s_h, 'boxes' => array());
             $row_key = last_key($rows);
             $out_h += $s_h;
         }
         // Add the sprite box to the row.
         $row = $rows[$row_key];
         $row['w'] += $s_w;
         $row['boxes'][] = array($s_w, $s_h);
         $rows[$row_key] = $row;
         $out_w = max($row['w'], $out_w);
     }
     $images = array();
     foreach ($this->scales as $scale) {
         $img = imagecreatetruecolor($out_w * $scale, $out_h * $scale);
         imagesavealpha($img, true);
         imagefill($img, 0, 0, imagecolorallocatealpha($img, 0, 0, 0, 127));
         $images[$scale] = $img;
     }
     // Put the shorter rows first. At the same height, put the wider rows first.
     // This makes the resulting sheet more human-readable.
     foreach ($rows as $key => $row) {
         $rows[$key]['sort'] = $row['h'] + (1 - $row['w'] / $out_w);
     }
     $rows = isort($rows, 'sort');
     $pos_x = 0;
     $pos_y = 0;
     $rules = array();
     foreach ($rows as $row) {
         $max_h = 0;
         foreach ($row['boxes'] as $box) {
             $sprite = array_pop($boxes[$box[0]][$box[1]]);
             foreach ($images as $scale => $img) {
                 $src = $this->loadSource($sprite, $scale);
                 imagecopy($img, $src, $scale * $pos_x, $scale * $pos_y, $scale * $sprite->getSourceX(), $scale * $sprite->getSourceY(), $scale * $sprite->getSourceW(), $scale * $sprite->getSourceH());
             }
             $rule = $sprite->getTargetCSS();
             $cssx = -$pos_x . 'px';
             $cssy = -$pos_y . 'px';
             $rules[$sprite->getName()] = "{$rule} {\n" . "  background-position: {$cssx} {$cssy};\n}";
             $pos_x += $sprite->getSourceW() + $margin_w;
             $max_h = max($max_h, $sprite->getSourceH());
         }
         $pos_x = 0;
         $pos_y += $max_h + $margin_h;
     }
     // Generate CSS rules in input order.
     foreach ($this->sprites as $sprite) {
         $css[] = $rules[$sprite->getName()];
     }
     $this->images = $images;
     $this->css = implode("\n\n", $css) . "\n";
     $this->generated = true;
 }
コード例 #20
0
 private function loadRevisionFromHash($hash)
 {
     // TODO -- de-hack this as permissions become more clear with things
     // like T848 (add scope to OAuth)
     if (!$this->isConduitAuthenticated()) {
         return null;
     }
     $conduit = $this->getConduit();
     $revisions = $conduit->callMethodSynchronous('differential.query', array('commitHashes' => array($hash)));
     // grab the latest closed revision only
     $found_revision = null;
     $revisions = isort($revisions, 'dateModified');
     foreach ($revisions as $revision) {
         if ($revision['status'] == ArcanistDifferentialRevisionStatus::CLOSED) {
             $found_revision = $revision;
         }
     }
     return $found_revision;
 }
コード例 #21
0
 public function loadActualSchema()
 {
     $databases = $this->getDatabaseNames();
     $conn = $this->getConn();
     $tables = queryfx_all($conn, 'SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_COLLATION
     FROM INFORMATION_SCHEMA.TABLES
     WHERE TABLE_SCHEMA IN (%Ls)', $databases);
     $database_info = queryfx_all($conn, 'SELECT SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME
     FROM INFORMATION_SCHEMA.SCHEMATA
     WHERE SCHEMA_NAME IN (%Ls)', $databases);
     $database_info = ipull($database_info, null, 'SCHEMA_NAME');
     // Find databases which exist, but which the user does not have permission
     // to see.
     $invisible_databases = array();
     foreach ($databases as $database_name) {
         if (isset($database_info[$database_name])) {
             continue;
         }
         try {
             queryfx($conn, 'SHOW TABLES IN %T', $database_name);
         } catch (AphrontAccessDeniedQueryException $ex) {
             // This database exists, the user just doesn't have permission to
             // see it.
             $invisible_databases[] = $database_name;
         } catch (AphrontSchemaQueryException $ex) {
             // This database is legitimately missing.
         }
     }
     $sql = array();
     foreach ($tables as $table) {
         $sql[] = qsprintf($conn, '(TABLE_SCHEMA = %s AND TABLE_NAME = %s)', $table['TABLE_SCHEMA'], $table['TABLE_NAME']);
     }
     if ($sql) {
         $column_info = queryfx_all($conn, 'SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, CHARACTER_SET_NAME,
         COLLATION_NAME, COLUMN_TYPE, IS_NULLABLE, EXTRA
       FROM INFORMATION_SCHEMA.COLUMNS
       WHERE (%Q)', '(' . implode(') OR (', $sql) . ')');
         $column_info = igroup($column_info, 'TABLE_SCHEMA');
     } else {
         $column_info = array();
     }
     // NOTE: Tables like KEY_COLUMN_USAGE and TABLE_CONSTRAINTS only contain
     // primary, unique, and foreign keys, so we can't use them here. We pull
     // indexes later on using SHOW INDEXES.
     $server_schema = new PhabricatorConfigServerSchema();
     $tables = igroup($tables, 'TABLE_SCHEMA');
     foreach ($tables as $database_name => $database_tables) {
         $info = $database_info[$database_name];
         $database_schema = id(new PhabricatorConfigDatabaseSchema())->setName($database_name)->setCharacterSet($info['DEFAULT_CHARACTER_SET_NAME'])->setCollation($info['DEFAULT_COLLATION_NAME']);
         $database_column_info = idx($column_info, $database_name, array());
         $database_column_info = igroup($database_column_info, 'TABLE_NAME');
         foreach ($database_tables as $table) {
             $table_name = $table['TABLE_NAME'];
             $table_schema = id(new PhabricatorConfigTableSchema())->setName($table_name)->setCollation($table['TABLE_COLLATION']);
             $columns = idx($database_column_info, $table_name, array());
             foreach ($columns as $column) {
                 if (strpos($column['EXTRA'], 'auto_increment') === false) {
                     $auto_increment = false;
                 } else {
                     $auto_increment = true;
                 }
                 $column_schema = id(new PhabricatorConfigColumnSchema())->setName($column['COLUMN_NAME'])->setCharacterSet($column['CHARACTER_SET_NAME'])->setCollation($column['COLLATION_NAME'])->setColumnType($column['COLUMN_TYPE'])->setNullable($column['IS_NULLABLE'] == 'YES')->setAutoIncrement($auto_increment);
                 $table_schema->addColumn($column_schema);
             }
             $key_parts = queryfx_all($conn, 'SHOW INDEXES FROM %T.%T', $database_name, $table_name);
             $keys = igroup($key_parts, 'Key_name');
             foreach ($keys as $key_name => $key_pieces) {
                 $key_pieces = isort($key_pieces, 'Seq_in_index');
                 $head = head($key_pieces);
                 // This handles string indexes which index only a prefix of a field.
                 $column_names = array();
                 foreach ($key_pieces as $piece) {
                     $name = $piece['Column_name'];
                     if ($piece['Sub_part']) {
                         $name = $name . '(' . $piece['Sub_part'] . ')';
                     }
                     $column_names[] = $name;
                 }
                 $key_schema = id(new PhabricatorConfigKeySchema())->setName($key_name)->setColumnNames($column_names)->setUnique(!$head['Non_unique'])->setIndexType($head['Index_type']);
                 $table_schema->addKey($key_schema);
             }
             $database_schema->addTable($table_schema);
         }
         $server_schema->addDatabase($database_schema);
     }
     foreach ($invisible_databases as $database_name) {
         $server_schema->addDatabase(id(new PhabricatorConfigDatabaseSchema())->setName($database_name)->setAccessDenied(true));
     }
     return $server_schema;
 }
コード例 #22
0
ファイル: PhutilTest.php プロジェクト: PaulAntunes/gclf-paul
 public function testIsort()
 {
     $list = ['b' => ['name' => 'b', 'value' => 2], 'a' => ['name' => 'a', 'value' => 1], 'c' => ['name' => 'c', 'value' => 3]];
     $expected = ['a' => ['name' => 'a', 'value' => 1], 'b' => ['name' => 'b', 'value' => 2], 'c' => ['name' => 'c', 'value' => 3]];
     $this->assertEquals($expected, isort($list, 'name'));
 }
コード例 #23
0
 private function getLintersInfo(array $linters, array $built)
 {
     // Note that an engine can emit multiple linters of the same class to run
     // different rulesets on different groups of files, so these linters do not
     // necessarily have unique classes or types.
     $groups = array();
     foreach ($built as $linter) {
         $groups[get_class($linter)][] = $linter;
     }
     $linter_info = array();
     foreach ($linters as $key => $linter) {
         $installed = idx($groups, $key, array());
         $exception = null;
         if ($installed) {
             $status = 'configured';
             try {
                 $version = head($installed)->getVersion();
             } catch (Exception $ex) {
                 $status = 'error';
                 $exception = $ex;
             }
         } else {
             $status = 'available';
             $version = null;
         }
         $linter_info[$key] = array('name' => $linter->getLinterConfigurationName(), 'class' => get_class($linter), 'status' => $status, 'version' => $version, 'short' => $linter->getInfoName(), 'uri' => $linter->getInfoURI(), 'description' => $linter->getInfoDescription(), 'exception' => $exception, 'options' => $linter->getLinterConfigurationOptions());
     }
     return isort($linter_info, 'short');
 }
コード例 #24
0
 /**
  * Get a list of all packages which control a path or its parent directories,
  * ordered from weakest to strongest.
  *
  * The first package has the most specific claim on the path; the last
  * package has the most general claim. Multiple packages may have claims of
  * equal strength, so this ordering is primarily one of usability and
  * convenience.
  *
  * @return list<PhabricatorOwnersPackage> List of controlling packages.
  */
 public function getControllingPackagesForPath($repository_phid, $path)
 {
     $path = (string) $path;
     if (!isset($this->controlMap[$repository_phid][$path])) {
         throw new PhutilInvalidStateException('withControl');
     }
     if ($this->controlResults === null) {
         throw new PhutilInvalidStateException('execute');
     }
     $packages = $this->controlResults;
     $weak_dominion = PhabricatorOwnersPackage::DOMINION_WEAK;
     $matches = array();
     foreach ($packages as $package_id => $package) {
         $best_match = null;
         $include = false;
         // If this package is archived, it's no longer a controlling package
         // for the given path. In particular, it can not force active packages
         // with weak dominion to give up control.
         if ($package->isArchived()) {
             continue;
         }
         foreach ($package->getPaths() as $package_path) {
             if ($package_path->getRepositoryPHID() != $repository_phid) {
                 // If this path is for some other repository, skip it.
                 continue;
             }
             $strength = $package_path->getPathMatchStrength($path);
             if ($strength > $best_match) {
                 $best_match = $strength;
                 $include = !$package_path->getExcluded();
             }
         }
         if ($best_match && $include) {
             $matches[$package_id] = array('strength' => $best_match, 'weak' => $package->getDominion() == $weak_dominion, 'package' => $package);
         }
     }
     $matches = isort($matches, 'strength');
     $matches = array_reverse($matches);
     $first_id = null;
     foreach ($matches as $package_id => $match) {
         if ($first_id === null) {
             $first_id = $package_id;
             continue;
         }
         if ($match['weak']) {
             unset($matches[$package_id]);
         }
     }
     return array_values(ipull($matches, 'package'));
 }
コード例 #25
0
 public function renderOpenTasks()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $query = id(new ManiphestTaskQuery())->withStatus(ManiphestTaskQuery::STATUS_OPEN);
     $project_phid = $request->getStr('project');
     $project_handle = null;
     if ($project_phid) {
         $phids = array($project_phid);
         $handles = $this->loadViewerHandles($phids);
         $project_handle = $handles[$project_phid];
         $query->withAnyProjects($phids);
     }
     $tasks = $query->execute();
     $recently_closed = $this->loadRecentlyClosedTasks();
     $date = phabricator_date(time(), $user);
     switch ($this->view) {
         case 'user':
             $result = mgroup($tasks, 'getOwnerPHID');
             $leftover = idx($result, '', array());
             unset($result['']);
             $result_closed = mgroup($recently_closed, 'getOwnerPHID');
             $leftover_closed = idx($result_closed, '', array());
             unset($result_closed['']);
             $base_link = '/maniphest/?users=';
             $leftover_name = phutil_render_tag('a', array('href' => $base_link . ManiphestTaskOwner::OWNER_UP_FOR_GRABS), '<em>(Up For Grabs)</em>');
             $col_header = 'User';
             $header = 'Open Tasks by User and Priority (' . $date . ')';
             break;
         case 'project':
             $result = array();
             $leftover = array();
             foreach ($tasks as $task) {
                 $phids = $task->getProjectPHIDs();
                 if ($phids) {
                     foreach ($phids as $project_phid) {
                         $result[$project_phid][] = $task;
                     }
                 } else {
                     $leftover[] = $task;
                 }
             }
             $result_closed = array();
             $leftover_closed = array();
             foreach ($recently_closed as $task) {
                 $phids = $task->getProjectPHIDs();
                 if ($phids) {
                     foreach ($phids as $project_phid) {
                         $result_closed[$project_phid][] = $task;
                     }
                 } else {
                     $leftover_closed[] = $task;
                 }
             }
             $base_link = '/maniphest/view/all/?projects=';
             $leftover_name = phutil_render_tag('a', array('href' => $base_link . ManiphestTaskOwner::PROJECT_NO_PROJECT), '<em>(No Project)</em>');
             $col_header = 'Project';
             $header = 'Open Tasks by Project and Priority (' . $date . ')';
             break;
     }
     $phids = array_keys($result);
     $handles = $this->loadViewerHandles($phids);
     $handles = msort($handles, 'getName');
     $order = $request->getStr('order', 'name');
     list($order, $reverse) = AphrontTableView::parseSort($order);
     require_celerity_resource('aphront-tooltip-css');
     Javelin::initBehavior('phabricator-tooltips', array());
     $rows = array();
     $pri_total = array();
     foreach (array_merge($handles, array(null)) as $handle) {
         if ($handle) {
             if ($project_handle && $project_handle->getPHID() == $handle->getPHID()) {
                 // If filtering by, e.g., "bugs", don't show a "bugs" group.
                 continue;
             }
             $tasks = idx($result, $handle->getPHID(), array());
             $name = phutil_render_tag('a', array('href' => $base_link . $handle->getPHID()), phutil_escape_html($handle->getName()));
             $closed = idx($result_closed, $handle->getPHID(), array());
         } else {
             $tasks = $leftover;
             $name = $leftover_name;
             $closed = $leftover_closed;
         }
         $taskv = $tasks;
         $tasks = mgroup($tasks, 'getPriority');
         $row = array();
         $row[] = $name;
         $total = 0;
         foreach (ManiphestTaskPriority::getTaskPriorityMap() as $pri => $label) {
             $n = count(idx($tasks, $pri, array()));
             if ($n == 0) {
                 $row[] = '-';
             } else {
                 $row[] = number_format($n);
             }
             $total += $n;
         }
         $row[] = number_format($total);
         list($link, $oldest_all) = $this->renderOldest($taskv);
         $row[] = $link;
         $normal_or_better = array();
         foreach ($taskv as $id => $task) {
             if ($task->getPriority() < ManiphestTaskPriority::PRIORITY_NORMAL) {
                 continue;
             }
             $normal_or_better[$id] = $task;
         }
         list($link, $oldest_pri) = $this->renderOldest($normal_or_better);
         $row[] = $link;
         if ($closed) {
             $task_ids = implode(',', mpull($closed, 'getID'));
             $row[] = phutil_render_tag('a', array('href' => '/maniphest/view/custom/?s=oc&tasks=' . $task_ids, 'target' => '_blank'), phutil_escape_html(number_format(count($closed))));
         } else {
             $row[] = '-';
         }
         switch ($order) {
             case 'total':
                 $row['sort'] = $total;
                 break;
             case 'oldest-all':
                 $row['sort'] = $oldest_all;
                 break;
             case 'oldest-pri':
                 $row['sort'] = $oldest_pri;
                 break;
             case 'closed':
                 $row['sort'] = count($closed);
                 break;
             case 'name':
             default:
                 $row['sort'] = $handle ? $handle->getName() : '~';
                 break;
         }
         $rows[] = $row;
     }
     $rows = isort($rows, 'sort');
     foreach ($rows as $k => $row) {
         unset($rows[$k]['sort']);
     }
     if ($reverse) {
         $rows = array_reverse($rows);
     }
     $cname = array($col_header);
     $cclass = array('pri right wide');
     $pri_map = ManiphestTaskPriority::getTaskBriefPriorityMap();
     foreach ($pri_map as $pri => $label) {
         $cname[] = $label;
         $cclass[] = 'n';
     }
     $cname[] = 'Total';
     $cclass[] = 'n';
     $cname[] = javelin_render_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => 'Oldest open task.', 'size' => 200)), 'Oldest (All)');
     $cclass[] = 'n';
     $cname[] = javelin_render_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => 'Oldest open task, excluding those with Low or Wishlist ' . 'priority.', 'size' => 200)), 'Oldest (Pri)');
     $cclass[] = 'n';
     list($ignored, $window_epoch) = $this->getWindow();
     $cname[] = javelin_render_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => 'Closed after ' . phabricator_datetime($window_epoch, $user), 'size' => 260)), 'Recently Closed');
     $cclass[] = 'n';
     $table = new AphrontTableView($rows);
     $table->setHeaders($cname);
     $table->setColumnClasses($cclass);
     $table->makeSortable($request->getRequestURI(), 'order', $order, $reverse, array('name', null, null, null, null, null, null, 'total', 'oldest-all', 'oldest-pri', 'closed'));
     $panel = new AphrontPanelView();
     $panel->setHeader($header);
     $panel->appendChild($table);
     $tokens = array();
     if ($project_handle) {
         $tokens = array($project_handle->getPHID() => $project_handle->getFullName());
     }
     $filter = $this->renderReportFilters($tokens, $has_window = true);
     return array($filter, $panel);
 }
コード例 #26
0
                throw new Exception("Package specification for '{$name}' mixes resources of type " . "'{$type}' with resources of type '{$ntype}'. Each package may only " . "contain one type of resource.");
            }
        }
        $hashes[] = $symbol . ':' . $hash_map[$symbol];
    }
    $key = substr(md5(implode("\n", $hashes)), 0, 8);
    $package_map['packages'][$key] = array('name' => $name, 'symbols' => $package, 'uri' => '/res/pkg/' . $key . '/' . $name, 'type' => $type);
    foreach ($package as $symbol) {
        $package_map['reverse'][$symbol] = $key;
    }
}
ksort($runtime_map);
$runtime_map = var_export($runtime_map, true);
$runtime_map = preg_replace('/\\s+$/m', '', $runtime_map);
$runtime_map = preg_replace('/array \\(/', 'array(', $runtime_map);
$package_map['packages'] = isort($package_map['packages'], 'name');
ksort($package_map['reverse']);
$package_map = var_export($package_map, true);
$package_map = preg_replace('/\\s+$/m', '', $package_map);
$package_map = preg_replace('/array \\(/', 'array(', $package_map);
$generated = '@' . 'generated';
$resource_map = <<<EOFILE
<?php

/**
 * This file is automatically generated. Use 'celerity_mapper.php' to rebuild
 * it.
 * {$generated}
 */

celerity_register_resource_map({$runtime_map}, {$package_map});
コード例 #27
0
 public function renderOpenTasks()
 {
     $request = $this->getRequest();
     $viewer = $request->getUser();
     $query = id(new ManiphestTaskQuery())->setViewer($viewer)->withStatuses(ManiphestTaskStatus::getOpenStatusConstants());
     switch ($this->view) {
         case 'project':
             $query->needProjectPHIDs(true);
             break;
     }
     $project_phid = $request->getStr('project');
     $project_handle = null;
     if ($project_phid) {
         $phids = array($project_phid);
         $handles = $this->loadViewerHandles($phids);
         $project_handle = $handles[$project_phid];
         $query->withEdgeLogicPHIDs(PhabricatorProjectObjectHasProjectEdgeType::EDGECONST, PhabricatorQueryConstraint::OPERATOR_OR, $phids);
     }
     $tasks = $query->execute();
     $recently_closed = $this->loadRecentlyClosedTasks();
     $date = phabricator_date(time(), $viewer);
     switch ($this->view) {
         case 'user':
             $result = mgroup($tasks, 'getOwnerPHID');
             $leftover = idx($result, '', array());
             unset($result['']);
             $result_closed = mgroup($recently_closed, 'getOwnerPHID');
             $leftover_closed = idx($result_closed, '', array());
             unset($result_closed['']);
             $base_link = '/maniphest/?assigned=';
             $leftover_name = phutil_tag('em', array(), pht('(Up For Grabs)'));
             $col_header = pht('User');
             $header = pht('Open Tasks by User and Priority (%s)', $date);
             break;
         case 'project':
             $result = array();
             $leftover = array();
             foreach ($tasks as $task) {
                 $phids = $task->getProjectPHIDs();
                 if ($phids) {
                     foreach ($phids as $project_phid) {
                         $result[$project_phid][] = $task;
                     }
                 } else {
                     $leftover[] = $task;
                 }
             }
             $result_closed = array();
             $leftover_closed = array();
             foreach ($recently_closed as $task) {
                 $phids = $task->getProjectPHIDs();
                 if ($phids) {
                     foreach ($phids as $project_phid) {
                         $result_closed[$project_phid][] = $task;
                     }
                 } else {
                     $leftover_closed[] = $task;
                 }
             }
             $base_link = '/maniphest/?projects=';
             $leftover_name = phutil_tag('em', array(), pht('(No Project)'));
             $col_header = pht('Project');
             $header = pht('Open Tasks by Project and Priority (%s)', $date);
             break;
     }
     $phids = array_keys($result);
     $handles = $this->loadViewerHandles($phids);
     $handles = msort($handles, 'getName');
     $order = $request->getStr('order', 'name');
     list($order, $reverse) = AphrontTableView::parseSort($order);
     require_celerity_resource('aphront-tooltip-css');
     Javelin::initBehavior('phabricator-tooltips', array());
     $rows = array();
     $pri_total = array();
     foreach (array_merge($handles, array(null)) as $handle) {
         if ($handle) {
             if ($project_handle && $project_handle->getPHID() == $handle->getPHID()) {
                 // If filtering by, e.g., "bugs", don't show a "bugs" group.
                 continue;
             }
             $tasks = idx($result, $handle->getPHID(), array());
             $name = phutil_tag('a', array('href' => $base_link . $handle->getPHID()), $handle->getName());
             $closed = idx($result_closed, $handle->getPHID(), array());
         } else {
             $tasks = $leftover;
             $name = $leftover_name;
             $closed = $leftover_closed;
         }
         $taskv = $tasks;
         $tasks = mgroup($tasks, 'getPriority');
         $row = array();
         $row[] = $name;
         $total = 0;
         foreach (ManiphestTaskPriority::getTaskPriorityMap() as $pri => $label) {
             $n = count(idx($tasks, $pri, array()));
             if ($n == 0) {
                 $row[] = '-';
             } else {
                 $row[] = number_format($n);
             }
             $total += $n;
         }
         $row[] = number_format($total);
         list($link, $oldest_all) = $this->renderOldest($taskv);
         $row[] = $link;
         $normal_or_better = array();
         foreach ($taskv as $id => $task) {
             // TODO: This is sort of a hard-code for the default "normal" status.
             // When reports are more powerful, this should be made more general.
             if ($task->getPriority() < 50) {
                 continue;
             }
             $normal_or_better[$id] = $task;
         }
         list($link, $oldest_pri) = $this->renderOldest($normal_or_better);
         $row[] = $link;
         if ($closed) {
             $task_ids = implode(',', mpull($closed, 'getID'));
             $row[] = phutil_tag('a', array('href' => '/maniphest/?ids=' . $task_ids, 'target' => '_blank'), number_format(count($closed)));
         } else {
             $row[] = '-';
         }
         switch ($order) {
             case 'total':
                 $row['sort'] = $total;
                 break;
             case 'oldest-all':
                 $row['sort'] = $oldest_all;
                 break;
             case 'oldest-pri':
                 $row['sort'] = $oldest_pri;
                 break;
             case 'closed':
                 $row['sort'] = count($closed);
                 break;
             case 'name':
             default:
                 $row['sort'] = $handle ? $handle->getName() : '~';
                 break;
         }
         $rows[] = $row;
     }
     $rows = isort($rows, 'sort');
     foreach ($rows as $k => $row) {
         unset($rows[$k]['sort']);
     }
     if ($reverse) {
         $rows = array_reverse($rows);
     }
     $cname = array($col_header);
     $cclass = array('pri right wide');
     $pri_map = ManiphestTaskPriority::getShortNameMap();
     foreach ($pri_map as $pri => $label) {
         $cname[] = $label;
         $cclass[] = 'n';
     }
     $cname[] = pht('Total');
     $cclass[] = 'n';
     $cname[] = javelin_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => pht('Oldest open task.'), 'size' => 200)), pht('Oldest (All)'));
     $cclass[] = 'n';
     $cname[] = javelin_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => pht('Oldest open task, excluding those with Low or Wishlist priority.'), 'size' => 200)), pht('Oldest (Pri)'));
     $cclass[] = 'n';
     list($ignored, $window_epoch) = $this->getWindow();
     $edate = phabricator_datetime($window_epoch, $viewer);
     $cname[] = javelin_tag('span', array('sigil' => 'has-tooltip', 'meta' => array('tip' => pht('Closed after %s', $edate), 'size' => 260)), pht('Recently Closed'));
     $cclass[] = 'n';
     $table = new AphrontTableView($rows);
     $table->setHeaders($cname);
     $table->setColumnClasses($cclass);
     $table->makeSortable($request->getRequestURI(), 'order', $order, $reverse, array('name', null, null, null, null, null, null, 'total', 'oldest-all', 'oldest-pri', 'closed'));
     $panel = new PHUIObjectBoxView();
     $panel->setHeaderText($header);
     $panel->setTable($table);
     $tokens = array();
     if ($project_handle) {
         $tokens = array($project_handle);
     }
     $filter = $this->renderReportFilters($tokens, $has_window = true);
     return array($filter, $panel);
 }
コード例 #28
0
 public function run()
 {
     $console = PhutilConsole::getConsole();
     $linters = id(new PhutilSymbolLoader())->setAncestorClass('ArcanistLinter')->loadObjects();
     try {
         $built = $this->newLintEngine()->buildLinters();
     } catch (ArcanistNoEngineException $ex) {
         $built = array();
     }
     // Note that an engine can emit multiple linters of the same class to run
     // different rulesets on different groups of files, so these linters do not
     // necessarily have unique classes or types.
     $groups = array();
     foreach ($built as $linter) {
         $groups[get_class($linter)][] = $linter;
     }
     $linter_info = array();
     foreach ($linters as $key => $linter) {
         $installed = idx($groups, $key, array());
         $exception = null;
         if ($installed) {
             $status = 'configured';
             try {
                 $version = head($installed)->getVersion();
             } catch (Exception $ex) {
                 $status = 'error';
                 $exception = $ex;
             }
         } else {
             $status = 'available';
             $version = null;
         }
         $linter_info[$key] = array('short' => $linter->getLinterConfigurationName(), 'class' => get_class($linter), 'status' => $status, 'version' => $version, 'name' => $linter->getInfoName(), 'uri' => $linter->getInfoURI(), 'description' => $linter->getInfoDescription(), 'exception' => $exception, 'options' => $linter->getLinterConfigurationOptions());
     }
     $linter_info = isort($linter_info, 'short');
     $status_map = $this->getStatusMap();
     $pad = '    ';
     $color_map = array('configured' => 'green', 'available' => 'yellow', 'error' => 'red');
     foreach ($linter_info as $key => $linter) {
         $status = $linter['status'];
         $color = $color_map[$status];
         $text = $status_map[$status];
         $print_tail = false;
         $console->writeOut("<bg:" . $color . ">** %s **</bg> **%s** (%s)\n", $text, nonempty($linter['short'], '-'), $linter['name']);
         if ($linter['exception']) {
             $console->writeOut("\n%s**%s**\n%s\n", $pad, get_class($linter['exception']), phutil_console_wrap($linter['exception']->getMessage(), strlen($pad)));
             $print_tail = true;
         }
         $version = $linter['version'];
         $uri = $linter['uri'];
         if ($version || $uri) {
             $console->writeOut("\n");
             $print_tail = true;
         }
         if ($version) {
             $console->writeOut("%s%s **%s**\n", $pad, pht('Version'), $version);
         }
         if ($uri) {
             $console->writeOut("%s__%s__\n", $pad, $linter['uri']);
         }
         $description = $linter['description'];
         if ($description) {
             $console->writeOut("\n%s\n", phutil_console_wrap($linter['description'], strlen($pad)));
             $print_tail = true;
         }
         $options = $linter['options'];
         if ($options && $this->getArgument('verbose')) {
             $console->writeOut("\n%s**%s**\n\n", $pad, pht('Configuration Options'));
             $last_option = last_key($options);
             foreach ($options as $option => $option_spec) {
                 $console->writeOut("%s__%s__ (%s)\n", $pad, $option, $option_spec['type']);
                 $console->writeOut("%s\n", phutil_console_wrap($option_spec['help'], strlen($pad) + 2));
                 if ($option != $last_option) {
                     $console->writeOut("\n");
                 }
             }
             $print_tail = true;
         }
         if ($print_tail) {
             $console->writeOut("\n");
         }
     }
     if (!$this->getArgument('verbose')) {
         $console->writeOut("%s\n", pht('(Run `%s` for more details.)', 'arc linters --verbose'));
     }
 }
コード例 #29
0
 /**
  * To get paging to work for "group by project", we need to do a bunch of
  * server-side magic since there's currently no way to sort by project name on
  * the database.
  *
  * TODO: Move this all to the database.
  */
 private function applyGroupByProject(array $tasks)
 {
     assert_instances_of($tasks, 'ManiphestTask');
     $project_phids = array();
     foreach ($tasks as $task) {
         foreach ($task->getProjectPHIDs() as $phid) {
             $project_phids[$phid] = true;
         }
     }
     $handles = id(new PhabricatorObjectHandleData(array_keys($project_phids)))->loadHandles();
     $max = 1;
     foreach ($handles as $handle) {
         $max = max($max, strlen($handle->getName()));
     }
     $items = array();
     $ii = 0;
     foreach ($tasks as $key => $task) {
         $phids = $task->getProjectPHIDs();
         if (!$this->anyProject && $this->projectPHIDs) {
             $phids = array_diff($phids, $this->projectPHIDs);
         }
         if ($phids) {
             foreach ($phids as $phid) {
                 $items[] = array('key' => $key, 'seq' => sprintf('%' . $max . 's%d', $handles[$phid]->getName(), $ii));
             }
         } else {
             // Sort "no project" tasks first.
             $items[] = array('key' => $key, 'seq' => '');
         }
         ++$ii;
     }
     $items = isort($items, 'seq');
     $items = array_slice($items, nonempty($this->offset), nonempty($this->limit, self::DEFAULT_PAGE_SIZE));
     $result = array();
     foreach ($items as $item) {
         $result[] = $tasks[$item['key']];
     }
     return $result;
 }
コード例 #30
0
 private function printBranches(array $branches, array $revisions)
 {
     $revisions = ipull($revisions, null, 'id');
     static $color_map = array('Closed' => 'cyan', 'Needs Review' => 'magenta', 'Needs Revision' => 'red', 'Accepted' => 'green', 'No Revision' => 'blue', 'Abandoned' => 'default');
     static $ssort_map = array('Closed' => 1, 'No Revision' => 2, 'Needs Review' => 3, 'Needs Revision' => 4, 'Accepted' => 5);
     $out = array();
     foreach ($branches as $branch) {
         $revision = idx($revisions, idx($branch, 'revisionID'));
         // If we haven't identified a revision by ID, try to identify it by hash.
         if (!$revision) {
             foreach ($revisions as $rev) {
                 $hashes = idx($rev, 'hashes', array());
                 foreach ($hashes as $hash) {
                     if ($hash[0] == 'gtcm' && $hash[1] == $branch['hash'] || $hash[0] == 'gttr' && $hash[1] == $branch['tree']) {
                         $revision = $rev;
                         break;
                     }
                 }
             }
         }
         if ($revision) {
             $desc = 'D' . $revision['id'] . ': ' . $revision['title'];
             $status = $revision['statusName'];
         } else {
             $desc = $branch['desc'];
             $status = 'No Revision';
         }
         if (!$this->getArgument('view-all') && !$branch['current']) {
             if ($status == 'Closed' || $status == 'Abandoned') {
                 continue;
             }
         }
         $epoch = $branch['epoch'];
         $color = idx($color_map, $status, 'default');
         $ssort = sprintf('%d%012d', idx($ssort_map, $status, 0), $epoch);
         $out[] = array('name' => $branch['name'], 'current' => $branch['current'], 'status' => $status, 'desc' => $desc, 'color' => $color, 'esort' => $epoch, 'ssort' => $ssort);
     }
     $len_name = max(array_map('strlen', ipull($out, 'name'))) + 2;
     $len_status = max(array_map('strlen', ipull($out, 'status'))) + 2;
     if ($this->getArgument('by-status')) {
         $out = isort($out, 'ssort');
     } else {
         $out = isort($out, 'esort');
     }
     $console = PhutilConsole::getConsole();
     foreach ($out as $line) {
         $color = $line['color'];
         $console->writeOut("%s **%s** <fg:{$color}>%s</fg> %s\n", $line['current'] ? '* ' : '  ', str_pad($line['name'], $len_name), str_pad($line['status'], $len_status), $line['desc']);
     }
 }