public function processRequest() { $request = $this->getRequest(); $repository = id(new PhabricatorRepository())->load($this->id); if (!$repository) { return new Aphront404Response(); } $views = array('basic' => 'Basics', 'tracking' => 'Tracking'); $this->repository = $repository; if (!isset($views[$this->view])) { $this->view = head_key($views); } $nav = new AphrontSideNavView(); foreach ($views as $view => $name) { $nav->addNavItem(phutil_render_tag('a', array('class' => $view == $this->view ? 'aphront-side-nav-selected' : null, 'href' => '/repository/edit/' . $repository->getID() . '/' . $view . '/'), phutil_escape_html($name))); } $nav->appendChild($this->renderDaemonNotice()); $this->sideNav = $nav; switch ($this->view) { case 'basic': return $this->processBasicRequest(); case 'tracking': return $this->processTrackingRequest(); default: throw new Exception("Unknown view."); } }
public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) { $query = id(new PhabricatorMacroQuery())->needFiles(true)->withIDs($saved->getParameter('ids', array()))->withPHIDs($saved->getParameter('phids', array()))->withAuthorPHIDs($saved->getParameter('authorPHIDs', array())); $status = $saved->getParameter('status'); $options = PhabricatorMacroQuery::getStatusOptions(); if (empty($options[$status])) { $status = head_key($options); } $query->withStatus($status); $names = $saved->getParameter('names', array()); if ($names) { $query->withNames($names); } $like = $saved->getParameter('nameLike'); if (strlen($like)) { $query->withNameLike($like); } $start = $this->parseDateTime($saved->getParameter('createdStart')); $end = $this->parseDateTime($saved->getParameter('createdEnd')); if ($start) { $query->withDateCreatedAfter($start); } if ($end) { $query->withDateCreatedBefore($end); } $color = $saved->getParameter('flagColor'); if (strlen($color)) { $query->withFlagColor($color); } return $query; }
protected function buildBareRepository($callsign) { $existing_repository = id(new PhabricatorRepositoryQuery())->withCallsigns(array($callsign))->setViewer(PhabricatorUser::getOmnipotentUser())->executeOne(); if ($existing_repository) { $existing_repository->delete(); } $data_dir = dirname(__FILE__) . '/data/'; $types = array('svn' => PhabricatorRepositoryType::REPOSITORY_TYPE_SVN, 'hg' => PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL, 'git' => PhabricatorRepositoryType::REPOSITORY_TYPE_GIT); $hits = array(); foreach ($types as $type => $const) { $path = $data_dir . $callsign . '.' . $type . '.tgz'; if (Filesystem::pathExists($path)) { $hits[$const] = $path; } } if (!$hits) { throw new Exception("No test data for callsign '{$callsign}'. Expected an archive " . "like '{$callsign}.git.tgz' in '{$data_dir}'."); } if (count($hits) > 1) { throw new Exception("Expected exactly one archive matching callsign '{$callsign}', " . "found too many: " . implode(', ', $hits)); } $path = head($hits); $vcs_type = head_key($hits); $dir = PhutilDirectoryFixture::newFromArchive($path); $local = new TempFile('.ignore'); $user = $this->generateNewTestUser(); $repo = PhabricatorRepository::initializeNewRepository($user)->setCallsign($callsign)->setName(pht('Test Repo "%s"', $callsign))->setVersionControlSystem($vcs_type)->setDetail('local-path', dirname($local) . '/' . $callsign)->setDetail('remote-uri', 'file://' . $dir->getPath() . '/'); $this->didConstructRepository($repo); $repo->save(); $repo->makeEphemeral(); // Keep the disk resources around until we exit. $this->dirs[] = $dir; $this->dirs[] = $local; return $repo; }
public function run() { $ids = $this->getArgument('task_id'); $message = $this->getArgument('message'); $status = strtolower($this->getArgument('status')); if (!isset($status) || $status == '') { $status = head_key($this->statusOptions); } if (isset($this->statusOptions[$status])) { $status = $this->statusOptions[$status]; } else { $options = array_keys($this->statusOptions); $last = array_pop($options); echo "Invalid status {$status}, valid options are " . implode(', ', $options) . ", or {$last}.\n"; return; } foreach ($ids as $id) { if (!preg_match("/^T?\\d+\$/", $id)) { echo "Invalid Task ID: {$id}.\n"; return 1; } $id = ltrim($id, 'T'); $result = $this->closeTask($id, $status, $message); $status_options = array_flip($this->statusOptions); $current_status = $status_options[$status]; if ($result) { echo "T{$id}'s status is now set to {$current_status}.\n"; } else { echo "T{$id} is already set to {$current_status}.\n"; } } return 0; }
public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $content_type_map = HeraldContentTypeConfig::getContentTypeMap(); if (empty($content_type_map[$this->contentType])) { $this->contentType = head_key($content_type_map); } $rule_type_map = HeraldRuleTypeConfig::getRuleTypeMap(); if (empty($rule_type_map[$this->ruleType])) { $this->ruleType = HeraldRuleTypeConfig::RULE_TYPE_PERSONAL; } // Reorder array to put "personal" first. $rule_type_map = array_select_keys($rule_type_map, array(HeraldRuleTypeConfig::RULE_TYPE_PERSONAL)) + $rule_type_map; $captions = array(HeraldRuleTypeConfig::RULE_TYPE_PERSONAL => 'Personal rules notify you about events. You own them, but they can ' . 'only affect you.', HeraldRuleTypeConfig::RULE_TYPE_GLOBAL => 'Global rules notify anyone about events. No one owns them, and ' . 'anyone can edit them. Usually, Global rules are used to notify ' . 'mailing lists.'); $radio = id(new AphrontFormRadioButtonControl())->setLabel('Type')->setName('rule_type')->setValue($this->ruleType); foreach ($rule_type_map as $value => $name) { $radio->addButton($value, $name, idx($captions, $value)); } $form = id(new AphrontFormView())->setUser($user)->setAction('/herald/rule/')->appendChild(id(new AphrontFormSelectControl())->setLabel('New rule for')->setName('content_type')->setValue($this->contentType)->setOptions($content_type_map))->appendChild($radio)->appendChild(id(new AphrontFormSubmitControl())->setValue('Create Rule')->addCancelButton('/herald/view/' . $this->contentType . '/')); $panel = new AphrontPanelView(); $panel->setHeader('Create New Herald Rule'); $panel->setWidth(AphrontPanelView::WIDTH_FULL); $panel->appendChild($form); $nav = $this->renderNav(); $nav->selectFilter('new'); $nav->appendChild($panel); return $this->buildStandardPageResponse($nav, array('title' => 'Create Herald Rule')); }
public function handleRequest(AphrontRequest $request) { $id = $request->getURIData('class'); $classes = id(new PhutilSymbolLoader())->setAncestorClass('PhabricatorUIExample')->loadObjects(); $classes = msort($classes, 'getName'); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI($this->getApplicationURI('view/'))); foreach ($classes as $class => $obj) { $name = $obj->getName(); $nav->addFilter($class, $name); } $selected = $nav->selectFilter($id, head_key($classes)); $example = $classes[$selected]; $example->setRequest($this->getRequest()); $result = $example->renderExample(); if ($result instanceof AphrontResponse) { // This allows examples to generate dialogs, etc., for demonstration. return $result; } require_celerity_resource('phabricator-ui-example-css'); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb($example->getName()); $note = id(new PHUIInfoView())->setTitle(pht('%s (%s)', $example->getName(), get_class($example)))->appendChild($example->getDescription())->setSeverity(PHUIInfoView::SEVERITY_NODATA); $nav->appendChild(array($crumbs, $note, $result)); return $this->buildApplicationPage($nav, array('title' => $example->getName())); }
public function processRequest() { $classes = id(new PhutilSymbolLoader())->setAncestorClass('PhabricatorUIExample')->loadObjects(); $classes = msort($classes, 'getName'); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI($this->getApplicationURI('view/'))); foreach ($classes as $class => $obj) { $name = $obj->getName(); $nav->addFilter($class, $name); } $selected = $nav->selectFilter($this->class, head_key($classes)); $example = $classes[$selected]; $example->setRequest($this->getRequest()); $result = $example->renderExample(); if ($result instanceof AphrontResponse) { // This allows examples to generate dialogs, etc., for demonstration. return $result; } require_celerity_resource('phabricator-ui-example-css'); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb($example->getName()); $header = id(new PHUIHeaderView())->setHeader(pht('%s (%s)', $example->getName(), get_class($example)))->setSubheader($example->getDescription())->setNoBackground(true); $nav->appendChild(array($crumbs, $header, phutil_tag('br'), $result)); return $this->buildApplicationPage($nav, array('title' => $example->getName())); }
public function processRequest() { $classes = id(new PhutilSymbolLoader())->setAncestorClass('PhabricatorUIExample')->selectAndLoadSymbols(); $classes = ipull($classes, 'name', 'name'); $selected = null; foreach ($classes as $class => $ignored) { $classes[$class] = newv($class, array()); if ($this->class == $classes[$class]->getName()) { $selected = $class; } } if (!$selected) { $selected = head_key($classes); } $nav = new AphrontSideNavView(); foreach ($classes as $class => $obj) { $name = $obj->getName(); $nav->addNavItem(phutil_render_tag('a', array('href' => '/uiexample/view/' . $name . '/', 'class' => $selected == $class ? 'aphront-side-nav-selected' : null), phutil_escape_html($obj->getName()))); } require_celerity_resource('phabricator-ui-example-css'); $example = $classes[$selected]; $example->setRequest($this->getRequest()); $nav->appendChild('<div class="phabricator-ui-example-header">' . '<h1 class="phabricator-ui-example-name">' . phutil_escape_html($example->getName()) . ' (' . get_class($example) . ')' . '</h1>' . '<p class="phabricator-ui-example-description">' . $example->getDescription() . '</p>' . '</div>'); $nav->appendChild($example->renderExample()); return $this->buildStandardPageResponse($nav, array('title' => 'UI Example')); }
public function processRequest() { $classes = id(new PhutilSymbolLoader())->setAncestorClass('PhabricatorUIExample')->setConcreteOnly(true)->selectAndLoadSymbols(); $classes = ipull($classes, 'name', 'name'); foreach ($classes as $class => $ignored) { $classes[$class] = newv($class, array()); } $classes = msort($classes, 'getName'); $nav = new AphrontSideNavFilterView(); $nav->setBaseURI(new PhutilURI($this->getApplicationURI('view/'))); foreach ($classes as $class => $obj) { $name = $obj->getName(); $nav->addFilter($class, $name); } $selected = $nav->selectFilter($this->class, head_key($classes)); require_celerity_resource('phabricator-ui-example-css'); $example = $classes[$selected]; $example->setRequest($this->getRequest()); $result = $example->renderExample(); if ($result instanceof AphrontResponse) { // This allows examples to generate dialogs, etc., for demonstration. return $result; } $nav->appendChild('<div class="phabricator-ui-example-header">' . '<h1 class="phabricator-ui-example-name">' . phutil_escape_html($example->getName()) . ' (' . get_class($example) . ')' . '</h1>' . '<p class="phabricator-ui-example-description">' . $example->getDescription() . '</p>' . '</div>'); $nav->appendChild($result); return $this->buildApplicationPage($nav, array('title' => 'UI Example', 'device' => true)); }
public function render(AphrontRequest $request) { $user = $request->getUser(); $plugins = $this->getEnabledPlugins(); foreach ($plugins as $plugin) { $plugin->setRequest($request); $plugin->willShutdown(); } foreach ($plugins as $plugin) { $plugin->didShutdown(); } foreach ($plugins as $plugin) { $plugin->setData($plugin->generateData()); } $selected = $user->getConsoleTab(); $visible = $user->getConsoleVisible(); if (!isset($plugins[$selected])) { $selected = head_key($plugins); } $tabs = array(); foreach ($plugins as $key => $plugin) { $tabs[$key] = array('name' => $plugin->getName(), 'panel' => $plugin->render()); } $tabs_markup = array(); $panel_markup = array(); foreach ($tabs as $key => $data) { $is_selected = $key == $selected; if ($is_selected) { $style = null; $tabclass = 'dark-console-tab-selected'; } else { $style = 'display: none;'; $tabclass = null; } $tabs_markup[] = javelin_render_tag('a', array('class' => "dark-console-tab {$tabclass}", 'sigil' => 'dark-console-tab', 'id' => 'dark-console-tab-' . $key), (string) $data['name']); $panel_markup[] = javelin_render_tag('div', array('class' => 'dark-console-panel dark-console-panel-' . $key, 'style' => $style, 'sigil' => 'dark-console-panel'), (string) $data['panel']); } $console = javelin_render_tag('table', array('class' => 'dark-console', 'sigil' => 'dark-console', 'style' => $visible ? '' : 'display: none;'), '<tr>' . '<th class="dark-console-tabs">' . implode("\n", $tabs_markup) . '</th>' . '<td>' . implode("\n", $panel_markup) . '</td>' . '</tr>'); if (!empty($_COOKIE['phsid'])) { $console = str_replace($_COOKIE['phsid'], phutil_escape_html('<session-key>'), $console); } if ($request->isAjax()) { // for ajax this HTML gets updated on the client $request_history = null; } else { $request_table_header = '<div class="dark-console-panel-request-log-separator"></div>'; $rows = array(); $table = new AphrontTableView($rows); $table->setHeaders(array('Sequence', 'Type', 'URI')); $table->setColumnClasses(array('', '', 'wide')); $request_table = $request_table_header . $table->render(); $request_history = javelin_render_tag('table', array('class' => 'dark-console dark-console-request-log', 'sigil' => 'dark-console-request-log', 'style' => $visible ? '' : 'display: none;'), '<tr>' . '<th class="dark-console-tabs">' . javelin_render_tag('a', array('class' => 'dark-console-tab dark-console-tab-selected'), 'Request Log') . '</th>' . '<td>' . javelin_render_tag('div', array('class' => 'dark-console-panel dark-console-panel-RequestLog'), $request_table) . '</td>' . '</tr>'); } return "\n\n\n\n" . $console . $request_history . "\n\n\n\n"; }
public function handleRequest(AphrontRequest $request) { $viewer = $request->getViewer(); $color_map = PhabricatorFilesComposeIconBuiltinFile::getAllColors(); $icon_map = $this->getIconMap(); if ($request->isFormPost()) { $project_phid = $request->getStr('projectPHID'); if ($project_phid) { $project = id(new PhabricatorProjectQuery())->setViewer($viewer)->withPHIDs(array($project_phid))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->executeOne(); if (!$project) { return new Aphront404Response(); } } $icon = $request->getStr('icon'); $color = $request->getStr('color'); $composer = id(new PhabricatorFilesComposeIconBuiltinFile())->setIcon($icon)->setColor($color); $data = $composer->loadBuiltinFileData(); $file = PhabricatorFile::buildFromFileDataOrHash($data, array('name' => $composer->getBuiltinDisplayName(), 'profile' => true, 'canCDN' => true)); if ($project_phid) { $edit_uri = '/project/history/' . $project->getID() . '/'; $xactions = array(); $xactions[] = id(new PhabricatorProjectTransaction())->setTransactionType(PhabricatorProjectTransaction::TYPE_IMAGE)->setNewValue($file->getPHID()); $editor = id(new PhabricatorProjectTransactionEditor())->setActor($viewer)->setContentSourceFromRequest($request)->setContinueOnMissingFields(true)->setContinueOnNoEffect(true); $editor->applyTransactions($project, $xactions); return id(new AphrontRedirectResponse())->setURI($edit_uri); } else { $content = array('phid' => $file->getPHID()); return id(new AphrontAjaxResponse())->setContent($content); } } $value_color = head_key($color_map); $value_icon = head_key($icon_map); require_celerity_resource('people-profile-css'); $buttons = array(); foreach ($color_map as $color => $info) { $quip = idx($info, 'quip'); $buttons[] = javelin_tag('button', array('class' => 'grey profile-image-button', 'sigil' => 'has-tooltip compose-select-color', 'style' => 'margin: 0 8px 8px 0', 'meta' => array('color' => $color, 'tip' => $quip)), id(new PHUIIconView())->addClass('compose-background-' . $color)); } $icons = array(); foreach ($icon_map as $icon => $spec) { $quip = idx($spec, 'quip'); $icons[] = javelin_tag('button', array('class' => 'grey profile-image-button', 'sigil' => 'has-tooltip compose-select-icon', 'style' => 'margin: 0 8px 8px 0', 'meta' => array('icon' => $icon, 'tip' => $quip)), id(new PHUIIconView())->setIconFont($icon)->addClass('compose-icon-bg')); } $dialog_id = celerity_generate_unique_node_id(); $color_input_id = celerity_generate_unique_node_id(); $icon_input_id = celerity_generate_unique_node_id(); $preview_id = celerity_generate_unique_node_id(); $preview = id(new PHUIIconView())->setID($preview_id)->addClass('compose-background-' . $value_color)->setIconFont($value_icon)->addClass('compose-icon-bg'); $color_input = javelin_tag('input', array('type' => 'hidden', 'name' => 'color', 'value' => $value_color, 'id' => $color_input_id)); $icon_input = javelin_tag('input', array('type' => 'hidden', 'name' => 'icon', 'value' => $value_icon, 'id' => $icon_input_id)); Javelin::initBehavior('phabricator-tooltips'); Javelin::initBehavior('icon-composer', array('dialogID' => $dialog_id, 'colorInputID' => $color_input_id, 'iconInputID' => $icon_input_id, 'previewID' => $preview_id, 'defaultColor' => $value_color, 'defaultIcon' => $value_icon)); $dialog = id(new AphrontDialogView())->setUser($viewer)->setFormID($dialog_id)->setClass('compose-dialog')->setTitle(pht('Compose Image'))->appendChild(phutil_tag('div', array('class' => 'compose-header'), pht('Choose Background Color')))->appendChild($buttons)->appendChild(phutil_tag('div', array('class' => 'compose-header'), pht('Choose Icon')))->appendChild($icons)->appendChild(phutil_tag('div', array('class' => 'compose-header'), pht('Preview')))->appendChild($preview)->appendChild($color_input)->appendChild($icon_input)->addCancelButton('/')->addSubmitButton(pht('Save Image')); return id(new AphrontDialogResponse())->setDialog($dialog); }
public function render() { if (!$this->mock) { throw new Exception('Call setMock() before render()!'); } $mock = $this->mock; require_celerity_resource('javelin-behavior-pholio-mock-view'); $images = array(); $panel_id = celerity_generate_unique_node_id(); $viewport_id = celerity_generate_unique_node_id(); $ids = mpull($mock->getImages(), 'getID'); if ($this->imageID && isset($ids[$this->imageID])) { $selected_id = $this->imageID; } else { $selected_id = head_key($ids); } // TODO: We could maybe do a better job with tailoring this, which is the // image shown on the review stage. $nonimage_uri = celerity_get_resource_uri('rsrc/image/icon/fatcow/thumbnails/default.p100.png'); $engine = id(new PhabricatorMarkupEngine())->setViewer($this->getUser()); foreach ($mock->getAllImages() as $image) { $engine->addObject($image, 'default'); } $engine->process(); $current_set = 0; foreach ($mock->getAllImages() as $image) { $file = $image->getFile(); $metadata = $file->getMetadata(); $x = idx($metadata, PhabricatorFile::METADATA_IMAGE_WIDTH); $y = idx($metadata, PhabricatorFile::METADATA_IMAGE_HEIGHT); $is_obs = (bool) $image->getIsObsolete(); if (!$is_obs) { $current_set++; } $history_uri = '/pholio/image/history/' . $image->getID() . '/'; $images[] = array('id' => $image->getID(), 'fullURI' => $file->getBestURI(), 'stageURI' => $file->isViewableImage() ? $file->getBestURI() : $nonimage_uri, 'pageURI' => $this->getImagePageURI($image, $mock), 'downloadURI' => $file->getDownloadURI(), 'historyURI' => $history_uri, 'width' => $x, 'height' => $y, 'title' => $image->getName(), 'descriptionMarkup' => $engine->getOutput($image, 'default'), 'isObsolete' => (bool) $image->getIsObsolete(), 'isImage' => $file->isViewableImage(), 'isViewable' => $file->isViewableInBrowser()); } $navsequence = array(); foreach ($mock->getImages() as $image) { $navsequence[] = $image->getID(); } $full_icon = array(javelin_tag('span', array('aural' => true), pht('View Raw File')), id(new PHUIIconView())->setIconFont('fa-file-image-o')); $download_icon = array(javelin_tag('span', array('aural' => true), pht('Download File')), id(new PHUIIconView())->setIconFont('fa-download')); $login_uri = id(new PhutilURI('/login/'))->setQueryParam('next', (string) $this->getRequestURI()); $config = array('mockID' => $mock->getID(), 'panelID' => $panel_id, 'viewportID' => $viewport_id, 'commentFormID' => $this->getCommentFormID(), 'images' => $images, 'selectedID' => $selected_id, 'loggedIn' => $this->getUser()->isLoggedIn(), 'logInLink' => (string) $login_uri, 'navsequence' => $navsequence, 'fullIcon' => hsprintf('%s', $full_icon), 'downloadIcon' => hsprintf('%s', $download_icon), 'currentSetSize' => $current_set); Javelin::initBehavior('pholio-mock-view', $config); $mockview = ''; $mock_wrapper = javelin_tag('div', array('id' => $viewport_id, 'sigil' => 'mock-viewport', 'class' => 'pholio-mock-image-viewport'), ''); $image_header = javelin_tag('div', array('id' => 'mock-image-header', 'class' => 'pholio-mock-image-header'), ''); $mock_wrapper = javelin_tag('div', array('id' => $panel_id, 'sigil' => 'mock-panel touchable', 'class' => 'pholio-mock-image-panel'), array($image_header, $mock_wrapper)); $inline_comments_holder = javelin_tag('div', array('id' => 'mock-image-description', 'sigil' => 'mock-image-description', 'class' => 'mock-image-description'), ''); $mockview[] = phutil_tag('div', array('class' => 'pholio-mock-image-container', 'id' => 'pholio-mock-image-container'), array($mock_wrapper, $inline_comments_holder)); return $mockview; }
protected function applyAssign(array $phids) { $adapter = $this->getAdapter(); $object = $adapter->getObject(); $current = array($object->getOwnerPHID()); $allowed_types = array(PhabricatorPeopleUserPHIDType::TYPECONST); $targets = $this->loadStandardTargets($phids, $allowed_types, $current); if (!$targets) { return; } $phid = head_key($targets); $xaction = $adapter->newTransaction()->setTransactionType(ManiphestTransaction::TYPE_OWNER)->setNewValue($phid); $adapter->queueTransaction($xaction); $this->logEffect(self::DO_ASSIGN, array($phid)); }
public function handleRequest(AphrontRequest $request) { $response = $this->loadDiffusionContext(); if ($response) { return $response; } $viewer = $this->getViewer(); $drequest = $this->getDiffusionRequest(); $repository = $drequest->getRepository(); $panels = DiffusionRepositoryManagementPanel::getAllPanels(); foreach ($panels as $key => $panel) { $panel->setViewer($viewer)->setRepository($repository)->setController($this); if (!$panel->shouldEnableForRepository($repository)) { unset($panels[$key]); continue; } } $selected = $request->getURIData('panel'); if (!strlen($selected)) { $selected = head_key($panels); } if (empty($panels[$selected])) { return new Aphront404Response(); } $nav = $this->renderSideNav($repository, $panels, $selected); $this->navigation = $nav; $panel = $panels[$selected]; $content = $panel->buildManagementPanelContent(); $title = array($panel->getManagementPanelLabel(), $repository->getDisplayName()); $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb($panel->getManagementPanelLabel()); $crumbs->setBorder(true); $header_text = pht('%s: %s', $repository->getDisplayName(), $panel->getManagementPanelLabel()); $header = id(new PHUIHeaderView())->setHeader($header_text)->setHeaderIcon('fa-pencil'); if ($repository->isTracked()) { $header->setStatus('fa-check', 'bluegrey', pht('Active')); } else { $header->setStatus('fa-ban', 'dark', pht('Inactive')); } $header->addActionLink(id(new PHUIButtonView())->setTag('a')->setText(pht('View Repository'))->setHref($repository->getURI())->setIcon('fa-code')); $view = id(new PHUITwoColumnView())->setHeader($header)->setNavigation($nav)->setMainColumn($content); $curtain = $panel->buildManagementPanelCurtain(); if ($curtain) { $view->setCurtain($curtain); } return $this->newPage()->setTitle($title)->setCrumbs($crumbs)->appendChild($view); }
public function processRequest() { $request = $this->getRequest(); $viewer = $request->getUser(); $colors = array('red' => pht('Verbillion'), 'orange' => pht('Navel Orange'), 'yellow' => pht('Prim Goldenrod'), 'green' => pht('Lustrous Verdant'), 'blue' => pht('Tropical Deep'), 'sky' => pht('Wide Open Sky'), 'indigo' => pht('Pleated Khaki'), 'violet' => pht('Aged Merlot'), 'charcoal' => pht('Gemstone'), 'backdrop' => pht('Driven Snow')); $manifest = PHUIIconView::getSheetManifest(PHUIIconView::SPRITE_PROJECTS); if ($request->isFormPost()) { $icon = $request->getStr('icon'); $color = $request->getStr('color'); if (isset($colors[$color]) && isset($manifest['projects-' . $icon])) { $root = dirname(phutil_get_library_root('phabricator')); $icon_file = $root . '/resources/sprite/projects_1x/' . $icon . '.png'; $icon_data = Filesystem::readFile($icon_file); $data = $this->composeImage($color, $icon_data); $file = PhabricatorFile::buildFromFileDataOrHash($data, array('name' => 'project.png', 'canCDN' => true)); $content = array('phid' => $file->getPHID()); return id(new AphrontAjaxResponse())->setContent($content); } } $value_color = head_key($colors); $value_icon = head_key($manifest); $value_icon = substr($value_icon, strlen('projects-')); require_celerity_resource('people-profile-css'); $buttons = array(); foreach ($colors as $color => $name) { $buttons[] = javelin_tag('button', array('class' => 'grey profile-image-button', 'sigil' => 'has-tooltip compose-select-color', 'style' => 'margin: 0 8px 8px 0', 'meta' => array('color' => $color, 'tip' => $name)), id(new PHUIIconView())->addClass('compose-background-' . $color)); } $icons = array(); $icon_quips = array('8ball' => pht('Take a Risk'), 'alien' => pht('Foreign Interface'), 'announce' => pht('Louder is Better'), 'art' => pht('Unique Snowflake'), 'award' => pht('Shooting Star'), 'bacon' => pht('Healthy Vegetables'), 'bandaid' => pht('Durable Infrastructure'), 'beer' => pht('Healthy Vegetable Juice'), 'bomb' => pht('Imminent Success'), 'briefcase' => pht('Adventure Pack'), 'bug' => pht('Costumed Egg'), 'calendar' => pht('Everyone Loves Meetings'), 'cloud' => pht('Water Cycle'), 'coffee' => pht('Half-Whip Nonfat Soy Latte'), 'creditcard' => pht('Expense It'), 'death' => pht('Calcium Promotes Bone Health'), 'desktop' => pht('Magical Portal'), 'dropbox' => pht('Cardboard Box'), 'education' => pht('Debt'), 'experimental' => pht('CAUTION: Dangerous Chemicals'), 'facebook' => pht('Popular Social Network'), 'facility' => pht('Pollution Solves Problems'), 'film' => pht('Actual Physical Film'), 'forked' => pht('You Can\'t Eat Soup'), 'games' => pht('Serious Business'), 'ghost' => pht('Haunted'), 'gift' => pht('Surprise!'), 'globe' => pht('Scanner Sweep'), 'golf' => pht('Business Meeting'), 'heart' => pht('Undergoing a Major Surgery'), 'intergalactic' => pht('Jupiter'), 'lock' => pht('Extremely Secret'), 'mail' => pht('Oragami'), 'martini' => pht('Healthy Olive Drink'), 'medical' => pht('Medic!'), 'mobile' => pht('Cellular Telephone'), 'music' => pht("♫"), 'news' => pht('Actual Physical Newspaper'), 'orgchart' => pht('It\'s Good to be King'), 'peoples' => pht('Angel and Devil'), 'piechart' => pht('Actual Physical Pie'), 'poison' => pht('Healthy Bone Juice'), 'putabirdonit' => pht('Put a Bird On It'), 'radiate' => pht('Radiant Beauty'), 'savings' => pht('Oink Oink'), 'search' => pht('Sleuthing'), 'shield' => pht('Royal Crest'), 'speed' => pht('Slow and Steady'), 'sprint' => pht('Fire Exit'), 'star' => pht('The More You Know'), 'storage' => pht('Stack of Pancakes'), 'tablet' => pht('Cellular Telephone For Giants'), 'travel' => pht('Pretty Clearly an Airplane'), 'twitter' => pht('Bird Stencil'), 'warning' => pht('No Caution Required, Everything Looks Safe'), 'whale' => pht('Friendly Walrus')); foreach ($manifest as $icon => $spec) { $icon = substr($icon, strlen('projects-')); $icons[] = javelin_tag('button', array('class' => 'grey profile-image-button', 'sigil' => 'has-tooltip compose-select-icon', 'style' => 'margin: 0 8px 8px 0', 'meta' => array('icon' => $icon, 'tip' => idx($icon_quips, $icon, $icon))), id(new PHUIIconView())->setSpriteIcon($icon)->setSpriteSheet(PHUIIconView::SPRITE_PROJECTS)); } $dialog_id = celerity_generate_unique_node_id(); $color_input_id = celerity_generate_unique_node_id(); $icon_input_id = celerity_generate_unique_node_id(); $preview_id = celerity_generate_unique_node_id(); $preview = id(new PHUIIconView())->setID($preview_id)->addClass('compose-background-' . $value_color)->setSpriteIcon($value_icon)->setSpriteSheet(PHUIIconView::SPRITE_PROJECTS); $color_input = javelin_tag('input', array('type' => 'hidden', 'name' => 'color', 'value' => $value_color, 'id' => $color_input_id)); $icon_input = javelin_tag('input', array('type' => 'hidden', 'name' => 'icon', 'value' => $value_icon, 'id' => $icon_input_id)); Javelin::initBehavior('phabricator-tooltips'); Javelin::initBehavior('icon-composer', array('dialogID' => $dialog_id, 'colorInputID' => $color_input_id, 'iconInputID' => $icon_input_id, 'previewID' => $preview_id, 'defaultColor' => $value_color, 'defaultIcon' => $value_icon)); $dialog = id(new AphrontDialogView())->setUser($viewer)->setFormID($dialog_id)->setClass('compose-dialog')->setTitle(pht('Compose Image'))->appendChild(phutil_tag('div', array('class' => 'compose-header'), pht('Choose Background Color')))->appendChild($buttons)->appendChild(phutil_tag('div', array('class' => 'compose-header'), pht('Choose Icon')))->appendChild($icons)->appendChild(phutil_tag('div', array('class' => 'compose-header'), pht('Preview')))->appendChild($preview)->appendChild($color_input)->appendChild($icon_input)->addCancelButton('/')->addSubmitButton(pht('Save Image')); return id(new AphrontDialogResponse())->setDialog($dialog); }
protected function discoverCommits() { $repository = $this->getRepository(); $vcs = $repository->getVersionControlSystem(); if ($vcs != PhabricatorRepositoryType::REPOSITORY_TYPE_SVN) { throw new Exception("Repository is not a svn repository."); } $uri = $this->getBaseSVNLogURI(); list($xml) = $repository->execxRemoteCommand('log --xml --quiet --limit 1 %s@HEAD', $uri); $results = $this->parseSVNLogXML($xml); $commit = head_key($results); $epoch = head($results); if ($this->isKnownCommit($commit)) { return false; } $this->discoverCommit($commit, $epoch); return true; }
public function render(AphrontRequest $request) { $user = $request->getUser(); $plugins = $this->getEnabledPlugins(); foreach ($plugins as $plugin) { $plugin->setRequest($request); $plugin->willShutdown(); } foreach ($plugins as $plugin) { $plugin->didShutdown(); } foreach ($plugins as $plugin) { $plugin->setData($plugin->generateData()); } $selected = $user->getConsoleTab(); $visible = $user->getConsoleVisible(); if (!isset($plugins[$selected])) { $selected = head_key($plugins); } $tabs = array(); foreach ($plugins as $key => $plugin) { $tabs[$key] = array('name' => $plugin->getName(), 'panel' => $plugin->render()); } $tabs_markup = array(); $panel_markup = array(); foreach ($tabs as $key => $data) { $is_selected = $key == $selected; if ($is_selected) { $style = null; $tabclass = 'dark-console-tab-selected'; } else { $style = 'display: none;'; $tabclass = null; } $tabs_markup[] = javelin_render_tag('a', array('class' => "dark-console-tab {$tabclass}", 'sigil' => 'dark-console-tab', 'id' => 'dark-console-tab-' . $key), (string) $data['name']); $panel_markup[] = javelin_render_tag('div', array('class' => 'dark-console-panel dark-console-panel-' . $key, 'style' => $style, 'sigil' => 'dark-console-panel'), (string) $data['panel']); } $console = javelin_render_tag('table', array('class' => 'dark-console', 'sigil' => 'dark-console', 'style' => $visible ? '' : 'display: none;'), '<tr>' . '<th class="dark-console-tabs">' . implode("\n", $tabs_markup) . '</th>' . '<td>' . implode("\n", $panel_markup) . '</td>' . '</tr>'); if (!empty($_COOKIE['phsid'])) { $console = str_replace($_COOKIE['phsid'], phutil_escape_html('<session-key>'), $console); } return "\n\n\n\n" . $console . "\n\n\n\n"; }
protected final function newCustomEditField($object) { $setting_key = $this->getSettingKey(); $default_value = $object->getDefaultValue($setting_key); $options = $this->getSelectOptionGroups(); $map = $this->getSelectOptionMap(); if (isset($map[$default_value])) { $default_label = pht('Default (%s)', $map[$default_value]); } else { $default_label = pht('Default (Unknown, "%s")', $default_value); } $head_key = head_key($options); $options[$head_key]['options'] = array('' => $default_label) + $options[$head_key]['options']; $flat_options = array(); foreach ($options as $group) { $flat_options[$group['label']] = $group['options']; } return $this->newEditField($object, new PhabricatorSelectEditField())->setOptions($flat_options); }
public function markupText($text, $children) { $lines = explode("\n", $text); $first_key = head_key($lines); $last_key = last_key($lines); while (trim($lines[$last_key]) === '') { unset($lines[$last_key]); $last_key = last_key($lines); } $matches = null; preg_match(self::START_BLOCK_PATTERN, head($lines), $matches); $argv = array(); if (isset($matches[2])) { $argv = id(new PhutilSimpleOptions())->parse($matches[2]); } $interpreters = id(new PhutilSymbolLoader())->setAncestorClass('PhutilRemarkupBlockInterpreter')->loadObjects(); foreach ($interpreters as $interpreter) { $interpreter->setEngine($this->getEngine()); } $lines[$first_key] = preg_replace(self::START_BLOCK_PATTERN, '', $lines[$first_key]); $lines[$last_key] = preg_replace(self::END_BLOCK_PATTERN, '', $lines[$last_key]); if (trim($lines[$first_key]) === '') { unset($lines[$first_key]); } if (trim($lines[$last_key]) === '') { unset($lines[$last_key]); } $content = implode("\n", $lines); $interpreters = mpull($interpreters, null, 'getInterpreterName'); if (isset($interpreters[$matches[1]])) { return $interpreters[$matches[1]]->markupContent($content, $argv); } $message = pht('No interpreter found: %s', $matches[1]); if ($this->getEngine()->isTextMode()) { return '(' . $message . ')'; } return phutil_tag('div', array('class' => 'remarkup-interpreter-error'), $message); }
protected function applyAssign(array $phids) { $adapter = $this->getAdapter(); $object = $adapter->getObject(); $current = array($object->getOwnerPHID()); $allowed_types = array(PhabricatorPeopleUserPHIDType::TYPECONST); if (head($phids) == PhabricatorPeopleNoOwnerDatasource::FUNCTION_TOKEN) { $phid = null; if ($object->getOwnerPHID() == null) { $this->logEffect(self::DO_STANDARD_NO_EFFECT); return; } } else { $targets = $this->loadStandardTargets($phids, $allowed_types, $current); if (!$targets) { return; } $phid = head_key($targets); } $xaction = $adapter->newTransaction()->setTransactionType(ManiphestTransaction::TYPE_OWNER)->setNewValue($phid); $adapter->queueTransaction($xaction); $this->logEffect(self::DO_ASSIGN, array($phid)); }
/** * Get diff parts, but replace large blocks of unchanged text with "." * parts representing missing context. */ public function getSummaryParts() { $parts = $this->getParts(); $head_key = head_key($parts); $last_key = last_key($parts); $results = array(); foreach ($parts as $key => $part) { $is_head = $key == $head_key; $is_last = $key == $last_key; switch ($part['type']) { case '=': $pieces = $this->splitTextForSummary($part['text']); if ($is_head || $is_last) { $need = 2; } else { $need = 3; } // We don't have enough pieces to omit anything, so just continue. if (count($pieces) < $need) { $results[] = $part; break; } if (!$is_head) { $results[] = array('type' => '=', 'text' => head($pieces)); } $results[] = array('type' => '.', 'text' => null); if (!$is_last) { $results[] = array('type' => '=', 'text' => last($pieces)); } break; default: $results[] = $part; break; } } return $results; }
public function processRequest() { $request = $this->getRequest(); $methods = $this->getAllMethods(); if (empty($methods[$this->method])) { $this->method = head_key($methods); } $this->setFilter('method/' . $this->method); $method_class = $methods[$this->method]; PhutilSymbolLoader::loadClass($method_class); $method_object = newv($method_class, array()); $error_description = array(); $error_types = $method_object->defineErrorTypes(); if ($error_types) { $error_description[] = '<ul>'; foreach ($error_types as $error => $meaning) { $error_description[] = '<li>' . '<strong>' . phutil_escape_html($error) . ':</strong> ' . phutil_escape_html($meaning) . '</li>'; } $error_description[] = '</ul>'; $error_description = implode("\n", $error_description); } else { $error_description = "This method does not raise any specific errors."; } $form = new AphrontFormView(); $form->setUser($request->getUser())->setAction('/api/' . $this->method)->appendChild(id(new AphrontFormStaticControl())->setLabel('Description')->setValue($method_object->getMethodDescription()))->appendChild(id(new AphrontFormStaticControl())->setLabel('Returns')->setValue($method_object->defineReturnType()))->appendChild(id(new AphrontFormMarkupControl())->setLabel('Errors')->setValue($error_description))->appendChild('<p class="aphront-form-instructions">Enter parameters using ' . '<strong>JSON</strong>. For instance, to enter a list, type: ' . '<tt>["apple", "banana", "cherry"]</tt>'); $params = $method_object->defineParamTypes(); foreach ($params as $param => $desc) { $form->appendChild(id(new AphrontFormTextControl())->setLabel($param)->setName("params[{$param}]")->setCaption(phutil_escape_html($desc))); } $form->appendChild(id(new AphrontFormSelectControl())->setLabel('Output Format')->setName('output')->setOptions(array('human' => 'Human Readable', 'json' => 'JSON')))->appendChild(id(new AphrontFormSubmitControl())->setValue('Call Method')); $panel = new AphrontPanelView(); $panel->setHeader('Conduit API: ' . phutil_escape_html($this->method)); $panel->appendChild($form); $panel->setWidth(AphrontPanelView::WIDTH_FULL); return $this->buildStandardPageResponse(array($panel), array('title' => 'Conduit Console')); }
/** * Executes the saved query. * * @param PhabricatorSavedQuery The saved query to operate on. * @return The result of the query. */ public function buildQueryFromSavedQuery(PhabricatorSavedQuery $original) { $saved = clone $original; $this->willUseSavedQuery($saved); $fields = $this->buildSearchFields(); $viewer = $this->requireViewer(); $map = array(); foreach ($fields as $field) { $field->setViewer($viewer); $field->readValueFromSavedQuery($saved); $value = $field->getValueForQuery($field->getValue()); $map[$field->getKey()] = $value; } $original->attachParameterMap($map); $query = $this->buildQueryFromParameters($map); $object = $this->newResultObject(); if (!$object) { return $query; } $extensions = $this->getEngineExtensions(); foreach ($extensions as $extension) { $extension->applyConstraintsToQuery($object, $query, $saved, $map); } $order = $saved->getParameter('order'); $builtin = $query->getBuiltinOrderAliasMap(); if (strlen($order) && isset($builtin[$order])) { $query->setOrder($order); } else { // If the order is invalid or not available, we choose the first // builtin order. This isn't always the default order for the query, // but is the first value in the "Order" dropdown, and makes the query // behavior more consistent with the UI. In queries where the two // orders differ, this order is the preferred order for humans. $query->setOrder(head_key($builtin)); } return $query; }
public function testHeadKeyLastKey() { $this->assertEquals('a', head_key(['a' => 0, 'b' => 1])); $this->assertEquals('b', last_key(['a' => 0, 'b' => 1])); $this->assertEquals(null, head_key([])); $this->assertEquals(null, last_key([])); }
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; }
private function processSearchRequest() { $parent = $this->getDelegatingController(); $request = $this->getRequest(); $user = $request->getUser(); $engine = $this->getSearchEngine(); $nav = $this->getNavigation(); if (!$nav) { $nav = $this->buildNavigation(); } if ($request->isFormPost()) { $saved_query = $engine->buildSavedQueryFromRequest($request); $engine->saveQuery($saved_query); return id(new AphrontRedirectResponse())->setURI($engine->getQueryResultsPageURI($saved_query->getQueryKey()) . '#R'); } $named_query = null; $run_query = true; $query_key = $this->queryKey; if ($this->queryKey == 'advanced') { $run_query = false; $query_key = $request->getStr('query'); } else { if (!strlen($this->queryKey)) { $found_query_data = false; if ($request->isHTTPGet() || $request->isQuicksand()) { // If this is a GET request and it has some query data, don't // do anything unless it's only before= or after=. We'll build and // execute a query from it below. This allows external tools to build // URIs like "/query/?users=a,b". $pt_data = $request->getPassthroughRequestData(); $exempt = array('before' => true, 'after' => true, 'nux' => true); foreach ($pt_data as $pt_key => $pt_value) { if (isset($exempt[$pt_key])) { continue; } $found_query_data = true; break; } } if (!$found_query_data) { // Otherwise, there's no query data so just run the user's default // query for this application. $query_key = head_key($engine->loadEnabledNamedQueries()); } } } if ($engine->isBuiltinQuery($query_key)) { $saved_query = $engine->buildSavedQueryFromBuiltin($query_key); $named_query = idx($engine->loadEnabledNamedQueries(), $query_key); } else { if ($query_key) { $saved_query = id(new PhabricatorSavedQueryQuery())->setViewer($user)->withQueryKeys(array($query_key))->executeOne(); if (!$saved_query) { return new Aphront404Response(); } $named_query = idx($engine->loadEnabledNamedQueries(), $query_key); } else { $saved_query = $engine->buildSavedQueryFromRequest($request); // Save the query to generate a query key, so "Save Custom Query..." and // other features like Maniphest's "Export..." work correctly. $engine->saveQuery($saved_query); } } $nav->selectFilter('query/' . $saved_query->getQueryKey(), 'query/advanced'); $form = id(new AphrontFormView())->setUser($user)->setAction($request->getPath()); $engine->buildSearchForm($form, $saved_query); $errors = $engine->getErrors(); if ($errors) { $run_query = false; } $submit = id(new AphrontFormSubmitControl())->setValue(pht('Execute Query')); if ($run_query && !$named_query && $user->isLoggedIn()) { $submit->addCancelButton('/search/edit/' . $saved_query->getQueryKey() . '/', pht('Save Custom Query...')); } // TODO: A "Create Dashboard Panel" action goes here somewhere once // we sort out T5307. $form->appendChild($submit); $body = array(); if ($this->getPreface()) { $body[] = $this->getPreface(); } if ($named_query) { $title = $named_query->getQueryName(); } else { $title = pht('Advanced Search'); } $header = id(new PHUIHeaderView())->setHeader($title); $box = id(new PHUIObjectBoxView())->setHeader($header); if ($run_query || $named_query) { $box->setShowHide(pht('Edit Query'), pht('Hide Query'), $form, $this->getApplicationURI('query/advanced/?query=' . $query_key), !$named_query ? true : false); } else { $box->setForm($form); } $body[] = $box; if ($run_query) { $box->setAnchor(id(new PhabricatorAnchorView())->setAnchorName('R')); try { $engine->setRequest($request); $query = $engine->buildQueryFromSavedQuery($saved_query); $pager = $engine->newPagerForSavedQuery($saved_query); $pager->readFromRequest($request); $objects = $engine->executeQuery($query, $pager); $force_nux = $request->getBool('nux'); if (!$objects || $force_nux) { $nux_view = $this->renderNewUserView($engine, $force_nux); } else { $nux_view = null; } if ($nux_view) { $box->appendChild($nux_view); } else { $list = $engine->renderResults($objects, $saved_query); if (!$list instanceof PhabricatorApplicationSearchResultView) { throw new Exception(pht('SearchEngines must render a "%s" object, but this engine ' . '(of class "%s") rendered something else.', 'PhabricatorApplicationSearchResultView', get_class($engine))); } if ($list->getActions()) { foreach ($list->getActions() as $action) { $header->addActionLink($action); } } if ($list->getObjectList()) { $box->setObjectList($list->getObjectList()); } if ($list->getTable()) { $box->setTable($list->getTable()); } if ($list->getInfoView()) { $box->setInfoView($list->getInfoView()); } if ($list->getContent()) { $box->appendChild($list->getContent()); } if ($list->getCollapsed()) { $box->setCollapsed(true); } if ($pager->willShowPagingControls()) { $pager_box = id(new PHUIBoxView())->addPadding(PHUI::PADDING_MEDIUM)->addMargin(PHUI::MARGIN_LARGE)->setBorder(true)->appendChild($pager); $body[] = $pager_box; } } } catch (PhabricatorTypeaheadInvalidTokenException $ex) { $errors[] = pht('This query specifies an invalid parameter. Review the ' . 'query parameters and correct errors.'); } } if ($errors) { $box->setFormErrors($errors, pht('Query Errors')); } $crumbs = $parent->buildApplicationCrumbs()->addTextCrumb($title); return $this->newPage()->setApplicationMenu($this->buildApplicationMenu())->setTitle(pht('Query: %s', $title))->setCrumbs($crumbs)->setNavigation($nav)->appendChild($body); }
private function attachToRevision(DifferentialRevision $revision, $actor_phid) { $drequest = DiffusionRequest::newFromDictionary(array('repository' => $this->repository, 'commit' => $this->commit->getCommitIdentifier())); $raw_diff = DiffusionRawDiffQuery::newFromDiffusionRequest($drequest)->loadRawDiff(); $changes = id(new ArcanistDiffParser())->parseDiff($raw_diff); $diff = DifferentialDiff::newFromRawChanges($changes)->setRevisionID($revision->getID())->setAuthorPHID($actor_phid)->setCreationMethod('commit')->setSourceControlSystem($this->repository->getVersionControlSystem())->setLintStatus(DifferentialLintStatus::LINT_SKIP)->setUnitStatus(DifferentialUnitStatus::UNIT_SKIP)->setDateCreated($this->commit->getEpoch())->setDescription('Commit r' . $this->repository->getCallsign() . $this->commit->getCommitIdentifier()); // TODO: This is not correct in SVN where one repository can have multiple // Arcanist projects. $arcanist_project = id(new PhabricatorRepositoryArcanistProject())->loadOneWhere('repositoryID = %d LIMIT 1', $this->repository->getID()); if ($arcanist_project) { $diff->setArcanistProjectPHID($arcanist_project->getPHID()); } $parents = DiffusionCommitParentsQuery::newFromDiffusionRequest($drequest)->loadParents(); if ($parents) { $diff->setSourceControlBaseRevision(head_key($parents)); } // TODO: Attach binary files. $revision->setLineCount($diff->getLineCount()); return $diff->save(); }
public function activateLease(DrydockBlueprint $blueprint, DrydockResource $resource, DrydockLease $lease) { $host_lease = $this->loadHostLease($resource); $command_type = DrydockCommandInterface::INTERFACE_TYPE; $interface = $host_lease->getInterface($command_type); $map = $lease->getAttribute('repositories.map'); $root = $resource->getAttribute('workingcopy.root'); $default = null; foreach ($map as $directory => $spec) { $cmd = array(); $arg = array(); $cmd[] = 'cd %s'; $arg[] = "{$root}/repo/{$directory}/"; $cmd[] = 'git clean -d --force'; $cmd[] = 'git fetch'; $commit = idx($spec, 'commit'); $branch = idx($spec, 'branch'); $ref = idx($spec, 'ref'); if ($commit !== null) { $cmd[] = 'git reset --hard %s'; $arg[] = $commit; } else { if ($branch !== null) { $cmd[] = 'git checkout %s'; $arg[] = $branch; $cmd[] = 'git reset --hard origin/%s'; $arg[] = $branch; } else { if ($ref) { $ref_uri = $ref['uri']; $ref_ref = $ref['ref']; $cmd[] = 'git fetch --no-tags -- %s +%s:%s'; $arg[] = $ref_uri; $arg[] = $ref_ref; $arg[] = $ref_ref; $cmd[] = 'git checkout %s'; $arg[] = $ref_ref; $cmd[] = 'git reset --hard %s'; $arg[] = $ref_ref; } else { $cmd[] = 'git reset --hard HEAD'; } } } $cmd = implode(' && ', $cmd); $argv = array_merge(array($cmd), $arg); $result = call_user_func_array(array($interface, 'execx'), $argv); if (idx($spec, 'default')) { $default = $directory; } } if ($default === null) { $default = head_key($map); } // TODO: Use working storage? $lease->setAttribute('workingcopy.default', "{$root}/repo/{$default}/"); $lease->activateOnResource($resource); }
public function processRequest() { $request = $this->getRequest(); $uri = $request->getStr('uri'); $id = $request->getStr('id'); $repositories = id(new PhabricatorRepository())->loadAll(); if ($uri) { $uri_path = id(new PhutilURI($uri))->getPath(); $matches = array(); // Try to figure out which tracked repository this external lives in by // comparing repository metadata. We look for an exact match, but accept // a partial match. foreach ($repositories as $key => $repository) { $remote_uri = new PhutilURI($repository->getRemoteURI()); if ($remote_uri->getPath() == $uri_path) { $matches[$key] = 1; } if ($repository->getPublicRemoteURI() == $uri) { $matches[$key] = 2; } if ($repository->getRemoteURI() == $uri) { $matches[$key] = 3; } } arsort($matches); $best_match = head_key($matches); if ($best_match) { $repository = $repositories[$best_match]; $redirect = DiffusionRequest::generateDiffusionURI(array('action' => 'browse', 'callsign' => $repository->getCallsign(), 'branch' => $repository->getDefaultBranch(), 'commit' => $id)); return id(new AphrontRedirectResponse())->setURI($redirect); } } // TODO: This is a rare query but does a table scan, add a key? $commits = id(new PhabricatorRepositoryCommit())->loadAllWhere('commitIdentifier = %s', $id); if (empty($commits)) { $desc = null; if ($uri) { $desc = phutil_escape_html($uri) . ', at '; } $desc .= phutil_escape_html($id); $content = id(new AphrontErrorView())->setTitle('Unknown External')->setSeverity(AphrontErrorView::SEVERITY_WARNING)->appendChild("<p>This external ({$desc}) does not appear in any tracked " . "repository. It may exist in an untracked repository that " . "Diffusion does not know about.</p>"); } else { if (count($commits) == 1) { $commit = head($commits); $repo = $repositories[$commit->getRepositoryID()]; $redirect = DiffusionRequest::generateDiffusionURI(array('action' => 'browse', 'callsign' => $repo->getCallsign(), 'branch' => $repo->getDefaultBranch(), 'commit' => $commit->getCommitIdentifier())); return id(new AphrontRedirectResponse())->setURI($redirect); } else { $rows = array(); foreach ($commits as $commit) { $repo = $repositories[$commit->getRepositoryID()]; $href = DiffusionRequest::generateDiffusionURI(array('action' => 'browse', 'callsign' => $repo->getCallsign(), 'branch' => $repo->getDefaultBranch(), 'commit' => $commit->getCommitIdentifier())); $rows[] = array(phutil_render_tag('a', array('href' => $href), phutil_escape_html('r' . $repo->getCallsign() . $commit->getCommitIdentifier())), phutil_escape_html($commit->loadCommitData()->getSummary())); } $table = new AphrontTableView($rows); $table->setHeaders(array('Commit', 'Description')); $table->setColumnClasses(array('pri', 'wide')); $content = new AphrontPanelView(); $content->setHeader('Multiple Matching Commits'); $content->setCaption('This external reference matches multiple known commits.'); $content->appendChild($table); } } return $this->buildStandardPageResponse($content, array('title' => 'Unresolvable External')); }
public function handleRequest(AphrontRequest $request) { $uri = $request->getStr('uri'); $id = $request->getStr('id'); $repositories = id(new PhabricatorRepositoryQuery())->setViewer($request->getUser())->execute(); if ($uri) { $uri_path = id(new PhutilURI($uri))->getPath(); $matches = array(); // Try to figure out which tracked repository this external lives in by // comparing repository metadata. We look for an exact match, but accept // a partial match. foreach ($repositories as $key => $repository) { $remote_uri = new PhutilURI($repository->getRemoteURI()); if ($remote_uri->getPath() == $uri_path) { $matches[$key] = 1; } if ($repository->getPublicCloneURI() == $uri) { $matches[$key] = 2; } if ($repository->getRemoteURI() == $uri) { $matches[$key] = 3; } } arsort($matches); $best_match = head_key($matches); if ($best_match) { $repository = $repositories[$best_match]; $redirect = $repository->generateURI(array('action' => 'browse', 'branch' => $repository->getDefaultBranch(), 'commit' => $id)); return id(new AphrontRedirectResponse())->setURI($redirect); } } // TODO: This is a rare query but does a table scan, add a key? $commits = id(new PhabricatorRepositoryCommit())->loadAllWhere('commitIdentifier = %s', $id); if (empty($commits)) { $desc = null; if (strlen($uri)) { $desc = pht('"%s", at "%s"', $uri, $id); } else { $desc = pht('"%s"', $id); } $content = id(new PHUIInfoView())->setTitle(pht('Unknown External'))->setSeverity(PHUIInfoView::SEVERITY_WARNING)->appendChild(phutil_tag('p', array(), pht('This external (%s) does not appear in any tracked ' . 'repository. It may exist in an untracked repository that ' . 'Diffusion does not know about.', $desc))); } else { if (count($commits) == 1) { $commit = head($commits); $repo = $repositories[$commit->getRepositoryID()]; $redirect = $repo->generateURI(array('action' => 'browse', 'branch' => $repo->getDefaultBranch(), 'commit' => $commit->getCommitIdentifier())); return id(new AphrontRedirectResponse())->setURI($redirect); } else { $rows = array(); foreach ($commits as $commit) { $repo = $repositories[$commit->getRepositoryID()]; $href = $repo->generateURI(array('action' => 'browse', 'branch' => $repo->getDefaultBranch(), 'commit' => $commit->getCommitIdentifier())); $rows[] = array(phutil_tag('a', array('href' => $href), $commit->getURI()), $commit->loadCommitData()->getSummary()); } $table = new AphrontTableView($rows); $table->setHeaders(array(pht('Commit'), pht('Description'))); $table->setColumnClasses(array('pri', 'wide')); $caption = id(new PHUIInfoView())->setSeverity(PHUIInfoView::SEVERITY_NOTICE)->appendChild(pht('This external reference matches multiple known commits.')); $content = new PHUIObjectBoxView(); $content->setHeaderText(pht('Multiple Matching Commits')); $content->setInfoView($caption); $content->setTable($table); } } $crumbs = $this->buildApplicationCrumbs(); $crumbs->addTextCrumb(pht('External')); return $this->newPage()->setTitle(pht('Unresolvable External'))->setCrumbs($crumbs)->appendChild($content); }