コード例 #1
0
 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.");
     }
 }
コード例 #2
0
 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;
 }
コード例 #3
0
 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;
 }
コード例 #4
0
 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;
 }
コード例 #5
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()));
 }
コード例 #7
0
 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()));
 }
コード例 #8
0
 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'));
 }
コード例 #9
0
 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));
 }
コード例 #10
0
 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";
 }
コード例 #11
0
 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);
 }
コード例 #12
0
 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;
 }
コード例 #13
0
 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);
 }
コード例 #15
0
 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;
 }
コード例 #17
0
 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";
 }
コード例 #18
0
 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);
 }
コード例 #19
0
 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);
 }
コード例 #20
0
 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));
 }
コード例 #21
0
 /**
  * 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;
 }
コード例 #22
0
 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'));
 }
コード例 #23
0
 /**
  * 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;
 }
コード例 #24
0
ファイル: PhutilTest.php プロジェクト: PaulAntunes/gclf-paul
 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([]));
 }
コード例 #25
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;
 }
コード例 #26
0
 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);
 }
コード例 #29
0
 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'));
 }
コード例 #30
0
 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);
 }